/******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};

/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {

/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId])
/******/ 			return installedModules[moduleId].exports;

/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};

/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

/******/ 		// Flag the module as loaded
/******/ 		module.l = true;

/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}


/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;

/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;

/******/ 	// identity function for calling harmony imports with the correct context
/******/ 	__webpack_require__.i = function(value) { return value; };

/******/ 	// define getter function for harmony exports
/******/ 	__webpack_require__.d = function(exports, name, getter) {
/******/ 		if(!__webpack_require__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, {
/******/ 				configurable: false,
/******/ 				enumerable: true,
/******/ 				get: getter
/******/ 			});
/******/ 		}
/******/ 	};

/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__webpack_require__.n = function(module) {
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() { return module['default']; } :
/******/ 			function getModuleExports() { return module; };
/******/ 		__webpack_require__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};

/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };

/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";

/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = 87);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {

var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! jQuery v3.0.0 | (c) jQuery Foundation | jquery.org/license */
!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.0.0",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:f.call(this)},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:h,sort:c.sort,splice:c.splice},r.extend=r.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||r.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(r.isPlainObject(d)||(e=r.isArray(d)))?(e?(e=!1,f=c&&r.isArray(c)?c:[]):f=c&&r.isPlainObject(c)?c:{},g[b]=r.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},r.extend({expando:"jQuery"+(q+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===r.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=r.type(a);return("number"===b||"string"===b)&&!isNaN(a-parseFloat(a))},isPlainObject:function(a){var b,c;return a&&"[object Object]"===k.call(a)?(b=e(a))?(c=l.call(b,"constructor")&&b.constructor,"function"==typeof c&&m.call(c)===n):!0:!1},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?j[k.call(a)]||"object":typeof a},globalEval:function(a){p(a)},camelCase:function(a){return a.replace(t,"ms-").replace(u,v)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(w(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(s,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(w(Object(a))?r.merge(c,"string"==typeof a?[a]:a):h.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:i.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,f=0,h=[];if(w(a))for(d=a.length;d>f;f++)e=b(a[f],f,c),null!=e&&h.push(e);else for(f in a)e=b(a[f],f,c),null!=e&&h.push(e);return g.apply([],h)},guid:1,proxy:function(a,b){var c,d,e;return"string"==typeof b&&(c=a[b],b=a,a=c),r.isFunction(a)?(d=f.call(arguments,2),e=function(){return a.apply(b||this,d.concat(f.call(arguments)))},e.guid=a.guid=a.guid||r.guid++,e):void 0},now:Date.now,support:o}),"function"==typeof Symbol&&(r.fn[Symbol.iterator]=c[Symbol.iterator]),r.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){j["[object "+b+"]"]=b.toLowerCase()});function w(a){var b=!!a&&"length"in a&&a.length,c=r.type(a);return"function"===c||r.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\x00-\\xa0])+",M="\\["+K+"*("+L+")(?:"+K+"*([*^$|!~]?=)"+K+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+L+"))|)"+K+"*\\]",N=":("+L+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+M+")*)|.*)\\)|)",O=new RegExp(K+"+","g"),P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g,ca=function(a,b){return b?"\x00"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"label"in b&&b.disabled===a||"form"in b&&b.disabled===a||"form"in b&&b.disabled===!1&&(b.isDisabled===a||b.isDisabled!==!a&&("label"in b||!ea(b))!==a)}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\r\\' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[0>c?c+b:c]}),even:pa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:pa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:pa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function ra(){}ra.prototype=d.filters=d.pseudos,d.setFilters=new ra,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=Q.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P," ")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function sa(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function ta(a,b,c){var d=b.dir,e=b.next,f=e||d,g=c&&"parentNode"===f,h=x++;return b.first?function(b,c,e){while(b=b[d])if(1===b.nodeType||g)return a(b,c,e)}:function(b,c,i){var j,k,l,m=[w,h];if(i){while(b=b[d])if((1===b.nodeType||g)&&a(b,c,i))return!0}else while(b=b[d])if(1===b.nodeType||g)if(l=b[u]||(b[u]={}),k=l[b.uniqueID]||(l[b.uniqueID]={}),e&&e===b.nodeName.toLowerCase())b=b[d]||b;else{if((j=k[f])&&j[0]===w&&j[1]===h)return m[2]=j[2];if(k[f]=m,m[2]=a(b,c,i))return!0}}}function ua(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function wa(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function xa(a,b,c,d,e,f){return d&&!d[u]&&(d=xa(d)),e&&!e[u]&&(e=xa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||va(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:wa(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=wa(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ta(ua(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return xa(i>1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,e>i&&ya(a.slice(i,e)),f>e&&ya(a=a.slice(e)),f>e&&sa(a))}m.push(c)}return ua(m)}function za(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(_,aa),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=V.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(_,aa),$.test(j[0].type)&&qa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&sa(j),!a)return G.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||$.test(a)&&qa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext,B=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,C=/^.[^:#\[\.,]*$/;function D(a,b,c){if(r.isFunction(b))return r.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return r.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(C.test(b))return r.filter(b,a,c);b=r.filter(b,a)}return r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType})}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;d>b;b++)if(r.contains(e[b],this))return!0}));for(c=this.pushStack([]),b=0;d>b;b++)r.find(a,e[b],c);return d>1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(D(this,a||[],!1))},not:function(a){return this.pushStack(D(this,a||[],!0))},is:function(a){return!!D(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var E,F=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,G=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||E,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:F.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),B.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};G.prototype=r.fn,E=r(d);var H=/^(?:parents|prev(?:Until|All))/,I={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(r.contains(this,b[a]))return!0})},closest:function(a,b){var c,d=0,e=this.length,f=[],g="string"!=typeof a&&r(a);if(!A.test(a))for(;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function J(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return J(a,"nextSibling")},prev:function(a){return J(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return a.contentDocument||r.merge([],a.childNodes)}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(I[a]||r.uniqueSort(e),H.test(a)&&e.reverse()),this.pushStack(e)}});var K=/\S+/g;function L(a){var b={};return r.each(a.match(K)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?L(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:"")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){r.each(b,function(b,c){r.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&"string"!==r.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return r.each(arguments,function(a,b){var c;while((c=r.inArray(b,f,c))>-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function M(a){return a}function N(a){throw a}function O(a,b,c){var d;try{a&&r.isFunction(d=a.promise)?d.call(a).done(b).fail(c):a&&r.isFunction(d=a.then)?d.call(a,b,c):b.call(void 0,a)}catch(a){c.call(void 0,a)}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(f>b)){if(a=d.apply(h,i),a===c.promise())throw new TypeError("Thenable self-resolution");j=a&&("object"==typeof a||"function"==typeof a)&&a.then,r.isFunction(j)?e?j.call(a,g(f,c,M,e),g(f,c,N,e)):(f++,j.call(a,g(f,c,M,e),g(f,c,N,e),g(f,c,M,c.notifyWith))):(d!==M&&(h=void 0,i=[a]),(e||c.resolveWith)(h,i))}},k=e?j:function(){try{j()}catch(a){r.Deferred.exceptionHook&&r.Deferred.exceptionHook(a,k.stackTrace),b+1>=f&&(d!==N&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:M,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:M)),c[2][3].add(g(0,a,r.isFunction(d)?d:N))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(1>=b&&(O(a,g.done(h(c)).resolve,g.reject),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)O(e[c],h(c),g.reject);return g.promise()}});var P=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&P.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)};var Q=r.Deferred();r.fn.ready=function(a){return Q.then(a),this},r.extend({isReady:!1,readyWait:1,holdReady:function(a){a?r.readyWait++:r.ready(!0)},ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||Q.resolveWith(d,[r]))}}),r.ready.then=Q.then;function R(){d.removeEventListener("DOMContentLoaded",R),a.removeEventListener("load",R),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",R),a.addEventListener("load",R));var S=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)S(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){
return j.call(r(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},T=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function U(){this.expando=r.expando+U.uid++}U.uid=1,U.prototype={cache:function(a){var b=a[this.expando];return b||(b={},T(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[r.camelCase(b)]=c;else for(d in b)e[r.camelCase(d)]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][r.camelCase(b)]},access:function(a,b,c){return void 0===b||b&&"string"==typeof b&&void 0===c?this.get(a,b):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d=a[this.expando];if(void 0!==d){if(void 0!==b){r.isArray(b)?b=b.map(r.camelCase):(b=r.camelCase(b),b=b in d?[b]:b.match(K)||[]),c=b.length;while(c--)delete d[b[c]]}(void 0===b||r.isEmptyObject(d))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!r.isEmptyObject(b)}};var V=new U,W=new U,X=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Y=/[A-Z]/g;function Z(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Y,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:X.test(c)?JSON.parse(c):c}catch(e){}W.set(a,b,c)}else c=void 0;return c}r.extend({hasData:function(a){return W.hasData(a)||V.hasData(a)},data:function(a,b,c){return W.access(a,b,c)},removeData:function(a,b){W.remove(a,b)},_data:function(a,b,c){return V.access(a,b,c)},_removeData:function(a,b){V.remove(a,b)}}),r.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=W.get(f),1===f.nodeType&&!V.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=r.camelCase(d.slice(5)),Z(f,d,e[d])));V.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){W.set(this,a)}):S(this,function(b){var c;if(f&&void 0===b){if(c=W.get(f,a),void 0!==c)return c;if(c=Z(f,a),void 0!==c)return c}else this.each(function(){W.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){W.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=V.get(a,b),c&&(!d||r.isArray(c)?d=V.access(a,b,r.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return V.get(a,c)||V.access(a,c,{empty:r.Callbacks("once memory").add(function(){V.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?r.queue(this[0],a):void 0===b?this:this.each(function(){var c=r.queue(this,a,b);r._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&r.dequeue(this,a)})},dequeue:function(a){return this.each(function(){r.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=r.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=V.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var $=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,_=new RegExp("^(?:([+-])=|)("+$+")([a-z%]*)$","i"),aa=["Top","Right","Bottom","Left"],ba=function(a,b){return a=b||a,"none"===a.style.display||""===a.style.display&&r.contains(a.ownerDocument,a)&&"none"===r.css(a,"display")},ca=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};function da(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return r.css(a,b,"")},i=h(),j=c&&c[3]||(r.cssNumber[b]?"":"px"),k=(r.cssNumber[b]||"px"!==j&&+i)&&_.exec(r.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,r.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var ea={};function fa(a){var b,c=a.ownerDocument,d=a.nodeName,e=ea[d];return e?e:(b=c.body.appendChild(c.createElement(d)),e=r.css(b,"display"),b.parentNode.removeChild(b),"none"===e&&(e="block"),ea[d]=e,e)}function ga(a,b){for(var c,d,e=[],f=0,g=a.length;g>f;f++)d=a[f],d.style&&(c=d.style.display,b?("none"===c&&(e[f]=V.get(d,"display")||null,e[f]||(d.style.display="")),""===d.style.display&&ba(d)&&(e[f]=fa(d))):"none"!==c&&(e[f]="none",V.set(d,"display",c)));for(f=0;g>f;f++)null!=e[f]&&(a[f].style.display=e[f]);return a}r.fn.extend({show:function(){return ga(this,!0)},hide:function(){return ga(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){ba(this)?r(this).show():r(this).hide()})}});var ha=/^(?:checkbox|radio)$/i,ia=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,ja=/^$|\/(?:java|ecma)script/i,ka={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ka.optgroup=ka.option,ka.tbody=ka.tfoot=ka.colgroup=ka.caption=ka.thead,ka.th=ka.td;function la(a,b){var c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&r.nodeName(a,b)?r.merge([a],c):c}function ma(a,b){for(var c=0,d=a.length;d>c;c++)V.set(a[c],"globalEval",!b||V.get(b[c],"globalEval"))}var na=/<|&#?\w+;/;function oa(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],n=0,o=a.length;o>n;n++)if(f=a[n],f||0===f)if("object"===r.type(f))r.merge(m,f.nodeType?[f]:f);else if(na.test(f)){g=g||l.appendChild(b.createElement("div")),h=(ia.exec(f)||["",""])[1].toLowerCase(),i=ka[h]||ka._default,g.innerHTML=i[1]+r.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;r.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",n=0;while(f=m[n++])if(d&&r.inArray(f,d)>-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=la(l.appendChild(f),"script"),j&&ma(g),c){k=0;while(f=g[k++])ja.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var pa=d.documentElement,qa=/^key/,ra=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,sa=/^([^.]*)(?:\.(.+)|)/;function ta(){return!0}function ua(){return!1}function va(){try{return d.activeElement}catch(a){}}function wa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)wa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=ua;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(pa,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(K)||[""],j=b.length;while(j--)h=sa.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.hasData(a)&&V.get(a);if(q&&(i=q.events)){b=(b||"").match(K)||[""],j=b.length;while(j--)if(h=sa.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&V.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(V.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c<arguments.length;c++)i[c]=arguments[c];if(b.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,b)!==!1){h=r.event.handlers.call(this,b,j),c=0;while((f=h[c++])&&!b.isPropagationStopped()){b.currentTarget=f.elem,d=0;while((g=f.handlers[d++])&&!b.isImmediatePropagationStopped())b.rnamespace&&!b.rnamespace.test(g.namespace)||(b.handleObj=g,b.data=g.data,e=((r.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(b.result=e)===!1&&(b.preventDefault(),b.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,b),b.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!==this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?r(e,this).index(i)>-1:r.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},addProp:function(a,b){Object.defineProperty(r.Event.prototype,a,{enumerable:!0,configurable:!0,get:r.isFunction(b)?function(){return this.originalEvent?b(this.originalEvent):void 0}:function(){return this.originalEvent?this.originalEvent[a]:void 0},set:function(b){Object.defineProperty(this,a,{enumerable:!0,configurable:!0,writable:!0,value:b})}})},fix:function(a){return a[r.expando]?a:new r.Event(a)},special:{load:{noBubble:!0},focus:{trigger:function(){return this!==va()&&this.focus?(this.focus(),!1):void 0},delegateType:"focusin"},blur:{trigger:function(){return this===va()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return"checkbox"===this.type&&this.click&&r.nodeName(this,"input")?(this.click(),!1):void 0},_default:function(a){return r.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}}},r.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)},r.Event=function(a,b){return this instanceof r.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?ta:ua,this.target=a.target&&3===a.target.nodeType?a.target.parentNode:a.target,this.currentTarget=a.currentTarget,this.relatedTarget=a.relatedTarget):this.type=a,b&&r.extend(this,b),this.timeStamp=a&&a.timeStamp||r.now(),void(this[r.expando]=!0)):new r.Event(a,b)},r.Event.prototype={constructor:r.Event,isDefaultPrevented:ua,isPropagationStopped:ua,isImmediatePropagationStopped:ua,isSimulated:!1,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=ta,a&&!this.isSimulated&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=ta,a&&!this.isSimulated&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=ta,a&&!this.isSimulated&&a.stopImmediatePropagation(),this.stopPropagation()}},r.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(a){var b=a.button;return null==a.which&&qa.test(a.type)?null!=a.charCode?a.charCode:a.keyCode:!a.which&&void 0!==b&&ra.test(a.type)?1&b?1:2&b?3:4&b?2:0:a.which}},r.event.addProp),r.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){r.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||r.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),r.fn.extend({on:function(a,b,c,d){return wa(this,a,b,c,d)},one:function(a,b,c,d){return wa(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,r(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&"function"!=typeof b||(c=b,b=void 0),c===!1&&(c=ua),this.each(function(){r.event.remove(this,a,c,b)})}});var xa=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,ya=/<script|<style|<link/i,za=/checked\s*(?:[^=]|=\s*.checked.)/i,Aa=/^true\/(.*)/,Ba=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function Ca(a,b){return r.nodeName(a,"table")&&r.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a:a}function Da(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Ea(a){var b=Aa.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Fa(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(V.hasData(a)&&(f=V.access(a),g=V.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)r.event.add(b,e,j[e][c])}W.hasData(a)&&(h=W.access(a),i=r.extend({},h),W.set(b,i))}}function Ga(a,b){var c=b.nodeName.toLowerCase();"input"===c&&ha.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function Ha(a,b,c,d){b=g.apply([],b);var e,f,h,i,j,k,l=0,m=a.length,n=m-1,q=b[0],s=r.isFunction(q);if(s||m>1&&"string"==typeof q&&!o.checkClone&&za.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(m&&(e=oa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(la(e,"script"),Da),i=h.length;m>l;l++)j=e,l!==n&&(j=r.clone(j,!0,!0),i&&r.merge(h,la(j,"script"))),c.call(a[l],j,l);if(i)for(k=h[h.length-1].ownerDocument,r.map(h,Ea),l=0;i>l;l++)j=h[l],ja.test(j.type||"")&&!V.access(j,"globalEval")&&r.contains(k,j)&&(j.src?r._evalUrl&&r._evalUrl(j.src):p(j.textContent.replace(Ba,""),k))}return a}function Ia(a,b,c){for(var d,e=b?r.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||r.cleanData(la(d)),d.parentNode&&(c&&r.contains(d.ownerDocument,d)&&ma(la(d,"script")),d.parentNode.removeChild(d));return a}r.extend({htmlPrefilter:function(a){return a.replace(xa,"<$1></$2>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=la(h),f=la(a),d=0,e=f.length;e>d;d++)Ga(f[d],g[d]);if(b)if(c)for(f=f||la(a),g=g||la(h),d=0,e=f.length;e>d;d++)Fa(f[d],g[d]);else Fa(a,h);return g=la(h,"script"),g.length>0&&ma(g,!i&&la(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(T(c)){if(b=c[V.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[V.expando]=void 0}c[W.expando]&&(c[W.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return S(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(la(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return S(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!ya.test(a)&&!ka[(ia.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(r.cleanData(la(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;r.inArray(this,a)<0&&(r.cleanData(la(this)),c&&c.replaceChild(b,this))},a)}}),r.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){r.fn[a]=function(a){for(var c,d=[],e=r(a),f=e.length-1,g=0;f>=g;g++)c=g===f?this:this.clone(!0),r(e[g])[b](c),h.apply(d,c.get());return this.pushStack(d)}});var Ja=/^margin/,Ka=new RegExp("^("+$+")(?!px)[a-z%]+$","i"),La=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)};!function(){function b(){if(i){i.style.cssText="box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",i.innerHTML="",pa.appendChild(h);var b=a.getComputedStyle(i);c="1%"!==b.top,g="2px"===b.marginLeft,e="4px"===b.width,i.style.marginRight="50%",f="4px"===b.marginRight,pa.removeChild(h),i=null}}var c,e,f,g,h=d.createElement("div"),i=d.createElement("div");i.style&&(i.style.backgroundClip="content-box",i.cloneNode(!0).style.backgroundClip="",o.clearCloneStyle="content-box"===i.style.backgroundClip,h.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",h.appendChild(i),r.extend(o,{pixelPosition:function(){return b(),c},boxSizingReliable:function(){return b(),e},pixelMarginRight:function(){return b(),f},reliableMarginLeft:function(){return b(),g}}))}();function Ma(a,b,c){var d,e,f,g,h=a.style;return c=c||La(a),c&&(g=c.getPropertyValue(b)||c[b],""!==g||r.contains(a.ownerDocument,a)||(g=r.style(a,b)),!o.pixelMarginRight()&&Ka.test(g)&&Ja.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function Na(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Oa=/^(none|table(?!-c[ea]).+)/,Pa={position:"absolute",visibility:"hidden",display:"block"},Qa={letterSpacing:"0",fontWeight:"400"},Ra=["Webkit","Moz","ms"],Sa=d.createElement("div").style;function Ta(a){if(a in Sa)return a;var b=a[0].toUpperCase()+a.slice(1),c=Ra.length;while(c--)if(a=Ra[c]+b,a in Sa)return a}function Ua(a,b,c){var d=_.exec(b);return d?Math.max(0,d[2]-(c||0))+(d[3]||"px"):b}function Va(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=r.css(a,c+aa[f],!0,e)),d?("content"===c&&(g-=r.css(a,"padding"+aa[f],!0,e)),"margin"!==c&&(g-=r.css(a,"border"+aa[f]+"Width",!0,e))):(g+=r.css(a,"padding"+aa[f],!0,e),"padding"!==c&&(g+=r.css(a,"border"+aa[f]+"Width",!0,e)));return g}function Wa(a,b,c){var d,e=!0,f=La(a),g="border-box"===r.css(a,"boxSizing",!1,f);if(a.getClientRects().length&&(d=a.getBoundingClientRect()[b]),0>=d||null==d){if(d=Ma(a,b,f),(0>d||null==d)&&(d=a.style[b]),Ka.test(d))return d;e=g&&(o.boxSizingReliable()||d===a.style[b]),d=parseFloat(d)||0}return d+Va(a,b,c||(g?"border":"content"),e,f)+"px"}r.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Ma(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=r.camelCase(b),i=a.style;return b=r.cssProps[h]||(r.cssProps[h]=Ta(h)||h),g=r.cssHooks[b]||r.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,"string"===f&&(e=_.exec(c))&&e[1]&&(c=da(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(r.cssNumber[h]?"":"px")),o.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=r.camelCase(b);return b=r.cssProps[h]||(r.cssProps[h]=Ta(h)||h),g=r.cssHooks[b]||r.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=Ma(a,b,d)),"normal"===e&&b in Qa&&(e=Qa[b]),""===c||c?(f=parseFloat(e),c===!0||isFinite(f)?f||0:e):e}}),r.each(["height","width"],function(a,b){r.cssHooks[b]={get:function(a,c,d){return c?!Oa.test(r.css(a,"display"))||a.getClientRects().length&&a.getBoundingClientRect().width?Wa(a,b,d):ca(a,Pa,function(){return Wa(a,b,d)}):void 0},set:function(a,c,d){var e,f=d&&La(a),g=d&&Va(a,b,d,"border-box"===r.css(a,"boxSizing",!1,f),f);return g&&(e=_.exec(c))&&"px"!==(e[3]||"px")&&(a.style[b]=c,c=r.css(a,b)),Ua(a,c,g)}}}),r.cssHooks.marginLeft=Na(o.reliableMarginLeft,function(a,b){return b?(parseFloat(Ma(a,"marginLeft"))||a.getBoundingClientRect().left-ca(a,{marginLeft:0},function(){return a.getBoundingClientRect().left}))+"px":void 0}),r.each({margin:"",padding:"",border:"Width"},function(a,b){r.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+aa[d]+b]=f[d]||f[d-2]||f[0];return e}},Ja.test(a)||(r.cssHooks[a+b].set=Ua)}),r.fn.extend({css:function(a,b){return S(this,function(a,b,c){var d,e,f={},g=0;if(r.isArray(b)){for(d=La(a),e=b.length;e>g;g++)f[b[g]]=r.css(a,b[g],!1,d);return f}return void 0!==c?r.style(a,b,c):r.css(a,b)},a,b,arguments.length>1)}});function Xa(a,b,c,d,e){return new Xa.prototype.init(a,b,c,d,e)}r.Tween=Xa,Xa.prototype={constructor:Xa,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=Xa.propHooks[this.prop];return a&&a.get?a.get(this):Xa.propHooks._default.get(this)},run:function(a){var b,c=Xa.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Xa.propHooks._default.set(this),this}},Xa.prototype.init.prototype=Xa.prototype,Xa.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},Xa.propHooks.scrollTop=Xa.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=Xa.prototype.init,r.fx.step={};var Ya,Za,$a=/^(?:toggle|show|hide)$/,_a=/queueHooks$/;function ab(){Za&&(a.requestAnimationFrame(ab),r.fx.tick())}function bb(){return a.setTimeout(function(){Ya=void 0}),Ya=r.now()}function cb(a,b){var c,d=0,e={height:a};for(b=b?1:0;4>d;d+=2-b)c=aa[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function db(a,b,c){for(var d,e=(gb.tweeners[b]||[]).concat(gb.tweeners["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function eb(a,b,c){var d,e,f,g,h,i,j,k,l="width"in b||"height"in b,m=this,n={},o=a.style,p=a.nodeType&&ba(a),q=V.get(a,"fxshow");c.queue||(g=r._queueHooks(a,"fx"),null==g.unqueued&&(g.unqueued=0,h=g.empty.fire,g.empty.fire=function(){g.unqueued||h()}),g.unqueued++,m.always(function(){m.always(function(){g.unqueued--,r.queue(a,"fx").length||g.empty.fire()})}));for(d in b)if(e=b[d],$a.test(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}n[d]=q&&q[d]||r.style(a,d)}if(i=!r.isEmptyObject(b),i||!r.isEmptyObject(n)){l&&1===a.nodeType&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=q&&q.display,null==j&&(j=V.get(a,"display")),k=r.css(a,"display"),"none"===k&&(j?k=j:(ga([a],!0),j=a.style.display||j,k=r.css(a,"display"),ga([a]))),("inline"===k||"inline-block"===k&&null!=j)&&"none"===r.css(a,"float")&&(i||(m.done(function(){o.display=j}),null==j&&(k=o.display,j="none"===k?"":k)),o.display="inline-block")),c.overflow&&(o.overflow="hidden",m.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]})),i=!1;for(d in n)i||(q?"hidden"in q&&(p=q.hidden):q=V.access(a,"fxshow",{display:j}),f&&(q.hidden=!p),p&&ga([a],!0),m.done(function(){p||ga([a]),V.remove(a,"fxshow");for(d in n)r.style(a,d,n[d])})),i=db(p?q[d]:0,d,m),d in q||(q[d]=i.start,p&&(i.end=i.start,i.start=0))}}function fb(a,b){var c,d,e,f,g;for(c in a)if(d=r.camelCase(c),e=b[d],f=a[c],r.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=r.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function gb(a,b,c){var d,e,f=0,g=gb.prefilters.length,h=r.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=Ya||bb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:r.extend({},b),opts:r.extend(!0,{specialEasing:{},easing:r.easing._default},c),originalProperties:b,originalOptions:c,startTime:Ya||bb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=r.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(fb(k,j.opts.specialEasing);g>f;f++)if(d=gb.prefilters[f].call(j,a,k,j.opts))return r.isFunction(d.stop)&&(r._queueHooks(j.elem,j.opts.queue).stop=r.proxy(d.stop,d)),d;return r.map(k,db,j),r.isFunction(j.opts.start)&&j.opts.start.call(a,j),r.fx.timer(r.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}r.Animation=r.extend(gb,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return da(c.elem,a,_.exec(b),c),c}]},tweener:function(a,b){r.isFunction(a)?(b=a,a=["*"]):a=a.match(K);for(var c,d=0,e=a.length;e>d;d++)c=a[d],gb.tweeners[c]=gb.tweeners[c]||[],gb.tweeners[c].unshift(b)},prefilters:[eb],prefilter:function(a,b){b?gb.prefilters.unshift(a):gb.prefilters.push(a)}}),r.speed=function(a,b,c){var e=a&&"object"==typeof a?r.extend({},a):{complete:c||!c&&b||r.isFunction(a)&&a,duration:a,easing:c&&b||b&&!r.isFunction(b)&&b};return r.fx.off||d.hidden?e.duration=0:e.duration="number"==typeof e.duration?e.duration:e.duration in r.fx.speeds?r.fx.speeds[e.duration]:r.fx.speeds._default,null!=e.queue&&e.queue!==!0||(e.queue="fx"),e.old=e.complete,e.complete=function(){r.isFunction(e.old)&&e.old.call(this),e.queue&&r.dequeue(this,e.queue)},e},r.fn.extend({fadeTo:function(a,b,c,d){return this.filter(ba).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=r.isEmptyObject(a),f=r.speed(b,c,d),g=function(){var b=gb(this,r.extend({},a),f);(e||V.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=r.timers,g=V.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&_a.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||r.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=V.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=r.timers,g=d?d.length:0;for(c.finish=!0,r.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),r.each(["toggle","show","hide"],function(a,b){var c=r.fn[b];r.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(cb(b,!0),a,d,e)}}),r.each({slideDown:cb("show"),slideUp:cb("hide"),slideToggle:cb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){r.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),r.timers=[],r.fx.tick=function(){var a,b=0,c=r.timers;for(Ya=r.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||r.fx.stop(),Ya=void 0},r.fx.timer=function(a){r.timers.push(a),a()?r.fx.start():r.timers.pop()},r.fx.interval=13,r.fx.start=function(){Za||(Za=a.requestAnimationFrame?a.requestAnimationFrame(ab):a.setInterval(r.fx.tick,r.fx.interval))},r.fx.stop=function(){a.cancelAnimationFrame?a.cancelAnimationFrame(Za):a.clearInterval(Za),Za=null},r.fx.speeds={slow:600,fast:200,_default:400},r.fn.delay=function(b,c){return b=r.fx?r.fx.speeds[b]||b:b,c=c||"fx",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a=d.createElement("input"),b=d.createElement("select"),c=b.appendChild(d.createElement("option"));a.type="checkbox",o.checkOn=""!==a.value,o.optSelected=c.selected,a=d.createElement("input"),a.value="t",a.type="radio",o.radioValue="t"===a.value}();var hb,ib=r.expr.attrHandle;r.fn.extend({attr:function(a,b){return S(this,r.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?hb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&r.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(K);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c);
}}),hb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=ib[b]||r.find.attr;ib[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=ib[g],ib[g]=e,e=null!=c(a,b,d)?g:null,ib[g]=f),e}});var jb=/^(?:input|select|textarea|button)$/i,kb=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return S(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):jb.test(a.nodeName)||kb.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});var lb=/[\t\r\n\f]/g;function mb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,mb(this)))});if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=mb(c),d=1===c.nodeType&&(" "+e+" ").replace(lb," ")){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=r.trim(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,mb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=mb(c),d=1===c.nodeType&&(" "+e+" ").replace(lb," ")){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=r.trim(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,mb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(K)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=mb(this),b&&V.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":V.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+mb(c)+" ").replace(lb," ").indexOf(b)>-1)return!0;return!1}});var nb=/\r/g,ob=/[\x20\t\r\n\f]+/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":r.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(nb,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:r.trim(r.text(a)).replace(ob," ")}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],(c.selected||i===e)&&!c.disabled&&(!c.parentNode.disabled||!r.nodeName(c.parentNode,"optgroup"))){if(b=r(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=r.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=r.inArray(r.valHooks.option.get(d),f)>-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){return r.isArray(b)?a.checked=r.inArray(r(a).val(),b)>-1:void 0}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var pb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!pb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,pb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(V.get(h,"events")||{})[b.type]&&V.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&T(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!T(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?r.event.trigger(a,b,c,!0):void 0}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=V.access(d,b);e||d.addEventListener(a,c,!0),V.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=V.access(d,b)-1;e?V.access(d,b,e):(d.removeEventListener(a,c,!0),V.remove(d,b))}}});var qb=a.location,rb=r.now(),sb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var tb=/\[\]$/,ub=/\r?\n/g,vb=/^(?:submit|button|image|reset|file)$/i,wb=/^(?:input|select|textarea|keygen)/i;function xb(a,b,c,d){var e;if(r.isArray(b))r.each(b,function(b,e){c||tb.test(a)?d(a,e):xb(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)xb(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(r.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)xb(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&wb.test(this.nodeName)&&!vb.test(a)&&(this.checked||!ha.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:r.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(ub,"\r\n")}}):{name:b.name,value:c.replace(ub,"\r\n")}}).get()}});var yb=/%20/g,zb=/#.*$/,Ab=/([?&])_=[^&]*/,Bb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Cb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Db=/^(?:GET|HEAD)$/,Eb=/^\/\//,Fb={},Gb={},Hb="*/".concat("*"),Ib=d.createElement("a");Ib.href=qb.href;function Jb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(K)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Kb(a,b,c,d){var e={},f=a===Gb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Lb(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Mb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Nb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:qb.href,type:"GET",isLocal:Cb.test(qb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Hb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Lb(Lb(a,r.ajaxSettings),b):Lb(r.ajaxSettings,a)},ajaxPrefilter:Jb(Fb),ajaxTransport:Jb(Gb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Bb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||qb.href)+"").replace(Eb,qb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(K)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Ib.protocol+"//"+Ib.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Kb(Fb,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Db.test(o.type),f=o.url.replace(zb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(yb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(sb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Ab,""),n=(sb.test(f)?"&":"?")+"_="+rb++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Hb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Kb(Gb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&300>b||304===b,d&&(v=Mb(o,y,d)),v=Nb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",0>b&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Ob={0:200,1223:204},Pb=r.ajaxSettings.xhr();o.cors=!!Pb&&"withCredentials"in Pb,o.ajax=Pb=!!Pb,r.ajaxTransport(function(b){var c,d;return o.cors||Pb&&!b.crossDomain?{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Ob[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}:void 0}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r("<script>").prop({charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&f("error"===a.type?404:200,a.type)}),d.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Qb=[],Rb=/(=)\?(?=&|$)|\?\?/;r.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Qb.pop()||r.expando+"_"+rb++;return this[a]=!0,a}}),r.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Rb.test(b.url)?"url":"string"==typeof b.data&&0===(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Rb.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=r.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Rb,"$1"+e):b.jsonp!==!1&&(b.url+=(sb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||r.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?r(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Qb.push(e)),g&&r.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),o.createHTMLDocument=function(){var a=d.implementation.createHTMLDocument("").body;return a.innerHTML="<form></form><form></form>",2===a.childNodes.length}(),r.parseHTML=function(a,b,c){if("string"!=typeof a)return[];"boolean"==typeof b&&(c=b,b=!1);var e,f,g;return b||(o.createHTMLDocument?(b=d.implementation.createHTMLDocument(""),e=b.createElement("base"),e.href=d.location.href,b.head.appendChild(e)):b=d),f=B.exec(a),g=!c&&[],f?[b.createElement(f[1])]:(f=oa([a],b,g),g&&g.length&&r(g).remove(),r.merge([],f.childNodes))},r.fn.load=function(a,b,c){var d,e,f,g=this,h=a.indexOf(" ");return h>-1&&(d=r.trim(a.slice(h)),a=a.slice(0,h)),r.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&r.ajax({url:a,type:e||"GET",dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?r("<div>").append(r.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},r.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){r.fn[b]=function(a){return this.on(b,a)}}),r.expr.pseudos.animated=function(a){return r.grep(r.timers,function(b){return a===b.elem}).length};function Sb(a){return r.isWindow(a)?a:9===a.nodeType&&a.defaultView}r.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=r.css(a,"position"),l=r(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=r.css(a,"top"),i=r.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),r.isFunction(b)&&(b=b.call(a,c,r.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},r.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){r.offset.setOffset(this,a,b)});var b,c,d,e,f=this[0];if(f)return f.getClientRects().length?(d=f.getBoundingClientRect(),d.width||d.height?(e=f.ownerDocument,c=Sb(e),b=e.documentElement,{top:d.top+c.pageYOffset-b.clientTop,left:d.left+c.pageXOffset-b.clientLeft}):d):{top:0,left:0}},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===r.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),r.nodeName(a[0],"html")||(d=a.offset()),d={top:d.top+r.css(a[0],"borderTopWidth",!0),left:d.left+r.css(a[0],"borderLeftWidth",!0)}),{top:b.top-d.top-r.css(c,"marginTop",!0),left:b.left-d.left-r.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&"static"===r.css(a,"position"))a=a.offsetParent;return a||pa})}}),r.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c="pageYOffset"===b;r.fn[a]=function(d){return S(this,function(a,d,e){var f=Sb(a);return void 0===e?f?f[b]:a[d]:void(f?f.scrollTo(c?f.pageXOffset:e,c?e:f.pageYOffset):a[d]=e)},a,d,arguments.length)}}),r.each(["top","left"],function(a,b){r.cssHooks[b]=Na(o.pixelPosition,function(a,c){return c?(c=Ma(a,b),Ka.test(c)?r(a).position()[b]+"px":c):void 0})}),r.each({Height:"height",Width:"width"},function(a,b){r.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){r.fn[d]=function(e,f){var g=arguments.length&&(c||"boolean"!=typeof e),h=c||(e===!0||f===!0?"margin":"border");return S(this,function(b,c,e){var f;return r.isWindow(b)?0===d.indexOf("outer")?b["inner"+a]:b.document.documentElement["client"+a]:9===b.nodeType?(f=b.documentElement,Math.max(b.body["scroll"+a],f["scroll"+a],b.body["offset"+a],f["offset"+a],f["client"+a])):void 0===e?r.css(b,c,h):r.style(b,c,e,h)},b,g?e:void 0,g)}})}),r.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}}),r.parseJSON=JSON.parse,"function"=="function"&&__webpack_require__(31)&&!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function(){return r}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));var Tb=a.jQuery,Ub=a.$;return r.noConflict=function(b){return a.$===r&&(a.$=Ub),b&&a.jQuery===r&&(a.jQuery=Tb),r},b||(a.jQuery=a.$=r),r});


/***/ }),
/* 1 */
/***/ (function(module, exports) {

/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/
module.exports = function(src) {
	function log(error) {
		(typeof console !== "undefined")
		&& (console.error || console.log)("[Script Loader]", error);
	}

	// Check for IE =< 8
	function isIE() {
		return typeof attachEvent !== "undefined" && typeof addEventListener === "undefined";
	}

	try {
		if (typeof execScript !== "undefined" && isIE()) {
			execScript(src);
		} else if (typeof eval !== "undefined") {
			eval.call(null, src);
		} else {
			log("EvalError: No eval function available");
		}
	} catch (error) {
		log(error);
	}
}


/***/ }),
/* 2 */
/***/ (function(module, exports) {

/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/
// css base code, injected by the css-loader
module.exports = function(useSourceMap) {
	var list = [];

	// return the list of modules as css string
	list.toString = function toString() {
		return this.map(function (item) {
			var content = cssWithMappingToString(item, useSourceMap);
			if(item[2]) {
				return "@media " + item[2] + "{" + content + "}";
			} else {
				return content;
			}
		}).join("");
	};

	// import a list of modules into the list
	list.i = function(modules, mediaQuery) {
		if(typeof modules === "string")
			modules = [[null, modules, ""]];
		var alreadyImportedModules = {};
		for(var i = 0; i < this.length; i++) {
			var id = this[i][0];
			if(typeof id === "number")
				alreadyImportedModules[id] = true;
		}
		for(i = 0; i < modules.length; i++) {
			var item = modules[i];
			// skip already imported module
			// this implementation is not 100% perfect for weird media query combinations
			//  when a module is imported multiple times with different media queries.
			//  I hope this will never occur (Hey this way we have smaller bundles)
			if(typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) {
				if(mediaQuery && !item[2]) {
					item[2] = mediaQuery;
				} else if(mediaQuery) {
					item[2] = "(" + item[2] + ") and (" + mediaQuery + ")";
				}
				list.push(item);
			}
		}
	};
	return list;
};

function cssWithMappingToString(item, useSourceMap) {
	var content = item[1] || '';
	var cssMapping = item[3];
	if (!cssMapping) {
		return content;
	}

	if (useSourceMap && typeof btoa === 'function') {
		var sourceMapping = toComment(cssMapping);
		var sourceURLs = cssMapping.sources.map(function (source) {
			return '/*# sourceURL=' + cssMapping.sourceRoot + source + ' */'
		});

		return [content].concat(sourceURLs).concat([sourceMapping]).join('\n');
	}

	return [content].join('\n');
}

// Adapted from convert-source-map (MIT)
function toComment(sourceMap) {
	// eslint-disable-next-line no-undef
	var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))));
	var data = 'sourceMappingURL=data:application/json;charset=utf-8;base64,' + base64;

	return '/*# ' + data + ' */';
}


/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {

/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/

var stylesInDom = {};

var	memoize = function (fn) {
	var memo;

	return function () {
		if (typeof memo === "undefined") memo = fn.apply(this, arguments);
		return memo;
	};
};

var isOldIE = memoize(function () {
	// Test for IE <= 9 as proposed by Browserhacks
	// @see http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805
	// Tests for existence of standard globals is to allow style-loader
	// to operate correctly into non-standard environments
	// @see https://github.com/webpack-contrib/style-loader/issues/177
	return window && document && document.all && !window.atob;
});

var getTarget = function (target) {
  return document.querySelector(target);
};

var getElement = (function (fn) {
	var memo = {};

	return function(target) {
                // If passing function in options, then use it for resolve "head" element.
                // Useful for Shadow Root style i.e
                // {
                //   insertInto: function () { return document.querySelector("#foo").shadowRoot }
                // }
                if (typeof target === 'function') {
                        return target();
                }
                if (typeof memo[target] === "undefined") {
			var styleTarget = getTarget.call(this, target);
			// Special case to return head of iframe instead of iframe itself
			if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {
				try {
					// This will throw an exception if access to iframe is blocked
					// due to cross-origin restrictions
					styleTarget = styleTarget.contentDocument.head;
				} catch(e) {
					styleTarget = null;
				}
			}
			memo[target] = styleTarget;
		}
		return memo[target]
	};
})();

var singleton = null;
var	singletonCounter = 0;
var	stylesInsertedAtTop = [];

var	fixUrls = __webpack_require__(17);

module.exports = function(list, options) {
	if (typeof DEBUG !== "undefined" && DEBUG) {
		if (typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment");
	}

	options = options || {};

	options.attrs = typeof options.attrs === "object" ? options.attrs : {};

	// Force single-tag solution on IE6-9, which has a hard limit on the # of <style>
	// tags it will allow on a page
	if (!options.singleton && typeof options.singleton !== "boolean") options.singleton = isOldIE();

	// By default, add <style> tags to the <head> element
        if (!options.insertInto) options.insertInto = "head";

	// By default, add <style> tags to the bottom of the target
	if (!options.insertAt) options.insertAt = "bottom";

	var styles = listToStyles(list, options);

	addStylesToDom(styles, options);

	return function update (newList) {
		var mayRemove = [];

		for (var i = 0; i < styles.length; i++) {
			var item = styles[i];
			var domStyle = stylesInDom[item.id];

			domStyle.refs--;
			mayRemove.push(domStyle);
		}

		if(newList) {
			var newStyles = listToStyles(newList, options);
			addStylesToDom(newStyles, options);
		}

		for (var i = 0; i < mayRemove.length; i++) {
			var domStyle = mayRemove[i];

			if(domStyle.refs === 0) {
				for (var j = 0; j < domStyle.parts.length; j++) domStyle.parts[j]();

				delete stylesInDom[domStyle.id];
			}
		}
	};
};

function addStylesToDom (styles, options) {
	for (var i = 0; i < styles.length; i++) {
		var item = styles[i];
		var domStyle = stylesInDom[item.id];

		if(domStyle) {
			domStyle.refs++;

			for(var j = 0; j < domStyle.parts.length; j++) {
				domStyle.parts[j](item.parts[j]);
			}

			for(; j < item.parts.length; j++) {
				domStyle.parts.push(addStyle(item.parts[j], options));
			}
		} else {
			var parts = [];

			for(var j = 0; j < item.parts.length; j++) {
				parts.push(addStyle(item.parts[j], options));
			}

			stylesInDom[item.id] = {id: item.id, refs: 1, parts: parts};
		}
	}
}

function listToStyles (list, options) {
	var styles = [];
	var newStyles = {};

	for (var i = 0; i < list.length; i++) {
		var item = list[i];
		var id = options.base ? item[0] + options.base : item[0];
		var css = item[1];
		var media = item[2];
		var sourceMap = item[3];
		var part = {css: css, media: media, sourceMap: sourceMap};

		if(!newStyles[id]) styles.push(newStyles[id] = {id: id, parts: [part]});
		else newStyles[id].parts.push(part);
	}

	return styles;
}

function insertStyleElement (options, style) {
	var target = getElement(options.insertInto)

	if (!target) {
		throw new Error("Couldn't find a style target. This probably means that the value for the 'insertInto' parameter is invalid.");
	}

	var lastStyleElementInsertedAtTop = stylesInsertedAtTop[stylesInsertedAtTop.length - 1];

	if (options.insertAt === "top") {
		if (!lastStyleElementInsertedAtTop) {
			target.insertBefore(style, target.firstChild);
		} else if (lastStyleElementInsertedAtTop.nextSibling) {
			target.insertBefore(style, lastStyleElementInsertedAtTop.nextSibling);
		} else {
			target.appendChild(style);
		}
		stylesInsertedAtTop.push(style);
	} else if (options.insertAt === "bottom") {
		target.appendChild(style);
	} else if (typeof options.insertAt === "object" && options.insertAt.before) {
		var nextSibling = getElement(options.insertInto + " " + options.insertAt.before);
		target.insertBefore(style, nextSibling);
	} else {
		throw new Error("[Style Loader]\n\n Invalid value for parameter 'insertAt' ('options.insertAt') found.\n Must be 'top', 'bottom', or Object.\n (https://github.com/webpack-contrib/style-loader#insertat)\n");
	}
}

function removeStyleElement (style) {
	if (style.parentNode === null) return false;
	style.parentNode.removeChild(style);

	var idx = stylesInsertedAtTop.indexOf(style);
	if(idx >= 0) {
		stylesInsertedAtTop.splice(idx, 1);
	}
}

function createStyleElement (options) {
	var style = document.createElement("style");

	if(options.attrs.type === undefined) {
		options.attrs.type = "text/css";
	}

	addAttrs(style, options.attrs);
	insertStyleElement(options, style);

	return style;
}

function createLinkElement (options) {
	var link = document.createElement("link");

	if(options.attrs.type === undefined) {
		options.attrs.type = "text/css";
	}
	options.attrs.rel = "stylesheet";

	addAttrs(link, options.attrs);
	insertStyleElement(options, link);

	return link;
}

function addAttrs (el, attrs) {
	Object.keys(attrs).forEach(function (key) {
		el.setAttribute(key, attrs[key]);
	});
}

function addStyle (obj, options) {
	var style, update, remove, result;

	// If a transform function was defined, run it on the css
	if (options.transform && obj.css) {
	    result = options.transform(obj.css);

	    if (result) {
	    	// If transform returns a value, use that instead of the original css.
	    	// This allows running runtime transformations on the css.
	    	obj.css = result;
	    } else {
	    	// If the transform function returns a falsy value, don't add this css.
	    	// This allows conditional loading of css
	    	return function() {
	    		// noop
	    	};
	    }
	}

	if (options.singleton) {
		var styleIndex = singletonCounter++;

		style = singleton || (singleton = createStyleElement(options));

		update = applyToSingletonTag.bind(null, style, styleIndex, false);
		remove = applyToSingletonTag.bind(null, style, styleIndex, true);

	} else if (
		obj.sourceMap &&
		typeof URL === "function" &&
		typeof URL.createObjectURL === "function" &&
		typeof URL.revokeObjectURL === "function" &&
		typeof Blob === "function" &&
		typeof btoa === "function"
	) {
		style = createLinkElement(options);
		update = updateLink.bind(null, style, options);
		remove = function () {
			removeStyleElement(style);

			if(style.href) URL.revokeObjectURL(style.href);
		};
	} else {
		style = createStyleElement(options);
		update = applyToTag.bind(null, style);
		remove = function () {
			removeStyleElement(style);
		};
	}

	update(obj);

	return function updateStyle (newObj) {
		if (newObj) {
			if (
				newObj.css === obj.css &&
				newObj.media === obj.media &&
				newObj.sourceMap === obj.sourceMap
			) {
				return;
			}

			update(obj = newObj);
		} else {
			remove();
		}
	};
}

var replaceText = (function () {
	var textStore = [];

	return function (index, replacement) {
		textStore[index] = replacement;

		return textStore.filter(Boolean).join('\n');
	};
})();

function applyToSingletonTag (style, index, remove, obj) {
	var css = remove ? "" : obj.css;

	if (style.styleSheet) {
		style.styleSheet.cssText = replaceText(index, css);
	} else {
		var cssNode = document.createTextNode(css);
		var childNodes = style.childNodes;

		if (childNodes[index]) style.removeChild(childNodes[index]);

		if (childNodes.length) {
			style.insertBefore(cssNode, childNodes[index]);
		} else {
			style.appendChild(cssNode);
		}
	}
}

function applyToTag (style, obj) {
	var css = obj.css;
	var media = obj.media;

	if(media) {
		style.setAttribute("media", media)
	}

	if(style.styleSheet) {
		style.styleSheet.cssText = css;
	} else {
		while(style.firstChild) {
			style.removeChild(style.firstChild);
		}

		style.appendChild(document.createTextNode(css));
	}
}

function updateLink (link, options, obj) {
	var css = obj.css;
	var sourceMap = obj.sourceMap;

	/*
		If convertToAbsoluteUrls isn't defined, but sourcemaps are enabled
		and there is no publicPath defined then lets turn convertToAbsoluteUrls
		on by default.  Otherwise default to the convertToAbsoluteUrls option
		directly
	*/
	var autoFixUrls = options.convertToAbsoluteUrls === undefined && sourceMap;

	if (options.convertToAbsoluteUrls || autoFixUrls) {
		css = fixUrls(css);
	}

	if (sourceMap) {
		// http://stackoverflow.com/a/26603875
		css += "\n/*# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + " */";
	}

	var blob = new Blob([css], { type: "text/css" });

	var oldSrc = link.href;

	link.href = URL.createObjectURL(blob);

	if(oldSrc) URL.revokeObjectURL(oldSrc);
}


/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
/* WEBPACK VAR INJECTION */(function($, jQuery) {
// Python Tutor: https://github.com/pgbovine/OnlinePythonTutor/
// Copyright (C) Philip Guo (philip@pgbovine.net)
// LICENSE: https://github.com/pgbovine/OnlinePythonTutor/blob/master/LICENSE.txt
Object.defineProperty(exports, "__esModule", { value: true });
/* TODO:

- substitute in a non-live version of the live editor from opt-live.js
  in addition to the janky current version of the editor

*/
/* pytutor coding gotchas:

- *NEVER* use raw $(__) or d3.select(__) statements to select DOM elements.

  *ALWAYS* use myViz.domRoot or myViz.domRootD3 for jQuery and D3, respectively.

  Otherwise things will break in weird ways when you have more than one
  visualization embedded within a webpage, due to multiple matches in
  the global namespace.

  By doing myViz.domRoot / .domRootD3, you're guaranteed to select DOM elements
  within the current ExecutionVisualizer object

- always use generateID and generateHeapObjID to generate unique CSS
  IDs, or else things will break when multiple ExecutionVisualizer
  instances are on a webpage

*/
__webpack_require__(9);
__webpack_require__(0);
__webpack_require__(12); // DO NOT UPGRADE ABOVE 1.3.10 OR ELSE BREAKAGE WILL OCCUR 
__webpack_require__(10);
__webpack_require__(16);
__webpack_require__(11); // contains slight pgbovine modifications
__webpack_require__(7); // for $.doTimeout
__webpack_require__(15);
var footer_html_1 = __webpack_require__(6);
exports.SVG_ARROW_POLYGON = '0,3 12,3 12,0 18,5 12,10 12,7 0,7';
var SVG_ARROW_HEIGHT = 10; // must match height of SVG_ARROW_POLYGON
/* colors - see pytutor.css for more colors */
exports.brightRed = '#e93f34';
var connectorBaseColor = '#005583';
var connectorHighlightColor = exports.brightRed;
var connectorInactiveColor = '#cccccc';
var errorColor = exports.brightRed;
var breakpointColor = exports.brightRed;
// Unicode arrow types: '\u21d2', '\u21f0', '\u2907'
exports.darkArrowColor = exports.brightRed;
exports.lightArrowColor = '#c9e6ca';
var heapPtrSrcRE = /__heap_pointer_src_/;
var rightwardNudgeHack = true; // suggested by John DeNero, toggle with global
// returns a list of length a.length * b.length with elements from both
// mixed. the elements of a and b should be primitives, but if the first element
// is a list, it flattens it. e.g.,:
//   multiplyLists([1, 2, 3], [4, 5]) -> [[1,4], [1,5], [2,4], [2,5], [3,4], [3,5]]
function multiplyLists(a, b) {
    var ret = [];
    for (var i = 0; i < a.length; i++) {
        for (var j = 0; j < b.length; j++) {
            var elt = a[i];
            // flatten list
            if ($.isArray(elt)) {
                ret.push(elt.concat(b[j]));
            }
            else {
                ret.push([elt, b[j]]);
            }
        }
    }
    return ret;
}
// BEGIN utilities for selectively hiding variables
// use htmlspecialchars to escape contents before printing to HTML,
// then UNDO &nbsp; -> ' ' since we want spaces to nicely line-wrap
// instead of being non-breaking
function varlistToHtml(lst) {
    return htmlspecialchars(lst.join(", ")).replace(/&nbsp;/g, ' ');
}
// take a string of something to hide, replace newlines with ','
// so users can conveniently use newlines as delimiters, then split
// by ',', filter out empty entries, and return trimmed ones:
function processHideString(s) {
    return s.replace(/\n/g, ',')
        .split(',')
        .filter(function (e) { return e.trim().length > 0; })
        .map(function (e) { return e.trim(); });
}
// END utilities for selectively hiding variables
var newlineAllRegex = new RegExp('\n', 'g');
var doubleQuoteAllRegex = new RegExp('\"', 'g');
var tabAllRegex = new RegExp("\t", 'g');
// the main event!
var ExecutionVisualizer = /** @class */ (function () {
    // Constructor with an ever-growing feature-crepped list of options :)
    // domRootID is the string ID of the root element where to render this instance
    //
    // dat is data returned by the Python Tutor backend consisting of two fields:
    //   code  - string of executed code
    //   trace - a full execution trace
    //
    // params is an object containing optional parameters, such as:
    //   jumpToEnd - if non-null, jump to the very end of execution if
    //               there's no error, or if there's an error, jump to the
    //               FIRST ENTRY with an error
    //   startingInstruction - the (zero-indexed) execution point to display upon rendering
    //                         if this is set, then it *overrides* jumpToEnd
    //   codeDivHeight - maximum height of #pyCodeOutputDiv (in integer pixels)
    //   codeDivWidth  - maximum width  of #pyCodeOutputDiv (in integer pixels)
    //   editCodeBaseURL - the base URL to visit when the user clicks 'Edit code' (if null, then 'Edit code' link hidden)
    //   embeddedMode         - shortcut for codeDivWidth=DEFAULT_EMBEDDED_CODE_DIV_WIDTH,
    //                                       codeDivHeight=DEFAULT_EMBEDDED_CODE_DIV_HEIGHT
    //                          (and hide a bunch of other stuff & don't activate keyboard shortcuts!)
    //   disableHeapNesting   - if true, then render all heap objects at the top level (i.e., no nested objects)
    //   alwaysNestTypes      - if non-null, a list of type names to ALWAYS nest within heap objects
    //                          (supersedes disableHeapNesting, defaults to DEFAULT_ALWAYS_NEST_TYPES)
    //   drawParentPointers   - if true, then draw environment diagram parent pointers for all frames
    //                          WARNING: there are hard-to-debug MEMORY LEAKS associated with activating this option
    //   textualMemoryLabels  - render references using textual memory labels rather than as jsPlumb arrows.
    //                          this is good for slow browsers or when used with disableHeapNesting
    //                          to prevent "arrow overload"
    //   updateOutputCallback - function to call (with 'this' as parameter)
    //                          whenever this.updateOutput() is called
    //                          (BEFORE rendering the output display)
    //   heightChangeCallback - function to call (with 'this' as parameter)
    //                          whenever the HEIGHT of #dataViz changes
    //   verticalStack - if true, then stack code display ON TOP of visualization
    //                   (else place side-by-side)
    //   visualizerIdOverride - override visualizer ID instead of auto-assigning it
    //                          (BE CAREFUL ABOUT NOT HAVING DUPLICATE IDs ON THE SAME PAGE,
    //                           OR ELSE ARROWS AND OTHER STUFF WILL GO HAYWIRE!)
    //   executeCodeWithRawInputFunc - function to call when you want to re-execute the given program
    //                                 with some new user input (somewhat hacky!)
    //   compactFuncLabels - render functions with a 'func' prefix and no type label
    //   showAllFrameLabels - display frame and parent frame labels for all functions (default: false)
    //   hideCode - hide the code display and show only the data structure viz
    //   lang - to render labels in a style appropriate for other languages,
    //          and to display the proper language in langDisplayDiv:
    //          'py2' for Python 2, 'py3' for Python 3, 'js' for JavaScript, 'java' for Java,
    //          'ts' for TypeScript, 'ruby' for Ruby, 'c' for C, 'cpp' for C++
    //          'py3anaconda' for Python 3 with Anaconda
    //          [default is Python-style labels]
    function ExecutionVisualizer(domRootID, dat, params) {
        this.params = {};
        // an array of objects with the following fields:
        //   'text' - the text of the line of code
        //   'lineNumber' - one-indexed (always the array index + 1)
        //   'executionPoints' - an ordered array of zero-indexed execution points where this line was executed
        //   'breakpointHere' - has a breakpoint been set here?
        this.codeOutputLines = [];
        this.curInstr = 0;
        // API for adding a hook, created by David Pritchard
        // keys, hook names; values, list of functions
        this.pytutor_hooks = {};
        // true iff trace ended prematurely since maximum instruction limit has
        // been reached
        this.instrLimitReached = false;
        this.hasRendered = false;
        this.breakpoints = d3.map(); // set of execution points to set as breakpoints
        this.sortedBreakpointsList = []; // sorted and synced with breakpoints
        this.curInputCode = dat.code.rtrim(); // kill trailing spaces
        this.params = params;
        this.curTrace = dat.trace;
        // postprocess the trace
        if (this.curTrace.length > 0) {
            var lastEntry = this.curTrace[this.curTrace.length - 1];
            // if the final entry is raw_input or mouse_input, then trim it from the trace and
            // set a flag to prompt for user input when execution advances to the
            // end of the trace
            if (lastEntry.event === 'raw_input') {
                this.promptForUserInput = true;
                this.userInputPromptStr = htmlspecialchars(lastEntry.prompt);
                this.curTrace.pop(); // kill last entry so that it doesn't get displayed
            }
            else if (lastEntry.event === 'mouse_input') {
                this.promptForMouseInput = true;
                this.userInputPromptStr = htmlspecialchars(lastEntry.prompt);
                this.curTrace.pop(); // kill last entry so that it doesn't get displayed
            }
            else if (lastEntry.event === 'instruction_limit_reached') {
                this.instrLimitReached = true;
                this.instrLimitReachedWarningMsg = lastEntry.exception_msg;
                this.curTrace.pop(); // postprocess to kill last entry
            }
        }
        // if you have multiple ExecutionVisualizer on a page, their IDs
        // better be unique or else you'll run into rendering problems
        if (this.params.visualizerIdOverride) {
            this.visualizerID = this.params.visualizerIdOverride;
        }
        else {
            this.visualizerID = ExecutionVisualizer.curVisualizerID;
            assert(this.visualizerID > 0);
            ExecutionVisualizer.curVisualizerID++;
        }
        // sanitize to avoid nasty 'undefined' states
        this.params.disableHeapNesting = (this.params.disableHeapNesting === true);
        this.params.drawParentPointers = (this.params.drawParentPointers === true);
        this.params.textualMemoryLabels = (this.params.textualMemoryLabels === true);
        this.params.showAllFrameLabels = (this.params.showAllFrameLabels === true);
        if (this.params.alwaysNestTypes === undefined) {
            this.params.alwaysNestTypes = ExecutionVisualizer.DEFAULT_ALWAYS_NEST_TYPES;
        }
        assert($.isArray(this.params.alwaysNestTypes));
        // insert ExecutionVisualizer into domRootID in the DOM
        var tmpRoot = $('#' + domRootID);
        var tmpRootD3 = d3.select('#' + domRootID);
        tmpRoot.html('<div class="ExecutionVisualizer"></div>');
        // the root elements for jQuery and D3 selections, respectively.
        // ALWAYS use these and never use raw $(__) or d3.select(__)
        this.domRoot = tmpRoot.find('div.ExecutionVisualizer');
        this.domRootD3 = tmpRootD3.select('div.ExecutionVisualizer');
        if (this.params.lang === 'java') {
            this.activateJavaFrontend(); // ohhhh yeah! do this before initializing codeOutputLines (ugh order dependency)
        }
        var lines = this.curInputCode.split('\n');
        for (var i = 0; i < lines.length; i++) {
            var cod = lines[i];
            var n = {
                text: cod,
                lineNumber: i + 1,
                executionPoints: [],
                breakpointHere: false,
            };
            $.each(this.curTrace, function (j, elt) {
                if (elt.line === n.lineNumber) {
                    n.executionPoints.push(j);
                }
            });
            // if there is a comment containing 'breakpoint' and this line was actually executed,
            // then set a breakpoint on this line
            var breakpointInComment = false;
            var toks = cod.split('#');
            for (var j = 1 /* start at index 1, not 0 */; j < toks.length; j++) {
                if (toks[j].indexOf('breakpoint') != -1) {
                    breakpointInComment = true;
                }
            }
            if (breakpointInComment && n.executionPoints.length > 0) {
                n.breakpointHere = true;
                this.addToBreakpoints(n.executionPoints);
            }
            this.codeOutputLines.push(n);
        }
        this.try_hook("end_constructor", { myViz: this });
        this.render(); // go for it!
    }
    ExecutionVisualizer.prototype.objInAlwaysNestTypes = function (obj) {
        if (!obj)
            return false;
        assert($.isArray(obj));
        if (this.params.alwaysNestTypes.indexOf(obj[0]) >= 0) {
            // is the type name in alwaysNestTypes?
            return true;
        }
        else if (obj.length >= 2 &&
            (obj[0] == 'INSTANCE' || obj[0] == 'INSTANCE_PPRINT') &&
            (this.params.alwaysNestTypes.indexOf(obj[1]) >= 0)) {
            // otherwise is this an INSTANCE with the type name (obj[1]) in alwaysNestTypes?
            return true;
        }
        else {
            return false;
        }
    };
    // should this object be nested within another one?
    ExecutionVisualizer.prototype.shouldNestObject = function (obj) {
        return (!this.params.disableHeapNesting || this.objInAlwaysNestTypes(obj));
    };
    /* API for adding a hook, created by David Pritchard
       https://github.com/daveagp
  
      [this documentation is a bit deprecated since Philip made try_hook a
       method of ExecutionVisualizer, but the general ideas remain]
  
     An external user should call
       add_pytutor_hook("hook_name_here", function(args) {...})
     args will be a javascript object with several named properties;
     this is meant to be similar to Python's keyword arguments.
  
     The hooked function should return an array whose first element is a boolean:
     true if it completely handled the situation (no further hooks
     nor the base function should be called); false otherwise (wasn't handled).
     If the hook semantically represents a function that returns something,
     the second value of the returned array is that semantic return value.
  
     E.g. for the Java visualizer a simplified version of a hook we use is:
  
    add_pytutor_hook(
      "isPrimitiveType",
      function(args) {
        var obj = args.obj; // unpack
        if (obj instanceof Array && obj[0] == "CHAR-LITERAL")
          return [true, true]; // yes we handled it, yes it's primitive
        return [false]; // didn't handle it, let someone else
      });
  
     Hook callbacks can return false or undefined (i.e. no return
     value) in lieu of [false].
  
     NB: If multiple functions are added to a hook, the oldest goes first. */
    ExecutionVisualizer.prototype.add_pytutor_hook = function (hook_name, func) {
        if (this.pytutor_hooks[hook_name])
            this.pytutor_hooks[hook_name].push(func);
        else
            this.pytutor_hooks[hook_name] = [func];
    };
    /*  [this documentation is a bit deprecated since Philip made try_hook a
         method of ExecutionVisualizer, but the general ideas remain]
  
    try_hook(hook_name, args): how the internal codebase invokes a hook.
  
    args will be a javascript object with several named properties;
    this is meant to be similar to Python's keyword arguments. E.g.,
  
    function isPrimitiveType(obj) {
      var hook_result = try_hook("isPrimitiveType", {obj:obj});
      if (hook_result[0]) return hook_result[1];
      // go on as normal if the hook didn't handle it
  
    Although add_pytutor_hook allows the hooked function to
    return false or undefined, try_hook will always return
    something with the strict format [false], [true] or [true, ...]. */
    ExecutionVisualizer.prototype.try_hook = function (hook_name, args) {
        if (this.pytutor_hooks[hook_name]) {
            for (var i = 0; i < this.pytutor_hooks[hook_name].length; i++) {
                // apply w/o "this", and pack sole arg into array as required by apply
                var handled_and_result = this.pytutor_hooks[hook_name][i].apply(null, [args]);
                if (handled_and_result && handled_and_result[0])
                    return handled_and_result;
            }
        }
        return [false];
    };
    // create a unique ID, which is often necessary so that jsPlumb doesn't get confused
    // due to multiple ExecutionVisualizer instances being displayed simultaneously
    ExecutionVisualizer.prototype.generateID = function (original_id) {
        // (it's safer to start names with a letter rather than a number)
        return 'v' + this.visualizerID + '__' + original_id;
    };
    ExecutionVisualizer.prototype.render = function () {
        var _this = this;
        if (this.hasRendered) {
            alert('ERROR: You should only call render() ONCE on an ExecutionVisualizer object.');
            return;
        }
        var myViz = this; // to prevent confusion of 'this' inside of nested functions
        if (this.params.verticalStack) {
            this.domRoot.html('<table border="0" class="visualizer">\
                           <tr><td class="vizLayoutTd" id="vizLayoutTdFirst""></td></tr>\
                           <tr><td class="vizLayoutTd" id="vizLayoutTdSecond"></td></tr>\
                         </table>');
        }
        else {
            this.domRoot.html('<table border="0" class="visualizer"><tr>\
                           <td class="vizLayoutTd" id="vizLayoutTdFirst"></td>\
                           <td class="vizLayoutTd" id="vizLayoutTdSecond"></td>\
                         </tr></table>');
        }
        // create a container for a resizable slider to encompass
        // both CodeDisplay and NavigationController
        this.domRoot.find('#vizLayoutTdFirst').append('<div id="codAndNav" style="width: 550px;"/>');
        var base = this.domRoot.find('#vizLayoutTdFirst #codAndNav');
        var baseD3 = this.domRootD3.select('#vizLayoutTdFirst #codAndNav');
        this.codDisplay = new CodeDisplay(this, base, baseD3, this.curInputCode, this.params.lang, this.params.editCodeBaseURL);
        this.navControls = new NavigationController(this, base, baseD3, this.curTrace.length);
        if (this.params.embeddedMode) {
            // don't override if they've already been set!
            if (this.params.codeDivWidth === undefined) {
                this.params.codeDivWidth = ExecutionVisualizer.DEFAULT_EMBEDDED_CODE_DIV_WIDTH;
            }
            if (this.params.codeDivHeight === undefined) {
                this.params.codeDivHeight = ExecutionVisualizer.DEFAULT_EMBEDDED_CODE_DIV_HEIGHT;
            }
            // add an extra label to link back to the main site, so that viewers
            // on the embedded page know that they're seeing an OPT visualization
            base.find('#creditsPane').html('<div style="font-size: 8pt; margin-top: 5px; margin-bottom: 5px;"><a href="http://pythontutor.com/" target="_blank" style="color: #3D58A2;">Python Tutor</a> by <a href="http://pgbovine.net/" target="_blank" style="color: #3D58A2;">Philip Guo</a></div>');
            base.find('#codeFooterDocs').hide(); // cut out extraneous docs
        }
        else {
        }
        // not enough room for these extra buttons ...
        if (this.params.codeDivWidth &&
            this.params.codeDivWidth < 470) {
            this.domRoot.find('#jmpFirstInstr').hide();
            this.domRoot.find('#jmpLastInstr').hide();
        }
        if (this.params.codeDivWidth) {
            this.domRoot.find('#codAndNav').width(this.params.codeDivWidth);
        }
        if (this.params.codeDivHeight) {
            this.domRoot.find('#pyCodeOutputDiv')
                .css('max-height', this.params.codeDivHeight + 'px');
        }
        // enable left-right draggable pane resizer (originally from David Pritchard)
        base.resizable({
            handles: "e",
            minWidth: 100,
            resize: function (event, ui) {
                _this.domRoot.find("#codeDisplayDiv").css("height", "auto"); // redetermine height if necessary
                _this.navControls.renderSliderBreakpoints(_this.sortedBreakpointsList); // update breakpoint display accordingly on resize
                if (_this.params.updateOutputCallback) // report size change
                    _this.params.updateOutputCallback(_this);
            }
        });
        this.outputBox = new ProgramOutputBox(this, this.domRoot.find('#vizLayoutTdSecond'), this.params.embeddedMode ? '45px' : null);
        this.dataViz = new DataVisualizer(this, this.domRoot.find('#vizLayoutTdSecond'), this.domRootD3.select('#vizLayoutTdSecond'));
        myViz.navControls.showError(this.instrLimitReachedWarningMsg);
        myViz.navControls.setupSlider(this.curTrace.length - 1);
        if (this.params.startingInstruction) {
            this.params.jumpToEnd = false; // override! make sure to handle FIRST
            // weird special case for something like:
            // e=raw_input(raw_input("Enter something:"))
            if (this.params.startingInstruction == this.curTrace.length) {
                this.params.startingInstruction--;
            }
            // fail-soft with out-of-bounds startingInstruction values:
            if (this.params.startingInstruction < 0) {
                this.params.startingInstruction = 0;
            }
            if (this.params.startingInstruction >= this.curTrace.length) {
                this.params.startingInstruction = this.curTrace.length - 1;
            }
            assert(0 <= this.params.startingInstruction &&
                this.params.startingInstruction < this.curTrace.length);
            this.curInstr = this.params.startingInstruction;
        }
        if (this.params.jumpToEnd) {
            var firstErrorStep = -1;
            for (var i = 0; i < this.curTrace.length; i++) {
                var e = this.curTrace[i];
                if (e.event == 'exception' || e.event == 'uncaught_exception') {
                    firstErrorStep = i;
                    break;
                }
            }
            // set to first error step if relevant since that's more informative
            // than simply jumping to the very end
            if (firstErrorStep >= 0) {
                this.curInstr = firstErrorStep;
            }
            else {
                this.curInstr = this.curTrace.length - 1;
            }
        }
        if (this.params.hideCode) {
            this.domRoot.find('#vizLayoutTdFirst').hide(); // gigantic hack!
        }
        this.dataViz.precomputeCurTraceLayouts();
        if (!this.params.hideCode) {
            this.codDisplay.renderPyCodeOutput();
        }
        this.updateOutput();
        this.redrawConnectors(); // do this at the end
        this.hasRendered = true;
        this.try_hook("end_render", { myViz: this });
    };
    ExecutionVisualizer.prototype._getSortedBreakpointsList = function () {
        var ret = [];
        this.breakpoints.forEach(function (k, v) {
            ret.push(Number(k)); // these should be NUMBERS, not strings
        });
        ret.sort(function (x, y) { return x - y; }); // WTF, javascript sort is lexicographic by default!
        return ret;
    };
    ExecutionVisualizer.prototype.addToBreakpoints = function (executionPoints) {
        var _this = this;
        $.each(executionPoints, function (i, ep) {
            _this.breakpoints.set(ep, 1);
        });
        this.sortedBreakpointsList = this._getSortedBreakpointsList(); // keep synced!
    };
    ExecutionVisualizer.prototype.removeFromBreakpoints = function (executionPoints) {
        var _this = this;
        $.each(executionPoints, function (i, ep) {
            _this.breakpoints.remove(ep);
        });
        this.sortedBreakpointsList = this._getSortedBreakpointsList(); // keep synced!
    };
    ExecutionVisualizer.prototype.setBreakpoint = function (d) {
        this.addToBreakpoints(d.executionPoints);
        this.navControls.renderSliderBreakpoints(this.sortedBreakpointsList);
    };
    ExecutionVisualizer.prototype.unsetBreakpoint = function (d) {
        this.removeFromBreakpoints(d.executionPoints);
        this.navControls.renderSliderBreakpoints(this.sortedBreakpointsList);
    };
    // find the previous/next breakpoint to c or return -1 if it doesn't exist
    ExecutionVisualizer.prototype.findPrevBreakpoint = function () {
        var c = this.curInstr;
        if (this.sortedBreakpointsList.length == 0) {
            return -1;
        }
        else {
            for (var i = 1; i < this.sortedBreakpointsList.length; i++) {
                var prev = this.sortedBreakpointsList[i - 1];
                var cur = this.sortedBreakpointsList[i];
                if (c <= prev)
                    return -1;
                if (cur >= c)
                    return prev;
            }
            // final edge case:
            var lastElt = this.sortedBreakpointsList[this.sortedBreakpointsList.length - 1];
            return (lastElt < c) ? lastElt : -1;
        }
    };
    ExecutionVisualizer.prototype.findNextBreakpoint = function () {
        var c = this.curInstr;
        if (this.sortedBreakpointsList.length == 0) {
            return -1;
        }
        // usability hack: if you're currently on a breakpoint, then
        // single-step forward to the next execution point, NOT the next
        // breakpoint. it's often useful to see what happens when the line
        // at a breakpoint executes.
        else if ($.inArray(c, this.sortedBreakpointsList) >= 0) {
            return c + 1;
        }
        else {
            for (var i = 0; i < this.sortedBreakpointsList.length - 1; i++) {
                var cur = this.sortedBreakpointsList[i];
                var next = this.sortedBreakpointsList[i + 1];
                if (c < cur)
                    return cur;
                if (cur <= c && c < next) // subtle
                    return next;
            }
            // final edge case:
            var lastElt = this.sortedBreakpointsList[this.sortedBreakpointsList.length - 1];
            return (lastElt > c) ? lastElt : -1;
        }
    };
    // returns true if action successfully taken
    ExecutionVisualizer.prototype.stepForward = function () {
        var myViz = this;
        if (myViz.curInstr < myViz.curTrace.length - 1) {
            // if there is a next breakpoint, then jump to it ...
            if (myViz.sortedBreakpointsList.length > 0) {
                var nextBreakpoint = myViz.findNextBreakpoint();
                if (nextBreakpoint != -1)
                    myViz.curInstr = nextBreakpoint;
                else
                    myViz.curInstr += 1; // prevent "getting stuck" on a solitary breakpoint
            }
            else {
                myViz.curInstr += 1;
            }
            myViz.updateOutput(true);
            return true;
        }
        return false;
    };
    // returns true if action successfully taken
    ExecutionVisualizer.prototype.stepBack = function () {
        var myViz = this;
        if (myViz.curInstr > 0) {
            // if there is a prev breakpoint, then jump to it ...
            if (myViz.sortedBreakpointsList.length > 0) {
                var prevBreakpoint = myViz.findPrevBreakpoint();
                if (prevBreakpoint != -1)
                    myViz.curInstr = prevBreakpoint;
                else
                    myViz.curInstr -= 1; // prevent "getting stuck" on a solitary breakpoint
            }
            else {
                myViz.curInstr -= 1;
            }
            myViz.updateOutput();
            return true;
        }
        return false;
    };
    // This function is called every time the display needs to be updated
    ExecutionVisualizer.prototype.updateOutput = function (smoothTransition) {
        if (smoothTransition === void 0) { smoothTransition = false; }
        if (this.params.hideCode) {
            this.updateOutputMini();
        }
        else {
            this.updateOutputFull(smoothTransition);
        }
        this.outputBox.renderOutput(this.curTrace[this.curInstr].stdout);
        this.try_hook("end_updateOutput", { myViz: this });
    };
    // does a LOT of stuff, called by updateOutput
    ExecutionVisualizer.prototype.updateOutputFull = function (smoothTransition) {
        assert(this.curTrace);
        assert(!this.params.hideCode);
        var myViz = this; // to prevent confusion of 'this' inside of nested functions
        // there's no point in re-rendering if this pane isn't even visible in the first place!
        if (!myViz.domRoot.is(':visible')) {
            return;
        }
        myViz.updateLineAndExceptionInfo(); // very important to call this before rendering code (argh order dependency)
        var prevDataVizHeight = myViz.dataViz.height();
        this.codDisplay.updateCodOutput(smoothTransition);
        // call the callback if necessary (BEFORE rendering)
        if (this.params.updateOutputCallback) {
            this.params.updateOutputCallback(this);
        }
        var totalInstrs = this.curTrace.length;
        var isFirstInstr = (this.curInstr == 0);
        var isLastInstr = (this.curInstr == (totalInstrs - 1));
        var msg = "Step " + String(this.curInstr + 1) + " of " + String(totalInstrs - 1);
        if (isLastInstr) {
            if (this.promptForUserInput || this.promptForMouseInput) {
                msg = '<b><font color="' + exports.brightRed + '">Enter user input:</font></b>';
            }
            else if (this.instrLimitReached) {
                msg = "Step limit reached";
            }
            else {
                msg = "Done running (" + String(totalInstrs - 1) + " steps)";
            }
        }
        this.navControls.setVcrControls(msg, isFirstInstr, isLastInstr);
        this.navControls.setSliderVal(this.curInstr);
        // render error (if applicable):
        if (myViz.curLineExceptionMsg) {
            if (myViz.curLineExceptionMsg === "Unknown error") {
                myViz.navControls.showError('Unknown error: ' + footer_html_1.unsupportedFeaturesStr);
            }
            else {
                myViz.navControls.showError(myViz.curLineExceptionMsg);
            }
        }
        else if (!this.instrLimitReached) { // ugly, I know :/
            myViz.navControls.showError(null);
        }
        // finally, render all of the data structures
        this.dataViz.renderDataStructures(this.curInstr);
        // call the callback if necessary (AFTER rendering)
        if (myViz.dataViz.height() != prevDataVizHeight) {
            if (this.params.heightChangeCallback) {
                this.params.heightChangeCallback(this);
            }
        }
        if (isLastInstr &&
            myViz.params.executeCodeWithRawInputFunc &&
            myViz.promptForUserInput) {
            this.navControls.showUserInputDiv();
        }
        else {
            this.navControls.hideUserInputDiv();
        }
    }; // end of updateOutputFull
    ExecutionVisualizer.prototype.updateOutputMini = function () {
        assert(this.params.hideCode);
        this.dataViz.renderDataStructures(this.curInstr);
    };
    ExecutionVisualizer.prototype.renderStep = function (step) {
        assert(0 <= step);
        assert(step < this.curTrace.length);
        // ignore redundant calls
        if (this.curInstr == step) {
            return;
        }
        this.curInstr = step;
        this.updateOutput();
    };
    ExecutionVisualizer.prototype.redrawConnectors = function () {
        this.dataViz.redrawConnectors();
    };
    // All of the Java frontend code in this function was written by David
    // Pritchard and Will Gwozdz, and integrated into pytutor.js by Philip Guo
    ExecutionVisualizer.prototype.activateJavaFrontend = function () {
        var prevLine = null;
        this.curTrace.forEach(function (e, i) {
            // ugh the Java backend doesn't attach line numbers to exception
            // events, so just take the previous line number as our best guess
            if (e.event === 'exception' && !e.line) {
                e.line = prevLine;
            }
            // super hack by Philip that reverses the direction of the stack so
            // that it grows DOWN and renders the same way as the Python and JS
            // visualizer stacks
            if (e.stack_to_render !== undefined) {
                e.stack_to_render.reverse();
            }
            prevLine = e.line;
        });
        this.add_pytutor_hook("renderPrimitiveObject", function (args) {
            var obj = args.obj, d3DomElement = args.d3DomElement;
            var typ = typeof obj;
            if (obj instanceof Array && obj[0] == "VOID") {
                d3DomElement.append('<span class="voidObj">void</span>');
            }
            else if (obj instanceof Array && obj[0] == "NUMBER-LITERAL") {
                // actually transmitted as a string
                d3DomElement.append('<span class="numberObj">' + obj[1] + '</span>');
            }
            else if (obj instanceof Array && obj[0] == "CHAR-LITERAL") {
                var asc = obj[1].charCodeAt(0);
                var ch = obj[1];
                // default
                var show = asc.toString(16);
                while (show.length < 4)
                    show = "0" + show;
                show = "\\u" + show;
                if (ch == "\n")
                    show = "\\n";
                else if (ch == "\r")
                    show = "\\r";
                else if (ch == "\t")
                    show = "\\t";
                else if (ch == "\b")
                    show = "\\b";
                else if (ch == "\f")
                    show = "\\f";
                else if (ch == "\'")
                    show = "\\\'";
                else if (ch == "\"")
                    show = "\\\"";
                else if (ch == "\\")
                    show = "\\\\";
                else if (asc >= 32)
                    show = ch;
                // stringObj to make monospace
                d3DomElement.append('<span class="stringObj">\'' + show + '\'</span>');
            }
            else
                return [false]; // we didn't handle it
            return [true]; // we handled it
        });
        this.add_pytutor_hook("isPrimitiveType", function (args) {
            var obj = args.obj;
            if ((obj instanceof Array && obj[0] == "VOID")
                || (obj instanceof Array && obj[0] == "NUMBER-LITERAL")
                || (obj instanceof Array && obj[0] == "CHAR-LITERAL")
                || (obj instanceof Array && obj[0] == "ELIDE"))
                return [true, true]; // we handled it, it's primitive
            return [false]; // didn't handle it
        });
        this.add_pytutor_hook("end_updateOutput", function (args) {
            var myViz = args.myViz;
            var curEntry = myViz.curTrace[myViz.curInstr];
            if (myViz.params.stdin && myViz.params.stdin != "") {
                var stdinPosition = curEntry.stdinPosition || 0;
                var stdinContent = '<span style="color:lightgray;text-decoration: line-through">' +
                    escapeHtml(myViz.params.stdin.substr(0, stdinPosition)) +
                    '</span>' +
                    escapeHtml(myViz.params.stdin.substr(stdinPosition));
                myViz.domRoot.find('#stdinShow').html(stdinContent);
            }
            return [false];
        });
        this.add_pytutor_hook("end_render", function (args) {
            var myViz = args.myViz;
            if (myViz.params.stdin && myViz.params.stdin != "") {
                var stdinHTML = '<div id="stdinWrap">stdin:<pre id="stdinShow" style="border:1px solid gray"></pre></div>';
                myViz.domRoot.find('#dataViz').append(stdinHTML); // TODO: leaky abstraction with #dataViz
            }
            myViz.domRoot.find('#' + myViz.generateID('globals_header')).html("Static fields");
        });
        this.add_pytutor_hook("isLinearObject", function (args) {
            var heapObj = args.heapObj;
            if (heapObj[0] == 'STACK' || heapObj[0] == 'QUEUE')
                return ['true', 'true'];
            return ['false'];
        });
        this.add_pytutor_hook("renderCompoundObject", function (args) {
            var objID = args.objID;
            var d3DomElement = args.d3DomElement;
            var obj = args.obj;
            var typeLabelPrefix = args.typeLabelPrefix;
            var myViz = args.myViz;
            var stepNum = args.stepNum;
            if (!(obj[0] == 'LIST' || obj[0] == 'QUEUE' || obj[0] == 'STACK'))
                return [false]; // didn't handle
            var label = obj[0].toLowerCase();
            var visibleLabel = { list: 'array', queue: 'queue', stack: 'stack' }[label];
            if (obj.length == 1) {
                d3DomElement.append('<div class="typeLabel">' + typeLabelPrefix + 'empty ' + visibleLabel + '</div>');
                return [true]; //handled
            }
            d3DomElement.append('<div class="typeLabel">' + typeLabelPrefix + visibleLabel + '</div>');
            d3DomElement.append('<table class="' + label + 'Tbl"></table>');
            var tbl = d3DomElement.children('table');
            if (obj[0] == 'LIST') {
                tbl.append('<tr></tr><tr></tr>');
                var headerTr = tbl.find('tr:first');
                var contentTr = tbl.find('tr:last');
                // i: actual index in json object; ind: apparent index
                for (var i = 1, ind = 0; i < obj.length; i++) {
                    var val = obj[i];
                    var elide = val instanceof Array && val[0] == 'ELIDE';
                    // add a new column and then pass in that newly-added column
                    // as d3DomElement to the recursive call to child:
                    headerTr.append('<td class="' + label + 'Header"></td>');
                    headerTr.find('td:last').append(elide ? "&hellip;" : ind);
                    contentTr.append('<td class="' + label + 'Elt"></td>');
                    if (!elide) {
                        myViz.renderNestedObject(val, stepNum, contentTr.find('td:last'));
                        ind++;
                    }
                    else {
                        contentTr.find('td:last').append("&hellip;");
                        ind += val[1]; // val[1] is the number of cells to skip
                    }
                }
            } // end of LIST handling
            // Stack and Queue handling code by Will Gwozdz
            /* The table produced for stacks and queues is formed slightly differently than the others,
           missing the header row. Two rows made the dashed border not line up properly */
            if (obj[0] == 'STACK') {
                tbl.append('<tr></tr><tr></tr>');
                var contentTr = tbl.find('tr:last');
                contentTr.append('<td class="' + label + 'FElt">' + '<span class="stringObj symbolic">&#8596;</span>' + '</td>');
                $.each(obj, function (ind, val) {
                    if (ind < 1)
                        return; // skip type tag and ID entry
                    contentTr.append('<td class="' + label + 'Elt"></td>');
                    myViz.renderNestedObject(val, stepNum, contentTr.find('td:last'));
                });
                contentTr.append('<td class="' + label + 'LElt">' + '</td>');
            }
            if (obj[0] == 'QUEUE') {
                tbl.append('<tr></tr><tr></tr>');
                var contentTr = tbl.find('tr:last');
                // Add arrows showing in/out direction
                contentTr.append('<td class="' + label + 'FElt">' + '<span class="stringObj symbolic">&#8592;</span></td>');
                $.each(obj, function (ind, val) {
                    if (ind < 1)
                        return; // skip type tag and ID entry
                    contentTr.append('<td class="' + label + 'Elt"></td>');
                    myViz.renderNestedObject(val, stepNum, contentTr.find('td:last'));
                });
                contentTr.append('<td class="' + label + 'LElt">' + '<span class="stringObj symbolic">&#8592;</span></td>');
            }
            return [true]; // did handle
        });
        this.add_pytutor_hook("end_renderDataStructures", function (args) {
            var myViz = args.myViz;
            myViz.domRoot.find("td.instKey:contains('___NO_LABEL!___')").hide();
            myViz.domRoot.find(".typeLabel:contains('dict')").each(function (i) {
                if ($(this).html() == 'dict')
                    $(this).html('symbol table');
                if ($(this).html() == 'empty dict')
                    $(this).html('empty symbol table');
            });
        });
        // java synthetics cause things which javascript doesn't like in an id
        // VERY important to bind(this) so that when it's called, 'this' is this current object
        var old_generateID = ExecutionVisualizer.prototype.generateID.bind(this);
        this.generateID = function (original_id) {
            var sanitized = original_id.replace(/[^0-9a-zA-Z_]/g, function (match) { return '-' + match.charCodeAt(0) + '-'; });
            return old_generateID(sanitized);
        };
        // utility functions
        var entityMap = {
            "&": "&amp;",
            "<": "&lt;",
            ">": "&gt;",
            '"': '&quot;',
            "'": '&#39;',
            "/": '&#x2F;'
        };
        var escapeHtml = function (string) {
            return String(string).replace(/[&<>"'\/]/g, function (s) {
                return entityMap[s];
            });
        };
    };
    // update fields corresponding to the current and previously executed lines
    // in the trace so that they can be properly highlighted; must call before
    // rendering code output (NB: argh pesky ordering dependency)
    ExecutionVisualizer.prototype.updateLineAndExceptionInfo = function () {
        var myViz = this;
        var totalInstrs = myViz.curTrace.length;
        var isLastInstr = myViz.curInstr === (totalInstrs - 1);
        myViz.curLineNumber = undefined;
        myViz.prevLineNumber = undefined;
        myViz.curLineIsReturn = undefined;
        myViz.prevLineIsReturn = undefined;
        myViz.curLineExceptionMsg = undefined;
        /* if instrLimitReached, then treat like a normal non-terminating line */
        var isTerminated = (!myViz.instrLimitReached && isLastInstr);
        var curLineNumber = null;
        var prevLineNumber = null;
        var curEntry = myViz.curTrace[myViz.curInstr];
        var curIsReturn = (curEntry.event == 'return');
        var prevIsReturn = false;
        if (myViz.curInstr > 0) {
            prevLineNumber = myViz.curTrace[myViz.curInstr - 1].line;
            prevIsReturn = (myViz.curTrace[myViz.curInstr - 1].event == 'return');
            /* kinda nutsy hack: if the previous line is a return line, don't
               highlight it. instead, highlight the line in the enclosing
               function that called this one (i.e., the call site). e.g.,:
      
               1. def foo(lst):
               2.   return len(lst)
               3.
               4. y = foo([1,2,3])
               5. print y
      
               If prevLineNumber is 2 and prevIsReturn, then curLineNumber is
               5, since that's the line that executes right after line 2
               finishes. However, this looks confusing to the user since what
               actually happened here was that the return value of foo was
               assigned to y on line 4. I want to have prevLineNumber be line
               4 so that it gets highlighted. There's no ideal solution, but I
               think that looks more sensible, since line 4 was the previous
               line that executed *in this function's frame*.
            */
            if (prevIsReturn) {
                var idx = myViz.curInstr - 1;
                var retStack = myViz.curTrace[idx].stack_to_render;
                // retStack.length == 0 in rare cases such as inside of an
                // exec() statement. #weird
                if (retStack.length > 0) {
                    var retFrameId = retStack[retStack.length - 1].frame_id;
                    // now go backwards until we find a 'call' to this frame
                    while (idx >= 0) {
                        var entry = myViz.curTrace[idx];
                        if (entry.event == 'call' && entry.stack_to_render) {
                            var topFrame = entry.stack_to_render[entry.stack_to_render.length - 1];
                            if (topFrame.frame_id == retFrameId) {
                                break; // DONE, we found the call that corresponds to this return
                            }
                        }
                        idx--;
                    }
                    // now idx is the index of the 'call' entry. we need to find the
                    // entry before that, which is the instruction before the call.
                    // THAT's the line of the call site.
                    if (idx > 0) {
                        var callingEntry = myViz.curTrace[idx - 1];
                        prevLineNumber = callingEntry.line; // WOOHOO!!!
                        prevIsReturn = false; // this is now a call site, not a return
                    }
                }
            }
        }
        var hasError = false;
        if (curEntry.event === 'exception' || curEntry.event === 'uncaught_exception') {
            assert(curEntry.exception_msg);
            hasError = true;
            myViz.curLineExceptionMsg = curEntry.exception_msg;
        }
        curLineNumber = curEntry.line;
        // edge case for the final instruction :0
        if (isTerminated && !hasError) {
            // don't show redundant arrows on the same line when terminated ...
            if (prevLineNumber == curLineNumber) {
                curLineNumber = null;
            }
        }
        // add these fields to myViz, which is the point of this function!
        myViz.curLineNumber = curLineNumber;
        myViz.prevLineNumber = prevLineNumber;
        myViz.curLineIsReturn = curIsReturn;
        myViz.prevLineIsReturn = prevIsReturn;
    };
    ExecutionVisualizer.prototype.isOutputLineVisibleForBubbles = function (lineDivID) {
        var pcod = this.domRoot.find('#pyCodeOutputDiv');
        var lineNoTd = $('#' + lineDivID);
        var LO = lineNoTd.offset().top;
        var PO = pcod.offset().top;
        var ST = pcod.scrollTop();
        var H = pcod.height();
        // add a few pixels of fudge factor on the bottom end due to bottom scrollbar
        return (PO <= LO) && (LO < (PO + H - 25));
    };
    ExecutionVisualizer.curVisualizerID = 1;
    ExecutionVisualizer.DEFAULT_EMBEDDED_CODE_DIV_WIDTH = 350;
    ExecutionVisualizer.DEFAULT_EMBEDDED_CODE_DIV_HEIGHT = 400;
    // always nest values of these types within objects to make the
    // visualization look cleaner:
    // - functions should be nested within heap objects since that's a more
    //   intuitive rendering for methods (i.e., functions within objects)
    // - lots of special cases for function/property-like python types that we should inline
    ExecutionVisualizer.DEFAULT_ALWAYS_NEST_TYPES = ['FUNCTION', 'JS_FUNCTION',
        'property', 'classmethod', 'staticmethod', 'builtin_function_or_method',
        'member_descriptor', 'getset_descriptor', 'method_descriptor', 'wrapper_descriptor'];
    return ExecutionVisualizer;
}()); // END class ExecutionVisualizer
exports.ExecutionVisualizer = ExecutionVisualizer;
// implements the data structure visualization for an entire trace
var DataVisualizer = /** @class */ (function () {
    function DataVisualizer(owner, domRoot, domRootD3) {
        this.owner = owner;
        this.params = this.owner.params;
        this.curTrace = this.owner.curTrace;
        this.domRoot = domRoot;
        this.domRootD3 = domRootD3;
        this.hideVarsSet = null;
        this.hideFieldsSet = null;
        this.draggedHeapObjectCSS = d3.map(); // see above for description
        var codeVizHTML = "\n      <div id=\"selectiveHideStatus\"></div>\n      <div id=\"dataViz\">\n         <table id=\"stackHeapTable\">\n           <tr>\n             <td id=\"stack_td\">\n               <div id=\"globals_area\">\n                 <div id=\"stackHeader\">" + this.getRealLabel("Frames") + "</div>\n               </div>\n               <div id=\"stack\"></div>\n             </td>\n             <td id=\"heap_td\">\n               <div id=\"heap\">\n                 <div id=\"heapHeader\">" + this.getRealLabel("Objects") + "</div>\n               </div>\n             </td>\n           </tr>\n         </table>\n       </div>";
        this.domRoot.append(codeVizHTML);
        // create a persistent globals frame
        // (note that we need to keep #globals_area separate from #stack for d3 to work its magic)
        this.domRoot.find("#globals_area").append('<div class="stackFrame" id="'
            + this.owner.generateID('globals') + '"><div id="' + this.owner.generateID('globals_header')
            + '" class="stackFrameHeader">' + this.getRealLabel('Global frame') + '</div><table class="stackFrameVarTable" id="'
            + this.owner.generateID('global_table') + '"></table></div>');
        this.jsPlumbInstance = jsPlumb.getInstance({
            Endpoint: ["Dot", { radius: 3 }],
            EndpointStyles: [{ fillStyle: connectorBaseColor }, { fillstyle: null } /* make right endpoint invisible */],
            Anchors: ["RightMiddle", "LeftMiddle"],
            PaintStyle: { lineWidth: 1, strokeStyle: connectorBaseColor },
            // From: http://jsplumb.github.io/jsplumb/home.html#container
            // "It is strongly recommended that you set a Container before you begin plumbing."
            // - if you don't do this, then jsplumb arrow elements will live next to
            //   the elements that anchor them, which INTERACTS REALLY REALLY BADLY
            //   with jQuery draggable in weird ways. so set this.domRoot as container
            Container: this.domRoot,
            // note that this documentation covers a newer version of jsPlumb, and
            // we're still on a super-old jsPlumb-1.3.10 in lib/
            // https://docs.jsplumbtoolkit.com/toolkit/current/articles/connectors.html
            Connector: ["StateMachine"],
            Overlays: [["Arrow", { length: 10, width: 7, foldback: 0.55, location: 1 /* 1 = display at target */ }]],
            EndpointHoverStyles: [{ fillStyle: connectorHighlightColor }, { fillstyle: null } /* make right endpoint invisible */],
            HoverPaintStyle: { lineWidth: 1, strokeStyle: connectorHighlightColor },
        });
    }
    DataVisualizer.prototype.height = function () {
        return this.domRoot.find('#dataViz').height();
    };
    // create a unique CSS ID for a heap object, which should include both
    // its ID and the current step number. this is necessary if we want to
    // display the same heap object at multiple execution steps.
    //
    // 2020-02-05: why do we need stepNum in the ID? what happens if we
    // remove it? it may be more convenient if we remove it since we can
    // then track the state of the same object across multiple execution steps
    // such as its location (if the user dragged it to a custom location)
    // or whether it's hidden or not, since it will have the same CSS ID
    // when it's being rendered at different execution steps. what might go wrong?
    DataVisualizer.prototype.generateHeapObjID = function (objID, stepNum) {
        // 2020-02-05 - remove stepNum from returned CSS ID and see what happens:
        //return this.owner.generateID('heap_object_' + objID + '_s' + stepNum);
        return this.owner.generateID('heap_object_' + objID);
    };
    // customize labels for each language's preferred vocabulary
    DataVisualizer.prototype.getRealLabel = function (label) {
        if (this.params.lang === 'js' || this.params.lang === 'ts' || this.params.lang === 'ruby') {
            if (label === 'list') {
                return 'array';
            }
            else if (label === 'instance') {
                return 'object';
            }
            else if (label === 'True') {
                return 'true';
            }
            else if (label === 'False') {
                return 'false';
            }
        }
        if (this.params.lang === 'js') {
            if (label === 'dict') {
                return 'Map';
            }
            else if (label === 'set') {
                return 'Set';
            }
        }
        else if (this.params.lang === 'ruby') {
            if (label === 'dict') {
                return 'hash';
            }
            else if (label === 'set') {
                return 'Set'; // the Ruby Set class is capitalized
            }
            else if (label === 'function') {
                return 'method';
            }
            else if (label === 'None') {
                return 'nil';
            }
            else if (label === 'Global frame') {
                return 'Global Object';
            }
        }
        else if (this.params.lang === 'java') {
            if (label === 'None') {
                return 'null';
            }
            else if (label === 'True') {
                return 'true';
            }
            else if (label === 'False') {
                return 'false';
            }
        }
        else if (this.params.lang === 'c' || this.params.lang === 'cpp') {
            if (label === 'Global frame') {
                return 'Global variables';
            }
            else if (label === 'Frames') {
                return 'Stack';
            }
            else if (label === 'Objects') {
                return 'Heap';
            }
        }
        // default fallthrough case if no matches above
        return label;
    };
    // for managing state related to pesky jsPlumb connectors, need to reset
    // before every call to renderDataStructures, or else all hell breaks
    // loose. yeah, this is kludgy and stateful, but at least all of the
    // relevant state gets shoved into one unified place
    DataVisualizer.prototype.resetJsPlumbManager = function () {
        this.jsPlumbManager = {
            heap_pointer_src_id: 1,
            // Key:   CSS ID of the div element representing the stack frame variable
            //        (for stack->heap connections) or heap object (for heap->heap connections)
            //        the format is: '<this.visualizerID>__heap_pointer_src_<src id>'
            // Value: CSS ID of the div element representing the value rendered in the heap
            //        (the format is given by generateHeapObjID())
            //
            // The reason we need to prepend this.visualizerID is because jsPlumb needs
            // GLOBALLY UNIQUE IDs for use as connector endpoints.
            //
            // TODO: jsPlumb might be able to directly take DOM elements rather
            // than IDs, which makes the above point moot. But let's just stick
            // with this for now until I want to majorly refactor :)
            // the only elements in these sets are NEW elements to be rendered in this
            // particular call to renderDataStructures.
            connectionEndpointIDs: d3.map(),
            heapConnectionEndpointIDs: d3.map(),
            // analogous to connectionEndpointIDs, except for environment parent pointers
            parentPointerConnectionEndpointIDs: d3.map(),
            renderedHeapObjectIDs: d3.map(),
        };
    };
    // gets all global and local variable names used in this program
    // execution as indicated by this.curTrace
    DataVisualizer.prototype.getAllProgramVarnames = function () {
        var me = this;
        var allVarnames = [];
        $.each(this.curTrace, function (i, curEntry) {
            $.each(curEntry.ordered_globals, function (i, varname) {
                var encodedVarname = DataVisualizer.GLOBAL_PREFIX + ':' + varname;
                if (allVarnames.indexOf(encodedVarname) < 0) { // don't insert duplicates
                    allVarnames.push(encodedVarname);
                }
            });
            $.each(curEntry.stack_to_render, function (i, frame) {
                // some functions are unnamed, so use a placeholder:
                var func_prefix = frame.func_name ? frame.func_name : DataVisualizer.UNNAMED_PREFIX;
                $.each(frame.ordered_varnames, function (xxx, varname) {
                    var encodedVarname = func_prefix + ':' + varname;
                    if (allVarnames.indexOf(encodedVarname) < 0) { // don't insert duplicates
                        allVarnames.push(encodedVarname);
                    }
                });
            });
        });
        return allVarnames;
    };
    // gets all field names of classes, objects, dicts, C structs, and anything
    // else that has attribute/field names, as indicated by this.curTrace
    DataVisualizer.prototype.getAllProgramObjectFieldNames = function () {
        var me = this;
        var allFieldnames = [];
        // copied from recurseIntoCStructArray ...
        // see inside comments for an optimization opportunity:
        function traverseCStructArray(val) {
            if (val[0] == 'C_STRUCT') {
                // grab all field names and add to allFieldnames
                var structName_1 = val[2] ? val[2] : DataVisualizer.UNNAMED_PREFIX;
                $.each(val, function (ind, kvPair) {
                    if (ind < 3)
                        return; // these have 3 header fields
                    var fieldName = kvPair[0];
                    var encodedFieldname = structName_1 + ':' + fieldName;
                    if (allFieldnames.indexOf(encodedFieldname) < 0) { // don't insert duplicates
                        allFieldnames.push(encodedFieldname);
                    }
                });
            }
            // recurse inside if necessary ...
            //
            // TODO: if you really want to make this more efficient
            // (especially for huge arrays), you can simply traverse into the
            // *first element* of C_ARRAY or C_MULTIDIMENSIONAL_ARRAY since
            // they're supposedly homogeneous, so the type of the first element
            // should be identical to the type of all other elements :)
            // (just beware of the case of empty (zero-sized) arrays, though)
            if (val[0] === 'C_ARRAY') {
                $.each(val, function (ind, elt) {
                    if (ind < 2)
                        return; // these have 2 header fields
                    traverseCStructArray(elt);
                });
            }
            else if (val[0] === 'C_MULTIDIMENSIONAL_ARRAY' || val[0] === 'C_STRUCT') {
                $.each(val, function (ind, kvPair) {
                    if (ind < 3)
                        return; // these have 3 header fields
                    traverseCStructArray(kvPair[1]);
                });
            }
        }
        $.each(this.curTrace, function (i, curEntry) {
            //console.log(i, curEntry);
            // iterate through the heap looking for relevant objects with fields
            // expected format from ../pg_encoder.py
            // #   * instance - ['INSTANCE', class name, [attr1, value1], [attr2, value2], ..., [attrN, valueN]]
            // #   * instance with non-trivial __str__ defined - ['INSTANCE_PPRINT', class name, <__str__ value>, [attr1, value1], [attr2, value2], ..., [attrN, valueN]]
            // #   * class    - ['CLASS', class name, [list of superclass names], [attr1, value1], [attr2, value2], ..., [attrN, valueN]]
            //
            // also for javascript, JS_FUNCTION objects may have funcProperties
            //
            // [NB: we don't count DICT here since those don't technically contain
            // 'fields'; they contain dict keys, which don't necessarily need to be
            // strings, so it's confusing to try to ignore a non-string dict key]
            $.each(curEntry.heap, function (k, obj) {
                var typ = obj[0];
                if (typ == 'INSTANCE' || typ == 'INSTANCE_PPRINT' || typ == 'CLASS') {
                    var _a = DataVisualizer.getClassInstanceMetadata(obj), className = _a[0], headerLength = _a[1];
                    for (var i_1 = headerLength; i_1 < obj.length; i_1++) {
                        var fieldName = obj[i_1][0];
                        // className can possibly be null ...
                        var encodedFieldname = className ? className + ':' + fieldName : fieldName;
                        if (allFieldnames.indexOf(encodedFieldname) < 0) { // don't insert duplicates
                            allFieldnames.push(encodedFieldname);
                        }
                    }
                }
                else if (typ == 'JS_FUNCTION') {
                    var funcProperties = obj[3];
                    if (funcProperties) {
                        var funcName = obj[1];
                        // special-case handling: prefix with function name if appropriate
                        for (var i_2 = 0; i_2 < funcProperties.length; i_2++) {
                            var fieldName = funcProperties[i_2][0];
                            // funcName can possibly be empty ...
                            var encodedFieldname = funcName ? funcName + ':' + fieldName : fieldName;
                            if (allFieldnames.indexOf(encodedFieldname) < 0) { // don't insert duplicates
                                allFieldnames.push(encodedFieldname);
                            }
                        }
                    }
                }
                else if (typ == 'C_ARRAY' || typ == 'C_MULTIDIMENSIONAL_ARRAY' || typ == 'C_STRUCT') {
                    traverseCStructArray(obj);
                }
            });
            // C and C++ objects can exist directly within the global frame or
            // stack frames (not just on the heap), so we need to traverse
            // through those as well
            if (me.isCppMode()) {
                $.each(curEntry.ordered_globals, function (i, varname) {
                    var val = curEntry.globals[varname];
                    traverseCStructArray(val);
                });
                // iterate thru all stack frames
                $.each(curEntry.stack_to_render, function (i, frame) {
                    $.each(frame.ordered_varnames, function (xxx, varname) {
                        var val = frame.encoded_locals[varname];
                        traverseCStructArray(val);
                    });
                });
            }
        });
        return allFieldnames;
    };
    // this method initializes curTraceLayouts
    //
    // Pre-compute the layout of top-level heap objects for ALL execution
    // points as soon as a trace is first loaded. The reason why we want to
    // do this is so that when the user steps through execution points, the
    // heap objects don't "jiggle around" (i.e., preserving positional
    // invariance). Also, if we set up the layout objects properly, then we
    // can take full advantage of d3 to perform rendering and transitions.
    //
    // (also call this function whenever the user chooses to selectively
    //  hide/show variables/objects, since we want to get the latest layout)
    DataVisualizer.prototype.precomputeCurTraceLayouts = function () {
        //console.log('precomputeCurTraceLayouts');
        // curTraceLayouts is a list of top-level heap layout "objects" with the
        // same length as curTrace after it's been fully initialized. Each
        // element of curTraceLayouts is computed from the contents of its
        // immediate predecessor, thus ensuring that objects don't "jiggle
        // around" between consecutive execution points.
        //
        // Each top-level heap layout "object" is itself a LIST of LISTS of
        // object IDs, where each element of the outer list represents a row,
        // and each element of the inner list represents columns within a
        // particular row. Each row can have a different number of columns. Most
        // rows have exactly ONE column (representing ONE object ID), but rows
        // containing 1-D linked data structures have multiple columns. Each
        // inner list element looks something like ['row1', 3, 2, 1] where the
        // first element is a unique row ID tag, which is used as a key for d3 to
        // preserve "object constancy" for updates, transitions, etc. The row ID
        // is derived from the FIRST object ID inserted into the row. Since all
        // object IDs are unique, all row IDs will also be unique.
        /* This is a good, simple example to test whether objects "jiggle"
    
        x = [1, [2, [3, None]]]
        y = [4, [5, [6, None]]]
    
        x[1][1] = y[1]
    
        */
        this.curTraceLayouts = [];
        this.curTraceLayouts.push([]); // pre-seed with an empty sentinel to simplify the code
        var myViz = this; // to prevent confusion of 'this' inside of nested functions
        assert(this.curTrace && this.curTrace.length > 0);
        $.each(this.curTrace, function (i, curEntry) {
            var prevLayout = myViz.curTraceLayouts[myViz.curTraceLayouts.length - 1];
            // make a DEEP COPY of prevLayout to use as the basis for curLine
            var curLayout = $.extend(true /* deep copy */, [], prevLayout);
            // initialize with all IDs from curLayout
            var idsToRemove = d3.map();
            $.each(curLayout, function (i, row) {
                for (var j = 1 /* ignore row ID tag */; j < row.length; j++) {
                    idsToRemove.set(row[j], 1);
                }
            });
            var idsAlreadyLaidOut = d3.map(); // to prevent infinite recursion
            function curLayoutIndexOf(id) {
                for (var i = 0; i < curLayout.length; i++) {
                    var row = curLayout[i];
                    var index = row.indexOf(id);
                    if (index > 0) { // index of 0 is impossible since it's the row ID tag
                        return { row: row, index: index };
                    }
                }
                return null;
            }
            function isLinearObj(heapObj) {
                var hook_result = myViz.owner.try_hook("isLinearObj", { heapObj: heapObj });
                if (hook_result[0])
                    return hook_result[1];
                return heapObj[0] == 'LIST' || heapObj[0] == 'TUPLE' || heapObj[0] == 'SET';
            }
            function recurseIntoObject(id, curRow, newRow) {
                // heuristic for laying out 1-D linked data structures: check for enclosing elements
                // that are structurallyEquivalent() and then lay them out as siblings in the same "row"
                var heapObj = curEntry.heap[id];
                if (myViz.isCppMode()) {
                    // soften this assumption since C-style pointers might not point
                    // to the heap; they can point to any piece of data!
                    if (!heapObj) {
                        return;
                    }
                }
                else {
                    assert(heapObj);
                }
                if (isLinearObj(heapObj)) {
                    $.each(heapObj, function (ind, child) {
                        if (ind < 1)
                            return; // skip type tag
                        if (!myViz.isPrimitiveType(child)) {
                            var childID = getRefID(child);
                            if (myViz.structurallyEquivalent(heapObj, curEntry.heap[childID])) {
                                updateCurLayout(childID, curRow, newRow);
                            }
                            else if (!myViz.owner.shouldNestObject(curEntry.heap[childID])) {
                                updateCurLayout(childID, [], []);
                            }
                        }
                    });
                }
                else if (heapObj[0] == 'DICT') {
                    $.each(heapObj, function (ind, child) {
                        if (ind < 1)
                            return; // skip type tag
                        var dictKey = child[0];
                        if (!myViz.isPrimitiveType(dictKey)) {
                            var keyChildID = getRefID(dictKey);
                            if (!myViz.owner.shouldNestObject(curEntry.heap[keyChildID])) {
                                updateCurLayout(keyChildID, [], []);
                            }
                        }
                        var dictVal = child[1];
                        if (!myViz.isPrimitiveType(dictVal)) {
                            var childID = getRefID(dictVal);
                            if (myViz.structurallyEquivalent(heapObj, curEntry.heap[childID])) {
                                updateCurLayout(childID, curRow, newRow);
                            }
                            else if (!myViz.owner.shouldNestObject(curEntry.heap[childID])) {
                                updateCurLayout(childID, [], []);
                            }
                        }
                    });
                }
                else if (heapObj[0] == 'INSTANCE' || heapObj[0] == 'INSTANCE_PPRINT' || heapObj[0] == 'CLASS') {
                    var _a = DataVisualizer.getClassInstanceMetadata(heapObj), className_1 = _a[0], headerLength_1 = _a[1];
                    jQuery.each(heapObj, function (ind, child) {
                        if (ind < headerLength_1)
                            return;
                        var instKey = child[0];
                        if (myViz.inHideFieldsSet(className_1, instKey)) {
                            //console.log('precompute HIDING', className, instKey);
                            return; // get out!
                        }
                        if (!myViz.isPrimitiveType(instKey)) {
                            var keyChildID = getRefID(instKey);
                            if (!myViz.owner.shouldNestObject(curEntry.heap[keyChildID])) {
                                updateCurLayout(keyChildID, [], []);
                            }
                        }
                        var instVal = child[1];
                        if (!myViz.isPrimitiveType(instVal)) {
                            var childID = getRefID(instVal);
                            if (myViz.structurallyEquivalent(heapObj, curEntry.heap[childID])) {
                                updateCurLayout(childID, curRow, newRow);
                            }
                            else if (!myViz.owner.shouldNestObject(curEntry.heap[childID])) {
                                updateCurLayout(childID, [], []);
                            }
                        }
                    });
                }
                else if (heapObj[0] == 'FUNCTION' || heapObj[0] == 'JS_FUNCTION') {
                    // a Python function object has an optional element at index=3
                    // (zero-indexed) that represents default arg names/values
                    //
                    // a JavaScript function object has funcProperties that we should
                    // recurse into in order to precompute their layouts
                    var funcProperties = null;
                    // traverse into default argument values to precompute their
                    // layouts, if applicable
                    if (heapObj[0] == 'FUNCTION' && heapObj.length > 3) {
                        funcProperties = heapObj[3];
                    }
                    if (heapObj[0] == 'JS_FUNCTION') {
                        assert(heapObj.length == 5);
                        funcProperties = heapObj[3];
                    }
                    if (funcProperties) {
                        assert(funcProperties.length > 0);
                        var funcName_1 = heapObj[1];
                        $.each(funcProperties, function (ind, kvPair) {
                            // only check this for JS_FUNCTION! we're overloading
                            // funcProperties to use for both FUNCTION and
                            // JS_FUNCTION, which might be confusing ...
                            if (heapObj[0] == 'JS_FUNCTION') {
                                var instKey = kvPair[0];
                                if (myViz.inHideFieldsSet(funcName_1, instKey)) {
                                    //console.log('precompute HIDING', funcName, instKey);
                                    return; // get out!
                                }
                            }
                            // copy/paste from INSTANCE/CLASS code above
                            var instVal = kvPair[1];
                            if (!myViz.isPrimitiveType(instVal)) {
                                var childID = getRefID(instVal);
                                if (!myViz.owner.shouldNestObject(curEntry.heap[childID])) {
                                    updateCurLayout(childID, [], []);
                                }
                            }
                        });
                    }
                }
                else if ((heapObj[0] == 'C_ARRAY') || (heapObj[0] == 'C_MULTIDIMENSIONAL_ARRAY') || (heapObj[0] == 'C_STRUCT')) {
                    updateCurLayoutAndRecurse(heapObj);
                }
            }
            // a krazy function!
            // id     - the new object ID to be inserted somewhere in curLayout
            //          (if it's not already in there)
            // curRow - a row within curLayout where new linked list
            //          elements can be appended onto (might be null)
            // newRow - a new row that might be spliced into curRow or appended
            //          as a new row in curLayout
            function updateCurLayout(id, curRow, newRow) {
                if (idsAlreadyLaidOut.has(id)) {
                    return; // PUNT!
                }
                var curLayoutLoc = curLayoutIndexOf(id);
                var alreadyLaidOut = idsAlreadyLaidOut.has(id);
                idsAlreadyLaidOut.set(id, 1); // unconditionally set now
                // if id is already in curLayout ...
                if (curLayoutLoc) {
                    var foundRow = curLayoutLoc.row;
                    var foundIndex = curLayoutLoc.index;
                    idsToRemove.remove(id); // this id is already accounted for!
                    // very subtle ... if id hasn't already been handled in
                    // this iteration, then splice newRow into foundRow. otherwise
                    // (later) append newRow onto curLayout as a truly new row
                    if (!alreadyLaidOut) {
                        // splice the contents of newRow right BEFORE foundIndex.
                        // (Think about when you're trying to insert in id=3 into ['row1', 2, 1]
                        //  to represent a linked list 3->2->1. You want to splice the 3
                        //  entry right before the 2 to form ['row1', 3, 2, 1])
                        if (newRow.length > 1) {
                            var args = [foundIndex, 0];
                            for (var i = 1; i < newRow.length; i++) { // ignore row ID tag
                                args.push(newRow[i]);
                                idsToRemove.remove(newRow[i]);
                            }
                            foundRow.splice.apply(foundRow, args);
                            // remove ALL elements from newRow since they've all been accounted for
                            // (but don't reassign it away to an empty list, since the
                            // CALLER checks its value. TODO: how to get rid of this gross hack?!?)
                            newRow.splice(0, newRow.length);
                        }
                    }
                    // recurse to find more top-level linked entries to append onto foundRow
                    recurseIntoObject(id, foundRow, []);
                }
                else {
                    // push id into newRow ...
                    if (newRow.length == 0) {
                        newRow.push('row' + id); // unique row ID (since IDs are unique)
                    }
                    newRow.push(id);
                    // recurse to find more top-level linked entries ...
                    recurseIntoObject(id, curRow, newRow);
                    // if newRow hasn't been spliced into an existing row yet during
                    // a child recursive call ...
                    if (newRow.length > 0) {
                        if (curRow && curRow.length > 0) {
                            // append onto the END of curRow if it exists
                            for (var i = 1; i < newRow.length; i++) { // ignore row ID tag
                                curRow.push(newRow[i]);
                            }
                        }
                        else {
                            // otherwise push to curLayout as a new row
                            //
                            // TODO: this might not always look the best, since we might
                            // sometimes want to splice newRow in the MIDDLE of
                            // curLayout. Consider this example:
                            //
                            // x = [1,2,3]
                            // y = [4,5,6]
                            // x = [7,8,9]
                            //
                            // when the third line is executed, the arrows for x and y
                            // will be crossed (ugly!) since the new row for the [7,8,9]
                            // object is pushed to the end (bottom) of curLayout. The
                            // proper behavior is to push it to the beginning of
                            // curLayout where the old row for 'x' used to be.
                            curLayout.push($.extend(true /* make a deep copy */, [], newRow));
                        }
                        // regardless, newRow is now accounted for, so clear it
                        for (var i = 1; i < newRow.length; i++) { // ignore row ID tag
                            idsToRemove.remove(newRow[i]);
                        }
                        newRow.splice(0, newRow.length); // kill it!
                    }
                }
            }
            function updateCurLayoutAndRecurse(elt) {
                if (!elt)
                    return; // early bail out
                if (isHeapRef(elt, curEntry.heap)) {
                    var id = getRefID(elt);
                    updateCurLayout(id, null, []);
                }
                recurseIntoCStructArray(elt);
            }
            // traverse inside of C structs and arrays to find whether they
            // (recursively) contain any references to heap objects within
            // themselves. be able to handle arbitrary nesting!
            function recurseIntoCStructArray(val) {
                if (val[0] === 'C_ARRAY') {
                    $.each(val, function (ind, elt) {
                        if (ind < 2)
                            return; // these have 2 header fields
                        updateCurLayoutAndRecurse(elt);
                    });
                }
                else if (val[0] === 'C_MULTIDIMENSIONAL_ARRAY' || val[0] === 'C_STRUCT') {
                    $.each(val, function (ind, kvPair) {
                        if (ind < 3)
                            return; // these have 3 header fields
                        if (val[0] === 'C_STRUCT') {
                            var structName = val[2] ? val[2] : DataVisualizer.UNNAMED_PREFIX;
                            var fieldName = kvPair[0];
                            if (myViz.inHideFieldsSet(structName, fieldName)) {
                                //console.log('precompute HIDING', structName, fieldName);
                                return; // get out!
                            }
                        }
                        updateCurLayoutAndRecurse(kvPair[1]);
                    });
                }
            }
            // iterate through all globals and ordered stack frames and call updateCurLayout
            $.each(curEntry.ordered_globals, function (i, varname) {
                if (myViz.inHideVarsSet(DataVisualizer.GLOBAL_PREFIX, varname)) {
                    //console.log('precompute HIDING', DataVisualizer.GLOBAL_PREFIX, varname);
                    return; // get out!
                }
                var val = curEntry.globals[varname];
                if (val !== undefined) { // might not be defined at this line, which is OKAY!
                    // TODO: try to unify this behavior between C/C++ and other languages:
                    if (myViz.isCppMode()) {
                        updateCurLayoutAndRecurse(val);
                    }
                    else {
                        if (!myViz.isPrimitiveType(val)) {
                            var id = getRefID(val);
                            updateCurLayout(id, null, []);
                        }
                    }
                }
            });
            $.each(curEntry.stack_to_render, function (i, frame) {
                // some functions are unnamed, so use a placeholder:
                var func_prefix = frame.func_name ? frame.func_name : DataVisualizer.UNNAMED_PREFIX;
                $.each(frame.ordered_varnames, function (xxx, varname) {
                    if (myViz.inHideVarsSet(func_prefix, varname)) {
                        //console.log('precompute HIDING', func_prefix, varname);
                        return; // get out!
                    }
                    var val = frame.encoded_locals[varname];
                    // TODO: try to unify this behavior between C/C++ and other languages:
                    if (myViz.isCppMode()) {
                        updateCurLayoutAndRecurse(val);
                    }
                    else {
                        if (!myViz.isPrimitiveType(val)) {
                            var id = getRefID(val);
                            updateCurLayout(id, null, []);
                        }
                    }
                });
            });
            // iterate through remaining elements of idsToRemove and REMOVE them from curLayout
            idsToRemove.forEach(function (id, xxx) {
                var idInt = Number(id); // keys are stored as strings, so convert!!!
                $.each(curLayout, function (rownum, row) {
                    var ind = row.indexOf(idInt);
                    if (ind > 0) { // remember that index 0 of the row is the row ID tag
                        row.splice(ind, 1);
                    }
                });
            });
            // now remove empty rows (i.e., those with only a row ID tag) from curLayout
            curLayout = curLayout.filter(function (row) { return row.length > 1; });
            myViz.curTraceLayouts.push(curLayout);
        });
        this.curTraceLayouts.splice(0, 1); // remove seeded empty sentinel element
        assert(this.curTrace.length == this.curTraceLayouts.length);
    };
    // is this visualizer in C or C++ mode? the eventual goal is to remove
    // this special-case kludge check altogether and have the entire
    // codebase be unified. but for now, keep C/C++ separate because I don't
    // want to risk screwing up the visualizations for the other languages
    DataVisualizer.prototype.isCppMode = function () {
        return (this.params.lang === 'c' || this.params.lang === 'cpp');
    };
    // compare two JSON-encoded compound objects for structural equivalence:
    DataVisualizer.prototype.structurallyEquivalent = function (obj1, obj2) {
        // punt if either isn't a compound type
        if (this.isPrimitiveType(obj1) || this.isPrimitiveType(obj2)) {
            return false;
        }
        // must be the same compound type
        if (obj1[0] != obj2[0]) {
            return false;
        }
        // must have the same number of elements or fields
        if (obj1.length != obj2.length) {
            return false;
        }
        // for a list or tuple, same size (e.g., a cons cell is a list/tuple of size 2)
        if (obj1[0] == 'LIST' || obj1[0] == 'TUPLE') {
            return true;
        }
        else {
            var startingInd = -1;
            if (obj1[0] == 'DICT') {
                startingInd = 1;
            }
            else if (obj1[0] == 'INSTANCE') {
                startingInd = 2;
            }
            else if (obj1[0] == 'INSTANCE_PPRINT') {
                startingInd = 3;
            }
            else {
                return false; // punt on all other types
            }
            var obj1fields = d3.map();
            // for a dict or object instance, same names of fields (ordering doesn't matter)
            for (var i = startingInd; i < obj1.length; i++) {
                obj1fields.set(obj1[i][0], 1); // use as a set
            }
            for (var i = startingInd; i < obj2.length; i++) {
                if (!obj1fields.has(obj2[i][0])) {
                    return false;
                }
            }
            return true;
        }
    };
    DataVisualizer.prototype.isPrimitiveType = function (obj) {
        var hook_result = this.owner.try_hook("isPrimitiveType", { obj: obj });
        if (hook_result[0])
            return hook_result[1];
        // null is a primitive
        if (obj === null) {
            return true;
        }
        if (typeof obj == "object") {
            // kludgy
            return (obj[0] == 'IMPORTED_FAUX_PRIMITIVE' ||
                obj[0] == 'SPECIAL_FLOAT' || obj[0] == 'JS_SPECIAL_VAL' ||
                obj[0] == 'C_DATA' /* TODO: is this right?!? */);
        }
        else {
            // non-objects are primitives
            return true;
        }
    };
    // This is the main event right here!!!
    //
    // The "4.0" version of renderDataStructures was refactored to be much
    // less monolithic and more modular. It was made possible by first
    // creating a suite of frontend JS regression tests so that I felt more
    // comfortable mucking around with the super-brittle code in this
    // function. This version was created in April 2014. For reference,
    // before refactoring, this function was 1,030 lines of convoluted code!
    //
    // (Also added the rightward nudge hack to make tree-like structures
    // look more sane without any sophisticated graph rendering code. Thanks
    // to John DeNero for this suggestion all the way back in Fall 2012.)
    //
    // The "3.0" version of renderDataStructures renders variables in
    // a stack, values in a separate heap, and draws line connectors
    // to represent both stack->heap object references and, more importantly,
    // heap->heap references. This version was created in August 2012.
    //
    // The "2.0" version of renderDataStructures renders variables in
    // a stack and values in a separate heap, with data structure aliasing
    // explicitly represented via line connectors (thanks to jsPlumb lib).
    // This version was created in September 2011.
    //
    // The ORIGINAL "1.0" version of renderDataStructures
    // was created in January 2010 and rendered variables and values
    // INLINE within each stack frame without any explicit representation
    // of data structure aliasing. That is, aliased objects were rendered
    // multiple times, and a unique ID label was used to identify aliases.
    DataVisualizer.prototype.renderDataStructures = function (curInstr) {
        //console.log('renderDataStructures', curInstr);
        var myViz = this; // to prevent confusion of 'this' inside of nested functions
        var curEntry = this.curTrace[curInstr];
        var curToplevelLayout = this.curTraceLayouts[curInstr];
        myViz.resetJsPlumbManager(); // very important!!!
        // for simplicity (but sacrificing some performance), delete all
        // connectors and redraw them from scratch. doing so avoids mysterious
        // jsPlumb connector alignment issues when the visualizer's enclosing
        // div contains, say, a "position: relative;" CSS tag
        // (which happens in the IPython Notebook)
        var existingConnectionEndpointIDs = d3.map();
        myViz.jsPlumbInstance.select({ scope: 'varValuePointer' }).each(function (c) {
            // This is VERY crude, but to prevent multiple redundant HEAP->HEAP
            // connectors from being drawn with the same source and origin, we need to first
            // DELETE ALL existing HEAP->HEAP connections, and then re-render all of
            // them in each call to this function. The reason why we can't safely
            // hold onto them is because there's no way to guarantee that the
            // *__heap_pointer_src_<src id> IDs are consistent across execution points.
            //
            // thus, only add to existingConnectionEndpointIDs if this is NOT heap->heap
            if (!c.sourceId.match(heapPtrSrcRE)) {
                existingConnectionEndpointIDs.set(c.sourceId, c.targetId);
            }
        });
        var existingParentPointerConnectionEndpointIDs = d3.map();
        myViz.jsPlumbInstance.select({ scope: 'frameParentPointer' }).each(function (c) {
            existingParentPointerConnectionEndpointIDs.set(c.sourceId, c.targetId);
        });
        // what variables/fields were hidden in this call to renderDataStructures?
        // (make these fields and not locals so that we can access them in
        // other methods too, ergh)
        myViz.varsHidden = [];
        myViz.fieldsHidden = [];
        // Heap object rendering phase:
        // count everything in curToplevelLayout as already rendered since we will render them
        // in d3 .each() statements
        $.each(curToplevelLayout, function (xxx, row) {
            for (var i = 0; i < row.length; i++) {
                var objID = row[i];
                var heapObjID = myViz.generateHeapObjID(objID, curInstr);
                myViz.jsPlumbManager.renderedHeapObjectIDs.set(heapObjID, 1);
            }
        });
        // use d3 to render the heap by mapping curToplevelLayout into <table class="heapRow">
        // and <td class="toplevelHeapObject"> elements
        // before we clear the heap div below, record the custom positions
        // of any heapObjects that we've made as draggable *and* that's been
        // dragged somewhere different (as indicated by the jQuery
        // data('draggedCSS') attribute being set to the custom CSS of the
        // dragged object, which should contain its current custom position)
        myViz.domRoot.find('.heapObject').each(function (i, e) {
            var draggedCSS = $(e).data('draggedCSS');
            if (draggedCSS) {
                // save a mapping between the .heapObject id and its draggedCSS
                myViz.draggedHeapObjectCSS.set($(e).attr('id'), draggedCSS);
            }
        });
        // now it's safe to totally erase all .heapObject elements by
        // emptying '#heap' below ...
        // for simplicity, CLEAR this entire div every time, which totally
        // gets rid of the incremental benefits of using d3 for, say,
        // transitions or efficient updates. but it provides more
        // deterministic and predictable output for other functions. sigh, i'm
        // not really using d3 to the fullest, but oh wells!
        myViz.domRoot.find('#heap')
            .empty()
            .html("<div id=\"heapHeader\">" + myViz.getRealLabel("Objects") + "</div>");
        var heapRows = myViz.domRootD3.select('#heap')
            .selectAll('table.heapRow')
            .attr('id', function (d, i) { return 'heapRow' + i; }) // add unique ID
            .data(curToplevelLayout, function (objLst) {
            return objLst[0]; // return first element, which is the row ID tag
        });
        // insert new heap rows
        heapRows.enter().append('table')
            //.each(function(objLst, i) {console.log('NEW ROW:', objLst, i);})
            .attr('id', function (d, i) { return 'heapRow' + i; }) // add unique ID
            .attr('class', 'heapRow');
        // delete a heap row
        var hrExit = heapRows.exit();
        hrExit
            .each(function (d, idx) {
            //console.log('DEL ROW:', d, idx);
            $(this).empty(); // crucial for garbage collecting jsPlumb connectors!
        })
            .remove();
        // update an existing heap row
        var toplevelHeapObjects = heapRows
            //.each(function(objLst, i) { console.log('UPDATE ROW:', objLst, i); })
            .selectAll('td.toplevelHeapObject')
            .data(function (d, i) { return d.slice(1, d.length); }, /* map over each row, skipping row ID tag */ function (objID) { return objID; } /* each object ID is unique for constancy */);
        // insert a new toplevelHeapObject
        var tlhEnter = toplevelHeapObjects.enter().append('td')
            .attr('class', 'toplevelHeapObject')
            .attr('id', function (d, i) { return 'toplevel_heap_object_' + d; }); // TODO: is this CSS ID unique?
        // remember that the enter selection is added to the update
        // selection so that we can process it later ...
        // update a toplevelHeapObject
        toplevelHeapObjects
            .order() // VERY IMPORTANT to put in the order corresponding to data elements
            .each(function (objID, i) {
            //console.log('NEW/UPDATE ELT', objID);
            // TODO: add a smoother transition in the future
            // Right now, just delete the old element and render a new one in its place
            $(this).empty();
            if (myViz.isCppMode()) {
                // TODO: why might this be undefined?!? because the object
                // disappeared from the heap all of a sudden?!?
                if (curEntry.heap[objID] !== undefined) {
                    myViz.renderCompoundObject(objID, curInstr, $(this), true);
                }
            }
            else {
                myViz.renderCompoundObject(objID, curInstr, $(this), true);
            }
        });
        // delete a toplevelHeapObject
        var tlhExit = toplevelHeapObjects.exit();
        tlhExit
            .each(function (d, idx) {
            $(this).empty(); // crucial for garbage collecting jsPlumb connectors!
        })
            .remove();
        // Render globals and then stack frames using d3:
        // TODO: this sometimes seems buggy on Safari, so nix it for now:
        function highlightAliasedConnectors(d, i) {
            // if this row contains a stack pointer, then highlight its arrow and
            // ALL aliases that also point to the same heap object
            var stackPtrId = $(this).find('div.stack_pointer').attr('id');
            if (stackPtrId) {
                var foundTargetId = null;
                myViz.jsPlumbInstance.select({ source: stackPtrId }).each(function (c) { foundTargetId = c.targetId; });
                // use foundTargetId to highlight ALL ALIASES
                myViz.jsPlumbInstance.select().each(function (c) {
                    if (c.targetId == foundTargetId) {
                        c.setHover(true);
                        $(c.canvas).css("z-index", 2000); // ... and move it to the VERY FRONT
                    }
                    else {
                        c.setHover(false);
                    }
                });
            }
        }
        function unhighlightAllConnectors(d, i) {
            myViz.jsPlumbInstance.select().each(function (c) {
                c.setHover(false);
            });
        }
        // TODO: coalesce code for rendering globals and stack frames,
        // since there's so much copy-and-paste grossness right now
        // render all global variables IN THE ORDER they were created by the program,
        // in order to ensure continuity:
        // Derive a list where each element contains varname
        // as long as value is NOT undefined.
        // (Sometimes entries in curEntry.ordered_globals are undefined,
        // so filter those out.)
        var realGlobalsLst = [];
        $.each(curEntry.ordered_globals, function (i, varname) {
            if (myViz.inHideVarsSet(DataVisualizer.GLOBAL_PREFIX, varname)) {
                console.log('render HIDING', DataVisualizer.GLOBAL_PREFIX, varname);
                myViz.varsHidden.push(DataVisualizer.GLOBAL_PREFIX + ':' + varname);
                return; // get out!
            }
            var val = curEntry.globals[varname];
            // (use '!==' to do an EXACT match against undefined)
            if (val !== undefined) { // might not be defined at this line, which is OKAY!
                realGlobalsLst.push(varname);
            }
        });
        var globalsID = myViz.owner.generateID('globals');
        var globalTblID = myViz.owner.generateID('global_table');
        var globalVarTable = myViz.domRootD3.select('#' + globalTblID)
            .selectAll('tr')
            .data(realGlobalsLst, function (d) { return d; } // use variable name as key
        );
        globalVarTable
            .enter()
            .append('tr')
            .attr('class', 'variableTr')
            .attr('id', function (d, i) {
            return myViz.owner.generateID(varnameToCssID('global__' + d + '_tr')); // make globally unique (within the page)
        });
        var globalVarTableCells = globalVarTable
            .selectAll('td.stackFrameVar,td.stackFrameValue')
            .data(function (d, i) { return [d, d]; }); /* map varname down both columns */
        globalVarTableCells.enter()
            .append('td')
            .attr('class', function (d, i) { return (i == 0) ? 'stackFrameVar' : 'stackFrameValue'; });
        // remember that the enter selection is added to the update
        // selection so that we can process it later ...
        // UPDATE
        globalVarTableCells
            .order() // VERY IMPORTANT to put in the order corresponding to data elements
            .each(function (varname, i) {
            if (i == 0) {
                $(this).html(varname);
            }
            else {
                // always delete and re-render the global var ...
                // NB: trying to cache and compare the old value using,
                // say -- $(this).attr('data-curvalue', valStringRepr) -- leads to
                // a mysterious and killer memory leak that I can't figure out yet
                $(this).empty();
                // make sure varname doesn't contain any weird
                // characters that are illegal for CSS ID's ...
                var varDivID = myViz.owner.generateID('global__' + varnameToCssID(varname));
                // need to get rid of the old connector in preparation for rendering a new one:
                existingConnectionEndpointIDs.remove(varDivID);
                var val = curEntry.globals[varname];
                if (myViz.isPrimitiveType(val)) {
                    myViz.renderPrimitiveObject(val, curInstr, $(this));
                }
                else if (val[0] === 'C_STRUCT' || val[0] === 'C_ARRAY' || val[0] === 'C_MULTIDIMENSIONAL_ARRAY') {
                    // C structs and arrays can be inlined in frames
                    myViz.renderCStructArray(val, curInstr, $(this));
                }
                else {
                    var heapObjID = myViz.generateHeapObjID(getRefID(val), curInstr);
                    if (myViz.params.textualMemoryLabels) {
                        var labelID = varDivID + '_text_label';
                        $(this).append('<div class="objectIdLabel" id="' + labelID + '">id' + getRefID(val) + '</div>');
                        $(this).find('div#' + labelID).hover(function () {
                            myViz.jsPlumbInstance.connect({ source: labelID, target: heapObjID,
                                scope: 'varValuePointer' });
                        }, function () {
                            myViz.jsPlumbInstance.select({ source: labelID }).detach();
                        });
                    }
                    else {
                        // add a stub so that we can connect it with a connector later.
                        // IE needs this div to be NON-EMPTY in order to properly
                        // render jsPlumb endpoints, so that's why we add an "&nbsp;"!
                        $(this).append('<div class="stack_pointer" id="' + varDivID + '">&nbsp;</div>');
                        assert(!myViz.jsPlumbManager.connectionEndpointIDs.has(varDivID));
                        myViz.jsPlumbManager.connectionEndpointIDs.set(varDivID, heapObjID);
                        //console.log('STACK->HEAP', varDivID, heapObjID);
                    }
                }
            }
        });
        globalVarTableCells.exit()
            .each(function (d, idx) {
            $(this).empty(); // crucial for garbage collecting jsPlumb connectors!
        })
            .remove();
        globalVarTable.exit()
            .each(function (d, i) {
            // detach all stack_pointer connectors for divs that are being removed
            $(this).find('.stack_pointer').each(function (i, sp) {
                existingConnectionEndpointIDs.remove($(sp).attr('id'));
            });
            $(this).empty(); // crucial for garbage collecting jsPlumb connectors!
        })
            .remove();
        // for aesthetics, hide globals if there aren't any globals to display
        if (curEntry.ordered_globals.length == 0) {
            this.domRoot.find('#' + globalsID).hide();
        }
        else {
            this.domRoot.find('#' + globalsID).show();
        }
        // holy cow, the d3 code for stack rendering is ABSOLUTELY NUTS!
        var stackDiv = myViz.domRootD3.select('#stack');
        // VERY IMPORTANT for selectAll selector to be SUPER specific here!
        var stackFrameDiv = stackDiv.selectAll('div.stackFrame,div.zombieStackFrame')
            .data(curEntry.stack_to_render, function (frame) {
            // VERY VERY VERY IMPORTANT for properly handling closures and nested functions
            // (see the backend code for more details)
            return frame.unique_hash;
        });
        var sfdEnter = stackFrameDiv.enter()
            .append('div')
            .attr('class', function (d, i) { return d.is_zombie ? 'zombieStackFrame' : 'stackFrame'; })
            .attr('id', function (d, i) {
            return d.is_zombie ? myViz.owner.generateID("zombie_stack" + i)
                : myViz.owner.generateID("stack" + i);
        })
            // HTML5 custom data attributes
            .attr('data-frame_id', function (frame, i) { return frame.frame_id; })
            .attr('data-parent_frame_id', function (frame, i) {
            return (frame.parent_frame_id_list.length > 0) ? frame.parent_frame_id_list[0] : null;
        })
            .each(function (frame, i) {
            if (!myViz.params.drawParentPointers) {
                return;
            }
            // only run if myViz.params.drawParentPointers is true ...
            var my_CSS_id = $(this).attr('id');
            //console.log(my_CSS_id, 'ENTER');
            // render a parent pointer whose SOURCE node is this frame
            // i.e., connect this frame to p, where this.parent_frame_id == p.frame_id
            // (if this.parent_frame_id is null, then p is the global frame)
            if (frame.parent_frame_id_list.length > 0) {
                var parent_frame_id = frame.parent_frame_id_list[0];
                // tricky turkey!
                // ok this hack just HAPPENS to work by luck ... usually there will only be ONE frame
                // that matches this selector, but sometimes multiple frames match, in which case the
                // FINAL frame wins out (since parentPointerConnectionEndpointIDs is a map where each
                // key can be mapped to only ONE value). it so happens that the final frame winning
                // out looks "desirable" for some of the closure test cases that I've tried. but
                // this code is quite brittle :(
                myViz.domRoot.find('div#stack [data-frame_id=' + parent_frame_id + ']').each(function (i, e) {
                    var parent_CSS_id = $(this).attr('id');
                    //console.log('connect', my_CSS_id, parent_CSS_id);
                    myViz.jsPlumbManager.parentPointerConnectionEndpointIDs.set(my_CSS_id, parent_CSS_id);
                });
            }
            else {
                // render a parent pointer to the global frame
                //console.log('connect', my_CSS_id, globalsID);
                // only do this if there are actually some global variables to display ...
                if (curEntry.ordered_globals.length > 0) {
                    myViz.jsPlumbManager.parentPointerConnectionEndpointIDs.set(my_CSS_id, globalsID);
                }
            }
            // tricky turkey: render parent pointers whose TARGET node is this frame.
            // i.e., for all frames f such that f.parent_frame_id == my_frame_id,
            // connect f to this frame.
            // (make sure not to confuse frame IDs with CSS IDs!!!)
            var my_frame_id = frame.frame_id;
            myViz.domRoot.find('div#stack [data-parent_frame_id=' + my_frame_id + ']').each(function (i, e) {
                var child_CSS_id = $(this).attr('id');
                //console.log('connect', child_CSS_id, my_CSS_id);
                myViz.jsPlumbManager.parentPointerConnectionEndpointIDs.set(child_CSS_id, my_CSS_id);
            });
        });
        sfdEnter
            .append('div')
            .attr('class', 'stackFrameHeader')
            .html(function (frame, i) {
            // pretty-print lambdas and display other weird characters
            // (might contain '<' or '>' for weird names like <genexpr>)
            var funcName = htmlspecialchars(frame.func_name).replace('&lt;lambda&gt;', '\u03bb');
            var headerLabel = funcName;
            // only display if you're someone's parent (unless showAllFrameLabels)
            if (frame.is_parent || myViz.params.showAllFrameLabels) {
                headerLabel = 'f' + frame.frame_id + ': ' + headerLabel;
            }
            // optional (btw, this isn't a CSS id)
            if (frame.parent_frame_id_list.length > 0) {
                var parentFrameID = frame.parent_frame_id_list[0];
                headerLabel = headerLabel + ' [parent=f' + parentFrameID + ']';
            }
            else if (myViz.params.showAllFrameLabels) {
                headerLabel = headerLabel + ' [parent=Global]';
            }
            return headerLabel;
        });
        sfdEnter
            .append('table')
            .attr('class', 'stackFrameVarTable');
        var stackVarTable = stackFrameDiv
            .order() // VERY IMPORTANT to put in the order corresponding to data elements
            .select('table').selectAll('tr')
            .data(function (frame) {
            if (myViz.hideVarsSet) {
                // filter out everything in hideVarsSet
                var func_prefix_1 = frame.func_name ? frame.func_name : DataVisualizer.UNNAMED_PREFIX;
                // a bit inefficient since we call filter twice, but whateves :)
                var hiddenVarnamesLst = frame.ordered_varnames.filter(function (varname) { return myViz.inHideVarsSet(func_prefix_1, varname); });
                console.log('render HIDING', func_prefix_1, hiddenVarnamesLst);
                hiddenVarnamesLst.forEach(function (e) { myViz.varsHidden.push(func_prefix_1 + ':' + e); });
                return frame.ordered_varnames
                    .filter(function (varname) { return !myViz.inHideVarsSet(func_prefix_1, varname); })
                    .map(function (varname) { return { varname: varname, frame: frame }; });
            }
            else {
                // each list element contains a reference to the entire frame
                // object as well as the variable name
                // TODO: look into whether we can use d3 parent nodes to avoid
                // this hack ... http://bost.ocks.org/mike/nest/
                return frame.ordered_varnames.map(function (varname) { return { varname: varname, frame: frame }; });
            }
        }, function (d) {
            // TODO: why would d ever be null?!? weird
            if (d) {
                return d.varname; // use variable name as key
            }
        });
        stackVarTable
            .enter()
            .append('tr')
            .attr('class', 'variableTr')
            .attr('id', function (d, i) {
            return myViz.owner.generateID(varnameToCssID(d.frame.unique_hash + '__' + d.varname + '_tr')); // make globally unique (within the page)
        });
        var stackVarTableCells = stackVarTable
            .selectAll('td.stackFrameVar,td.stackFrameValue')
            .data(function (d, i) { return [d, d] /* map identical data down both columns */; });
        stackVarTableCells.enter()
            .append('td')
            .attr('class', function (d, i) { return (i == 0) ? 'stackFrameVar' : 'stackFrameValue'; });
        stackVarTableCells
            .order() // VERY IMPORTANT to put in the order corresponding to data elements
            .each(function (d, i) {
            var varname = d.varname;
            var frame = d.frame;
            if (i == 0) {
                if (varname == '__return__')
                    $(this).html('<span class="retval">Return<br/>value</span>');
                else
                    $(this).html(varname);
            }
            else {
                // always delete and re-render the stack var ...
                // NB: trying to cache and compare the old value using,
                // say -- $(this).attr('data-curvalue', valStringRepr) -- leads to
                // a mysterious and killer memory leak that I can't figure out yet
                $(this).empty();
                // make sure varname and frame.unique_hash don't contain any weird
                // characters that are illegal for CSS ID's ...
                var varDivID = myViz.owner.generateID(varnameToCssID(frame.unique_hash + '__' + varname));
                // need to get rid of the old connector in preparation for rendering a new one:
                existingConnectionEndpointIDs.remove(varDivID);
                var val = frame.encoded_locals[varname];
                if (myViz.isPrimitiveType(val)) {
                    myViz.renderPrimitiveObject(val, curInstr, $(this));
                }
                else if (val[0] === 'C_STRUCT' || val[0] === 'C_ARRAY' || val[0] === 'C_MULTIDIMENSIONAL_ARRAY') {
                    // C structs and arrays can be inlined in frames
                    myViz.renderCStructArray(val, curInstr, $(this));
                }
                else {
                    var heapObjID = myViz.generateHeapObjID(getRefID(val), curInstr);
                    if (myViz.params.textualMemoryLabels) {
                        var labelID = varDivID + '_text_label';
                        $(this).append('<div class="objectIdLabel" id="' + labelID + '">id' + getRefID(val) + '</div>');
                        $(this).find('div#' + labelID).hover(function () {
                            myViz.jsPlumbInstance.connect({ source: labelID, target: heapObjID,
                                scope: 'varValuePointer' });
                        }, function () {
                            myViz.jsPlumbInstance.select({ source: labelID }).detach();
                        });
                    }
                    else {
                        // add a stub so that we can connect it with a connector later.
                        // IE needs this div to be NON-EMPTY in order to properly
                        // render jsPlumb endpoints, so that's why we add an "&nbsp;"!
                        $(this).append('<div class="stack_pointer" id="' + varDivID + '">&nbsp;</div>');
                        assert(!myViz.jsPlumbManager.connectionEndpointIDs.has(varDivID));
                        myViz.jsPlumbManager.connectionEndpointIDs.set(varDivID, heapObjID);
                        //console.log('STACK->HEAP', varDivID, heapObjID);
                    }
                }
            }
        });
        stackVarTableCells.exit()
            .each(function (d, idx) {
            $(this).empty(); // crucial for garbage collecting jsPlumb connectors!
        })
            .remove();
        stackVarTable.exit()
            .each(function (d, i) {
            $(this).find('.stack_pointer').each(function (i, sp) {
                // detach all stack_pointer connectors for divs that are being removed
                existingConnectionEndpointIDs.remove($(sp).attr('id'));
            });
            $(this).empty(); // crucial for garbage collecting jsPlumb connectors!
        })
            .remove();
        stackFrameDiv.exit()
            .each(function (frame, i) {
            $(this).find('.stack_pointer').each(function (i, sp) {
                // detach all stack_pointer connectors for divs that are being removed
                existingConnectionEndpointIDs.remove($(sp).attr('id'));
            });
            var my_CSS_id = $(this).attr('id');
            //console.log(my_CSS_id, 'EXIT');
            // Remove all pointers where either the source or destination end is my_CSS_id
            existingParentPointerConnectionEndpointIDs.forEach(function (k, v) {
                if (k == my_CSS_id || v == my_CSS_id) {
                    //console.log('remove EPP', k, v);
                    existingParentPointerConnectionEndpointIDs.remove(k);
                }
            });
            $(this).empty(); // crucial for garbage collecting jsPlumb connectors!
        })
            .remove();
        // Rightward nudge hack to make tree-like structures look more sane
        // without any sophisticated graph rendering code. Thanks to John
        // DeNero for this suggestion in Fall 2012.
        //
        // This hack tries to ensure that all pointers that span different
        // rows point RIGHTWARD (as much as possible), which makes tree-like
        // structures look decent. e.g.,:
        //
        // t = [[['a', 'b'], ['c', 'd']], [[1,2], [3,4]]]
        //
        // Do it here since all of the divs have been rendered by now, but no
        // jsPlumb arrows have been rendered yet.
        if (rightwardNudgeHack) {
            // Basic idea: keep a set of all nudged ROWS for each nudger row, so
            // that when you get nudged, you can, in turn, nudge all of the rows
            // that you've nudged. this algorithm nicely takes care of the fact
            // that there might not be cycles in objects that you've nudged, but
            // there are cycles in entire rows.
            //
            // Key:   ID of .heapRow object that did the nudging
            // Value: set of .heapRow ID that were (transitively) nudged by this element
            //        (represented as a d3.map)
            var nudger_to_nudged_rows = {};
            // VERY IMPORTANT to sort these connector IDs in ascending order,
            // since I think they're rendered left-to-right, top-to-bottom in ID
            // order, so we want to run the nudging algorithm in that same order.
            var srcHeapConnectorIDs = myViz.jsPlumbManager.heapConnectionEndpointIDs.keys();
            srcHeapConnectorIDs.sort();
            $.each(srcHeapConnectorIDs, function (i, srcID) {
                var dstID = myViz.jsPlumbManager.heapConnectionEndpointIDs.get(srcID);
                var srcAnchorObject = myViz.domRoot.find('#' + srcID);
                var srcHeapObject = srcAnchorObject.closest('.heapObject');
                var dstAnchorObject = myViz.domRoot.find('#' + dstID);
                var dstHeapObject = dstAnchorObject.closest('.heapObject');
                var srcHeapRow = srcHeapObject.closest('.heapRow');
                var dstHeapRow = dstHeapObject.closest('.heapRow');
                var srcRowID = srcHeapRow.attr('id');
                var dstRowID = dstHeapRow.attr('id');
                // only consider nudging if srcID and dstID are on different rows
                if (srcRowID != dstRowID) {
                    var srcAnchorLeft = srcAnchorObject.offset().left;
                    var srcHeapObjectLeft = srcHeapObject.offset().left;
                    var dstHeapObjectLeft = dstHeapObject.offset().left;
                    // if srcAnchorObject is to the RIGHT of dstHeapObject, then nudge
                    // dstHeapObject to the right
                    if (srcAnchorLeft > dstHeapObjectLeft) {
                        // an extra nudge of 32px matches up pretty well with the
                        // current CSS padding around .toplevelHeapObject
                        var delta = (srcAnchorLeft - dstHeapObjectLeft) + 32;
                        // set margin rather than padding so that arrows tips still end
                        // at the left edge of the element.
                        // whoa, set relative CSS using +=, nice!
                        //
                        // TODO: tried looking into setting 'left' directly instead of
                        // 'margin-left', but somehow the results look different
                        dstHeapObject.css('margin-left', '+=' + delta);
                        //console.log(srcRowID, 'nudged', dstRowID, 'by', delta);
                        var cur_nudgee_set = nudger_to_nudged_rows[srcRowID];
                        if (cur_nudgee_set === undefined) {
                            cur_nudgee_set = d3.map();
                            nudger_to_nudged_rows[srcRowID] = cur_nudgee_set;
                        }
                        cur_nudgee_set.set(dstRowID, 1 /* useless value */);
                        // now if dstRowID itself nudged some other nodes, then nudge
                        // all of its nudgees by delta as well
                        var dst_nudgee_set = nudger_to_nudged_rows[dstRowID];
                        if (dst_nudgee_set) {
                            dst_nudgee_set.forEach(function (k, v) {
                                // don't nudge if it's yourself, to make cycles look
                                // somewhat reasonable (although still not ideal). e.g.,:
                                //   x = [1,2]
                                //   y = [3,x]
                                //   x[1] = y
                                if (k != srcRowID) {
                                    // nudge this entire ROW by delta as well
                                    // 2020-02-05: OK instead of nudging the .heapRow
                                    // object, we will traverse inside of it and nudge all
                                    // of its .heapObject children that reside directly
                                    // within .heapRow > .toplevelHeapObject > .heapObject
                                    //
                                    // why are we doing this? because we want it to
                                    // interact well with draggedHeapObjectCSS ... if an
                                    // element is dragged, we want to restore its
                                    // cached position from draggedHeapObjectCSS, which
                                    // will override all nudges. if we had nudged .heapRow
                                    // like we used to do, then .heapRow may itself be
                                    // nudged, which would kind of override
                                    // draggedHeapObjectCSS, which is applied to .heapObject
                                    //
                                    // old code: nudge .heapRow itself ...
                                    //myViz.domRoot.find('#' + k).css('margin-left', '+=' + delta);
                                    // new code: nudge all .heapObject children of .heapRow
                                    // (which is separated by an intermediary .toplevelHeapObject)
                                    myViz.domRoot.find('#' + k)
                                        .children('.toplevelHeapObject')
                                        .children('.heapObject')
                                        .css('margin-left', '+=' + delta);
                                    // NB: why don't we just use .find() to directly get
                                    // all .heapObject elements? because there are
                                    // sometimes .heapObject that are nested *within*
                                    // other .heapObject, and we don't want to unnecessarily
                                    // nudge those ... thus, we stick to .toplevelHeapObject
                                    // then transitively add to entry for srcRowID
                                    cur_nudgee_set.set(k, 1 /* useless value */);
                                }
                            });
                        }
                    }
                }
            });
        }
        // NB: ugh, I'm not very happy about this hack, but it seems necessary
        // for embedding within sophisticated webpages such as IPython Notebook
        // delete all connectors. do this AS LATE AS POSSIBLE so that
        // (presumably) the calls to $(this).empty() earlier in this function
        // will properly garbage collect the connectors
        //
        // WARNING: for environment parent pointers, garbage collection doesn't seem to
        // be working as intended :(
        //
        // I suspect that this is due to the fact that parent pointers are SIBLINGS
        // of stackFrame divs and not children, so when stackFrame divs get destroyed,
        // their associated parent pointers do NOT.)
        myViz.jsPlumbInstance.reset();
        // use jsPlumb scopes to keep the different kinds of pointers separated
        function renderVarValueConnector(varID, valueID) {
            // special-case handling for C/C++ pointers, just to keep from rocking
            // the boat on my existing (battle-tested) code
            if (myViz.isCppMode()) {
                if (myViz.domRoot.find('#' + valueID).length) {
                    myViz.jsPlumbInstance.connect({ source: varID, target: valueID, scope: 'varValuePointer' });
                }
                else {
                    // pointer isn't pointing to anything valid; put a poo emoji here
                    myViz.domRoot.find('#' + varID).html('\uD83D\uDCA9' /* pile of poo emoji */);
                }
            }
            else {
                myViz.jsPlumbInstance.connect({ source: varID, target: valueID, scope: 'varValuePointer' });
            }
        }
        var totalParentPointersRendered = 0;
        function renderParentPointerConnector(srcID, dstID) {
            // SUPER-DUPER-ugly hack since I can't figure out a cleaner solution for now:
            // if either srcID or dstID no longer exists, then SKIP rendering ...
            if ((myViz.domRoot.find('#' + srcID).length == 0) ||
                (myViz.domRoot.find('#' + dstID).length == 0)) {
                return;
            }
            //console.log('renderParentPointerConnector:', srcID, dstID);
            myViz.jsPlumbInstance.connect({ source: srcID, target: dstID,
                anchors: ["LeftMiddle", "LeftMiddle"],
                // 'horizontally offset' the parent pointers up so that they don't look as ugly ...
                //connector: ["Flowchart", { stub: 9 + (6 * (totalParentPointersRendered + 1)) }],
                // actually let's try a bezier curve ...
                connector: ["Bezier", { curviness: 45 }],
                endpoint: ["Dot", { radius: 4 }],
                //hoverPaintStyle: {lineWidth: 1, strokeStyle: connectorInactiveColor}, // no hover colors
                scope: 'frameParentPointer' });
            totalParentPointersRendered++;
        }
        if (!myViz.params.textualMemoryLabels) {
            // re-render existing connectors and then ...
            //
            // NB: in C/C++ mode, to keep things simple, don't try to redraw
            // existingConnectionEndpointIDs since we want to redraw all arrows
            // each and every time.
            if (!myViz.isCppMode()) {
                existingConnectionEndpointIDs.forEach(renderVarValueConnector);
            }
            // add all the NEW connectors that have arisen in this call to renderDataStructures
            myViz.jsPlumbManager.connectionEndpointIDs.forEach(renderVarValueConnector);
        }
        // do the same for environment parent pointers
        if (myViz.params.drawParentPointers) {
            existingParentPointerConnectionEndpointIDs.forEach(renderParentPointerConnector);
            myViz.jsPlumbManager.parentPointerConnectionEndpointIDs.forEach(renderParentPointerConnector);
        }
        /*
        myViz.jsPlumbInstance.select().each(function(c) {
          console.log('CONN:', c.sourceId, c.targetId);
        });
        */
        //console.log('---', myViz.jsPlumbInstance.select().length, '---');
        function highlight_frame(frameID) {
            myViz.jsPlumbInstance.select().each(function (c) {
                // find the enclosing .stackFrame ...
                var stackFrameDiv = c.source.closest('.stackFrame');
                // if this connector starts in the selected stack frame ...
                if (stackFrameDiv.attr('id') == frameID) {
                    // then HIGHLIGHT IT!
                    c.setPaintStyle({ lineWidth: 1, strokeStyle: connectorBaseColor });
                    c.endpoints[0].setPaintStyle({ fillStyle: connectorBaseColor });
                    //c.endpoints[1].setVisible(false, true, true); // JUST set right endpoint to be invisible
                    $(c.canvas).css("z-index", 1000); // ... and move it to the VERY FRONT
                }
                // for heap->heap connectors
                else if (myViz.jsPlumbManager.heapConnectionEndpointIDs.has(c.endpoints[0].elementId)) {
                    // NOP since it's already the color and style we set by default
                }
                // TODO: maybe this needs special consideration for C/C++ code? dunno
                else if (stackFrameDiv.length > 0) {
                    // else unhighlight it
                    // (only if c.source actually belongs to a stackFrameDiv (i.e.,
                    //  it originated from the stack). for instance, in C there are
                    //  heap pointers, but we doesn't use heapConnectionEndpointIDs
                    //  NB: 2020-02-04 - upgraded C/C++ to use heapConnectionEndpointIDs )
                    c.setPaintStyle({ lineWidth: 1, strokeStyle: connectorInactiveColor });
                    c.endpoints[0].setPaintStyle({ fillStyle: connectorInactiveColor });
                    //c.endpoints[1].setVisible(false, true, true); // JUST set right endpoint to be invisible
                    $(c.canvas).css("z-index", 0);
                }
            });
            // clear everything, then just activate this one ...
            myViz.domRoot.find(".stackFrame").removeClass("highlightedStackFrame");
            myViz.domRoot.find('#' + frameID).addClass("highlightedStackFrame");
        }
        // highlight the top-most non-zombie stack frame or, if not available, globals
        var frame_already_highlighted = false;
        $.each(curEntry.stack_to_render, function (i, e) {
            if (e.is_highlighted) {
                highlight_frame(myViz.owner.generateID('stack' + i));
                frame_already_highlighted = true;
            }
        });
        if (!frame_already_highlighted) {
            highlight_frame(myViz.owner.generateID('globals'));
        }
        // if customizeVizOptionsShown ...
        // use jQueryUI's draggable to make all heap objects contained
        // within YOURSELF draggable (NB: use myViz.domRoot.find() and *not*
        // $() since the latter may select heap objects belonging to OTHER
        // ExecutionVisualizer objects on page!)
        var needToRedrawConnectors = false;
        myViz.domRoot.find('.heapObject').each(function (i, e) {
            // very subtle: if this is a .heapObject that's *nested* within
            // another one, then don't make it draggable, since it's weird to
            // be able to drag a nested object inside of its parent object; in
            // other words, we want to drag only .toplevelHeapObject, but it's
            // cleaner to make the .heapObject element draggable and not the
            // .toplevelHeapObject element
            //
            // note that this code may break if we're nesting an entire
            // ExecutionVisualizer instance inside the .heapObject of another
            // ExecutionVisualizer so that every .heapObject in the inner one is
            // actually in the outer one, but i don't see who would actually do that!
            if ($(e).parents('.heapObject').length) {
                return;
            }
            // set a custom position if one was found in draggedHeapObjectCSS ...
            // make sure to do this after applying rightwardNudgeHack so that
            // we override the positions of any nudged elements with ones from
            // draggedHeapObjectCSS
            var savedDraggedCSS = myViz.draggedHeapObjectCSS.get($(e).attr('id'));
            if (savedDraggedCSS) {
                $(e).attr('style', savedDraggedCSS);
                //console.log('GOT POSITION FROM CACHE!', $(e).attr('id'));
                needToRedrawConnectors = true;
            }
            // 2020-02-06: only make draggable() if customizeVizOptionsShown
            // (i.e., when the user has clicked "Customize visualization" so that
            // they purposely want to customize ... we do this to be conservative
            // so as not to rock the boat because i haven't tested draggable()
            // widely yet)
            if (myViz.owner.navControls.customizeVizOptionsShown) {
                $(e).css('cursor', 'pointer') // make the cursor a hand when you hover over it
                    .draggable({
                    drag: function () {
                        // debounce to prevent excessive repaints, which can get super-slow
                        $.doTimeout('heapObjectDrag', 10, function () {
                            console.log('drag'); // to make sure we're not adding too many callbacks
                            myViz.redrawConnectors(); // redraw all arrows whenever you drag!
                        });
                    },
                    start: function () {
                    },
                    stop: function () {
                        myViz.redrawConnectors(); // redraw all arrows when you drag stops
                        // unset width and height fields since those don't seem
                        // relevant and we don't want to save them in draggedCSS
                        $(e).css('width', '').css('height', '');
                        // save your current CSS, which has your custom position
                        $(e).data('draggedCSS', $(e).attr('style'));
                    },
                });
            }
        });
        // show which variables/fields were actually hidden during this call
        // to renderDataStructures:
        if (myViz.owner.navControls.customizeVizOptionsShown) {
            needToRedrawConnectors = true; // always redraw! TODO: will this get inefficient?!?
            var shs = this.domRoot.find('#selectiveHideStatus');
            shs.empty(); // ALWAYS start from scratch each time!
            if (myViz.varsHidden.length > 0 || myViz.fieldsHidden.length > 0) {
                // printing hidden vars/fields may move elements in the heap visualization
                if (myViz.varsHidden.length > 0) {
                    // filter out duplicates:
                    var varsHiddenNoDups_1 = [];
                    myViz.varsHidden.forEach(function (e) {
                        if (varsHiddenNoDups_1.indexOf(e) < 0) {
                            varsHiddenNoDups_1.push(e);
                        }
                    });
                    shs.append("Hidden variables: " + varlistToHtml(varsHiddenNoDups_1));
                }
                if (myViz.fieldsHidden.length > 0) {
                    // filter out duplicates:
                    var fieldsHiddenNoDups_1 = [];
                    myViz.fieldsHidden.forEach(function (e) {
                        if (fieldsHiddenNoDups_1.indexOf(e) < 0) {
                            fieldsHiddenNoDups_1.push(e);
                        }
                    });
                    shs.append("<br/>Hidden object fields: " + varlistToHtml(fieldsHiddenNoDups_1));
                }
            }
        }
        if (needToRedrawConnectors) {
            myViz.redrawConnectors();
        }
        myViz.owner.try_hook("end_renderDataStructures", { myViz: myViz.owner /* tricky! use owner to be safe */ });
    };
    // rendering functions, which all take a d3 dom element to anchor the
    // new element to render
    DataVisualizer.prototype.renderPrimitiveObject = function (obj, stepNum, d3DomElement) {
        var myViz = this; // to prevent confusion of 'this' inside of nested functions
        if (this.owner.try_hook("renderPrimitiveObject", { obj: obj, d3DomElement: d3DomElement })[0])
            return;
        var typ = typeof obj;
        if (obj == null) {
            d3DomElement.append('<span class="nullObj">' + this.getRealLabel('None') + '</span>');
        }
        else if (typ == "number") {
            d3DomElement.append('<span class="numberObj">' + obj + '</span>');
        }
        else if (typ == "boolean") {
            if (obj) {
                d3DomElement.append('<span class="boolObj">' + this.getRealLabel('True') + '</span>');
            }
            else {
                d3DomElement.append('<span class="boolObj">' + this.getRealLabel('False') + '</span>');
            }
        }
        else if (typ == "string") {
            // escape using htmlspecialchars to prevent HTML/script injection
            var literalStr = htmlspecialchars(obj);
            // print as a double-quoted string literal
            literalStr = literalStr.replace(doubleQuoteAllRegex, '\\"'); // replace ALL
            literalStr = '"' + literalStr + '"';
            d3DomElement.append('<span class="stringObj">' + literalStr + '</span>');
        }
        else if (typ == "object") {
            if (obj[0] == 'C_DATA') {
                var typeName = obj[2];
                // special cases for brevity:
                if (typeName === 'short int') {
                    typeName = 'short';
                }
                else if (typeName === 'short unsigned int') {
                    typeName = 'unsigned short';
                }
                else if (typeName === 'long int') {
                    typeName = 'long';
                }
                else if (typeName === 'long long int') {
                    typeName = 'long long';
                }
                else if (typeName === 'long unsigned int') {
                    typeName = 'unsigned long';
                }
                else if (typeName === 'long long unsigned int') {
                    typeName = 'unsigned long long int';
                }
                var isValidPtr = ((typeName === 'pointer') &&
                    (obj[3] !== '<UNINITIALIZED>') &&
                    (obj[3] !== '<UNALLOCATED>'));
                var addr = obj[1];
                var leader = '';
                // prefix with 'cdata_' so that we can distinguish this from a
                // top-level heap ID generated by generateHeapObjID
                var cdataId = myViz.generateHeapObjID('cdata_' + addr, stepNum);
                if (isValidPtr) {
                    // for pointers, put cdataId in the header
                    d3DomElement.append('<div id="' + cdataId + '" class="cdataHeader">' + leader + typeName + '</div>');
                    var ptrVal = obj[3];
                    // add a stub so that we can connect it with a connector later.
                    // IE needs this div to be NON-EMPTY in order to properly
                    // render jsPlumb endpoints, so that's why we add an "&nbsp;"!
                    var ptrSrcId = myViz.generateHeapObjID('ptrSrc_' + addr, stepNum);
                    var ptrTargetId = myViz.generateHeapObjID('cdata_' + ptrVal, stepNum); // don't forget cdata_ prefix!
                    var debugInfo = '';
                    // make it really narrow so that the div doesn't STRETCH too wide
                    d3DomElement.append('<div style="width: 10px;" id="' + ptrSrcId + '" class="cdataElt">&nbsp;' + debugInfo + '</div>');
                    // special case: display 0x0 address as a NULL pointer value,
                    // to distinguish it from all other pointers, since sometimes
                    // C/C++ programmers *explicitly* set a pointer to null
                    if (ptrVal === '0x0') {
                        $('#' + ptrSrcId).html('<span class="cdataUninit">NULL</span>');
                    }
                    else {
                        //console.log(ptrSrcId, '->', ptrTargetId);
                        assert(!myViz.jsPlumbManager.connectionEndpointIDs.has(ptrSrcId));
                        myViz.jsPlumbManager.connectionEndpointIDs.set(ptrSrcId, ptrTargetId);
                        // note that we can't tell whether ptrSrcId or ptrTargetId
                        // are on the stack or heap (since the C trace allows pointer
                        // objects to exist in both), so a hack to find out is to find
                        // its DOM element, look upward in tree for closest heapObject,
                        // and if we find it, then we assume it's on the heap
                        var srcAnchorObject = myViz.domRoot.find('#' + ptrSrcId);
                        var dstAnchorObject = myViz.domRoot.find('#' + ptrTargetId);
                        var srcHeapObject = srcAnchorObject.closest('.heapObject');
                        var dstHeapObject = dstAnchorObject.closest('.heapObject');
                        // only do this if BOTH ptrSrcId and ptrTargetId are on the heap
                        if (srcHeapObject.length > 0 && dstHeapObject.length > 0) {
                            myViz.jsPlumbManager.heapConnectionEndpointIDs.set(ptrSrcId, ptrTargetId);
                        }
                    }
                }
                else {
                    // for non-pointers, put cdataId on the element itself, so that
                    // pointers can point directly at the element, not the header
                    d3DomElement.append('<div class="cdataHeader">' + leader + typeName + '</div>');
                    var rep = '';
                    if (typeof obj[3] === 'string') {
                        var literalStr = obj[3];
                        if (literalStr === '<UNINITIALIZED>') {
                            rep = '<span class="cdataUninit">?</span>';
                            //rep = '\uD83D\uDCA9'; // pile of poo emoji
                        }
                        else if (literalStr == '<UNALLOCATED>') {
                            rep = '\uD83D\uDC80'; // skull emoji
                        }
                        else {
                            // a regular string
                            literalStr = literalStr.replace(newlineAllRegex, '\\n'); // replace ALL
                            literalStr = literalStr.replace(tabAllRegex, '\\t'); // replace ALL
                            literalStr = literalStr.replace(doubleQuoteAllRegex, '\\"'); // replace ALL
                            // unprintable chars are denoted with '???', so show them as
                            // a special unicode character:
                            if (typeName === 'char' && literalStr === '???') {
                                literalStr = '\uFFFD'; // question mark in black diamond unicode character
                            }
                            else {
                                // print as a SINGLE-quoted string literal (to emulate C-style chars)
                                literalStr = "'" + literalStr + "'";
                            }
                            rep = htmlspecialchars(literalStr);
                        }
                    }
                    else {
                        rep = htmlspecialchars(obj[3]);
                    }
                    d3DomElement.append('<div id="' + cdataId + '" class="cdataElt">' + rep + '</div>');
                }
            }
            else if (obj[0] == 'IMPORTED_FAUX_PRIMITIVE') {
                // these represent objects that you've imported from external
                // libraries/modules, which should be displayed as 'primitives'
                // so that we don't clutter up the display by dedicating heap
                // space for them or trying to recurse into viewing their insides
                d3DomElement.append('<span class="importedObj">' + obj[1] + '</span>');
            }
            else {
                assert(obj[0] == 'SPECIAL_FLOAT' || obj[0] == 'JS_SPECIAL_VAL');
                d3DomElement.append('<span class="numberObj">' + obj[1] + '</span>');
            }
        }
        else {
            assert(false);
        }
    };
    DataVisualizer.prototype.renderNestedObject = function (obj, stepNum, d3DomElement) {
        if (this.isPrimitiveType(obj)) {
            this.renderPrimitiveObject(obj, stepNum, d3DomElement);
        }
        else {
            if (obj[0] === 'REF') {
                // obj is a ["REF", <int>] so dereference the 'pointer' to render that object
                this.renderCompoundObject(getRefID(obj), stepNum, d3DomElement, false);
            }
            else {
                assert(obj[0] === 'C_STRUCT' || obj[0] === 'C_ARRAY' || obj[0] === 'C_MULTIDIMENSIONAL_ARRAY');
                this.renderCStructArray(obj, stepNum, d3DomElement);
            }
        }
    };
    DataVisualizer.prototype.renderCompoundObject = function (objID, stepNum, d3DomElement, isTopLevel) {
        var myViz = this; // to prevent confusion of 'this' inside of nested functions
        var heapObjID = myViz.generateHeapObjID(objID, stepNum);
        if (!isTopLevel && myViz.jsPlumbManager.renderedHeapObjectIDs.has(heapObjID)) {
            var srcDivID = myViz.owner.generateID('heap_pointer_src_' + myViz.jsPlumbManager.heap_pointer_src_id);
            myViz.jsPlumbManager.heap_pointer_src_id++; // just make sure each source has a UNIQUE ID
            var dstDivID = heapObjID;
            if (myViz.params.textualMemoryLabels) {
                var labelID = srcDivID + '_text_label';
                d3DomElement.append('<div class="objectIdLabel" id="' + labelID + '">id' + objID + '</div>');
                myViz.domRoot.find('div#' + labelID).hover(function () {
                    myViz.jsPlumbInstance.connect({ source: labelID, target: dstDivID,
                        scope: 'varValuePointer' });
                }, function () {
                    myViz.jsPlumbInstance.select({ source: labelID }).detach();
                });
            }
            else {
                // render jsPlumb arrow source since this heap object has already been rendered
                // (or will be rendered soon)
                // add a stub so that we can connect it with a connector later.
                // IE needs this div to be NON-EMPTY in order to properly
                // render jsPlumb endpoints, so that's why we add an "&nbsp;"!
                d3DomElement.append('<div id="' + srcDivID + '">&nbsp;</div>');
                assert(!myViz.jsPlumbManager.connectionEndpointIDs.has(srcDivID));
                myViz.jsPlumbManager.connectionEndpointIDs.set(srcDivID, dstDivID);
                //console.log('HEAP->HEAP', srcDivID, dstDivID);
                assert(!myViz.jsPlumbManager.heapConnectionEndpointIDs.has(srcDivID));
                myViz.jsPlumbManager.heapConnectionEndpointIDs.set(srcDivID, dstDivID);
            }
            return; // early return!
        }
        // wrap ALL compound objects in a heapObject div so that jsPlumb
        // connectors can point to it:
        // TODO: what about C/C++ objects on the stack that are the target of pointers?
        d3DomElement.append('<div class="heapObject" id="' + heapObjID + '"></div>');
        d3DomElement = myViz.domRoot.find('#' + heapObjID); // TODO: maybe inefficient
        myViz.jsPlumbManager.renderedHeapObjectIDs.set(heapObjID, 1);
        var curHeap = myViz.curTrace[stepNum].heap;
        var obj = curHeap[objID];
        assert($.isArray(obj));
        // prepend the type label with a memory address label
        var typeLabelPrefix = '';
        if (myViz.params.textualMemoryLabels) {
            typeLabelPrefix = 'id' + objID + ':';
        }
        var hook_result = myViz.owner.try_hook("renderCompoundObject", { objID: objID, d3DomElement: d3DomElement,
            isTopLevel: isTopLevel, obj: obj,
            typeLabelPrefix: typeLabelPrefix,
            stepNum: stepNum,
            myViz: myViz });
        if (hook_result[0])
            return;
        if (obj[0] == 'LIST' || obj[0] == 'TUPLE' || obj[0] == 'SET' || obj[0] == 'DICT') {
            var label = obj[0].toLowerCase();
            assert(obj.length >= 1);
            if (obj.length == 1) {
                d3DomElement.append('<div class="typeLabel">' + typeLabelPrefix + ' empty ' + myViz.getRealLabel(label) + '</div>');
            }
            else {
                d3DomElement.append('<div class="typeLabel">' + typeLabelPrefix + myViz.getRealLabel(label) + '</div>');
                d3DomElement.append('<table class="' + label + 'Tbl"></table>');
                var tbl = d3DomElement.children('table');
                if (obj[0] == 'LIST' || obj[0] == 'TUPLE') {
                    tbl.append('<tr></tr><tr></tr>');
                    var headerTr = tbl.find('tr:first');
                    var contentTr = tbl.find('tr:last');
                    $.each(obj, function (ind, val) {
                        if (ind < 1)
                            return; // skip type tag and ID entry
                        // add a new column and then pass in that newly-added column
                        // as d3DomElement to the recursive call to child:
                        headerTr.append('<td class="' + label + 'Header"></td>');
                        headerTr.find('td:last').append(ind - 1);
                        contentTr.append('<td class="' + label + 'Elt"></td>');
                        myViz.renderNestedObject(val, stepNum, contentTr.find('td:last'));
                    });
                }
                else if (obj[0] == 'SET') {
                    // create an R x C matrix:
                    var numElts = obj.length - 1;
                    // gives roughly a 3x5 rectangular ratio, square is too, err,
                    // 'square' and boring
                    var numRows = Math.round(Math.sqrt(numElts));
                    if (numRows > 3) {
                        numRows -= 1;
                    }
                    var numCols = Math.round(numElts / numRows);
                    // round up if not a perfect multiple:
                    if (numElts % numRows) {
                        numCols += 1;
                    }
                    jQuery.each(obj, function (ind, val) {
                        if (ind < 1)
                            return; // skip 'SET' tag
                        if (((ind - 1) % numCols) == 0) {
                            tbl.append('<tr></tr>');
                        }
                        var curTr = tbl.find('tr:last');
                        curTr.append('<td class="setElt"></td>');
                        myViz.renderNestedObject(val, stepNum, curTr.find('td:last'));
                    });
                }
                else if (obj[0] == 'DICT') {
                    $.each(obj, function (ind, kvPair) {
                        if (ind < 1)
                            return; // skip 'DICT' tag
                        tbl.append('<tr class="dictEntry"><td class="dictKey"></td><td class="dictVal"></td></tr>');
                        var newRow = tbl.find('tr:last');
                        var keyTd = newRow.find('td:first');
                        var valTd = newRow.find('td:last');
                        var key = kvPair[0];
                        var val = kvPair[1];
                        myViz.renderNestedObject(key, stepNum, keyTd);
                        myViz.renderNestedObject(val, stepNum, valTd);
                    });
                }
            }
        }
        else if (obj[0] == 'INSTANCE' || obj[0] == 'INSTANCE_PPRINT' || obj[0] == 'CLASS') {
            var isInstance = (obj[0] == 'INSTANCE');
            var isPprintInstance = (obj[0] == 'INSTANCE_PPRINT');
            var _a = DataVisualizer.getClassInstanceMetadata(obj), className_2 = _a[0], headerLength_2 = _a[1];
            assert(obj.length >= headerLength_2);
            if (isInstance) {
                d3DomElement.append('<div class="typeLabel">' + typeLabelPrefix + obj[1] + ' ' + myViz.getRealLabel('instance') + '</div>');
            }
            else if (isPprintInstance) {
                d3DomElement.append('<div class="typeLabel">' + typeLabelPrefix + obj[1] + ' ' + myViz.getRealLabel('instance') + '</div>');
                d3DomElement.append('<table class="customObjTbl"><tr><td class="customObjElt">' + htmlspecialchars(obj[2]) + '</td></tr></table>');
            }
            else {
                var superclassStr = '';
                if (obj[2].length > 0) {
                    superclassStr += ('[extends ' + obj[2].join(', ') + '] ');
                }
                d3DomElement.append('<div class="typeLabel">' + typeLabelPrefix + obj[1] + ' class ' + superclassStr + '</div>');
            }
            if (obj.length > headerLength_2) {
                var lab = isInstance ? 'inst' : 'class';
                d3DomElement.append('<table class="' + lab + 'Tbl"></table>');
                var tbl = d3DomElement.children('table:last'); // tricky, there's more than 1 table if isPprintInstance is true
                $.each(obj, function (ind, kvPair) {
                    if (ind < headerLength_2)
                        return; // skip header tags
                    if (myViz.inHideFieldsSet(className_2, kvPair[0])) {
                        console.log('render HIDING', className_2, kvPair[0]);
                        myViz.fieldsHidden.push((className_2 ? className_2 + ':' : '') + kvPair[0]);
                        return; // get out!
                    }
                    tbl.append('<tr class="' + lab + 'Entry"><td class="' + lab + 'Key"></td><td class="' + lab + 'Val"></td></tr>');
                    var newRow = tbl.find('tr:last');
                    var keyTd = newRow.find('td:first');
                    var valTd = newRow.find('td:last');
                    // the keys should always be strings, so render them directly (and without quotes):
                    // (actually this isn't the case when strings are rendered on the heap)
                    if (typeof kvPair[0] == "string") {
                        // common case ...
                        var attrnameStr = htmlspecialchars(kvPair[0]);
                        keyTd.append('<span class="keyObj">' + attrnameStr + '</span>');
                    }
                    else {
                        // when strings are rendered as heap objects ...
                        myViz.renderNestedObject(kvPair[0], stepNum, keyTd);
                    }
                    // values can be arbitrary objects, so recurse:
                    myViz.renderNestedObject(kvPair[1], stepNum, valTd);
                });
            }
        }
        else if (obj[0] == 'FUNCTION') {
            assert(obj.length == 3 || obj.length == 4);
            // pretty-print lambdas and display other weird characters:
            var funcName = htmlspecialchars(obj[1]).replace('&lt;lambda&gt;', '\u03bb');
            var parentFrameID = obj[2]; // optional
            if (!myViz.params.compactFuncLabels) {
                d3DomElement.append('<div class="typeLabel">' + typeLabelPrefix + myViz.getRealLabel('function') + '</div>');
            }
            var funcPrefix = myViz.params.compactFuncLabels ? 'func' : '';
            if (parentFrameID) {
                d3DomElement.append('<div class="funcObj">' + funcPrefix + ' ' + funcName + ' [parent=f' + parentFrameID + ']</div>');
            }
            else if (myViz.params.showAllFrameLabels) {
                d3DomElement.append('<div class="funcObj">' + funcPrefix + ' ' + funcName + ' [parent=Global]</div>');
            }
            else {
                d3DomElement.append('<div class="funcObj">' + funcPrefix + ' ' + funcName + '</div>');
            }
            // render default argument names/values (see ../pg_encoder.py)
            if (obj.length > 3) {
                var funcProperties = obj[3];
                assert(funcProperties.length > 0);
                d3DomElement.append('<div class="typeLabel" style="margin-top: 3px;">default arguments:</div>');
                d3DomElement.append('<table class="instTbl"></table>');
                var tbl = d3DomElement.children('table');
                $.each(funcProperties, function (ind, kvPair) {
                    tbl.append('<tr class="instEntry"><td class="instKey"></td><td class="instVal"></td></tr>');
                    var newRow = tbl.find('tr:last');
                    var keyTd = newRow.find('td:first');
                    var valTd = newRow.find('td:last');
                    keyTd.append('<span class="keyObj">' + htmlspecialchars(kvPair[0]) + '</span>');
                    myViz.renderNestedObject(kvPair[1], stepNum, valTd);
                });
            }
        }
        else if (obj[0] == 'JS_FUNCTION') { /* TODO: refactor me */
            // JavaScript function
            assert(obj.length == 5);
            var funcName = htmlspecialchars(obj[1]);
            var funcCode = typeLabelPrefix + htmlspecialchars(obj[2]);
            var funcProperties = obj[3]; // either null or a non-empty list of key-value pairs
            var parentFrameID = obj[4];
            if (funcProperties || parentFrameID || myViz.params.showAllFrameLabels) {
                d3DomElement.append('<table class="classTbl"></table>');
                var tbl = d3DomElement.children('table');
                tbl.append('<tr><td class="funcCod" colspan="2"><pre class="funcCode">' + funcCode + '</pre>' + '</td></tr>');
                if (funcProperties) {
                    assert(funcProperties.length > 0);
                    var rawFuncName_1 = obj[1];
                    $.each(funcProperties, function (ind, kvPair) {
                        var instKey = kvPair[0];
                        if (myViz.inHideFieldsSet(rawFuncName_1, kvPair[0])) {
                            console.log('render HIDING', rawFuncName_1, kvPair[0]);
                            myViz.fieldsHidden.push((rawFuncName_1 ? rawFuncName_1 + ':' : '') + kvPair[0]);
                            return; // get out!
                        }
                        tbl.append('<tr class="classEntry"><td class="classKey"></td><td class="classVal"></td></tr>');
                        var newRow = tbl.find('tr:last');
                        var keyTd = newRow.find('td:first');
                        var valTd = newRow.find('td:last');
                        keyTd.append('<span class="keyObj">' + htmlspecialchars(kvPair[0]) + '</span>');
                        myViz.renderNestedObject(kvPair[1], stepNum, valTd);
                    });
                }
                if (parentFrameID) {
                    tbl.append('<tr class="classEntry"><td class="classKey">parent</td><td class="classVal">' + 'f' + parentFrameID + '</td></tr>');
                }
                else if (myViz.params.showAllFrameLabels) {
                    tbl.append('<tr class="classEntry"><td class="classKey">parent</td><td class="classVal">' + 'global' + '</td></tr>');
                }
            }
            else {
                // compact form:
                d3DomElement.append('<pre class="funcCode">' + funcCode + '</pre>');
            }
        }
        else if (obj[0] == 'HEAP_PRIMITIVE') {
            assert(obj.length == 3);
            var typeName = obj[1];
            var primitiveVal = obj[2];
            // add a bit of padding to heap primitives, for aesthetics
            d3DomElement.append('<div class="heapPrimitive"></div>');
            d3DomElement.find('div.heapPrimitive').append('<div class="typeLabel">' + typeLabelPrefix + typeName + '</div>');
            myViz.renderPrimitiveObject(primitiveVal, stepNum, d3DomElement.find('div.heapPrimitive'));
        }
        else if (obj[0] == 'C_STRUCT' || obj[0] == 'C_ARRAY' || obj[0] === 'C_MULTIDIMENSIONAL_ARRAY') {
            myViz.renderCStructArray(obj, stepNum, d3DomElement);
        }
        else {
            // render custom data type
            assert(obj.length == 2);
            var typeName = obj[0];
            var strRepr = obj[1];
            strRepr = htmlspecialchars(strRepr); // escape strings!
            d3DomElement.append('<div class="typeLabel">' + typeLabelPrefix + typeName + '</div>');
            d3DomElement.append('<table class="customObjTbl"><tr><td class="customObjElt">' + strRepr + '</td></tr></table>');
        }
    };
    // special-case kludge for C/C++
    DataVisualizer.prototype.renderCStructArray = function (obj, stepNum, d3DomElement) {
        var myViz = this; // to prevent confusion of 'this' inside of nested functions
        if (obj[0] == 'C_STRUCT') {
            assert(obj.length >= 3);
            var addr = obj[1];
            var typename = obj[2];
            var leader = '';
            if (myViz.params.lang === 'cpp') {
                // call it 'object' instead of 'struct'
                d3DomElement.append('<div class="typeLabel">' + leader + 'object ' + typename + '</div>');
            }
            else {
                d3DomElement.append('<div class="typeLabel">' + leader + 'struct ' + typename + '</div>');
            }
            if (obj.length > 3) {
                d3DomElement.append('<table class="instTbl"></table>');
                var tbl = d3DomElement.children('table');
                var structName_2 = obj[2] ? obj[2] : DataVisualizer.UNNAMED_PREFIX;
                $.each(obj, function (ind, kvPair) {
                    if (ind < 3)
                        return; // skip header tags
                    var fieldName = kvPair[0];
                    if (myViz.inHideFieldsSet(structName_2, fieldName)) {
                        console.log('render HIDING', structName_2, fieldName);
                        myViz.fieldsHidden.push(structName_2 + ':' + fieldName);
                        return; // get out!
                    }
                    tbl.append('<tr class="instEntry"><td class="instKey"></td><td class="instVal"></td></tr>');
                    var newRow = tbl.find('tr:last');
                    var keyTd = newRow.find('td:first');
                    var valTd = newRow.find('td:last');
                    // the keys should always be strings, so render them directly (and without quotes):
                    // (actually this isn't the case when strings are rendered on the heap)
                    assert(typeof kvPair[0] == "string");
                    // common case ...
                    var attrnameStr = htmlspecialchars(kvPair[0]);
                    keyTd.append('<span class="keyObj">' + attrnameStr + '</span>');
                    // values can be arbitrary objects, so recurse:
                    myViz.renderNestedObject(kvPair[1], stepNum, valTd);
                });
            }
        }
        else if (obj[0] == 'C_MULTIDIMENSIONAL_ARRAY') {
            // since we can display only 2 dimensions sensibly, make the first
            // dimension into rows and flatten all other dimensions together into
            // columns. in the common case for a 2-D array, this will do the
            // perfect thing: first dimension is rows, second dimension is columns.
            // e.g., for a 4-D array, the first dimension is rows, and dimensions
            // 2, 3, and 4 are flattened together into columns. we can't do
            // any better than this since it doesn't make sense to display
            // more than 2 dimensions at once on screen
            assert(obj.length >= 3);
            var addr = obj[1];
            var dimensions = obj[2];
            assert(dimensions.length > 1); // make sure we're really multidimensional!
            var leader = '';
            d3DomElement.append('<div class="typeLabel">' + leader + 'array</div>');
            d3DomElement.append('<table class="cArrayTbl"></table>');
            var tbl = d3DomElement.children('table');
            // a list of array indices for each dimension
            var indicesByDimension = [];
            for (var d = 0; d < dimensions.length; d++) {
                indicesByDimension.push(d3.range(dimensions[d]));
            }
            // common case is 2-D:
            var allDimensions = multiplyLists(indicesByDimension[0], indicesByDimension[1]);
            // for all dimensions above the second one ...
            for (var d = 2; d < dimensions.length; d++) {
                allDimensions = multiplyLists(allDimensions, indicesByDimension[d]);
            }
            //console.log('allDimensions', JSON.stringify(allDimensions));
            // ignore dimensions[0], which is rows
            var numColumns = 1;
            for (var i = 1; i < dimensions.length; i++) {
                numColumns *= dimensions[i];
            }
            for (var row = 0; row < dimensions[0]; row++) {
                //console.log('row', row);
                // a pair of rows for header + content, respectively
                tbl.append('<tr></tr>');
                var headerTr = tbl.find('tr:last');
                tbl.append('<tr></tr>');
                var contentTr = tbl.find('tr:last');
                for (var col = 0; col < numColumns; col++) {
                    var flattenedInd = (row * numColumns) + col; // the real index into the 1-D flattened array stored in obj[3:]
                    var realInd = flattenedInd + 3; // skip 3 header fields to get to the real index in obj
                    var val = obj[realInd];
                    var indToDisplay = allDimensions[flattenedInd].join(',');
                    //console.log('  col', col, '| flattenedInd:', flattenedInd, indToDisplay, 'contents:', val);
                    // add a new column and then pass in that newly-added column
                    // as d3DomElement to the recursive call to child:
                    headerTr.append('<td class="cMultidimArrayHeader"></td>');
                    headerTr.find('td:last').append(indToDisplay);
                    contentTr.append('<td class="cMultidimArrayElt"></td>');
                    myViz.renderNestedObject(val, stepNum, contentTr.find('td:last'));
                }
            }
        }
        else {
            assert(obj[0] == 'C_ARRAY');
            assert(obj.length >= 2);
            var addr = obj[1];
            var leader = '';
            d3DomElement.append('<div class="typeLabel">' + leader + 'array</div>');
            d3DomElement.append('<table class="cArrayTbl"></table>');
            var tbl = d3DomElement.children('table');
            tbl.append('<tr></tr><tr></tr>');
            var headerTr = tbl.find('tr:first');
            var contentTr = tbl.find('tr:last');
            $.each(obj, function (ind, val) {
                if (ind < 2)
                    return; // skip 'C_ARRAY' and addr
                // add a new column and then pass in that newly-added column
                // as d3DomElement to the recursive call to child:
                headerTr.append('<td class="cArrayHeader"></td>');
                headerTr.find('td:last').append(ind - 2 /* adjust */);
                contentTr.append('<td class="cArrayElt"></td>');
                myViz.renderNestedObject(val, stepNum, contentTr.find('td:last'));
            });
        }
    };
    DataVisualizer.prototype.redrawConnectors = function () {
        this.jsPlumbInstance.repaintEverything();
    };
    // selectively hiding variables or fields
    //
    // note that C++ uses '::' in member function names, so for
    // the names in hideVarsLst and hideFieldsLst, we can't
    // reliably split on ':' to reconstruct its original function/class
    // name and its variable name. e.g., "Computer::setspeed(int):p"
    //
    // the more robust strategy is to keep this string intact and try to
    // reconstruct it when matching up with variables in the execution trace
    // ... but consider the case where there are NO COLONS in the string,
    // which indicates a variable/field name that should be matched
    // regardless of what function/object it belongs to
    DataVisualizer.prototype.selectivelyHideVarsAndFields = function (hideVarsLst, hideFieldsLst) {
        var _this = this;
        if (hideVarsLst.length > 0) {
            this.hideVarsSet = d3.map();
            hideVarsLst.forEach(function (e) { return _this.hideVarsSet.set(e, true); });
        }
        else {
            this.hideVarsSet = null; // reset
        }
        if (hideFieldsLst.length > 0) {
            this.hideFieldsSet = d3.map();
            hideFieldsLst.forEach(function (e) { return _this.hideFieldsSet.set(e, true); });
        }
        else {
            this.hideFieldsSet = null; // reset
        }
        // now that this.hideVarsSet and this.hideFieldsSet have been updated ...
        this.precomputeCurTraceLayouts(); // recompute layouts to account for hidden vars/objects
        this.renderDataStructures(this.owner.curInstr); // render current step again
        //this.owner.updateOutput(); // alternatively, try this
    };
    // precondition: obj[0] is in {'INSTANCE', 'INSTANCE_PPRINT', 'CLASS'}
    // returns: [class name, header length]
    DataVisualizer.getClassInstanceMetadata = function (obj) {
        var typ = obj[0];
        assert(typ == 'INSTANCE' || typ == 'INSTANCE_PPRINT' || typ == 'CLASS');
        var className = obj[1]; // might possibly be ''
        var headerLength = (typ == 'INSTANCE') ? 2 : 3;
        return [className, headerLength];
    };
    // returns true if funcname:varname is in this.hideVarsSet
    // OR if varname alone (without a funcname qualifier) is in this.hideVarsSet
    DataVisualizer.prototype.inHideVarsSet = function (funcname, varname) {
        return DataVisualizer._inHideSetHelper(this.hideVarsSet, funcname, varname);
    };
    // same as inHideVarsSet except for classname/fieldname in this.hideFieldsSet
    DataVisualizer.prototype.inHideFieldsSet = function (classname, fieldname) {
        return DataVisualizer._inHideSetHelper(this.hideFieldsSet, classname, fieldname);
    };
    DataVisualizer._inHideSetHelper = function (myMap, first, second) {
        if (!myMap) {
            return false;
        }
        else if (!first) { // only match on second, in that case
            return myMap.has(second);
        }
        else { // match on either first:second or second
            return myMap.has(first + ':' + second) || myMap.has(second);
        }
    };
    DataVisualizer.GLOBAL_PREFIX = 'global';
    DataVisualizer.UNNAMED_PREFIX = '<unnamed>';
    return DataVisualizer;
}()); // END class DataVisualizer
var ProgramOutputBox = /** @class */ (function () {
    function ProgramOutputBox(owner, domRoot, heightOverride) {
        if (heightOverride === void 0) { heightOverride = null; }
        // how many *maximum* lines get printed to stdout in the entire trace?
        this.numStdoutLines = 0;
        this.owner = owner;
        this.domRoot = domRoot;
        var outputsHTML = '<div id="progOutputs">\
         <div id="printOutputDocs">Print output (drag lower right corner to resize)</div>\n\
         <textarea id="pyStdout" cols="40" rows="5" wrap="off" readonly></textarea>\
       </div>';
        this.domRoot.append(outputsHTML);
        // go backwards from the end ... sometimes the final entry doesn't
        // have an stdout
        var lastStdout;
        for (var i = this.owner.curTrace.length - 1; i >= 0; i--) {
            lastStdout = this.owner.curTrace[i].stdout;
            if (lastStdout) {
                break;
            }
        }
        if (lastStdout) {
            this.numStdoutLines = lastStdout.rtrim().split('\n').length;
        }
        var stdoutHeight = '75px';
        // heuristic for code with really small outputs
        if (this.numStdoutLines <= 3) {
            stdoutHeight = (25 * this.numStdoutLines) + 'px';
        }
        if (heightOverride) {
            stdoutHeight = heightOverride;
        }
        // do this only after adding outputsHTML to the DOM
        this.domRoot.find('#pyStdout').width('350px')
            .height(stdoutHeight)
            .resizable();
    }
    ProgramOutputBox.prototype.renderOutput = function (stdoutStr) {
        if (!stdoutStr) {
            stdoutStr = '';
        }
        // if there isn't anything to display, don't even bother
        // displaying the pane (but this may cause jumpiness later)
        if (this.numStdoutLines > 0) {
            this.domRoot.find('#progOutputs').show();
            var pyStdout = this.domRoot.find("#pyStdout");
            // keep original horizontal scroll level:
            var oldLeft = pyStdout.scrollLeft();
            pyStdout.val(stdoutStr.rtrim() /* trim trailing spaces */);
            pyStdout.scrollLeft(oldLeft);
            pyStdout.scrollTop(pyStdout[0].scrollHeight); // scroll to bottom, though
        }
        else {
            this.domRoot.find('#progOutputs').hide();
        }
    };
    return ProgramOutputBox;
}()); // END class ProgramOutputBox
var CodeDisplay = /** @class */ (function () {
    function CodeDisplay(owner, domRoot, domRootD3, codToDisplay, lang, editCodeBaseURL) {
        this.leftGutterSvgInitialized = false;
        this.owner = owner;
        this.domRoot = domRoot;
        this.domRootD3 = domRootD3;
        this.codToDisplay = codToDisplay;
        // 2018-03-15 - removed "Live programming" link from
        // visualization mode to simplify the UI, even if it drives
        // fewer people to live programming mode; they can always click
        // the "Live Programming Mode" button in the code editor:
        //<span id="liveModeSpan" style="display: none;">| <a id="editLiveModeBtn" href="#">Live programming</a></a>\
        //
        // also changed 'Edit code' link to 'Edit this code' to make
        // it more clear to users
        var codeDisplayHTML = '<div id="codeDisplayDiv">\
         <div id="langDisplayDiv"></div>\
         <div id="pyCodeOutputDiv"/>\
         <div id="editCodeLinkDiv"><a id="editBtn">Edit this code</a>\
         </div>\
         <div id="legendDiv"/>\
         <div id="codeFooterDocs"></div>\
       </div>';
        this.domRoot.append(codeDisplayHTML);
        if (this.owner.params.embeddedMode) {
            this.domRoot.find('#editCodeLinkDiv').css('font-size', '10pt');
        }
        this.domRoot.find('#legendDiv')
            .append('<svg id="prevLegendArrowSVG"/> line that just executed')
            .append('<p style="margin-top: 4px"><svg id="curLegendArrowSVG"/> next line to execute</p>');
        this.domRootD3.select('svg#prevLegendArrowSVG')
            .append('polygon')
            .attr('points', exports.SVG_ARROW_POLYGON)
            .attr('fill', exports.lightArrowColor);
        this.domRootD3.select('svg#curLegendArrowSVG')
            .append('polygon')
            .attr('points', exports.SVG_ARROW_POLYGON)
            .attr('fill', exports.darkArrowColor);
        if (editCodeBaseURL) {
            // kinda kludgy
            var pyVer = '2'; // default
            if (lang === 'js') {
                pyVer = 'js';
            }
            else if (lang === 'ts') {
                pyVer = 'ts';
            }
            else if (lang === 'java') {
                pyVer = 'java';
            }
            else if (lang === 'py3') {
                pyVer = '3';
            }
            else if (lang === 'py3anaconda') {
                pyVer = 'py3anaconda';
            }
            else if (lang === 'c') {
                pyVer = 'c';
            }
            else if (lang === 'cpp') {
                pyVer = 'cpp';
            }
            var urlStr = $.param.fragment(editCodeBaseURL, { code: this.codToDisplay, py: pyVer }, 2);
            this.domRoot.find('#editBtn').attr('href', urlStr);
        }
        else {
            this.domRoot.find('#editCodeLinkDiv').hide(); // just hide for simplicity!
            this.domRoot.find('#editBtn').attr('href', "#");
            this.domRoot.find('#editBtn').click(function () { return false; }); // DISABLE the link!
        }
        if (lang !== undefined) {
            if (lang === 'js') {
                this.domRoot.find('#langDisplayDiv').html('JavaScript');
            }
            else if (lang === 'ts') {
                this.domRoot.find('#langDisplayDiv').html('TypeScript');
            }
            else if (lang === 'ruby') {
                this.domRoot.find('#langDisplayDiv').html('Ruby');
            }
            else if (lang === 'java') {
                this.domRoot.find('#langDisplayDiv').html('Java');
            }
            else if (lang === 'py2') {
                this.domRoot.find('#langDisplayDiv').html('Python 2.7');
            }
            else if (lang === 'py3') {
                this.domRoot.find('#langDisplayDiv').html('Python 3.6');
            }
            else if (lang === 'py3anaconda') {
                this.domRoot.find('#langDisplayDiv').html('Python 3.6 with <a target="_blank" href="https://docs.anaconda.com/anaconda/">Anaconda 5.2</a> <font color="#e93f34">EXPERIMENTAL!</font><br/>(much slower than <a target="_blank" href="visualize.html#py=3">regular Python 3.6</a>, but lets you import more modules)');
            }
            else if (lang === 'c') {
                if (this.owner.params.embeddedMode) {
                    this.domRoot.find('#langDisplayDiv').html('C (gcc 4.8, C11)');
                }
                else {
                    this.domRoot.find('#langDisplayDiv').html('C (gcc 4.8, C11)<br/><font color="#e93f34">EXPERIMENTAL!</font> <a href="https://github.com/pgbovine/OnlinePythonTutor/blob/master/unsupported-features.md#c-and-c-unsupported-features" target="_blank">known limitations</a>');
                }
            }
            else if (lang === 'cpp') {
                if (this.owner.params.embeddedMode) {
                    this.domRoot.find('#langDisplayDiv').html('C++ (gcc 4.8, C++11)');
                }
                else {
                    this.domRoot.find('#langDisplayDiv').html('C++ (gcc 4.8, C++11)<br/><font color="#e93f34">EXPERIMENTAL!</font> <a href="https://github.com/pgbovine/OnlinePythonTutor/blob/master/unsupported-features.md#c-and-c-unsupported-features" target="_blank">known limitations</a>');
                }
            }
            else {
                this.domRoot.find('#langDisplayDiv').hide();
            }
        }
    }
    CodeDisplay.prototype.renderPyCodeOutput = function () {
        var _this = this;
        var myCodOutput = this; // capture
        this.domRoot.find('#pyCodeOutputDiv').empty();
        // maps codeOutputLines down both table columns
        // TODO: get rid of pesky owner dependency
        var codeOutputD3 = this.domRootD3.select('#pyCodeOutputDiv')
            .append('table')
            .attr('id', 'pyCodeOutput')
            .selectAll('tr')
            .data(this.owner.codeOutputLines)
            .enter().append('tr')
            .selectAll('td')
            .data(function (d, i) { return [d, d] /* map full data item down both columns */; })
            .enter().append('td')
            .attr('class', function (d, i) {
            // add the togetherjsCloneClick class on here so that we can
            // sync clicks via TogetherJS for setting breakpoints in shared
            // sessions (kinda leaky abstraction since pytutor.ts shouldn't
            // need to know about TogetherJS, but oh wells)
            if (i == 0) {
                return 'lineNo togetherjsCloneClick';
            }
            else {
                return 'cod togetherjsCloneClick';
            }
        })
            .attr('id', function (d, i) {
            if (i == 0) {
                return 'lineNo' + d.lineNumber;
            }
            else {
                return _this.owner.generateID('cod' + d.lineNumber); // make globally unique (within the page)
            }
        })
            .html(function (d, i) {
            if (i == 0) {
                return d.lineNumber;
            }
            else {
                return htmlspecialchars(d.text);
            }
        });
        // create a left-most gutter td that spans ALL rows ...
        // (NB: valign="top" is CRUCIAL for this to work in IE)
        this.domRoot.find('#pyCodeOutput tr:first')
            .prepend('<td id="gutterTD" valign="top" rowspan="' + this.owner.codeOutputLines.length + '"><svg id="leftCodeGutterSVG"/></td>');
        // create prevLineArrow and curLineArrow
        this.domRootD3.select('svg#leftCodeGutterSVG')
            .append('polygon')
            .attr('id', 'prevLineArrow')
            .attr('points', exports.SVG_ARROW_POLYGON)
            .attr('fill', exports.lightArrowColor);
        this.domRootD3.select('svg#leftCodeGutterSVG')
            .append('polygon')
            .attr('id', 'curLineArrow')
            .attr('points', exports.SVG_ARROW_POLYGON)
            .attr('fill', exports.darkArrowColor);
        // 2012-09-05: Disable breakpoints for now to simplify UX
        // 2016-05-01: Revive breakpoint functionality
        codeOutputD3
            .style('cursor', function (d, i) {
            // don't do anything if exePts empty (i.e., this line was never executed)
            var exePts = d.executionPoints;
            if (!exePts || exePts.length == 0) {
                return;
            }
            else {
                return 'pointer';
            }
        })
            .on('click', function (d, i) {
            // don't do anything if exePts empty (i.e., this line was never executed)
            var exePts = d.executionPoints;
            if (!exePts || exePts.length == 0) {
                return;
            }
            d.breakpointHere = !d.breakpointHere; // toggle
            if (d.breakpointHere) {
                myCodOutput.owner.setBreakpoint(d);
                d3.select(this.parentNode).select('td.lineNo').style('color', breakpointColor);
                d3.select(this.parentNode).select('td.lineNo').style('font-weight', 'bold');
                d3.select(this.parentNode).select('td.cod').style('color', breakpointColor);
            }
            else {
                myCodOutput.owner.unsetBreakpoint(d);
                d3.select(this.parentNode).select('td.lineNo').style('color', '');
                d3.select(this.parentNode).select('td.lineNo').style('font-weight', '');
                d3.select(this.parentNode).select('td.cod').style('color', '');
            }
        });
    };
    CodeDisplay.prototype.updateCodOutput = function (smoothTransition) {
        var _this = this;
        if (smoothTransition === void 0) { smoothTransition = false; }
        var gutterSVG = this.domRoot.find('svg#leftCodeGutterSVG');
        // one-time initialization of the left gutter
        // (we often can't do this earlier since the entire pane
        //  might be invisible and hence returns a height of zero or NaN
        //  -- the exact format depends on browser)
        if (!this.leftGutterSvgInitialized) {
            // set the gutter's height to match that of its parent
            gutterSVG.height(gutterSVG.parent().height());
            var firstRowOffsetY = this.domRoot.find('table#pyCodeOutput tr:first').offset().top;
            // first take care of edge case when there's only one line ...
            this.codeRowHeight = this.domRoot.find('table#pyCodeOutput td.cod:first').height();
            // ... then handle the (much more common) multi-line case ...
            // this weird contortion is necessary to get the accurate row height on Internet Explorer
            // (simpler methods work on all other major browsers, erghhhhhh!!!)
            if (this.owner.codeOutputLines.length > 1) {
                var secondRowOffsetY = this.domRoot.find('table#pyCodeOutput tr:nth-child(2)').offset().top;
                this.codeRowHeight = secondRowOffsetY - firstRowOffsetY;
            }
            assert(this.codeRowHeight > 0);
            var gutterOffsetY = gutterSVG.offset().top;
            var teenyAdjustment = gutterOffsetY - firstRowOffsetY;
            // super-picky detail to adjust the vertical alignment of arrows so that they line up
            // well with the pointed-to code text ...
            // (if you want to manually adjust tableTop, then ~5 is a reasonable number)
            this.arrowOffsetY = Math.floor((this.codeRowHeight / 2) - (SVG_ARROW_HEIGHT / 2)) - teenyAdjustment;
            this.leftGutterSvgInitialized = true;
        }
        assert(this.arrowOffsetY !== undefined);
        assert(this.codeRowHeight !== undefined);
        assert(0 <= this.arrowOffsetY && this.arrowOffsetY <= this.codeRowHeight);
        // assumes that this.owner.updateLineAndExceptionInfo has already
        // been run, so line number info is up-to-date!
        // TODO: get rid of this pesky 'owner' dependency
        var myViz = this.owner;
        var isLastInstr = (myViz.curInstr === (myViz.curTrace.length - 1));
        var curEntry = myViz.curTrace[myViz.curInstr];
        var hasError = (curEntry.event === 'exception' || curEntry.event === 'uncaught_exception');
        var isTerminated = (!myViz.instrLimitReached && isLastInstr);
        var pcod = this.domRoot.find('#pyCodeOutputDiv');
        var prevVerticalNudge = myViz.prevLineIsReturn ? Math.floor(this.codeRowHeight / 3) : 0;
        var curVerticalNudge = myViz.curLineIsReturn ? Math.floor(this.codeRowHeight / 3) : 0;
        // ugly edge case for the final instruction :0
        if (isTerminated && !hasError) {
            if (myViz.prevLineNumber !== myViz.curLineNumber) {
                curVerticalNudge = curVerticalNudge - 2;
            }
        }
        if (myViz.prevLineNumber) {
            var pla = this.domRootD3.select('#prevLineArrow');
            var translatePrevCmd = 'translate(0, ' + (((myViz.prevLineNumber - 1) * this.codeRowHeight) + this.arrowOffsetY + prevVerticalNudge) + ')';
            if (smoothTransition) {
                pla
                    .transition()
                    .duration(200)
                    .attr('fill', 'white')
                    .each('end', function () {
                    pla
                        .attr('transform', translatePrevCmd)
                        .attr('fill', exports.lightArrowColor);
                    gutterSVG.find('#prevLineArrow').show(); // show at the end to avoid flickering
                });
            }
            else {
                pla.attr('transform', translatePrevCmd);
                gutterSVG.find('#prevLineArrow').show();
            }
        }
        else {
            gutterSVG.find('#prevLineArrow').hide();
        }
        if (myViz.curLineNumber) {
            var cla = this.domRootD3.select('#curLineArrow');
            var translateCurCmd = 'translate(0, ' + (((myViz.curLineNumber - 1) * this.codeRowHeight) + this.arrowOffsetY + curVerticalNudge) + ')';
            if (smoothTransition) {
                cla
                    .transition()
                    .delay(200)
                    .duration(250)
                    .attr('transform', translateCurCmd);
            }
            else {
                cla.attr('transform', translateCurCmd);
            }
            gutterSVG.find('#curLineArrow').show();
        }
        else {
            gutterSVG.find('#curLineArrow').hide();
        }
        this.domRootD3.selectAll('#pyCodeOutputDiv td.cod')
            .style('border-top', function (d) {
            if (hasError && (d.lineNumber == curEntry.line)) {
                return '1px solid ' + errorColor;
            }
            else {
                return '';
            }
        })
            .style('border-bottom', function (d) {
            // COPY AND PASTE ALERT!
            if (hasError && (d.lineNumber == curEntry.line)) {
                return '1px solid ' + errorColor;
            }
            else {
                return '';
            }
        });
        // returns True iff lineNo is visible in pyCodeOutputDiv
        var isOutputLineVisible = function (lineNo) {
            var lineNoTd = _this.domRoot.find('#lineNo' + lineNo);
            // if we can't even find this lineNo div, then punt!
            if (!lineNoTd || lineNoTd.length /* jQuery selector returns a list */ === 0) {
                return false;
            }
            var LO = lineNoTd.offset().top;
            var PO = pcod.offset().top;
            var ST = pcod.scrollTop();
            var H = pcod.height();
            // add a few pixels of fudge factor on the bottom end due to bottom scrollbar
            return (PO <= LO) && (LO < (PO + H - 30));
        };
        // smoothly scroll pyCodeOutputDiv so that the given line is at the center
        var scrollCodeOutputToLine = function (lineNo) {
            var lineNoTd = _this.domRoot.find('#lineNo' + lineNo);
            // if we can't even find this lineNo div, then punt!
            if (!lineNoTd || lineNoTd.length /* jQuery selector returns a list */ === 0) {
                return false;
            }
            var LO = lineNoTd.offset().top;
            var PO = pcod.offset().top;
            var ST = pcod.scrollTop();
            var H = pcod.height();
            pcod.stop(); // first stop all previously-queued animations
            pcod.animate({ scrollTop: (ST + (LO - PO - (Math.round(H / 2)))) }, 300);
        };
        // smoothly scroll code display
        if (!isOutputLineVisible(curEntry.line)) {
            scrollCodeOutputToLine(curEntry.line);
        }
    };
    return CodeDisplay;
}()); // END class CodeDisplay
var NavigationController = /** @class */ (function () {
    function NavigationController(owner, domRoot, domRootD3, nSteps) {
        var _this = this;
        var myself = this;
        this.owner = owner;
        this.domRoot = domRoot;
        this.domRootD3 = domRootD3;
        this.nSteps = nSteps;
        this.customizeVizOptionsShown = false;
        var navHTML = '<div id="navControlsDiv">\
                     <div id="executionSlider"/>\
                     <div id="executionSliderFooter"/>\
                     <div id="vcrControls">\
                       <button id="jmpFirstInstr", type="button">&lt;&lt; First</button>\
                       <button id="jmpStepBack", type="button">&lt; Prev</button>\
                       <button id="jmpStepFwd", type="button">Next &gt;</button>\
                       <button id="jmpLastInstr", type="button">Last &gt;&gt;</button>\
                     </div>\
                     <div id="curInstr">Step ? of ?</div>\
                     <div id="rawUserInputDiv">\
                       <span id="userInputPromptStr"/>\
                       <input type="text" id="raw_input_textbox" size="30"/>\
                       <button id="raw_input_submit_btn">Submit</button>\
                     </div>\
                     <div id="errorOutput"/>\
                     <div id="creditsPane"></div>\
                     <div id="uiControlsPane"><a id="customizeVizLink" href="#">Customize visualization</a> (<font color="#e93f34">NEW!</font>)</div>\
                   </div>';
        this.domRoot.append(navHTML);
        this.domRoot.find("#jmpFirstInstr").click(function () { _this.owner.renderStep(0); });
        this.domRoot.find("#jmpLastInstr").click(function () { _this.owner.renderStep(_this.nSteps - 1); });
        this.domRoot.find("#jmpStepBack").click(function () { _this.owner.stepBack(); });
        this.domRoot.find("#jmpStepFwd").click(function () { _this.owner.stepForward(); });
        // disable controls initially ...
        this.domRoot.find("#vcrControls #jmpFirstInstr").attr("disabled", true);
        this.domRoot.find("#vcrControls #jmpStepBack").attr("disabled", true);
        this.domRoot.find("#vcrControls #jmpStepFwd").attr("disabled", true);
        this.domRoot.find("#vcrControls #jmpLastInstr").attr("disabled", true);
        var ruiDiv = this.domRoot.find('#rawUserInputDiv');
        ruiDiv.find('#userInputPromptStr').html(this.owner.userInputPromptStr);
        ruiDiv.find('#raw_input_submit_btn').click(function () {
            var userInput = ruiDiv.find('#raw_input_textbox').val();
            // advance instruction count by 1 to get to the NEXT instruction
            _this.owner.params.executeCodeWithRawInputFunc(userInput, _this.owner.curInstr + 1);
        });
        // create customize visualization UI
        var uiControlsPane = this.domRoot.find("#uiControlsPane");
        // expose the customization UI
        uiControlsPane.find("#customizeVizLink").click(function () {
            if (_this.customizeVizOptionsShown) {
                return;
            }
            // do this up top so that renderDataStructures is called,
            // customizeVizOptionsShown is on, so objects get made .draggable()
            _this.customizeVizOptionsShown = true;
            uiControlsPane.append(' \
        <div style="margin-top: 8px;"/>\
          <font color="#e93f34">Warning:</font> Reloading this page loses all changes;\
          customizations <em>NOT</em> shared in URL or chat sessions\
          <p/><b>Drag</b> any object around to move it. Customize its pointers:\
          <div style="margin-top: 12px; margin-bottom: 5px;">\
          Line style:\
          <select id="jsplumbConnectorType">\
            <option value="StateMachine" selected>Default</option>\
            <option value="Bezier">Bezier</option>\
            <option value="Straight">Straight</option>\
            <option value="Flowchart">Flowchart</option>\
          </select>\
          </div>\
          <div class="sliderWrapper">Curve: <input type="range" min="0" max="100" value="10" class="jsplumbOptionSlider" id="smCurviness"><span class="sliderVal">10</span></div>\
          <div class="sliderWrapper">Curve: <input type="range" min="0" max="500" value="150" class="jsplumbOptionSlider" id="bezierCurviness"><span class="sliderVal">150</span></div>\
          <div class="sliderWrapper">Margin: <input type="range" min="0" max="20" value="5" class="jsplumbOptionSlider" id="margin"><span class="sliderVal">5</span></div>\
          <div class="sliderWrapper">Stub: <input type="range" min="0" max="50" value="0" class="jsplumbOptionSlider" id="stub"><span class="sliderVal">0</span></div>\
          <div class="sliderWrapper">Gap: <input type="range" min="0" max="50" value="0" class="jsplumbOptionSlider" id="gap"><span class="sliderVal">0</span></div>\
          <div class="sliderWrapper">Midpoint: <input type="range" min="0" max="10" value="0.5" step="0.5" class="jsplumbOptionSlider" id="midpoint"><span class="sliderVal">0.5</span></div>\
          <div class="sliderWrapper">CornerRadius: <input type="range" min="0" max="10" value="0" class="jsplumbOptionSlider" id="cornerRadius"><span class="sliderVal">0</span></div>\
          <div class="sliderWrapper">Arrow length: <input type="range" min="1" max="30" value="10" class="jsplumbOptionSlider" id="arrowLength"><span class="sliderVal">10</span></div>\
          <div class="sliderWrapper">Arrow width: <input type="range" min="1" max="30" value="7" class="jsplumbOptionSlider" id="arrowWidth"><span class="sliderVal">7</span></div>\
          <div class="sliderWrapper">Arrow fold: <input type="range" min="0" max="1" value="0.55" step="0.05" class="jsplumbOptionSlider" id="arrowFoldback"><span class="sliderVal">0.55</span></div>\
          <div id="selectiveHideDiv" style="margin-top: 15px; padding: 6px 6px 6px 6px; border: 1px solid #ccc;">\
            <b>Hide variables/fields</b> (elements may end up out of order, so reload page to reset)<br/>\
            <button id="updateHideVarsBtn" style="margin-top: 8px;">Update visualization</button>\
            <p/>All choices below; use part after colon to match all variables/fields with that name.<br/>\
            <font color="#e93f34">(Double-check your spelling!)</font>\
            <p/>Hide these variables:<br/>\
            <textarea id="hideVars" rows="3" cols="70"/>\
            <div id="hideVarsChoices" style="width: 500px;"></div>\
            <p style="margin-top: 15px;"/>Hide these object fields:<br/>\
            <textarea id="hideFields" rows="3" cols="70"/>\
            <div id="hideFieldsChoices" style="width: 500px;"></div>\
          </div>\
        </div>\
      ');
            // note that many of these options aren't present in the OLD OLD
            // OLD version of ./lib/jquery.jsPlumb-1.3.10-all-min.js that
            // we're using, so they might not do anything when they're
            // triggered. look at the inline comments/documentation in the source code
            // here for details: lib/jsplumb-1.3.10.zip
            function rerenderJsPlumbConnectors() {
                var connectorType = uiControlsPane.find('#jsplumbConnectorType').val();
                var connectorSpec = null;
                if (connectorType === "StateMachine") {
                    var curviness = uiControlsPane.find('#smCurviness').val();
                    connectorSpec = [connectorType, { curviness: curviness }]; // margin seems to have no effect
                }
                else if (connectorType === "Bezier") {
                    var curviness = uiControlsPane.find('#bezierCurviness').val();
                    connectorSpec = [connectorType, { curviness: curviness }];
                }
                else if (connectorType === "Straight") {
                    connectorSpec = [connectorType]; // stub and gap seem to have no effect
                }
                else {
                    assert(connectorType === "Flowchart");
                    // stub, midpoint, and radius seem to have no effect (actually
                    // stub causes crashes, ergh)
                    var gap = uiControlsPane.find('#gap').val();
                    connectorSpec = [connectorType, { gap: gap }];
                }
                if (connectorSpec) {
                    myself.owner.dataViz.jsPlumbInstance.importDefaults({
                        Connector: connectorSpec,
                        Overlays: [["Arrow", { length: uiControlsPane.find('#arrowLength').val(),
                                    width: uiControlsPane.find('#arrowWidth').val(),
                                    foldback: uiControlsPane.find('#arrowFoldback').val(),
                                    location: 1 // always 1, which means to display at target
                                }
                            ]],
                    });
                    myself.owner.dataViz.renderDataStructures(myself.owner.curInstr); // UGLY!
                }
            }
            // when any slider is moved, update its numeric display and then
            // redraw all jsPlumb connectors with new options
            uiControlsPane.find('.jsplumbOptionSlider').each(function (i, e) {
                e.oninput = function () {
                    $(e).siblings('.sliderVal').html(this.value);
                    rerenderJsPlumbConnectors();
                };
            });
            // show certain sliders depending on value of jsplumbConnectorType
            // use this as a reference:
            // https://community.jsplumbtoolkit.com/doc/connectors.html
            uiControlsPane.find('#jsplumbConnectorType').change(function () {
                var v = $(this).val();
                uiControlsPane.find('.sliderWrapper').hide();
                if (v === "StateMachine") {
                    uiControlsPane.find('#smCurviness').parent('.sliderWrapper').show();
                    /* margin seems to have no effect ...
                    uiControlsPane.find('#margin').parent('.sliderWrapper').show();
                    */
                }
                else if (v === "Bezier") {
                    uiControlsPane.find('#bezierCurviness').parent('.sliderWrapper').show();
                }
                else if (v === "Straight") {
                    /* neither stub nor gap seem to have any effect :/
                    uiControlsPane.find('#stub').val(0).siblings('.sliderVal').html(0); // set default
                    uiControlsPane.find('#stub').parent('.sliderWrapper').show();
                    uiControlsPane.find('#gap').parent('.sliderWrapper').show();
                    */
                }
                else {
                    assert(v === "Flowchart");
                    /* stub seems to be bogus and result in errors
                    uiControlsPane.find('#stub').val(30).siblings('.sliderVal').html(30); // set default
                    uiControlsPane.find('#stub').parent('.sliderWrapper').show();
          
                    // midpoint and cornerRadius seem equally useless
                    uiControlsPane.find('#midpoint').parent('.sliderWrapper').show();
                    uiControlsPane.find('#cornerRadius').parent('.sliderWrapper').show();
                    */
                    uiControlsPane.find('#gap').parent('.sliderWrapper').show();
                }
                // always show arrow stuff
                uiControlsPane.find('#arrowLength,#arrowWidth,#arrowFoldback').parent('.sliderWrapper').show();
                rerenderJsPlumbConnectors(); // re-render based on new connector type choice
            }).val('StateMachine').change(); // <-- trigger a change event on this
            // initial setting to get the change
            // handler above to run
            // set up infrastructure for showing/hiding variables / object fields
            var allVarnames = _this.owner.dataViz.getAllProgramVarnames();
            var allFieldnames = _this.owner.dataViz.getAllProgramObjectFieldNames();
            var varnameChoices = varlistToHtml(allVarnames);
            var fieldnameChoices = varlistToHtml(allFieldnames);
            uiControlsPane.find('#hideVarsChoices').html('<b><em>Choices:</em></b> ' + varnameChoices);
            uiControlsPane.find('#hideFieldsChoices').html('<b><em>Choices:</em></b> ' + fieldnameChoices);
            uiControlsPane.find('#updateHideVarsBtn').click(function () {
                var hideVarsLst = processHideString(uiControlsPane.find('#hideVars').val());
                var hideFieldsLst = processHideString(uiControlsPane.find('#hideFields').val());
                _this.owner.dataViz.selectivelyHideVarsAndFields(hideVarsLst, hideFieldsLst);
            });
            return false; // don't follow the link and reload the page!
        });
    }
    NavigationController.prototype.hideUserInputDiv = function () {
        this.domRoot.find('#rawUserInputDiv').hide();
    };
    NavigationController.prototype.showUserInputDiv = function () {
        this.domRoot.find('#rawUserInputDiv').show();
    };
    NavigationController.prototype.setSliderVal = function (v) {
        // PROGRAMMATICALLY change the value, so evt.originalEvent should be undefined
        this.domRoot.find('#executionSlider').slider('value', v);
    };
    NavigationController.prototype.setVcrControls = function (msg, isFirstInstr, isLastInstr) {
        var vcrControls = this.domRoot.find("#vcrControls");
        vcrControls.find("#jmpFirstInstr").attr("disabled", false);
        vcrControls.find("#jmpStepBack").attr("disabled", false);
        vcrControls.find("#jmpStepFwd").attr("disabled", false);
        vcrControls.find("#jmpLastInstr").attr("disabled", false);
        this.domRoot.find("#curInstr").html(msg);
        if (isFirstInstr) {
            vcrControls.find("#jmpFirstInstr").attr("disabled", true);
            vcrControls.find("#jmpStepBack").attr("disabled", true);
        }
        if (isLastInstr) {
            vcrControls.find("#jmpLastInstr").attr("disabled", true);
            vcrControls.find("#jmpStepFwd").attr("disabled", true);
        }
    };
    NavigationController.prototype.setupSlider = function (maxSliderVal) {
        var _this = this;
        assert(maxSliderVal >= 0);
        var sliderDiv = this.domRoot.find('#executionSlider');
        sliderDiv.slider({ min: 0, max: maxSliderVal, step: 1 });
        // disable keyboard actions on the slider itself (to prevent double-firing
        // of events), and make skinnier and taller
        sliderDiv
            .find(".ui-slider-handle")
            .unbind('keydown')
            .css('width', '0.8em')
            .css('height', '1.4em');
        this.domRoot.find(".ui-widget-content").css('font-size', '0.9em');
        this.domRoot.find('#executionSlider').bind('slide', function (evt, ui) {
            // this is SUPER subtle. if this value was changed programmatically,
            // then evt.originalEvent will be undefined. however, if this value
            // was changed by a user-initiated event, then this code should be
            // executed ...
            if (evt.originalEvent) {
                _this.owner.renderStep(ui.value);
            }
        });
    };
    NavigationController.prototype.renderSliderBreakpoints = function (sortedBreakpointsList) {
        this.domRoot.find("#executionSliderFooter").empty();
        var w = this.domRoot.find('#executionSlider').width();
        // I originally didn't want to delete and re-create this overlay every time,
        // but if I don't do so, there are weird flickering artifacts with clearing
        // the SVG container; so it's best to just delete and re-create the container each time
        var sliderOverlay = this.domRootD3.select('#executionSliderFooter')
            .append('svg')
            .attr('id', 'sliderOverlay')
            .attr('width', w)
            .attr('height', 12);
        var xrange = d3.scale.linear()
            .domain([0, this.nSteps - 1])
            .range([0, w]);
        sliderOverlay.selectAll('rect')
            .data(sortedBreakpointsList)
            .enter().append('rect')
            .attr('x', function (d, i) {
            // make edge case of 0 look decent:
            return (d === 0) ? 0 : xrange(d) - 1;
        })
            .attr('y', 0)
            .attr('width', 2)
            .attr('height', 12)
            .style('fill', function (d) {
            return breakpointColor;
        });
    };
    NavigationController.prototype.showError = function (msg) {
        if (msg) {
            this.domRoot.find("#errorOutput").html(htmlspecialchars(msg) + ("\n      <div style=\"font-size: 11pt; color: #666\">(" + footer_html_1.unsupportedFeaturesStr + ")</div>")).show();
        }
        else {
            this.domRoot.find("#errorOutput").hide();
        }
    };
    return NavigationController;
}()); // END class NavigationController
// Utilities
function assert(cond) {
    if (!cond) {
        console.trace();
        alert("Assertion Failure (see console log for backtrace)");
        throw 'Assertion Failure';
    }
}
exports.assert = assert;
// taken from http://www.toao.net/32-my-htmlspecialchars-function-for-javascript
function htmlspecialchars(str) {
    if (typeof (str) == "string") {
        str = str.replace(/&/g, "&amp;"); /* must do &amp; first */
        // ignore these for now ...
        //str = str.replace(/"/g, "&quot;");
        //str = str.replace(/'/g, "&#039;");
        str = str.replace(/</g, "&lt;");
        str = str.replace(/>/g, "&gt;");
        // replace spaces:
        str = str.replace(/ /g, "&nbsp;");
        // replace tab as four spaces:
        str = str.replace(/\t/g, "&nbsp;&nbsp;&nbsp;&nbsp;");
        // replace newline as <br/>
        str = str.replace(newlineAllRegex, '<br/>');
    }
    return str;
}
exports.htmlspecialchars = htmlspecialchars;
// same as htmlspecialchars except don't worry about expanding spaces or
// tabs since we want proper word wrapping in divs.
function htmlsanitize(str) {
    if (typeof (str) == "string") {
        str = str.replace(/&/g, "&amp;"); /* must do &amp; first */
        str = str.replace(/</g, "&lt;");
        str = str.replace(/>/g, "&gt;");
    }
    return str;
}
String.prototype /* TS too strict */.rtrim = function () {
    return this.replace(/\s*$/g, "");
};
// make sure varname doesn't contain any weird
// characters that are illegal for CSS ID's ...
//
// I know for a fact that iterator tmp variables named '_[1]'
// are NOT legal names for CSS ID's.
// I also threw in '{', '}', '(', ')', '<', '>' as illegal characters.
//
// also some variable names are like '.0' (for generator expressions),
// and '.' seems to be illegal.
//
// also '=', '!', and '?' are common in Ruby names, so escape those as well
// '$' sometimes found in JavaScript names, so escape as well
//
// also spaces are illegal, so convert to '_'
// TODO: what other characters are illegal???
var lbRE = new RegExp('\\[|{|\\(|<', 'g');
var rbRE = new RegExp('\\]|}|\\)|>', 'g');
function varnameToCssID(varname) {
    // make sure to REPLACE ALL (using the 'g' option)
    // rather than just replacing the first entry
    return varname.replace(lbRE, 'LeftB_')
        .replace(rbRE, '_RightB')
        .replace(/[!]/g, '_BANG_')
        .replace(/[?]/g, '_QUES_')
        .replace(/[:]/g, '_COLON_')
        .replace(/[=]/g, '_EQ_')
        .replace(/[.]/g, '_DOT_')
        .replace(/[$]/g, '_DOLLAR_')
        .replace(/ /g, '_');
}
function isHeapRef(obj, heap) {
    // ordinary REF
    if (obj[0] === 'REF') {
        return (heap[obj[1]] !== undefined);
    }
    else if (obj[0] === 'C_DATA' && obj[2] === 'pointer') {
        // C-style pointer that has a valid value
        if (obj[3] != '<UNINITIALIZED>' && obj[3] != '<UNALLOCATED>') {
            return (heap[obj[3]] !== undefined);
        }
    }
    return false;
}
function getRefID(obj) {
    if (obj[0] == 'REF') {
        return obj[1];
    }
    else {
        assert(obj[0] === 'C_DATA' && obj[2] === 'pointer');
        assert(obj[3] != '<UNINITIALIZED>' && obj[3] != '<UNALLOCATED>');
        return obj[3]; // pointed-to address
    }
}

/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0), __webpack_require__(0)))

/***/ }),
/* 5 */
/***/ (function(module, exports) {

module.exports = "data:image/png;base64,[encoded data, 6068 characters]"

/***/ }),
/* 6 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.privacyAndEndingHTML = "\n\n<p style=\"margin-top: 30px;\">Privacy Policy: By using Python Tutor, your\nvisualized code, options, user interactions, text chats, and IP address\nare logged on our server and may be analyzed for research purposes.\nNearly all web services collect this basic information from users in\ntheir server logs. However, Python Tutor does not collect any personally\nidentifiable information from its users. It uses Google Analytics for\nwebsite analytics.</p>\n\n<p>Terms of Service: The Python Tutor service is provided for free on an\nas-is basis. Use this service at your own risk. Do not use it to share\nconfidential information. The developers of Python Tutor are not\nresponsible for the chat messages or behaviors of any of the users on\nthis website. We are also not responsible for any damages caused by\nusing this website. Finally, it is your responsibility to follow\nappropriate academic integrity standards.</p>\n\n<p style=\"margin-top: 25px;\">\nCopyright &copy; <a href=\"http://www.pgbovine.net/\">Philip Guo</a>.  All rights reserved.\n</p>";
exports.footerHtml = "\n<p style=\"margin-top: 20px; margin-bottom: 30px;\"><a href=\"https://github.com/pgbovine/OnlinePythonTutor/blob/master/unsupported-features.md\" target=\"_blank\">unsupported features</a> |\n<a href=\"https://www.youtube.com/watch?v=80ztTXP90Vs&list=PLzV58Zm8FuBL2WxxZKGZ6j1dH8NKb_HYI&index=5\" target=\"_blank\">setting breakpoints</a> |\n<a href=\"https://www.youtube.com/watch?v=Mxt9HZWgwAM&list=PLzV58Zm8FuBL2WxxZKGZ6j1dH8NKb_HYI&index=6\" target=\"_blank\">hiding variables</a> |\n<a href=\"https://www.youtube.com/watch?v=JjGt95Te0wo&index=3&list=PLzV58Zm8FuBL2WxxZKGZ6j1dH8NKb_HYI\" target=\"_blank\">live programming</a>\n</p>\n\n<p>\n  <button id=\"genUrlBtn\" class=\"smallBtn\" type=\"button\">Generate permanent link</button> <input type=\"text\" id=\"urlOutput\" size=\"60\"/>\n(<a href=\"https://www.youtube.com/watch?v=h4q3UKdEFKE\" target=\"_blank\">video demo</a>)\n</p>\n\n<div id=\"embedLinkDiv\">\n<p>\n  <button id=\"genEmbedBtn\" class=\"smallBtn\" type=\"button\">Generate embed code</button> <input type=\"text\" id=\"embedCodeOutput\" size=\"60\"/> (also supports https://)\n</p>\n</div>\n\n<p style=\"margin-top: 25px;\">\n<a href=\"http://pythontutor.com/\">Python Tutor</a> (<a href=\"https://github.com/pgbovine/OnlinePythonTutor\">code on GitHub</a>) supports:\n\nPython <a href=\"https://docs.python.org/3.6/\">3.6</a> and <a\nhref=\"https://docs.python.org/2.7/\">2.7</a> with limited imports\n(__future__, abc, array, bisect, calendar,\ncmath, collections, copy, datetime, decimal,\ndoctest, fractions, functools, hashlib, heapq,\nio, itertools, json, locale, math,\noperator, pickle, pprint, random, re,\nstring, time, types, unittest, StringIO (Python 2), typing (Python 3)),\n\nOracle Java 8 (implemented by <a href=\"https://github.com/daveagp\">David Pritchard</a> and Will Gwozdz,\nsupports\n<code><a href=\"http://introcs.cs.princeton.edu/java/stdlib/javadoc/StdIn.html\">StdIn</a></code>, \n<code><a href=\"http://introcs.cs.princeton.edu/java/stdlib/javadoc/StdOut.html\">StdOut</a></code>, \nmost other <a href=\"http://introcs.cs.princeton.edu/java/stdlib\"><tt>stdlib</tt> libraries</a>,\n<a href=\"http://introcs.cs.princeton.edu/java/43stack/Stack.java.html\"><tt>Stack</tt></a>,\n<a href=\"http://introcs.cs.princeton.edu/java/43stack/Queue.java.html\"><tt>Queue</tt></a>,\nand <a href=\"http://introcs.cs.princeton.edu/java/44st/ST.java.html\"><tt>ST</tt></a>.\nTo access built-in <tt>Stack</tt>/<tt>Queue</tt> classes, write:\n<tt>import java.util.Stack;</tt> This won't work: <tt>import\njava.util.*;</tt>),\n\nJavaScript ES6 and TypeScript 1.4.1 (Node.js v6.0.0), Ruby 2 (MRI 2.2.2), C and C++ (gcc 4.8, C11/C++11, Valgrind Memcheck)</p>\n\n" + exports.privacyAndEndingHTML;
exports.nullTraceErrorLst = [
    "Unknown error: The server is OVERLOADED or your code has UNSUPPORTED FEATURES.",
    "Try again later. This site is free with NO available technical support. [#NullTrace]"
];
exports.unsupportedFeaturesStr = 'see <a target="_blank" href="https://github.com/pgbovine/OnlinePythonTutor/blob/master/unsupported-features.md">UNSUPPORTED FEATURES</a>';


/***/ }),
/* 7 */
/***/ (function(module, exports, __webpack_require__) {

/* WEBPACK VAR INJECTION */(function(jQuery) {/*
 * jQuery doTimeout: Like setTimeout, but better! - v1.0 - 3/3/2010
 * http://benalman.com/projects/jquery-dotimeout-plugin/
 * 
 * Copyright (c) 2010 "Cowboy" Ben Alman
 * Dual licensed under the MIT and GPL licenses.
 * http://benalman.com/about/license/
 */
(function($){var a={},c="doTimeout",d=Array.prototype.slice;$[c]=function(){return b.apply(window,[0].concat(d.call(arguments)))};$.fn[c]=function(){var f=d.call(arguments),e=b.apply(this,[c+f[0]].concat(f));return typeof f[0]==="number"||typeof f[1]==="number"?this:e};function b(l){var m=this,h,k={},g=l?$.fn:$,n=arguments,i=4,f=n[1],j=n[2],p=n[3];if(typeof f!=="string"){i--;f=l=0;j=n[1];p=n[2]}if(l){h=m.eq(0);h.data(l,k=h.data(l)||{})}else{if(f){k=a[f]||(a[f]={})}}k.id&&clearTimeout(k.id);delete k.id;function e(){if(l){h.removeData(l)}else{if(f){delete a[f]}}}function o(){k.id=setTimeout(function(){k.fn()},j)}if(p){k.fn=function(q){if(typeof p==="string"){p=g[p]}p.apply(m,d.call(n,i))===true&&!q?o():e()};o()}else{if(k.fn){j===undefined?e():k.fn(j===false);return true}else{e()}}}})(jQuery);
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0)))

/***/ }),
/* 8 */
/***/ (function(module, exports) {

module.exports = function escape(url) {
    if (typeof url !== 'string') {
        return url
    }
    // If url is already wrapped in quotes, remove them
    if (/^['"].*['"]$/.test(url)) {
        url = url.slice(1, -1);
    }
    // Should url be wrapped?
    // See https://drafts.csswg.org/css-values-3/#urls
    if (/["'() \t\n]/.test(url)) {
        return '"' + url.replace(/"/g, '\\"').replace(/\n/g, '\\n') + '"'
    }

    return url
}


/***/ }),
/* 9 */
/***/ (function(module, exports) {

(function(){function d(a,b){try{for(var c in b)Object.defineProperty(a.prototype,c,{value:b[c],enumerable:!1})}catch(d){a.prototype=b}}function f(a){var b=-1,c=a.length,d=[];while(++b<c)d.push(a[b]);return d}function g(a){return Array.prototype.slice.call(a)}function j(){}function m(a){return a}function n(){return this}function o(){return!0}function p(a){return typeof a=="function"?a:function(){return a}}function q(a,b,c){return function(){var d=c.apply(b,arguments);return arguments.length?a:d}}function r(a){return a!=null&&!isNaN(a)}function s(a){return a.length}function u(a){return a==null}function v(a){return a.replace(/^\s+|\s+$/g,"").replace(/\s+/g," ")}function w(a){var b=1;while(a*b%1)b*=10;return b}function z(){}function A(a){function d(){var c=b,d=-1,e=c.length,f;while(++d<e)(f=c[d].on)&&f.apply(this,arguments);return a}var b=[],c=new j;return d.on=function(d,e){var f=c.get(d),g;return arguments.length<2?f&&f.on:(f&&(f.on=null,b=b.slice(0,g=b.indexOf(f)).concat(b.slice(g+1)),c.remove(d)),e&&b.push(c.set(d,{on:e})),a)},d}function D(a,b){return b-(a?1+Math.floor(Math.log(a+Math.pow(10,1+Math.floor(Math.log(a)/Math.LN10)-b))/Math.LN10):1)}function E(a){return a+""}function F(a){var b=a.lastIndexOf("."),c=b>=0?a.substring(b):(b=a.length,""),d=[];while(b>0)d.push(a.substring(b-=3,b+3));return d.reverse().join(",")+c}function H(a,b){var c=Math.pow(10,Math.abs(8-b)*3);return{scale:b>8?function(a){return a/c}:function(a){return a*c},symbol:a}}function N(a){return function(b){return b<=0?0:b>=1?1:a(b)}}function O(a){return function(b){return 1-a(1-b)}}function P(a){return function(b){return.5*(b<.5?a(2*b):2-a(2-2*b))}}function Q(a){return a}function R(a){return function(b){return Math.pow(b,a)}}function S(a){return 1-Math.cos(a*Math.PI/2)}function T(a){return Math.pow(2,10*(a-1))}function U(a){return 1-Math.sqrt(1-a*a)}function V(a,b){var c;return arguments.length<2&&(b=.45),arguments.length<1?(a=1,c=b/4):c=b/(2*Math.PI)*Math.asin(1/a),function(d){return 1+a*Math.pow(2,10*-d)*Math.sin((d-c)*2*Math.PI/b)}}function W(a){return a||(a=1.70158),function(b){return b*b*((a+1)*b-a)}}function X(a){return a<1/2.75?7.5625*a*a:a<2/2.75?7.5625*(a-=1.5/2.75)*a+.75:a<2.5/2.75?7.5625*(a-=2.25/2.75)*a+.9375:7.5625*(a-=2.625/2.75)*a+.984375}function Y(){d3.event.stopPropagation(),d3.event.preventDefault()}function Z(){var a=d3.event,b;while(b=a.sourceEvent)a=b;return a}function $(a){var b=new z,c=0,d=arguments.length;while(++c<d)b[arguments[c]]=A(b);return b.of=function(c,d){return function(e){try{var f=e.sourceEvent=d3.event;e.target=a,d3.event=e,b[e.type].apply(c,d)}finally{d3.event=f}}},b}function ba(a){return a=="transform"?d3.interpolateTransform:d3.interpolate}function bb(a,b){return b=b-(a=+a)?1/(b-a):0,function(c){return(c-a)*b}}function bc(a,b){return b=b-(a=+a)?1/(b-a):0,function(c){return Math.max(0,Math.min(1,(c-a)*b))}}function bd(a,b,c){return new be(a,b,c)}function be(a,b,c){this.r=a,this.g=b,this.b=c}function bf(a){return a<16?"0"+Math.max(0,a).toString(16):Math.min(255,a).toString(16)}function bg(a,b,c){var d=0,e=0,f=0,g,h,i;g=/([a-z]+)\((.*)\)/i.exec(a);if(g){h=g[2].split(",");switch(g[1]){case"hsl":return c(parseFloat(h[0]),parseFloat(h[1])/100,parseFloat(h[2])/100);case"rgb":return b(bi(h[0]),bi(h[1]),bi(h[2]))}}return(i=bj.get(a))?b(i.r,i.g,i.b):(a!=null&&a.charAt(0)==="#"&&(a.length===4?(d=a.charAt(1),d+=d,e=a.charAt(2),e+=e,f=a.charAt(3),f+=f):a.length===7&&(d=a.substring(1,3),e=a.substring(3,5),f=a.substring(5,7)),d=parseInt(d,16),e=parseInt(e,16),f=parseInt(f,16)),b(d,e,f))}function bh(a,b,c){var d=Math.min(a/=255,b/=255,c/=255),e=Math.max(a,b,c),f=e-d,g,h,i=(e+d)/2;return f?(h=i<.5?f/(e+d):f/(2-e-d),a==e?g=(b-c)/f+(b<c?6:0):b==e?g=(c-a)/f+2:g=(a-b)/f+4,g*=60):h=g=0,bk(g,h,i)}function bi(a){var b=parseFloat(a);return a.charAt(a.length-1)==="%"?Math.round(b*2.55):b}function bk(a,b,c){return new bl(a,b,c)}function bl(a,b,c){this.h=a,this.s=b,this.l=c}function bm(a,b,c){function f(a){return a>360?a-=360:a<0&&(a+=360),a<60?d+(e-d)*a/60:a<180?e:a<240?d+(e-d)*(240-a)/60:d}function g(a){return Math.round(f(a)*255)}var d,e;return a%=360,a<0&&(a+=360),b=b<0?0:b>1?1:b,c=c<0?0:c>1?1:c,e=c<=.5?c*(1+b):c+b-c*b,d=2*c-e,bd(g(a+120),g(a),g(a-120))}function bn(a){return i(a,bt),a}function bu(a){return function(){return bo(a,this)}}function bv(a){return function(){return bp(a,this)}}function bw(a,b){function f(){if(b=this.classList)return b.add(a);var b=this.className,d=b.baseVal!=null,e=d?b.baseVal:b;c.lastIndex=0,c.test(e)||(e=v(e+" "+a),d?b.baseVal=e:this.className=e)}function g(){if(b=this.classList)return b.remove(a);var b=this.className,d=b.baseVal!=null,e=d?b.baseVal:b;e=v(e.replace(c," ")),d?b.baseVal=e:this.className=e}function h(){(b.apply(this,arguments)?f:g).call(this)}var c=new RegExp("(^|\\s+)"+d3.requote(a)+"(\\s+|$)","g");if(arguments.length<2){var d=this.node();if(e=d.classList)return e.contains(a);var e=d.className;return c.lastIndex=0,c.test(e.baseVal!=null?e.baseVal:e)}return this.each(typeof b=="function"?h:b?f:g)}function bx(a){return{__data__:a}}function by(a){return function(){return bs(this,a)}}function bz(a){return arguments.length||(a=d3.ascending),function(b,c){return a(b&&b.__data__,c&&c.__data__)}}function bA(a,b){for(var c=0,d=a.length;c<d;c++)for(var e=a[c],f=0,g=e.length,h;f<g;f++)(h=e[f])&&b(h,f,c);return a}function bC(a){return i(a,bD),a}function bE(a,b,c){i(a,bI);var d=new j,e=d3.dispatch("start","end"),f=bQ;return a.id=b,a.time=c,a.tween=function(b,c){return arguments.length<2?d.get(b):(c==null?d.remove(b):d.set(b,c),a)},a.ease=function(b){return arguments.length?(f=typeof b=="function"?b:d3.ease.apply(d3,arguments),a):f},a.each=function(b,c){return arguments.length<2?bR.call(a,b):(e.on(b,c),a)},d3.timer(function(g){return bA(a,function(a,h,i){function o(f){return m.active>b?q():(m.active=b,d.forEach(function(b,c){(c=c.call(a,n,h))&&j.push(c)}),e.start.call(a,n,h),p(f)||d3.timer(p,0,c),1)}function p(c){if(m.active!==b)return q();var d=(c-k)/l,g=f(d),i=j.length;while(i>0)j[--i].call(a,g);if(d>=1)return q(),bK=b,e.end.call(a,n,h),bK=0,1}function q(){return--m.count||delete a.__transition__,1}var j=[],k=a.delay,l=a.duration,m=(a=a.node).__transition__||(a.__transition__={active:0,count:0}),n=a.__data__;++m.count,k<=g?o(g):d3.timer(o,k,c)})},0,c),a}function bG(a,b,c){return c!=""&&bF}function bH(a,b){function d(a,d,e){var f=b.call(this,a,d);return f==null?e!=""&&bF:e!=f&&c(e,f)}function e(a,d,e){return e!=b&&c(e,b)}var c=ba(a);return typeof b=="function"?d:b==null?bG:(b+="",e)}function bR(a){var b=bK,c=bQ,d=bO,e=bP;return bK=this.id,bQ=this.ease(),bA(this,function(b,c,d){bO=b.delay,bP=b.duration,a.call(b=b.node,b.__data__,c,d)}),bK=b,bQ=c,bO=d,bP=e,this}function bV(){var a,b=Date.now(),c=bS;while(c)a=b-c.then,a>=c.delay&&(c.flush=c.callback(a)),c=c.next;var d=bW()-b;d>24?(isFinite(d)&&(clearTimeout(bU),bU=setTimeout(bV,d)),bT=0):(bT=1,bX(bV))}function bW(){var a=null,b=bS,c=Infinity;while(b)b.flush?b=a?a.next=b.next:bS=b.next:(c=Math.min(c,b.then+b.delay),b=(a=b).next);return c}function bY(a){var b=[a.a,a.b],c=[a.c,a.d],d=b$(b),e=bZ(b,c),f=b$(b_(c,b,-e))||0;b[0]*c[1]<c[0]*b[1]&&(b[0]*=-1,b[1]*=-1,d*=-1,e*=-1),this.rotate=(d?Math.atan2(b[1],b[0]):Math.atan2(-c[0],c[1]))*ca,this.translate=[a.e,a.f],this.scale=[d,f],this.skew=f?Math.atan2(e,f)*ca:0}function bZ(a,b){return a[0]*b[0]+a[1]*b[1]}function b$(a){var b=Math.sqrt(bZ(a,a));return b&&(a[0]/=b,a[1]/=b),b}function b_(a,b,c){return a[0]+=c*b[0],a[1]+=c*b[1],a}function cc(a,b){var c=a.ownerSVGElement||a;if(c.createSVGPoint){var d=c.createSVGPoint();if(cb<0&&(window.scrollX||window.scrollY)){c=d3.select(document.body).append("svg").style("position","absolute").style("top",0).style("left",0);var e=c[0][0].getScreenCTM();cb=!e.f&&!e.e,c.remove()}return cb?(d.x=b.pageX,d.y=b.pageY):(d.x=b.clientX,d.y=b.clientY),d=d.matrixTransform(a.getScreenCTM().inverse()),[d.x,d.y]}var f=a.getBoundingClientRect();return[b.clientX-f.left-a.clientLeft,b.clientY-f.top-a.clientTop]}function cd(){}function ce(a){var b=a[0],c=a[a.length-1];return b<c?[b,c]:[c,b]}function cf(a){return a.rangeExtent?a.rangeExtent():ce(a.range())}function cg(a,b){var c=0,d=a.length-1,e=a[c],f=a[d],g;f<e&&(g=c,c=d,d=g,g=e,e=f,f=g);if(g=f-e)b=b(g),a[c]=b.floor(e),a[d]=b.ceil(f);return a}function ch(){return Math}function ci(a,b,c,d){function g(){var g=Math.min(a.length,b.length)>2?cp:co,i=d?bc:bb;return e=g(a,b,i,c),f=g(b,a,i,d3.interpolate),h}function h(a){return e(a)}var e,f;return h.invert=function(a){return f(a)},h.domain=function(b){return arguments.length?(a=b.map(Number),g()):a},h.range=function(a){return arguments.length?(b=a,g()):b},h.rangeRound=function(a){return h.range(a).interpolate(d3.interpolateRound)},h.clamp=function(a){return arguments.length?(d=a,g()):d},h.interpolate=function(a){return arguments.length?(c=a,g()):c},h.ticks=function(b){return cm(a,b)},h.tickFormat=function(b){return cn(a,b)},h.nice=function(){return cg(a,ck),g()},h.copy=function(){return ci(a,b,c,d)},g()}function cj(a,b){return d3.rebind(a,b,"range","rangeRound","interpolate","clamp")}function ck(a){return a=Math.pow(10,Math.round(Math.log(a)/Math.LN10)-1),{floor:function(b){return Math.floor(b/a)*a},ceil:function(b){return Math.ceil(b/a)*a}}}function cl(a,b){var c=ce(a),d=c[1]-c[0],e=Math.pow(10,Math.floor(Math.log(d/b)/Math.LN10)),f=b/d*e;return f<=.15?e*=10:f<=.35?e*=5:f<=.75&&(e*=2),c[0]=Math.ceil(c[0]/e)*e,c[1]=Math.floor(c[1]/e)*e+e*.5,c[2]=e,c}function cm(a,b){return d3.range.apply(d3,cl(a,b))}function cn(a,b){return d3.format(",."+Math.max(0,-Math.floor(Math.log(cl(a,b)[2])/Math.LN10+.01))+"f")}function co(a,b,c,d){var e=c(a[0],a[1]),f=d(b[0],b[1]);return function(a){return f(e(a))}}function cp(a,b,c,d){var e=[],f=[],g=0,h=Math.min(a.length,b.length)-1;a[h]<a[0]&&(a=a.slice().reverse(),b=b.slice().reverse());while(++g<=h)e.push(c(a[g-1],a[g])),f.push(d(b[g-1],b[g]));return function(b){var c=d3.bisect(a,b,1,h)-1;return f[c](e[c](b))}}function cq(a,b){function d(c){return a(b(c))}var c=b.pow;return d.invert=function(b){return c(a.invert(b))},d.domain=function(e){return arguments.length?(b=e[0]<0?ct:cs,c=b.pow,a.domain(e.map(b)),d):a.domain().map(c)},d.nice=function(){return a.domain(cg(a.domain(),ch)),d},d.ticks=function(){var d=ce(a.domain()),e=[];if(d.every(isFinite)){var f=Math.floor(d[0]),g=Math.ceil(d[1]),h=c(d[0]),i=c(d[1]);if(b===ct){e.push(c(f));for(;f++<g;)for(var j=9;j>0;j--)e.push(c(f)*j)}else{for(;f<g;f++)for(var j=1;j<10;j++)e.push(c(f)*j);e.push(c(f))}for(f=0;e[f]<h;f++);for(g=e.length;e[g-1]>i;g--);e=e.slice(f,g)}return e},d.tickFormat=function(a,e){arguments.length<2&&(e=cr);if(arguments.length<1)return e;var f=Math.max(.1,a/d.ticks().length),g=b===ct?(h=-1e-12,Math.floor):(h=1e-12,Math.ceil),h;return function(a){return a/c(g(b(a)+h))<=f?e(a):""}},d.copy=function(){return cq(a.copy(),b)},cj(d,a)}function cs(a){return Math.log(a<0?0:a)/Math.LN10}function ct(a){return-Math.log(a>0?0:-a)/Math.LN10}function cu(a,b){function e(b){return a(c(b))}var c=cv(b),d=cv(1/b);return e.invert=function(b){return d(a.invert(b))},e.domain=function(b){return arguments.length?(a.domain(b.map(c)),e):a.domain().map(d)},e.ticks=function(a){return cm(e.domain(),a)},e.tickFormat=function(a){return cn(e.domain(),a)},e.nice=function(){return e.domain(cg(e.domain(),ck))},e.exponent=function(a){if(!arguments.length)return b;var f=e.domain();return c=cv(b=a),d=cv(1/b),e.domain(f)},e.copy=function(){return cu(a.copy(),b)},cj(e,a)}function cv(a){return function(b){return b<0?-Math.pow(-b,a):Math.pow(b,a)}}function cw(a,b){function f(b){return d[((c.get(b)||c.set(b,a.push(b)))-1)%d.length]}function g(b,c){return d3.range(a.length).map(function(a){return b+c*a})}var c,d,e;return f.domain=function(d){if(!arguments.length)return a;a=[],c=new j;var e=-1,g=d.length,h;while(++e<g)c.has(h=d[e])||c.set(h,a.push(h));return f[b.t](b.x,b.p)},f.range=function(a){return arguments.length?(d=a,e=0,b={t:"range",x:a},f):d},f.rangePoints=function(c,h){arguments.length<2&&(h=0);var i=c[0],j=c[1],k=(j-i)/(a.length-1+h);return d=g(a.length<2?(i+j)/2:i+k*h/2,k),e=0,b={t:"rangePoints",x:c,p:h},f},f.rangeBands=function(c,h){arguments.length<2&&(h=0);var i=c[1]<c[0],j=c[i-0],k=c[1-i],l=(k-j)/(a.length+h);return d=g(j+l*h,l),i&&d.reverse(),e=l*(1-h),b={t:"rangeBands",x:c,p:h},f},f.rangeRoundBands=function(c,h){arguments.length<2&&(h=0);var i=c[1]<c[0],j=c[i-0],k=c[1-i],l=Math.floor((k-j)/(a.length+h)),m=k-j-(a.length-h)*l;return d=g(j+Math.round(m/2),l),i&&d.reverse(),e=Math.round(l*(1-h)),b={t:"rangeRoundBands",x:c,p:h},f},f.rangeBand=function(){return e},f.rangeExtent=function(){return ce(b.x)},f.copy=function(){return cw(a,b)},f.domain(a)}function cB(a,b){function d(){var d=0,f=a.length,g=b.length;c=[];while(++d<g)c[d-1]=d3.quantile(a,d/g);return e}function e(a){return isNaN(a=+a)?NaN:b[d3.bisect(c,a)]}var c;return e.domain=function(b){return arguments.length?(a=b.filter(function(a){return!isNaN(a)}).sort(d3.ascending),d()):a},e.range=function(a){return arguments.length?(b=a,d()):b},e.quantiles=function(){return c},e.copy=function(){return cB(a,b)},d()}function cC(a,b,c){function f(b){return c[Math.max(0,Math.min(e,Math.floor(d*(b-a))))]}function g(){return d=c.length/(b-a),e=c.length-1,f}var d,e;return f.domain=function(c){return arguments.length?(a=+c[0],b=+c[c.length-1],g()):[a,b]},f.range=function(a){return arguments.length?(c=a,g()):c},f.copy=function(){return cC(a,b,c)},g()}function cD(a){function b(a){return+a}return b.invert=b,b.domain=b.range=function(c){return arguments.length?(a=c.map(b),b):a},b.ticks=function(b){return cm(a,b)},b.tickFormat=function(b){return cn(a,b)},b.copy=function(){return cD(a)},b}function cG(a){return a.innerRadius}function cH(a){return a.outerRadius}function cI(a){return a.startAngle}function cJ(a){return a.endAngle}function cK(a){function h(e){function o(){h.push("M",f(a(i),g))}var h=[],i=[],j=-1,k=e.length,l,m=p(b),n=p(c);while(++j<k)d.call(this,l=e[j],j)?i.push([+m.call(this,l,j),+n.call(this,l,j)]):i.length&&(o(),i=[]);return i.length&&o(),h.length?h.join(""):null}var b=cL,c=cM,d=o,e=cN,f=cP,g=.7;return h.x=function(a){return arguments.length?(b=a,h):b},h.y=function(a){return arguments.length?(c=a,h):c},h.defined=function(a){return arguments.length?(d=a,h):d},h.interpolate=function(a){return arguments.length?(cO.has(a+="")||(a=cN),f=cO.get(e=a),h):e},h.tension=function(a){return arguments.length?(g=a,h):g},h}function cL(a){return a[0]}function cM(a){return a[1]}function cP(a){var b=0,c=a.length,d=a[0],e=[d[0],",",d[1]];while(++b<c)e.push("L",(d=a[b])[0],",",d[1]);return e.join("")}function cQ(a){var b=0,c=a.length,d=a[0],e=[d[0],",",d[1]];while(++b<c)e.push("V",(d=a[b])[1],"H",d[0]);return e.join("")}function cR(a){var b=0,c=a.length,d=a[0],e=[d[0],",",d[1]];while(++b<c)e.push("H",(d=a[b])[0],"V",d[1]);return e.join("")}function cS(a,b){return a.length<4?cP(a):a[1]+cV(a.slice(1,a.length-1),cW(a,b))}function cT(a,b){return a.length<3?cP(a):a[0]+cV((a.push(a[0]),a),cW([a[a.length-2]].concat(a,[a[1]]),b))}function cU(a,b,c){return a.length<3?cP(a):a[0]+cV(a,cW(a,b))}function cV(a,b){if(b.length<1||a.length!=b.length&&a.length!=b.length+2)return cP(a);var c=a.length!=b.length,d="",e=a[0],f=a[1],g=b[0],h=g,i=1;c&&(d+="Q"+(f[0]-g[0]*2/3)+","+(f[1]-g[1]*2/3)+","+f[0]+","+f[1],e=a[1],i=2);if(b.length>1){h=b[1],f=a[i],i++,d+="C"+(e[0]+g[0])+","+(e[1]+g[1])+","+(f[0]-h[0])+","+(f[1]-h[1])+","+f[0]+","+f[1];for(var j=2;j<b.length;j++,i++)f=a[i],h=b[j],d+="S"+(f[0]-h[0])+","+(f[1]-h[1])+","+f[0]+","+f[1]}if(c){var k=a[i];d+="Q"+(f[0]+h[0]*2/3)+","+(f[1]+h[1]*2/3)+","+k[0]+","+k[1]}return d}function cW(a,b){var c=[],d=(1-b)/2,e,f=a[0],g=a[1],h=1,i=a.length;while(++h<i)e=f,f=g,g=a[h],c.push([d*(g[0]-e[0]),d*(g[1]-e[1])]);return c}function cX(a){if(a.length<3)return cP(a);var b=1,c=a.length,d=a[0],e=d[0],f=d[1],g=[e,e,e,(d=a[1])[0]],h=[f,f,f,d[1]],i=[e,",",f];dd(i,g,h);while(++b<c)d=a[b],g.shift(),g.push(d[0]),h.shift(),h.push(d[1]),dd(i,g,h);b=-1;while(++b<2)g.shift(),g.push(d[0]),h.shift(),h.push(d[1]),dd(i,g,h);return i.join("")}function cY(a){if(a.length<4)return cP(a);var b=[],c=-1,d=a.length,e,f=[0],g=[0];while(++c<3)e=a[c],f.push(e[0]),g.push(e[1]);b.push(c_(dc,f)+","+c_(dc,g)),--c;while(++c<d)e=a[c],f.shift(),f.push(e[0]),g.shift(),g.push(e[1]),dd(b,f,g);return b.join("")}function cZ(a){var b,c=-1,d=a.length,e=d+4,f,g=[],h=[];while(++c<4)f=a[c%d],g.push(f[0]),h.push(f[1]);b=[c_(dc,g),",",c_(dc,h)],--c;while(++c<e)f=a[c%d],g.shift(),g.push(f[0]),h.shift(),h.push(f[1]),dd(b,g,h);return b.join("")}function c$(a,b){var c=a.length-1;if(c){var d=a[0][0],e=a[0][1],f=a[c][0]-d,g=a[c][1]-e,h=-1,i,j;while(++h<=c)i=a[h],j=h/c,i[0]=b*i[0]+(1-b)*(d+j*f),i[1]=b*i[1]+(1-b)*(e+j*g)}return cX(a)}function c_(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3]}function dd(a,b,c){a.push("C",c_(da,b),",",c_(da,c),",",c_(db,b),",",c_(db,c),",",c_(dc,b),",",c_(dc,c))}function de(a,b){return(b[1]-a[1])/(b[0]-a[0])}function df(a){var b=0,c=a.length-1,d=[],e=a[0],f=a[1],g=d[0]=de(e,f);while(++b<c)d[b]=g+(g=de(e=f,f=a[b+1]));return d[b]=g,d}function dg(a){var b=[],c,d,e,f,g=df(a),h=-1,i=a.length-1;while(++h<i)c=de(a[h],a[h+1]),Math.abs(c)<1e-6?g[h]=g[h+1]=0:(d=g[h]/c,e=g[h+1]/c,f=d*d+e*e,f>9&&(f=c*3/Math.sqrt(f),g[h]=f*d,g[h+1]=f*e));h=-1;while(++h<=i)f=(a[Math.min(i,h+1)][0]-a[Math.max(0,h-1)][0])/(6*(1+g[h]*g[h])),b.push([f||0,g[h]*f||0]);return b}function dh(a){return a.length<3?cP(a):a[0]+cV(a,dg(a))}function di(a){var b,c=-1,d=a.length,e,f;while(++c<d)b=a[c],e=b[0],f=b[1]+cE,b[0]=e*Math.cos(f),b[1]=e*Math.sin(f);return a}function dj(a){function l(g){function y(){l.push("M",h(a(n),k),j,i(a(m.reverse()),k),"Z")}var l=[],m=[],n=[],o=-1,q=g.length,r,s=p(b),t=p(d),u=b===c?function(){return w}:p(c),v=d===e?function(){return x}:p(e),w,x;while(++o<q)f.call(this,r=g[o],o)?(m.push([w=+s.call(this,r,o),x=+t.call(this,r,o)]),n.push([+u.call(this,r,o),+v.call(this,r,o)])):m.length&&(y(),m=[],n=[]);return m.length&&y(),l.length?l.join(""):null}var b=cL,c=cL,d=0,e=cM,f=o,g=cN,h=cP,i=cP,j="L",k=.7;return l.x=function(a){return arguments.length?(b=c=a,l):c},l.x0=function(a){return arguments.length?(b=a,l):b},l.x1=function(a){return arguments.length?(c=a,l):c},l.y=function(a){return arguments.length?(d=e=a,l):e},l.y0=function(a){return arguments.length?(d=a,l):d},l.y1=function(a){return arguments.length?(e=a,l):e},l.defined=function(a){return arguments.length?(f=a,l):f},l.interpolate=function(a){return arguments.length?(cO.has(a+="")||(a=cN),h=cO.get(g=a),i=h.reverse||h,j=/-closed$/.test(a)?"M":"L",l):g},l.tension=function(a){return arguments.length?(k=a,l):k},l}function dk(a){return a.source}function dl(a){return a.target}function dm(a){return a.radius}function dn(a){return a.startAngle}function dp(a){return a.endAngle}function dq(a){return[a.x,a.y]}function dr(a){return function(){var b=a.apply(this,arguments),c=b[0],d=b[1]+cE;return[c*Math.cos(d),c*Math.sin(d)]}}function ds(){return 64}function dt(){return"circle"}function du(a){var b=Math.sqrt(a/Math.PI);return"M0,"+b+"A"+b+","+b+" 0 1,1 0,"+ -b+"A"+b+","+b+" 0 1,1 0,"+b+"Z"}function dy(a,b){a.attr("transform",function(a){return"translate("+b(a)+",0)"})}function dz(a,b){a.attr("transform",function(a){return"translate(0,"+b(a)+")"})}function dA(a,b,c){e=[];if(c&&b.length>1){var d=ce(a.domain()),e,f=-1,g=b.length,h=(b[1]-b[0])/++c,i,j;while(++f<g)for(i=c;--i>0;)(j=+b[f]-i*h)>=d[0]&&e.push(j);for(--f,i=0;++i<c&&(j=+b[f]+i*h)<d[1];)e.push(j)}return e}function dF(){dD||(dD=d3.select("body").append("div").style("visibility","hidden").style("top",0).style("height",0).style("width",0).style("overflow-y","scroll").append("div").style("height","2000px").node().parentNode);var a=d3.event,b;try{dD.scrollTop=1e3,dD.dispatchEvent(a),b=1e3-dD.scrollTop}catch(c){b=a.wheelDelta||-a.detail*5}return b}function dG(a){var b=a.source,c=a.target,d=dI(b,c),e=[b];while(b!==d)b=b.parent,e.push(b);var f=e.length;while(c!==d)e.splice(f,0,c),c=c.parent;return e}function dH(a){var b=[],c=a.parent;while(c!=null)b.push(a),a=c,c=c.parent;return b.push(a),b}function dI(a,b){if(a===b)return a;var c=dH(a),d=dH(b),e=c.pop(),f=d.pop(),g=null;while(e===f)g=e,e=c.pop(),f=d.pop();return g}function dL(a){a.fixed|=2}function dM(a){a!==dK&&(a.fixed&=1)}function dN(){dK.fixed&=1,dJ=dK=null}function dO(){dK.px=d3.event.x,dK.py=d3.event.y,dJ.resume()}function dP(a,b,c){var d=0,e=0;a.charge=0;if(!a.leaf){var f=a.nodes,g=f.length,h=-1,i;while(++h<g){i=f[h];if(i==null)continue;dP(i,b,c),a.charge+=i.charge,d+=i.charge*i.cx,e+=i.charge*i.cy}}if(a.point){a.leaf||(a.point.x+=Math.random()-.5,a.point.y+=Math.random()-.5);var j=b*c[a.point.index];a.charge+=a.pointCharge=j,d+=j*a.point.x,e+=j*a.point.y}a.cx=d/a.charge,a.cy=e/a.charge}function dQ(a){return 20}function dR(a){return 1}function dT(a){return a.x}function dU(a){return a.y}function dV(a,b,c){a.y0=b,a.y=c}function dY(a){return d3.range(a.length)}function dZ(a){var b=-1,c=a[0].length,d=[];while(++b<c)d[b]=0;return d}function d$(a){var b=1,c=0,d=a[0][1],e,f=a.length;for(;b<f;++b)(e=a[b][1])>d&&(c=b,d=e);return c}function d_(a){return a.reduce(ea,0)}function ea(a,b){return a+b[1]}function eb(a,b){return ec(a,Math.ceil(Math.log(b.length)/Math.LN2+1))}function ec(a,b){var c=-1,d=+a[0],e=(a[1]-d)/b,f=[];while(++c<=b)f[c]=e*c+d;return f}function ed(a){return[d3.min(a),d3.max(a)]}function ee(a,b){return d3.rebind(a,b,"sort","children","value"),a.links=ei,a.nodes=function(b){return ej=!0,(a.nodes=a)(b)},a}function ef(a){return a.children}function eg(a){return a.value}function eh(a,b){return b.value-a.value}function ei(a){return d3.merge(a.map(function(a){return(a.children||[]).map(function(b){return{source:a,target:b}})}))}function ek(a,b){return a.value-b.value}function el(a,b){var c=a._pack_next;a._pack_next=b,b._pack_prev=a,b._pack_next=c,c._pack_prev=b}function em(a,b){a._pack_next=b,b._pack_prev=a}function en(a,b){var c=b.x-a.x,d=b.y-a.y,e=a.r+b.r;return e*e-c*c-d*d>.001}function eo(a){function l(a){b=Math.min(a.x-a.r,b),c=Math.max(a.x+a.r,c),d=Math.min(a.y-a.r,d),e=Math.max(a.y+a.r,e)}var b=Infinity,c=-Infinity,d=Infinity,e=-Infinity,f=a.length,g,h,i,j,k;a.forEach(ep),g=a[0],g.x=-g.r,g.y=0,l(g);if(f>1){h=a[1],h.x=h.r,h.y=0,l(h);if(f>2){i=a[2],et(g,h,i),l(i),el(g,i),g._pack_prev=i,el(i,h),h=g._pack_next;for(var m=3;m<f;m++){et(g,h,i=a[m]);var n=0,o=1,p=1;for(j=h._pack_next;j!==h;j=j._pack_next,o++)if(en(j,i)){n=1;break}if(n==1)for(k=g._pack_prev;k!==j._pack_prev;k=k._pack_prev,p++)if(en(k,i))break;n?(o<p||o==p&&h.r<g.r?em(g,h=j):em(g=k,h),m--):(el(g,i),h=i,l(i))}}}var q=(b+c)/2,r=(d+e)/2,s=0;for(var m=0;m<f;m++){var t=a[m];t.x-=q,t.y-=r,s=Math.max(s,t.r+Math.sqrt(t.x*t.x+t.y*t.y))}return a.forEach(eq),s}function ep(a){a._pack_next=a._pack_prev=a}function eq(a){delete a._pack_next,delete a._pack_prev}function er(a){var b=a.children;b&&b.length?(b.forEach(er),a.r=eo(b)):a.r=Math.sqrt(a.value)}function es(a,b,c,d){var e=a.children;a.x=b+=d*a.x,a.y=c+=d*a.y,a.r*=d;if(e){var f=-1,g=e.length;while(++f<g)es(e[f],b,c,d)}}function et(a,b,c){var d=a.r+c.r,e=b.x-a.x,f=b.y-a.y;if(d&&(e||f)){var g=b.r+c.r,h=Math.sqrt(e*e+f*f),i=Math.max(-1,Math.min(1,(d*d+h*h-g*g)/(2*d*h))),j=Math.acos(i),k=i*(d/=h),l=Math.sin(j)*d;c.x=a.x+k*e+l*f,c.y=a.y+k*f-l*e}else c.x=a.x+d,c.y=a.y}function eu(a){return 1+d3.max(a,function(a){return a.y})}function ev(a){return a.reduce(function(a,b){return a+b.x},0)/a.length}function ew(a){var b=a.children;return b&&b.length?ew(b[0]):a}function ex(a){var b=a.children,c;return b&&(c=b.length)?ex(b[c-1]):a}function ey(a,b){return a.parent==b.parent?1:2}function ez(a){var b=a.children;return b&&b.length?b[0]:a._tree.thread}function eA(a){var b=a.children,c;return b&&(c=b.length)?b[c-1]:a._tree.thread}function eB(a,b){var c=a.children;if(c&&(e=c.length)){var d,e,f=-1;while(++f<e)b(d=eB(c[f],b),a)>0&&(a=d)}return a}function eC(a,b){return a.x-b.x}function eD(a,b){return b.x-a.x}function eE(a,b){return a.depth-b.depth}function eF(a,b){function c(a,d){var e=a.children;if(e&&(i=e.length)){var f,g=null,h=-1,i;while(++h<i)f=e[h],c(f,g),g=f}b(a,d)}c(a,null)}function eG(a){var b=0,c=0,d=a.children,e=d.length,f;while(--e>=0)f=d[e]._tree,f.prelim+=b,f.mod+=b,b+=f.shift+(c+=f.change)}function eH(a,b,c){a=a._tree,b=b._tree;var d=c/(b.number-a.number);a.change+=d,b.change-=d,b.shift+=c,b.prelim+=c,b.mod+=c}function eI(a,b,c){return a._tree.ancestor.parent==b.parent?a._tree.ancestor:c}function eJ(a){return{x:a.x,y:a.y,dx:a.dx,dy:a.dy}}function eK(a,b){var c=a.x+b[3],d=a.y+b[0],e=a.dx-b[1]-b[3],f=a.dy-b[0]-b[2];return e<0&&(c+=e/2,e=0),f<0&&(d+=f/2,f=0),{x:c,y:d,dx:e,dy:f}}function eL(a){return a.map(eM).join(",")}function eM(a){return/[",\n]/.test(a)?'"'+a.replace(/\"/g,'""')+'"':a}function eO(a,b){return function(c){return c&&a.hasOwnProperty(c.type)?a[c.type](c):b}}function eP(a){return"m0,"+a+"a"+a+","+a+" 0 1,1 0,"+ -2*a+"a"+a+","+a+" 0 1,1 0,"+2*a+"z"}function eQ(a,b){eR.hasOwnProperty(a.type)&&eR[a.type](a,b)}function eS(a,b){eQ(a.geometry,b)}function eT(a,b){for(var c=a.features,d=0,e=c.length;d<e;d++)eQ(c[d].geometry,b)}function eU(a,b){for(var c=a.geometries,d=0,e=c.length;d<e;d++)eQ(c[d],b)}function eV(a,b){for(var c=a.coordinates,d=0,e=c.length;d<e;d++)b.apply(null,c[d])}function eW(a,b){for(var c=a.coordinates,d=0,e=c.length;d<e;d++)for(var f=c[d],g=0,h=f.length;g<h;g++)b.apply(null,f[g])}function eX(a,b){for(var c=a.coordinates,d=0,e=c.length;d<e;d++)for(var f=c[d][0],g=0,h=f.length;g<h;g++)b.apply(null,f[g])}function eY(a,b){b.apply(null,a.coordinates)}function eZ(a,b){for(var c=a.coordinates[0],d=0,e=c.length;d<e;d++)b.apply(null,c[d])}function e$(a){return a.source}function e_(a){return a.target}function fa(){function o(a){var b=Math.sin(a*=m)*n,c=Math.sin(m-a)*n,g=c*e+b*k,h=c*f+b*l,i=c*d+b*j;return[Math.atan2(h,g)/eN,Math.atan2(i,Math.sqrt(g*g+h*h))/eN]}var a,b,c,d,e,f,g,h,i,j,k,l,m,n;return o.distance=function(){return m==null&&(n=1/Math.sin(m=Math.acos(Math.max(-1,Math.min(1,d*j+c*i*Math.cos(g-a)))))),m},o.source=function(g){var h=Math.cos(a=g[0]*eN),i=Math.sin(a);return c=Math.cos(b=g[1]*eN),d=Math.sin(b),e=c*h,f=c*i,m=null,o},o.target=function(a){var b=Math.cos(g=a[0]*eN),c=Math.sin(g);return i=Math.cos(h=a[1]*eN),j=Math.sin(h),k=i*b,l=i*c,m=null,o},o}function fb(a,b){var c=fa().source(a).target(b);return c.distance(),c}function fe(a){var b=0,c=0;for(;;){if(a(b,c))return[b,c];b===0?(b=c+1,c=0):(b-=1,c+=1)}}function ff(a,b,c,d){var e,f,g,h,i,j,k;return e=d[a],f=e[0],g=e[1],e=d[b],h=e[0],i=e[1],e=d[c],j=e[0],k=e[1],(k-g)*(h-f)-(i-g)*(j-f)>0}function fg(a,b,c){return(c[0]-b[0])*(a[1]-b[1])<(c[1]-b[1])*(a[0]-b[0])}function fh(a,b,c,d){var e=a[0],f=b[0],g=c[0],h=d[0],i=a[1],j=b[1],k=c[1],l=d[1],m=e-g,n=f-e,o=h-g,p=i-k,q=j-i,r=l-k,s=(o*p-r*m)/(r*n-o*q);return[e+s*n,i+s*q]}function fj(a,b){var c={list:a.map(function(a,b){return{index:b,x:a[0],y:a[1]}}).sort(function(a,b){return a.y<b.y?-1:a.y>b.y?1:a.x<b.x?-1:a.x>b.x?1:0}),bottomSite:null},d={list:[],leftEnd:null,rightEnd:null,init:function(){d.leftEnd=d.createHalfEdge(null,"l"),d.rightEnd=d.createHalfEdge(null,"l"),d.leftEnd.r=d.rightEnd,d.rightEnd.l=d.leftEnd,d.list.unshift(d.leftEnd,d.rightEnd)},createHalfEdge:function(a,b){return{edge:a,side:b,vertex:null,l:null,r:null}},insert:function(a,b){b.l=a,b.r=a.r,a.r.l=b,a.r=b},leftBound:function(a){var b=d.leftEnd;do b=b.r;while(b!=d.rightEnd&&e.rightOf(b,a));return b=b.l,b},del:function(a){a.l.r=a.r,a.r.l=a.l,a.edge=null},right:function(a){return a.r},left:function(a){return a.l},leftRegion:function(a){return a.edge==null?c.bottomSite:a.edge.region[a.side]},rightRegion:function(a){return a.edge==null?c.bottomSite:a.edge.region[fi[a.side]]}},e={bisect:function(a,b){var c={region:{l:a,r:b},ep:{l:null,r:null}},d=b.x-a.x,e=b.y-a.y,f=d>0?d:-d,g=e>0?e:-e;return c.c=a.x*d+a.y*e+(d*d+e*e)*.5,f>g?(c.a=1,c.b=e/d,c.c/=d):(c.b=1,c.a=d/e,c.c/=e),c},intersect:function(a,b){var c=a.edge,d=b.edge;if(!c||!d||c.region.r==d.region.r)return null;var e=c.a*d.b-c.b*d.a;if(Math.abs(e)<1e-10)return null;var f=(c.c*d.b-d.c*c.b)/e,g=(d.c*c.a-c.c*d.a)/e,h=c.region.r,i=d.region.r,j,k;h.y<i.y||h.y==i.y&&h.x<i.x?(j=a,k=c):(j=b,k=d);var l=f>=k.region.r.x;return l&&j.side==="l"||!l&&j.side==="r"?null:{x:f,y:g}},rightOf:function(a,b){var c=a.edge,d=c.region.r,e=b.x>d.x;if(e&&a.side==="l")return 1;if(!e&&a.side==="r")return 0;if(c.a===1){var f=b.y-d.y,g=b.x-d.x,h=0,i=0;!e&&c.b<0||e&&c.b>=0?i=h=f>=c.b*g:(i=b.x+b.y*c.b>c.c,c.b<0&&(i=!i),i||(h=1));if(!h){var j=d.x-c.region.l.x;i=c.b*(g*g-f*f)<j*f*(1+2*g/j+c.b*c.b),c.b<0&&(i=!i)}}else{var k=c.c-c.a*b.x,l=b.y-k,m=b.x-d.x,n=k-d.y;i=l*l>m*m+n*n}return a.side==="l"?i:!i},endPoint:function(a,c,d){a.ep[c]=d;if(!a.ep[fi[c]])return;b(a)},distance:function(a,b){var c=a.x-b.x,d=a.y-b.y;return Math.sqrt(c*c+d*d)}},f={list:[],insert:function(a,b,c){a.vertex=b,a.ystar=b.y+c;for(var d=0,e=f.list,g=e.length;d<g;d++){var h=e[d];if(a.ystar>h.ystar||a.ystar==h.ystar&&b.x>h.vertex.x)continue;break}e.splice(d,0,a)},del:function(a){for(var b=0,c=f.list,d=c.length;b<d&&c[b]!=a;++b);c.splice(b,1)},empty:function(){return f.list.length===0},nextEvent:function(a){for(var b=0,c=f.list,d=c.length;b<d;++b)if(c[b]==a)return c[b+1];return null},min:function(){var a=f.list[0];return{x:a.vertex.x,y:a.ystar}},extractMin:function(){return f.list.shift()}};d.init(),c.bottomSite=c.list.shift();var g=c.list.shift(),h,i,j,k,l,m,n,o,p,q,r,s,t;for(;;){f.empty()||(h=f.min());if(g&&(f.empty()||g.y<h.y||g.y==h.y&&g.x<h.x))i=d.leftBound(g),j=d.right(i),n=d.rightRegion(i),s=e.bisect(n,g),m=d.createHalfEdge(s,"l"),d.insert(i,m),q=e.intersect(i,m),q&&(f.del(i),f.insert(i,q,e.distance(q,g))),i=m,m=d.createHalfEdge(s,"r"),d.insert(i,m),q=e.intersect(m,j),q&&f.insert(m,q,e.distance(q,g)),g=c.list.shift();else if(!f.empty())i=f.extractMin(),k=d.left(i),j=d.right(i),l=d.right(j),n=d.leftRegion(i),o=d.rightRegion(j),r=i.vertex,e.endPoint(i.edge,i.side,r),e.endPoint(j.edge,j.side,r),d.del(i),f.del(j),d.del(j),t="l",n.y>o.y&&(p=n,n=o,o=p,t="r"),s=e.bisect(n,o),m=d.createHalfEdge(s,t),d.insert(k,m),e.endPoint(s,fi[t],r),q=e.intersect(k,m),q&&(f.del(k),f.insert(k,q,e.distance(q,n))),q=e.intersect(m,l),q&&f.insert(m,q,e.distance(q,n));else break}for(i=d.right(d.leftEnd);i!=d.rightEnd;i=d.right(i))b(i.edge)}function fk(){return{leaf:!0,nodes:[],point:null}}function fl(a,b,c,d,e,f){if(!a(b,c,d,e,f)){var g=(c+e)*.5,h=(d+f)*.5,i=b.nodes;i[0]&&fl(a,i[0],c,d,g,h),i[1]&&fl(a,i[1],g,d,e,h),i[2]&&fl(a,i[2],c,h,g,f),i[3]&&fl(a,i[3],g,h,e,f)}}function fm(a){return{x:a[0],y:a[1]}}function fo(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function fq(a,b,c,d){var e,f,g=0,h=b.length,i=c.length;while(g<h){if(d>=i)return-1;e=b.charCodeAt(g++);if(e==37){f=fw[b.charAt(g++)];if(!f||(d=f(a,c,d))<0)return-1}else if(e!=c.charCodeAt(d++))return-1}return d}function fx(a,b,c){return fz.test(b.substring(c,c+=3))?c:-1}function fy(a,b,c){fA.lastIndex=0;var d=fA.exec(b.substring(c,c+10));return d?c+=d[0].length:-1}function fC(a,b,c){var d=fD.get(b.substring(c,c+=3).toLowerCase());return d==null?-1:(a.m=d,c)}function fE(a,b,c){fF.lastIndex=0;var d=fF.exec(b.substring(c,c+12));return d?(a.m=fG.get(d[0].toLowerCase()),c+=d[0].length):-1}function fI(a,b,c){return fq(a,fv.c.toString(),b,c)}function fJ(a,b,c){return fq(a,fv.x.toString(),b,c)}function fK(a,b,c){return fq(a,fv.X.toString(),b,c)}function fL(a,b,c){fU.lastIndex=0;var d=fU.exec(b.substring(c,c+4));return d?(a.y=+d[0],c+=d[0].length):-1}function fM(a,b,c){fU.lastIndex=0;var d=fU.exec(b.substring(c,c+2));return d?(a.y=fN()+ +d[0],c+=d[0].length):-1}function fN(){return~~((new Date).getFullYear()/1e3)*1e3}function fO(a,b,c){fU.lastIndex=0;var d=fU.exec(b.substring(c,c+2));return d?(a.m=d[0]-1,c+=d[0].length):-1}function fP(a,b,c){fU.lastIndex=0;var d=fU.exec(b.substring(c,c+2));return d?(a.d=+d[0],c+=d[0].length):-1}function fQ(a,b,c){fU.lastIndex=0;var d=fU.exec(b.substring(c,c+2));return d?(a.H=+d[0],c+=d[0].length):-1}function fR(a,b,c){fU.lastIndex=0;var d=fU.exec(b.substring(c,c+2));return d?(a.M=+d[0],c+=d[0].length):-1}function fS(a,b,c){fU.lastIndex=0;var d=fU.exec(b.substring(c,c+2));return d?(a.S=+d[0],c+=d[0].length):-1}function fT(a,b,c){fU.lastIndex=0;var d=fU.exec(b.substring(c,c+3));return d?(a.L=+d[0],c+=d[0].length):-1}function fV(a,b,c){var d=fW.get(b.substring(c,c+=2).toLowerCase());return d==null?-1:(a.p=d,c)}function fX(a){var b=a.getTimezoneOffset(),c=b>0?"-":"+",d=~~(Math.abs(b)/60),e=Math.abs(b)%60;return c+fr(d)+fr(e)}function fZ(a){return a.toISOString()}function f$(a,b,c){function d(b){var c=a(b),d=f(c,1);return b-c<d-b?c:d}function e(c){return b(c=a(new fn(c-1)),1),c}function f(a,c){return b(a=new fn(+a),c),a}function g(a,d,f){var g=e(a),h=[];if(f>1)while(g<d)c(g)%f||h.push(new Date(+g)),b(g,1);else while(g<d)h.push(new Date(+g)),b(g,1);return h}function h(a,b,c){try{
fn=fo;var d=new fo;return d._=a,g(d,b,c)}finally{fn=Date}}a.floor=a,a.round=d,a.ceil=e,a.offset=f,a.range=g;var i=a.utc=f_(a);return i.floor=i,i.round=f_(d),i.ceil=f_(e),i.offset=f_(f),i.range=h,a}function f_(a){return function(b,c){try{fn=fo;var d=new fo;return d._=b,a(d,c)._}finally{fn=Date}}}function ga(a,b,c){function d(b){return a(b)}return d.invert=function(b){return gc(a.invert(b))},d.domain=function(b){return arguments.length?(a.domain(b),d):a.domain().map(gc)},d.nice=function(a){var b=gb(d.domain());return d.domain([a.floor(b[0]),a.ceil(b[1])])},d.ticks=function(c,e){var f=gb(d.domain());if(typeof c!="function"){var g=f[1]-f[0],h=g/c,i=d3.bisect(gg,h);if(i==gg.length)return b.year(f,c);if(!i)return a.ticks(c).map(gc);Math.log(h/gg[i-1])<Math.log(gg[i]/h)&&--i,c=b[i],e=c[1],c=c[0].range}return c(f[0],new Date(+f[1]+1),e)},d.tickFormat=function(){return c},d.copy=function(){return ga(a.copy(),b,c)},d3.rebind(d,a,"range","rangeRound","interpolate","clamp")}function gb(a){var b=a[0],c=a[a.length-1];return b<c?[b,c]:[c,b]}function gc(a){return new Date(a)}function gd(a){return function(b){var c=a.length-1,d=a[c];while(!d[1](b))d=a[--c];return d[0](b)}}function ge(a){var b=new Date(a,0,1);return b.setFullYear(a),b}function gf(a){var b=a.getFullYear(),c=ge(b),d=ge(b+1);return b+(a-c)/(d-c)}function go(a){var b=new Date(Date.UTC(a,0,1));return b.setUTCFullYear(a),b}function gp(a){var b=a.getUTCFullYear(),c=go(b),d=go(b+1);return b+(a-c)/(d-c)}Date.now||(Date.now=function(){return+(new Date)});try{document.createElement("div").style.setProperty("opacity",0,"")}catch(a){var b=CSSStyleDeclaration.prototype,c=b.setProperty;b.setProperty=function(a,b,d){c.call(this,a,b+"",d)}}d3={version:"2.9.6"};var e=g;try{e(document.documentElement.childNodes)[0].nodeType}catch(h){e=f}var i=[].__proto__?function(a,b){a.__proto__=b}:function(a,b){for(var c in b)a[c]=b[c]};d3.map=function(a){var b=new j;for(var c in a)b.set(c,a[c]);return b},d(j,{has:function(a){return k+a in this},get:function(a){return this[k+a]},set:function(a,b){return this[k+a]=b},remove:function(a){return a=k+a,a in this&&delete this[a]},keys:function(){var a=[];return this.forEach(function(b){a.push(b)}),a},values:function(){var a=[];return this.forEach(function(b,c){a.push(c)}),a},entries:function(){var a=[];return this.forEach(function(b,c){a.push({key:b,value:c})}),a},forEach:function(a){for(var b in this)b.charCodeAt(0)===l&&a.call(this,b.substring(1),this[b])}});var k="\0",l=k.charCodeAt(0);d3.functor=p,d3.rebind=function(a,b){var c=1,d=arguments.length,e;while(++c<d)a[e=arguments[c]]=q(a,b,b[e]);return a},d3.ascending=function(a,b){return a<b?-1:a>b?1:a>=b?0:NaN},d3.descending=function(a,b){return b<a?-1:b>a?1:b>=a?0:NaN},d3.mean=function(a,b){var c=a.length,d,e=0,f=-1,g=0;if(arguments.length===1)while(++f<c)r(d=a[f])&&(e+=(d-e)/++g);else while(++f<c)r(d=b.call(a,a[f],f))&&(e+=(d-e)/++g);return g?e:undefined},d3.median=function(a,b){return arguments.length>1&&(a=a.map(b)),a=a.filter(r),a.length?d3.quantile(a.sort(d3.ascending),.5):undefined},d3.min=function(a,b){var c=-1,d=a.length,e,f;if(arguments.length===1){while(++c<d&&((e=a[c])==null||e!=e))e=undefined;while(++c<d)(f=a[c])!=null&&e>f&&(e=f)}else{while(++c<d&&((e=b.call(a,a[c],c))==null||e!=e))e=undefined;while(++c<d)(f=b.call(a,a[c],c))!=null&&e>f&&(e=f)}return e},d3.max=function(a,b){var c=-1,d=a.length,e,f;if(arguments.length===1){while(++c<d&&((e=a[c])==null||e!=e))e=undefined;while(++c<d)(f=a[c])!=null&&f>e&&(e=f)}else{while(++c<d&&((e=b.call(a,a[c],c))==null||e!=e))e=undefined;while(++c<d)(f=b.call(a,a[c],c))!=null&&f>e&&(e=f)}return e},d3.extent=function(a,b){var c=-1,d=a.length,e,f,g;if(arguments.length===1){while(++c<d&&((e=g=a[c])==null||e!=e))e=g=undefined;while(++c<d)(f=a[c])!=null&&(e>f&&(e=f),g<f&&(g=f))}else{while(++c<d&&((e=g=b.call(a,a[c],c))==null||e!=e))e=undefined;while(++c<d)(f=b.call(a,a[c],c))!=null&&(e>f&&(e=f),g<f&&(g=f))}return[e,g]},d3.random={normal:function(a,b){return arguments.length<2&&(b=1),arguments.length<1&&(a=0),function(){var c,d,e;do c=Math.random()*2-1,d=Math.random()*2-1,e=c*c+d*d;while(!e||e>1);return a+b*c*Math.sqrt(-2*Math.log(e)/e)}}},d3.sum=function(a,b){var c=0,d=a.length,e,f=-1;if(arguments.length===1)while(++f<d)isNaN(e=+a[f])||(c+=e);else while(++f<d)isNaN(e=+b.call(a,a[f],f))||(c+=e);return c},d3.quantile=function(a,b){var c=(a.length-1)*b+1,d=Math.floor(c),e=a[d-1],f=c-d;return f?e+f*(a[d]-e):e},d3.transpose=function(a){return d3.zip.apply(d3,a)},d3.zip=function(){if(!(e=arguments.length))return[];for(var a=-1,b=d3.min(arguments,s),c=new Array(b);++a<b;)for(var d=-1,e,f=c[a]=new Array(e);++d<e;)f[d]=arguments[d][a];return c},d3.bisector=function(a){return{left:function(b,c,d,e){arguments.length<3&&(d=0),arguments.length<4&&(e=b.length);while(d<e){var f=d+e>>1;a.call(b,b[f],f)<c?d=f+1:e=f}return d},right:function(b,c,d,e){arguments.length<3&&(d=0),arguments.length<4&&(e=b.length);while(d<e){var f=d+e>>1;c<a.call(b,b[f],f)?e=f:d=f+1}return d}}};var t=d3.bisector(function(a){return a});d3.bisectLeft=t.left,d3.bisect=d3.bisectRight=t.right,d3.first=function(a,b){var c=0,d=a.length,e=a[0],f;arguments.length===1&&(b=d3.ascending);while(++c<d)b.call(a,e,f=a[c])>0&&(e=f);return e},d3.last=function(a,b){var c=0,d=a.length,e=a[0],f;arguments.length===1&&(b=d3.ascending);while(++c<d)b.call(a,e,f=a[c])<=0&&(e=f);return e},d3.nest=function(){function f(c,g){if(g>=b.length)return e?e.call(a,c):d?c.sort(d):c;var h=-1,i=c.length,k=b[g++],l,m,n=new j,o,p={};while(++h<i)(o=n.get(l=k(m=c[h])))?o.push(m):n.set(l,[m]);return n.forEach(function(a){p[a]=f(n.get(a),g)}),p}function g(a,d){if(d>=b.length)return a;var e=[],f=c[d++],h;for(h in a)e.push({key:h,values:g(a[h],d)});return f&&e.sort(function(a,b){return f(a.key,b.key)}),e}var a={},b=[],c=[],d,e;return a.map=function(a){return f(a,0)},a.entries=function(a){return g(f(a,0),0)},a.key=function(c){return b.push(c),a},a.sortKeys=function(d){return c[b.length-1]=d,a},a.sortValues=function(b){return d=b,a},a.rollup=function(b){return e=b,a},a},d3.keys=function(a){var b=[];for(var c in a)b.push(c);return b},d3.values=function(a){var b=[];for(var c in a)b.push(a[c]);return b},d3.entries=function(a){var b=[];for(var c in a)b.push({key:c,value:a[c]});return b},d3.permute=function(a,b){var c=[],d=-1,e=b.length;while(++d<e)c[d]=a[b[d]];return c},d3.merge=function(a){return Array.prototype.concat.apply([],a)},d3.split=function(a,b){var c=[],d=[],e,f=-1,g=a.length;arguments.length<2&&(b=u);while(++f<g)b.call(d,e=a[f],f)?d=[]:(d.length||c.push(d),d.push(e));return c},d3.range=function(a,b,c){arguments.length<3&&(c=1,arguments.length<2&&(b=a,a=0));if((b-a)/c===Infinity)throw new Error("infinite range");var d=[],e=w(Math.abs(c)),f=-1,g;a*=e,b*=e,c*=e;if(c<0)while((g=a+c*++f)>b)d.push(g/e);else while((g=a+c*++f)<b)d.push(g/e);return d},d3.requote=function(a){return a.replace(x,"\\$&")};var x=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;d3.round=function(a,b){return b?Math.round(a*(b=Math.pow(10,b)))/b:Math.round(a)},d3.xhr=function(a,b,c){var d=new XMLHttpRequest;arguments.length<3?(c=b,b=null):b&&d.overrideMimeType&&d.overrideMimeType(b),d.open("GET",a,!0),b&&d.setRequestHeader("Accept",b),d.onreadystatechange=function(){if(d.readyState===4){var a=d.status;c(!a&&d.response||a>=200&&a<300||a===304?d:null)}},d.send(null)},d3.text=function(a,b,c){function d(a){c(a&&a.responseText)}arguments.length<3&&(c=b,b=null),d3.xhr(a,b,d)},d3.json=function(a,b){d3.text(a,"application/json",function(a){b(a?JSON.parse(a):null)})},d3.html=function(a,b){d3.text(a,"text/html",function(a){if(a!=null){var c=document.createRange();c.selectNode(document.body),a=c.createContextualFragment(a)}b(a)})},d3.xml=function(a,b,c){function d(a){c(a&&a.responseXML)}arguments.length<3&&(c=b,b=null),d3.xhr(a,b,d)};var y={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};d3.ns={prefix:y,qualify:function(a){var b=a.indexOf(":"),c=a;return b>=0&&(c=a.substring(0,b),a=a.substring(b+1)),y.hasOwnProperty(c)?{space:y[c],local:a}:a}},d3.dispatch=function(){var a=new z,b=-1,c=arguments.length;while(++b<c)a[arguments[b]]=A(a);return a},z.prototype.on=function(a,b){var c=a.indexOf("."),d="";return c>0&&(d=a.substring(c+1),a=a.substring(0,c)),arguments.length<2?this[a].on(d):this[a].on(d,b)},d3.format=function(a){var b=B.exec(a),c=b[1]||" ",d=b[3]||"",e=b[5],f=+b[6],g=b[7],h=b[8],i=b[9],j=1,k="",l=!1;h&&(h=+h.substring(1)),e&&(c="0",g&&(f-=Math.floor((f-1)/4)));switch(i){case"n":g=!0,i="g";break;case"%":j=100,k="%",i="f";break;case"p":j=100,k="%",i="r";break;case"d":l=!0,h=0;break;case"s":j=-1,i="r"}return i=="r"&&!h&&(i="g"),i=C.get(i)||E,function(a){if(l&&a%1)return"";var b=a<0&&(a=-a)?"−":d;if(j<0){var m=d3.formatPrefix(a,h);a=m.scale(a),k=m.symbol}else a*=j;a=i(a,h);if(e){var n=a.length+b.length;n<f&&(a=(new Array(f-n+1)).join(c)+a),g&&(a=F(a)),a=b+a}else{g&&(a=F(a)),a=b+a;var n=a.length;n<f&&(a=(new Array(f-n+1)).join(c)+a)}return a+k}};var B=/(?:([^{])?([<>=^]))?([+\- ])?(#)?(0)?([0-9]+)?(,)?(\.[0-9]+)?([a-zA-Z%])?/,C=d3.map({g:function(a,b){return a.toPrecision(b)},e:function(a,b){return a.toExponential(b)},f:function(a,b){return a.toFixed(b)},r:function(a,b){return d3.round(a,b=D(a,b)).toFixed(Math.max(0,Math.min(20,b)))}}),G=["y","z","a","f","p","n","μ","m","","k","M","G","T","P","E","Z","Y"].map(H);d3.formatPrefix=function(a,b){var c=0;return a&&(a<0&&(a*=-1),b&&(a=d3.round(a,D(a,b))),c=1+Math.floor(1e-12+Math.log(a)/Math.LN10),c=Math.max(-24,Math.min(24,Math.floor((c<=0?c+1:c-1)/3)*3))),G[8+c/3]};var I=R(2),J=R(3),K=function(){return Q},L=d3.map({linear:K,poly:R,quad:function(){return I},cubic:function(){return J},sin:function(){return S},exp:function(){return T},circle:function(){return U},elastic:V,back:W,bounce:function(){return X}}),M=d3.map({"in":Q,out:O,"in-out":P,"out-in":function(a){return P(O(a))}});d3.ease=function(a){var b=a.indexOf("-"),c=b>=0?a.substring(0,b):a,d=b>=0?a.substring(b+1):"in";return c=L.get(c)||K,d=M.get(d)||Q,N(d(c.apply(null,Array.prototype.slice.call(arguments,1))))},d3.event=null,d3.interpolate=function(a,b){var c=d3.interpolators.length,d;while(--c>=0&&!(d=d3.interpolators[c](a,b)));return d},d3.interpolateNumber=function(a,b){return b-=a,function(c){return a+b*c}},d3.interpolateRound=function(a,b){return b-=a,function(c){return Math.round(a+b*c)}},d3.interpolateString=function(a,b){var c,d,e,f=0,g=0,h=[],i=[],j,k;_.lastIndex=0;for(d=0;c=_.exec(b);++d)c.index&&h.push(b.substring(f,g=c.index)),i.push({i:h.length,x:c[0]}),h.push(null),f=_.lastIndex;f<b.length&&h.push(b.substring(f));for(d=0,j=i.length;(c=_.exec(a))&&d<j;++d){k=i[d];if(k.x==c[0]){if(k.i)if(h[k.i+1]==null){h[k.i-1]+=k.x,h.splice(k.i,1);for(e=d+1;e<j;++e)i[e].i--}else{h[k.i-1]+=k.x+h[k.i+1],h.splice(k.i,2);for(e=d+1;e<j;++e)i[e].i-=2}else if(h[k.i+1]==null)h[k.i]=k.x;else{h[k.i]=k.x+h[k.i+1],h.splice(k.i+1,1);for(e=d+1;e<j;++e)i[e].i--}i.splice(d,1),j--,d--}else k.x=d3.interpolateNumber(parseFloat(c[0]),parseFloat(k.x))}while(d<j)k=i.pop(),h[k.i+1]==null?h[k.i]=k.x:(h[k.i]=k.x+h[k.i+1],h.splice(k.i+1,1)),j--;return h.length===1?h[0]==null?i[0].x:function(){return b}:function(a){for(d=0;d<j;++d)h[(k=i[d]).i]=k.x(a);return h.join("")}},d3.interpolateTransform=function(a,b){var c=[],d=[],e,f=d3.transform(a),g=d3.transform(b),h=f.translate,i=g.translate,j=f.rotate,k=g.rotate,l=f.skew,m=g.skew,n=f.scale,o=g.scale;return h[0]!=i[0]||h[1]!=i[1]?(c.push("translate(",null,",",null,")"),d.push({i:1,x:d3.interpolateNumber(h[0],i[0])},{i:3,x:d3.interpolateNumber(h[1],i[1])})):i[0]||i[1]?c.push("translate("+i+")"):c.push(""),j!=k?(j-k>180?k+=360:k-j>180&&(j+=360),d.push({i:c.push(c.pop()+"rotate(",null,")")-2,x:d3.interpolateNumber(j,k)})):k&&c.push(c.pop()+"rotate("+k+")"),l!=m?d.push({i:c.push(c.pop()+"skewX(",null,")")-2,x:d3.interpolateNumber(l,m)}):m&&c.push(c.pop()+"skewX("+m+")"),n[0]!=o[0]||n[1]!=o[1]?(e=c.push(c.pop()+"scale(",null,",",null,")"),d.push({i:e-4,x:d3.interpolateNumber(n[0],o[0])},{i:e-2,x:d3.interpolateNumber(n[1],o[1])})):(o[0]!=1||o[1]!=1)&&c.push(c.pop()+"scale("+o+")"),e=d.length,function(a){var b=-1,f;while(++b<e)c[(f=d[b]).i]=f.x(a);return c.join("")}},d3.interpolateRgb=function(a,b){a=d3.rgb(a),b=d3.rgb(b);var c=a.r,d=a.g,e=a.b,f=b.r-c,g=b.g-d,h=b.b-e;return function(a){return"#"+bf(Math.round(c+f*a))+bf(Math.round(d+g*a))+bf(Math.round(e+h*a))}},d3.interpolateHsl=function(a,b){a=d3.hsl(a),b=d3.hsl(b);var c=a.h,d=a.s,e=a.l,f=b.h-c,g=b.s-d,h=b.l-e;return f>180?f-=360:f<-180&&(f+=360),function(a){return bm(c+f*a,d+g*a,e+h*a).toString()}},d3.interpolateArray=function(a,b){var c=[],d=[],e=a.length,f=b.length,g=Math.min(a.length,b.length),h;for(h=0;h<g;++h)c.push(d3.interpolate(a[h],b[h]));for(;h<e;++h)d[h]=a[h];for(;h<f;++h)d[h]=b[h];return function(a){for(h=0;h<g;++h)d[h]=c[h](a);return d}},d3.interpolateObject=function(a,b){var c={},d={},e;for(e in a)e in b?c[e]=ba(e)(a[e],b[e]):d[e]=a[e];for(e in b)e in a||(d[e]=b[e]);return function(a){for(e in c)d[e]=c[e](a);return d}};var _=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g;d3.interpolators=[d3.interpolateObject,function(a,b){return b instanceof Array&&d3.interpolateArray(a,b)},function(a,b){return(typeof a=="string"||typeof b=="string")&&d3.interpolateString(a+"",b+"")},function(a,b){return(typeof b=="string"?bj.has(b)||/^(#|rgb\(|hsl\()/.test(b):b instanceof be||b instanceof bl)&&d3.interpolateRgb(a,b)},function(a,b){return!isNaN(a=+a)&&!isNaN(b=+b)&&d3.interpolateNumber(a,b)}],d3.rgb=function(a,b,c){return arguments.length===1?a instanceof be?bd(a.r,a.g,a.b):bg(""+a,bd,bm):bd(~~a,~~b,~~c)},be.prototype.brighter=function(a){a=Math.pow(.7,arguments.length?a:1);var b=this.r,c=this.g,d=this.b,e=30;return!b&&!c&&!d?bd(e,e,e):(b&&b<e&&(b=e),c&&c<e&&(c=e),d&&d<e&&(d=e),bd(Math.min(255,Math.floor(b/a)),Math.min(255,Math.floor(c/a)),Math.min(255,Math.floor(d/a))))},be.prototype.darker=function(a){return a=Math.pow(.7,arguments.length?a:1),bd(Math.floor(a*this.r),Math.floor(a*this.g),Math.floor(a*this.b))},be.prototype.hsl=function(){return bh(this.r,this.g,this.b)},be.prototype.toString=function(){return"#"+bf(this.r)+bf(this.g)+bf(this.b)};var bj=d3.map({aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"});bj.forEach(function(a,b){bj.set(a,bg(b,bd,bm))}),d3.hsl=function(a,b,c){return arguments.length===1?a instanceof bl?bk(a.h,a.s,a.l):bg(""+a,bh,bk):bk(+a,+b,+c)},bl.prototype.brighter=function(a){return a=Math.pow(.7,arguments.length?a:1),bk(this.h,this.s,this.l/a)},bl.prototype.darker=function(a){return a=Math.pow(.7,arguments.length?a:1),bk(this.h,this.s,a*this.l)},bl.prototype.rgb=function(){return bm(this.h,this.s,this.l)},bl.prototype.toString=function(){return this.rgb().toString()};var bo=function(a,b){return b.querySelector(a)},bp=function(a,b){return b.querySelectorAll(a)},bq=document.documentElement,br=bq.matchesSelector||bq.webkitMatchesSelector||bq.mozMatchesSelector||bq.msMatchesSelector||bq.oMatchesSelector,bs=function(a,b){return br.call(a,b)};typeof Sizzle=="function"&&(bo=function(a,b){return Sizzle(a,b)[0]||null},bp=function(a,b){return Sizzle.uniqueSort(Sizzle(a,b))},bs=Sizzle.matchesSelector);var bt=[];d3.selection=function(){return bB},d3.selection.prototype=bt,bt.select=function(a){var b=[],c,d,e,f;typeof a!="function"&&(a=bu(a));for(var g=-1,h=this.length;++g<h;){b.push(c=[]),c.parentNode=(e=this[g]).parentNode;for(var i=-1,j=e.length;++i<j;)(f=e[i])?(c.push(d=a.call(f,f.__data__,i)),d&&"__data__"in f&&(d.__data__=f.__data__)):c.push(null)}return bn(b)},bt.selectAll=function(a){var b=[],c,d;typeof a!="function"&&(a=bv(a));for(var f=-1,g=this.length;++f<g;)for(var h=this[f],i=-1,j=h.length;++i<j;)if(d=h[i])b.push(c=e(a.call(d,d.__data__,i))),c.parentNode=d;return bn(b)},bt.attr=function(a,b){function d(){this.removeAttribute(a)}function e(){this.removeAttributeNS(a.space,a.local)}function f(){this.setAttribute(a,b)}function g(){this.setAttributeNS(a.space,a.local,b)}function h(){var c=b.apply(this,arguments);c==null?this.removeAttribute(a):this.setAttribute(a,c)}function i(){var c=b.apply(this,arguments);c==null?this.removeAttributeNS(a.space,a.local):this.setAttributeNS(a.space,a.local,c)}a=d3.ns.qualify(a);if(arguments.length<2){var c=this.node();return a.local?c.getAttributeNS(a.space,a.local):c.getAttribute(a)}return this.each(b==null?a.local?e:d:typeof b=="function"?a.local?i:h:a.local?g:f)},bt.classed=function(a,b){var c=v(a).split(" "),d=c.length,e=-1;if(arguments.length>1){while(++e<d)bw.call(this,c[e],b);return this}while(++e<d)if(!bw.call(this,c[e]))return!1;return!0},bt.style=function(a,b,c){function d(){this.style.removeProperty(a)}function e(){this.style.setProperty(a,b,c)}function f(){var d=b.apply(this,arguments);d==null?this.style.removeProperty(a):this.style.setProperty(a,d,c)}return arguments.length<3&&(c=""),arguments.length<2?window.getComputedStyle(this.node(),null).getPropertyValue(a):this.each(b==null?d:typeof b=="function"?f:e)},bt.property=function(a,b){function c(){delete this[a]}function d(){this[a]=b}function e(){var c=b.apply(this,arguments);c==null?delete this[a]:this[a]=c}return arguments.length<2?this.node()[a]:this.each(b==null?c:typeof b=="function"?e:d)},bt.text=function(a){return arguments.length<1?this.node().textContent:this.each(typeof a=="function"?function(){var b=a.apply(this,arguments);this.textContent=b==null?"":b}:a==null?function(){this.textContent=""}:function(){this.textContent=a})},bt.html=function(a){return arguments.length<1?this.node().innerHTML:this.each(typeof a=="function"?function(){var b=a.apply(this,arguments);this.innerHTML=b==null?"":b}:a==null?function(){this.innerHTML=""}:function(){this.innerHTML=a})},bt.append=function(a){function b(){return this.appendChild(document.createElementNS(this.namespaceURI,a))}function c(){return this.appendChild(document.createElementNS(a.space,a.local))}return a=d3.ns.qualify(a),this.select(a.local?c:b)},bt.insert=function(a,b){function c(){return this.insertBefore(document.createElementNS(this.namespaceURI,a),bo(b,this))}function d(){return this.insertBefore(document.createElementNS(a.space,a.local),bo(b,this))}return a=d3.ns.qualify(a),this.select(a.local?d:c)},bt.remove=function(){return this.each(function(){var a=this.parentNode;a&&a.removeChild(this)})},bt.data=function(a,b){function g(a,c){var d,e=a.length,f=c.length,g=Math.min(e,f),l=Math.max(e,f),m=[],n=[],o=[],p,q;if(b){var r=new j,s=[],t,u=c.length;for(d=-1;++d<e;)t=b.call(p=a[d],p.__data__,d),r.has(t)?o[u++]=p:r.set(t,p),s.push(t);for(d=-1;++d<f;)t=b.call(c,q=c[d],d),r.has(t)?(m[d]=p=r.get(t),p.__data__=q,n[d]=o[d]=null):(n[d]=bx(q),m[d]=o[d]=null),r.remove(t);for(d=-1;++d<e;)r.has(s[d])&&(o[d]=a[d])}else{for(d=-1;++d<g;)p=a[d],q=c[d],p?(p.__data__=q,m[d]=p,n[d]=o[d]=null):(n[d]=bx(q),m[d]=o[d]=null);for(;d<f;++d)n[d]=bx(c[d]),m[d]=o[d]=null;for(;d<l;++d)o[d]=a[d],n[d]=m[d]=null}n.update=m,n.parentNode=m.parentNode=o.parentNode=a.parentNode,h.push(n),i.push(m),k.push(o)}var c=-1,d=this.length,e,f;if(!arguments.length){a=new Array(d=(e=this[0]).length);while(++c<d)if(f=e[c])a[c]=f.__data__;return a}var h=bC([]),i=bn([]),k=bn([]);if(typeof a=="function")while(++c<d)g(e=this[c],a.call(e,e.parentNode.__data__,c));else while(++c<d)g(e=this[c],a);return i.enter=function(){return h},i.exit=function(){return k},i},bt.datum=bt.map=function(a){return arguments.length<1?this.property("__data__"):this.property("__data__",a)},bt.filter=function(a){var b=[],c,d,e;typeof a!="function"&&(a=by(a));for(var f=0,g=this.length;f<g;f++){b.push(c=[]),c.parentNode=(d=this[f]).parentNode;for(var h=0,i=d.length;h<i;h++)(e=d[h])&&a.call(e,e.__data__,h)&&c.push(e)}return bn(b)},bt.order=function(){for(var a=-1,b=this.length;++a<b;)for(var c=this[a],d=c.length-1,e=c[d],f;--d>=0;)if(f=c[d])e&&e!==f.nextSibling&&e.parentNode.insertBefore(f,e),e=f;return this},bt.sort=function(a){a=bz.apply(this,arguments);for(var b=-1,c=this.length;++b<c;)this[b].sort(a);return this.order()},bt.on=function(a,b,c){arguments.length<3&&(c=!1);var d="__on"+a,e=a.indexOf(".");return e>0&&(a=a.substring(0,e)),arguments.length<2?(e=this.node()[d])&&e._:this.each(function(e,f){function i(a){var c=d3.event;d3.event=a;try{b.call(g,g.__data__,f)}finally{d3.event=c}}var g=this,h=g[d];h&&(g.removeEventListener(a,h,h.$),delete g[d]),b&&(g.addEventListener(a,g[d]=i,i.$=c),i._=b)})},bt.each=function(a){return bA(this,function(b,c,d){a.call(b,b.__data__,c,d)})},bt.call=function(a){return a.apply(this,(arguments[0]=this,arguments)),this},bt.empty=function(){return!this.node()},bt.node=function(a){for(var b=0,c=this.length;b<c;b++)for(var d=this[b],e=0,f=d.length;e<f;e++){var g=d[e];if(g)return g}return null},bt.transition=function(){var a=[],b,c;for(var d=-1,e=this.length;++d<e;){a.push(b=[]);for(var f=this[d],g=-1,h=f.length;++g<h;)b.push((c=f[g])?{node:c,delay:bO,duration:bP}:null)}return bE(a,bK||++bJ,Date.now())};var bB=bn([[document]]);bB[0].parentNode=bq,d3.select=function(a){return typeof a=="string"?bB.select(a):bn([[a]])},d3.selectAll=function(a){return typeof a=="string"?bB.selectAll(a):bn([e(a)])};var bD=[];d3.selection.enter=bC,d3.selection.enter.prototype=bD,bD.append=bt.append,bD.insert=bt.insert,bD.empty=bt.empty,bD.node=bt.node,bD.select=function(a){var b=[],c,d,e,f,g;for(var h=-1,i=this.length;++h<i;){e=(f=this[h]).update,b.push(c=[]),c.parentNode=f.parentNode;for(var j=-1,k=f.length;++j<k;)(g=f[j])?(c.push(e[j]=d=a.call(f.parentNode,g.__data__,j)),d.__data__=g.__data__):c.push(null)}return bn(b)};var bF={},bI=[],bJ=0,bK=0,bL=0,bM=250,bN=d3.ease("cubic-in-out"),bO=bL,bP=bM,bQ=bN;bI.call=bt.call,d3.transition=function(a){return arguments.length?bK?a.transition():a:bB.transition()},d3.transition.prototype=bI,bI.select=function(a){var b=[],c,d,e;typeof a!="function"&&(a=bu(a));for(var f=-1,g=this.length;++f<g;){b.push(c=[]);for(var h=this[f],i=-1,j=h.length;++i<j;)(e=h[i])&&(d=a.call(e.node,e.node.__data__,i))?("__data__"in e.node&&(d.__data__=e.node.__data__),c.push({node:d,delay:e.delay,duration:e.duration})):c.push(null)}return bE(b,this.id,this.time).ease(this.ease())},bI.selectAll=function(a){var b=[],c,d,e;typeof a!="function"&&(a=bv(a));for(var f=-1,g=this.length;++f<g;)for(var h=this[f],i=-1,j=h.length;++i<j;)if(e=h[i]){d=a.call(e.node,e.node.__data__,i),b.push(c=[]);for(var k=-1,l=d.length;++k<l;)c.push({node:d[k],delay:e.delay,duration:e.duration})}return bE(b,this.id,this.time).ease(this.ease())},bI.attr=function(a,b){return this.attrTween(a,bH(a,b))},bI.attrTween=function(a,b){function d(a,d){var e=b.call(this,a,d,this.getAttribute(c));return e===bF?(this.removeAttribute(c),null):e&&function(a){this.setAttribute(c,e(a))}}function e(a,d){var e=b.call(this,a,d,this.getAttributeNS(c.space,c.local));return e===bF?(this.removeAttributeNS(c.space,c.local),null):e&&function(a){this.setAttributeNS(c.space,c.local,e(a))}}var c=d3.ns.qualify(a);return this.tween("attr."+a,c.local?e:d)},bI.style=function(a,b,c){return arguments.length<3&&(c=""),this.styleTween(a,bH(a,b),c)},bI.styleTween=function(a,b,c){return arguments.length<3&&(c=""),this.tween("style."+a,function(d,e){var f=b.call(this,d,e,window.getComputedStyle(this,null).getPropertyValue(a));return f===bF?(this.style.removeProperty(a),null):f&&function(b){this.style.setProperty(a,f(b),c)}})},bI.text=function(a){return this.tween("text",function(b,c){this.textContent=typeof a=="function"?a.call(this,b,c):a})},bI.remove=function(){return this.each("end.transition",function(){var a;!this.__transition__&&(a=this.parentNode)&&a.removeChild(this)})},bI.delay=function(a){return bA(this,typeof a=="function"?function(b,c,d){b.delay=a.call(b=b.node,b.__data__,c,d)|0}:(a|=0,function(b){b.delay=a}))},bI.duration=function(a){return bA(this,typeof a=="function"?function(b,c,d){b.duration=Math.max(1,a.call(b=b.node,b.__data__,c,d)|0)}:(a=Math.max(1,a|0),function(b){b.duration=a}))},bI.transition=function(){return this.select(n)};var bS=null,bT,bU;d3.timer=function(a,b,c){var d=!1,e,f=bS;if(arguments.length<3){if(arguments.length<2)b=0;else if(!isFinite(b))return;c=Date.now()}while(f){if(f.callback===a){f.then=c,f.delay=b,d=!0;break}e=f,f=f.next}d||(bS={callback:a,then:c,delay:b,next:bS}),bT||(bU=clearTimeout(bU),bT=1,bX(bV))},d3.timer.flush=function(){var a,b=Date.now(),c=bS;while(c)a=b-c.then,c.delay||(c.flush=c.callback(a)),c=c.next;bW()};var bX=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(a){setTimeout(a,17)};d3.transform=function(a){var b=document.createElementNS(d3.ns.prefix.svg,"g"),c={a:1,b:0,c:0,d:1,e:0,f:0};return(d3.transform=function(a){b.setAttribute("transform",a);var d=b.transform.baseVal.consolidate();return new bY(d?d.matrix:c)})(a)},bY.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var ca=180/Math.PI;d3.mouse=function(a){return cc(a,Z())};var cb=/WebKit/.test(navigator.userAgent)?-1:0;d3.touches=function(a,b){return arguments.length<2&&(b=Z().touches),b?e(b).map(function(b){var c=cc(a,b);return c.identifier=b.identifier,c}):[]},d3.scale={},d3.scale.linear=function(){return ci([0,1],[0,1],d3.interpolate,!1)},d3.scale.log=function(){return cq(d3.scale.linear(),cs)};var cr=d3.format(".0e");cs.pow=function(a){return Math.pow(10,a)},ct.pow=function(a){return-Math.pow(10,-a)},d3.scale.pow=function(){return cu(d3.scale.linear(),1)},d3.scale.sqrt=function(){return d3.scale.pow().exponent(.5)},d3.scale.ordinal=function(){return cw([],{t:"range",x:[]})},d3.scale.category10=function(){return d3.scale.ordinal().range(cx)},d3.scale.category20=function(){return d3.scale.ordinal().range(cy)},d3.scale.category20b=function(){return d3.scale.ordinal().range(cz)},d3.scale.category20c=function(){return d3.scale.ordinal().range(cA)};var cx=["#1f77b4","#ff7f0e","#2ca02c","#d62728","#9467bd","#8c564b","#e377c2","#7f7f7f","#bcbd22","#17becf"],cy=["#1f77b4","#aec7e8","#ff7f0e","#ffbb78","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5","#8c564b","#c49c94","#e377c2","#f7b6d2","#7f7f7f","#c7c7c7","#bcbd22","#dbdb8d","#17becf","#9edae5"],cz=["#393b79","#5254a3","#6b6ecf","#9c9ede","#637939","#8ca252","#b5cf6b","#cedb9c","#8c6d31","#bd9e39","#e7ba52","#e7cb94","#843c39","#ad494a","#d6616b","#e7969c","#7b4173","#a55194","#ce6dbd","#de9ed6"],cA=["#3182bd","#6baed6","#9ecae1","#c6dbef","#e6550d","#fd8d3c","#fdae6b","#fdd0a2","#31a354","#74c476","#a1d99b","#c7e9c0","#756bb1","#9e9ac8","#bcbddc","#dadaeb","#636363","#969696","#bdbdbd","#d9d9d9"];d3.scale.quantile=function(){return cB([],[])},d3.scale.quantize=function(){return cC(0,1,[0,1])},d3.scale.identity=function(){return cD([0,1])},d3.svg={},d3.svg.arc=function(){function e(){var e=a.apply(this,arguments),f=b.apply(this,arguments),g=c.apply(this,arguments)+cE,h=d.apply(this,arguments)+cE,i=(h<g&&(i=g,g=h,h=i),h-g),j=i<Math.PI?"0":"1",k=Math.cos(g),l=Math.sin(g),m=Math.cos(h),n=Math.sin(h);return i>=cF?e?"M0,"+f+"A"+f+","+f+" 0 1,1 0,"+ -f+"A"+f+","+f+" 0 1,1 0,"+f+"M0,"+e+"A"+e+","+e+" 0 1,0 0,"+ -e+"A"+e+","+e+" 0 1,0 0,"+e+"Z":"M0,"+f+"A"+f+","+f+" 0 1,1 0,"+ -f+"A"+f+","+f+" 0 1,1 0,"+f+"Z":e?"M"+f*k+","+f*l+"A"+f+","+f+" 0 "+j+",1 "+f*m+","+f*n+"L"+e*m+","+e*n+"A"+e+","+e+" 0 "+j+",0 "+e*k+","+e*l+"Z":"M"+f*k+","+f*l+"A"+f+","+f+" 0 "+j+",1 "+f*m+","+f*n+"L0,0"+"Z"}var a=cG,b=cH,c=cI,d=cJ;return e.innerRadius=function(b){return arguments.length?(a=p(b),e):a},e.outerRadius=function(a){return arguments.length?(b=p(a),e):b},e.startAngle=function(a){return arguments.length?(c=p(a),e):c},e.endAngle=function(a){return arguments.length?(d=p(a),e):d},e.centroid=function(){var e=(a.apply(this,arguments)+b.apply(this,arguments))/2,f=(c.apply(this,arguments)+d.apply(this,arguments))/2+cE;return[Math.cos(f)*e,Math.sin(f)*e]},e};var cE=-Math.PI/2,cF=2*Math.PI-1e-6;d3.svg.line=function(){return cK(m)};var cN="linear",cO=d3.map({linear:cP,"step-before":cQ,"step-after":cR,basis:cX,"basis-open":cY,"basis-closed":cZ,bundle:c$,cardinal:cU,"cardinal-open":cS,"cardinal-closed":cT,monotone:dh}),da=[0,2/3,1/3,0],db=[0,1/3,2/3,0],dc=[0,1/6,2/3,1/6];d3.svg.line.radial=function(){var a=cK(di);return a.radius=a.x,delete a.x,a.angle=a.y,delete a.y,a},cQ.reverse=cR,cR.reverse=cQ,d3.svg.area=function(){return dj(Object)},d3.svg.area.radial=function(){var a=dj(di);return a.radius=a.x,delete a.x,a.innerRadius=a.x0,delete a.x0,a.outerRadius=a.x1,delete a.x1,a.angle=a.y,delete a.y,a.startAngle=a.y0,delete a.y0,a.endAngle=a.y1,delete a.y1,a},d3.svg.chord=function(){function f(c,d){var e=g(this,a,c,d),f=g(this,b,c,d);return"M"+e.p0+i(e.r,e.p1,e.a1-e.a0)+(h(e,f)?j(e.r,e.p1,e.r,e.p0):j(e.r,e.p1,f.r,f.p0)+i(f.r,f.p1,f.a1-f.a0)+j(f.r,f.p1,e.r,e.p0))+"Z"}function g(a,b,f,g){var h=b.call(a,f,g),i=c.call(a,h,g),j=d.call(a,h,g)+cE,k=e.call(a,h,g)+cE;return{r:i,a0:j,a1:k,p0:[i*Math.cos(j),i*Math.sin(j)],p1:[i*Math.cos(k),i*Math.sin(k)]}}function h(a,b){return a.a0==b.a0&&a.a1==b.a1}function i(a,b,c){return"A"+a+","+a+" 0 "+ +(c>Math.PI)+",1 "+b}function j(a,b,c,d){return"Q 0,0 "+d}var a=dk,b=dl,c=dm,d=cI,e=cJ;return f.radius=function(a){return arguments.length?(c=p(a),f):c},f.source=function(b){return arguments.length?(a=p(b),f):a},f.target=function(a){return arguments.length?(b=p(a),f):b},f.startAngle=function(a){return arguments.length?(d=p(a),f):d},f.endAngle=function(a){return arguments.length?(e=p(a),f):e},f},d3.svg.diagonal=function(){function d(d,e){var f=a.call(this,d,e),g=b.call(this,d,e),h=(f.y+g.y)/2,i=[f,{x:f.x,y:h},{x:g.x,y:h},g];return i=i.map(c),"M"+i[0]+"C"+i[1]+" "+i[2]+" "+i[3]}var a=dk,b=dl,c=dq;return d.source=function(b){return arguments.length?(a=p(b),d):a},d.target=function(a){return arguments.length?(b=p(a),d):b},d.projection=function(a){return arguments.length?(c=a,d):c},d},d3.svg.diagonal
.radial=function(){var a=d3.svg.diagonal(),b=dq,c=a.projection;return a.projection=function(a){return arguments.length?c(dr(b=a)):b},a},d3.svg.mouse=d3.mouse,d3.svg.touches=d3.touches,d3.svg.symbol=function(){function c(c,d){return(dv.get(a.call(this,c,d))||du)(b.call(this,c,d))}var a=dt,b=ds;return c.type=function(b){return arguments.length?(a=p(b),c):a},c.size=function(a){return arguments.length?(b=p(a),c):b},c};var dv=d3.map({circle:du,cross:function(a){var b=Math.sqrt(a/5)/2;return"M"+ -3*b+","+ -b+"H"+ -b+"V"+ -3*b+"H"+b+"V"+ -b+"H"+3*b+"V"+b+"H"+b+"V"+3*b+"H"+ -b+"V"+b+"H"+ -3*b+"Z"},diamond:function(a){var b=Math.sqrt(a/(2*dx)),c=b*dx;return"M0,"+ -b+"L"+c+",0"+" 0,"+b+" "+ -c+",0"+"Z"},square:function(a){var b=Math.sqrt(a)/2;return"M"+ -b+","+ -b+"L"+b+","+ -b+" "+b+","+b+" "+ -b+","+b+"Z"},"triangle-down":function(a){var b=Math.sqrt(a/dw),c=b*dw/2;return"M0,"+c+"L"+b+","+ -c+" "+ -b+","+ -c+"Z"},"triangle-up":function(a){var b=Math.sqrt(a/dw),c=b*dw/2;return"M0,"+ -c+"L"+b+","+c+" "+ -b+","+c+"Z"}});d3.svg.symbolTypes=dv.keys();var dw=Math.sqrt(3),dx=Math.tan(30*Math.PI/180);d3.svg.axis=function(){function k(k){k.each(function(){var k=d3.select(this),l=h==null?a.ticks?a.ticks.apply(a,g):a.domain():h,m=i==null?a.tickFormat?a.tickFormat.apply(a,g):String:i,n=dA(a,l,j),o=k.selectAll(".minor").data(n,String),p=o.enter().insert("line","g").attr("class","tick minor").style("opacity",1e-6),q=d3.transition(o.exit()).style("opacity",1e-6).remove(),r=d3.transition(o).style("opacity",1),s=k.selectAll("g").data(l,String),t=s.enter().insert("g","path").style("opacity",1e-6),u=d3.transition(s.exit()).style("opacity",1e-6).remove(),v=d3.transition(s).style("opacity",1),w,x=cf(a),y=k.selectAll(".domain").data([0]),z=y.enter().append("path").attr("class","domain"),A=d3.transition(y),B=a.copy(),C=this.__chart__||B;this.__chart__=B,t.append("line").attr("class","tick"),t.append("text");var D=t.select("line"),E=v.select("line"),F=s.select("text").text(m),G=t.select("text"),H=v.select("text");switch(b){case"bottom":w=dy,p.attr("y2",d),r.attr("x2",0).attr("y2",d),D.attr("y2",c),G.attr("y",Math.max(c,0)+f),E.attr("x2",0).attr("y2",c),H.attr("x",0).attr("y",Math.max(c,0)+f),F.attr("dy",".71em").attr("text-anchor","middle"),A.attr("d","M"+x[0]+","+e+"V0H"+x[1]+"V"+e);break;case"top":w=dy,p.attr("y2",-d),r.attr("x2",0).attr("y2",-d),D.attr("y2",-c),G.attr("y",-(Math.max(c,0)+f)),E.attr("x2",0).attr("y2",-c),H.attr("x",0).attr("y",-(Math.max(c,0)+f)),F.attr("dy","0em").attr("text-anchor","middle"),A.attr("d","M"+x[0]+","+ -e+"V0H"+x[1]+"V"+ -e);break;case"left":w=dz,p.attr("x2",-d),r.attr("x2",-d).attr("y2",0),D.attr("x2",-c),G.attr("x",-(Math.max(c,0)+f)),E.attr("x2",-c).attr("y2",0),H.attr("x",-(Math.max(c,0)+f)).attr("y",0),F.attr("dy",".32em").attr("text-anchor","end"),A.attr("d","M"+ -e+","+x[0]+"H0V"+x[1]+"H"+ -e);break;case"right":w=dz,p.attr("x2",d),r.attr("x2",d).attr("y2",0),D.attr("x2",c),G.attr("x",Math.max(c,0)+f),E.attr("x2",c).attr("y2",0),H.attr("x",Math.max(c,0)+f).attr("y",0),F.attr("dy",".32em").attr("text-anchor","start"),A.attr("d","M"+e+","+x[0]+"H0V"+x[1]+"H"+e)}if(a.ticks)t.call(w,C),v.call(w,B),u.call(w,B),p.call(w,C),r.call(w,B),q.call(w,B);else{var I=B.rangeBand()/2,J=function(a){return B(a)+I};t.call(w,J),v.call(w,J)}})}var a=d3.scale.linear(),b="bottom",c=6,d=6,e=6,f=3,g=[10],h=null,i,j=0;return k.scale=function(b){return arguments.length?(a=b,k):a},k.orient=function(a){return arguments.length?(b=a,k):b},k.ticks=function(){return arguments.length?(g=arguments,k):g},k.tickValues=function(a){return arguments.length?(h=a,k):h},k.tickFormat=function(a){return arguments.length?(i=a,k):i},k.tickSize=function(a,b,f){if(!arguments.length)return c;var g=arguments.length-1;return c=+a,d=g>1?+b:c,e=g>0?+arguments[g]:c,k},k.tickPadding=function(a){return arguments.length?(f=+a,k):f},k.tickSubdivide=function(a){return arguments.length?(j=+a,k):j},k},d3.svg.brush=function(){function g(a){a.each(function(){var a=d3.select(this),e=a.selectAll(".background").data([0]),f=a.selectAll(".extent").data([0]),l=a.selectAll(".resize").data(d,String),m;a.style("pointer-events","all").on("mousedown.brush",k).on("touchstart.brush",k),e.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),f.enter().append("rect").attr("class","extent").style("cursor","move"),l.enter().append("g").attr("class",function(a){return"resize "+a}).style("cursor",function(a){return dB[a]}).append("rect").attr("x",function(a){return/[ew]$/.test(a)?-3:null}).attr("y",function(a){return/^[ns]/.test(a)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),l.style("display",g.empty()?"none":null),l.exit().remove(),b&&(m=cf(b),e.attr("x",m[0]).attr("width",m[1]-m[0]),i(a)),c&&(m=cf(c),e.attr("y",m[0]).attr("height",m[1]-m[0]),j(a)),h(a)})}function h(a){a.selectAll(".resize").attr("transform",function(a){return"translate("+e[+/e$/.test(a)][0]+","+e[+/^s/.test(a)][1]+")"})}function i(a){a.select(".extent").attr("x",e[0][0]),a.selectAll(".extent,.n>rect,.s>rect").attr("width",e[1][0]-e[0][0])}function j(a){a.select(".extent").attr("y",e[0][1]),a.selectAll(".extent,.e>rect,.w>rect").attr("height",e[1][1]-e[0][1])}function k(){function x(){var a=d3.event.changedTouches;return a?d3.touches(d,a)[0]:d3.mouse(d)}function y(){d3.event.keyCode==32&&(q||(r=null,s[0]-=e[1][0],s[1]-=e[1][1],q=2),Y())}function z(){d3.event.keyCode==32&&q==2&&(s[0]+=e[1][0],s[1]+=e[1][1],q=0,Y())}function A(){var a=x(),d=!1;t&&(a[0]+=t[0],a[1]+=t[1]),q||(d3.event.altKey?(r||(r=[(e[0][0]+e[1][0])/2,(e[0][1]+e[1][1])/2]),s[0]=e[+(a[0]<r[0])][0],s[1]=e[+(a[1]<r[1])][1]):r=null),o&&B(a,b,0)&&(i(m),d=!0),p&&B(a,c,1)&&(j(m),d=!0),d&&(h(m),l({type:"brush",mode:q?"move":"resize"}))}function B(a,b,c){var d=cf(b),g=d[0],h=d[1],i=s[c],j=e[1][c]-e[0][c],k,l;q&&(g-=i,h-=j+i),k=Math.max(g,Math.min(h,a[c])),q?l=(k+=i)+j:(r&&(i=Math.max(g,Math.min(h,2*r[c]-k))),i<k?(l=k,k=i):l=i);if(e[0][c]!==k||e[1][c]!==l)return f=null,e[0][c]=k,e[1][c]=l,!0}function C(){A(),m.style("pointer-events","all").selectAll(".resize").style("display",g.empty()?"none":null),d3.select("body").style("cursor",null),u.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),l({type:"brushend"}),Y()}var d=this,k=d3.select(d3.event.target),l=a.of(d,arguments),m=d3.select(d),n=k.datum(),o=!/^(n|s)$/.test(n)&&b,p=!/^(e|w)$/.test(n)&&c,q=k.classed("extent"),r,s=x(),t,u=d3.select(window).on("mousemove.brush",A).on("mouseup.brush",C).on("touchmove.brush",A).on("touchend.brush",C).on("keydown.brush",y).on("keyup.brush",z);if(q)s[0]=e[0][0]-s[0],s[1]=e[0][1]-s[1];else if(n){var v=+/w$/.test(n),w=+/^n/.test(n);t=[e[1-v][0]-s[0],e[1-w][1]-s[1]],s[0]=e[v][0],s[1]=e[w][1]}else d3.event.altKey&&(r=s.slice());m.style("pointer-events","none").selectAll(".resize").style("display",null),d3.select("body").style("cursor",k.style("cursor")),l({type:"brushstart"}),A(),Y()}var a=$(g,"brushstart","brush","brushend"),b=null,c=null,d=dC[0],e=[[0,0],[0,0]],f;return g.x=function(a){return arguments.length?(b=a,d=dC[!b<<1|!c],g):b},g.y=function(a){return arguments.length?(c=a,d=dC[!b<<1|!c],g):c},g.extent=function(a){var d,h,i,j,k;return arguments.length?(f=[[0,0],[0,0]],b&&(d=a[0],h=a[1],c&&(d=d[0],h=h[0]),f[0][0]=d,f[1][0]=h,b.invert&&(d=b(d),h=b(h)),h<d&&(k=d,d=h,h=k),e[0][0]=d|0,e[1][0]=h|0),c&&(i=a[0],j=a[1],b&&(i=i[1],j=j[1]),f[0][1]=i,f[1][1]=j,c.invert&&(i=c(i),j=c(j)),j<i&&(k=i,i=j,j=k),e[0][1]=i|0,e[1][1]=j|0),g):(a=f||e,b&&(d=a[0][0],h=a[1][0],f||(d=e[0][0],h=e[1][0],b.invert&&(d=b.invert(d),h=b.invert(h)),h<d&&(k=d,d=h,h=k))),c&&(i=a[0][1],j=a[1][1],f||(i=e[0][1],j=e[1][1],c.invert&&(i=c.invert(i),j=c.invert(j)),j<i&&(k=i,i=j,j=k))),b&&c?[[d,i],[h,j]]:b?[d,h]:c&&[i,j])},g.clear=function(){return f=null,e[0][0]=e[0][1]=e[1][0]=e[1][1]=0,g},g.empty=function(){return b&&e[0][0]===e[1][0]||c&&e[0][1]===e[1][1]},d3.rebind(g,a,"on")};var dB={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},dC=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]];d3.behavior={},d3.behavior.drag=function(){function c(){this.on("mousedown.drag",d).on("touchstart.drag",d)}function d(){function j(){var a=c.parentNode,b=d3.event.changedTouches;return b?d3.touches(a,b)[0]:d3.mouse(a)}function k(){if(!c.parentNode)return l();var a=j(),b=a[0]-g[0],e=a[1]-g[1];h|=b|e,g=a,Y(),d({type:"drag",x:a[0]+f[0],y:a[1]+f[1],dx:b,dy:e})}function l(){d({type:"dragend"}),h&&(Y(),d3.event.target===e&&i.on("click.drag",m,!0)),i.on("mousemove.drag",null).on("touchmove.drag",null).on("mouseup.drag",null).on("touchend.drag",null)}function m(){Y(),i.on("click.drag",null)}var c=this,d=a.of(c,arguments),e=d3.event.target,f,g=j(),h=0,i=d3.select(window).on("mousemove.drag",k).on("touchmove.drag",k).on("mouseup.drag",l,!0).on("touchend.drag",l,!0);b?(f=b.apply(c,arguments),f=[f.x-g[0],f.y-g[1]]):f=[0,0],Y(),d({type:"dragstart"})}var a=$(c,"drag","dragstart","dragend"),b=null;return c.origin=function(a){return arguments.length?(b=a,c):b},d3.rebind(c,a,"on")},d3.behavior.zoom=function(){function l(){this.on("mousedown.zoom",r).on("mousewheel.zoom",s).on("mousemove.zoom",t).on("DOMMouseScroll.zoom",s).on("dblclick.zoom",u).on("touchstart.zoom",v).on("touchmove.zoom",w).on("touchend.zoom",v)}function m(b){return[(b[0]-a[0])/c,(b[1]-a[1])/c]}function n(b){return[b[0]*c+a[0],b[1]*c+a[1]]}function o(a){c=Math.max(e[0],Math.min(e[1],a))}function p(b,c){c=n(c),a[0]+=b[0]-c[0],a[1]+=b[1]-c[1]}function q(b){h&&h.domain(g.range().map(function(b){return(b-a[0])/c}).map(g.invert)),j&&j.domain(i.range().map(function(b){return(b-a[1])/c}).map(i.invert)),d3.event.preventDefault(),b({type:"zoom",scale:c,translate:a})}function r(){function h(){d=1,p(d3.mouse(a),g),q(b)}function i(){d&&Y(),e.on("mousemove.zoom",null).on("mouseup.zoom",null),d&&d3.event.target===c&&e.on("click.zoom",j,!0)}function j(){Y(),e.on("click.zoom",null)}var a=this,b=f.of(a,arguments),c=d3.event.target,d=0,e=d3.select(window).on("mousemove.zoom",h).on("mouseup.zoom",i),g=m(d3.mouse(a));window.focus(),Y()}function s(){b||(b=m(d3.mouse(this))),o(Math.pow(2,dF()*.002)*c),p(d3.mouse(this),b),q(f.of(this,arguments))}function t(){b=null}function u(){var a=d3.mouse(this),b=m(a);o(d3.event.shiftKey?c/2:c*2),p(a,b),q(f.of(this,arguments))}function v(){var a=d3.touches(this),e=Date.now();d=c,b={},a.forEach(function(a){b[a.identifier]=m(a)}),Y();if(a.length===1&&e-k<500){var g=a[0],h=m(a[0]);o(c*2),p(g,h),q(f.of(this,arguments))}k=e}function w(){var a=d3.touches(this),c=a[0],e=b[c.identifier];if(g=a[1]){var g,h=b[g.identifier];c=[(c[0]+g[0])/2,(c[1]+g[1])/2],e=[(e[0]+h[0])/2,(e[1]+h[1])/2],o(d3.event.scale*d)}p(c,e),q(f.of(this,arguments))}var a=[0,0],b,c=1,d,e=dE,f=$(l,"zoom"),g,h,i,j,k;return l.translate=function(b){return arguments.length?(a=b.map(Number),l):a},l.scale=function(a){return arguments.length?(c=+a,l):c},l.scaleExtent=function(a){return arguments.length?(e=a==null?dE:a.map(Number),l):e},l.x=function(a){return arguments.length?(h=a,g=a.copy(),l):h},l.y=function(a){return arguments.length?(j=a,i=a.copy(),l):j},d3.rebind(l,f,"on")};var dD,dE=[0,Infinity];d3.layout={},d3.layout.bundle=function(){return function(a){var b=[],c=-1,d=a.length;while(++c<d)b.push(dG(a[c]));return b}},d3.layout.chord=function(){function j(){var a={},j=[],l=d3.range(e),m=[],n,o,p,q,r;b=[],c=[],n=0,q=-1;while(++q<e){o=0,r=-1;while(++r<e)o+=d[q][r];j.push(o),m.push(d3.range(e)),n+=o}g&&l.sort(function(a,b){return g(j[a],j[b])}),h&&m.forEach(function(a,b){a.sort(function(a,c){return h(d[b][a],d[b][c])})}),n=(2*Math.PI-f*e)/n,o=0,q=-1;while(++q<e){p=o,r=-1;while(++r<e){var s=l[q],t=m[s][r],u=d[s][t],v=o,w=o+=u*n;a[s+"-"+t]={index:s,subindex:t,startAngle:v,endAngle:w,value:u}}c[s]={index:s,startAngle:p,endAngle:o,value:(o-p)/n},o+=f}q=-1;while(++q<e){r=q-1;while(++r<e){var x=a[q+"-"+r],y=a[r+"-"+q];(x.value||y.value)&&b.push(x.value<y.value?{source:y,target:x}:{source:x,target:y})}}i&&k()}function k(){b.sort(function(a,b){return i((a.source.value+a.target.value)/2,(b.source.value+b.target.value)/2)})}var a={},b,c,d,e,f=0,g,h,i;return a.matrix=function(f){return arguments.length?(e=(d=f)&&d.length,b=c=null,a):d},a.padding=function(d){return arguments.length?(f=d,b=c=null,a):f},a.sortGroups=function(d){return arguments.length?(g=d,b=c=null,a):g},a.sortSubgroups=function(c){return arguments.length?(h=c,b=null,a):h},a.sortChords=function(c){return arguments.length?(i=c,b&&k(),a):i},a.chords=function(){return b||j(),b},a.groups=function(){return c||j(),c},a},d3.layout.force=function(){function t(a){return function(b,c,d,e,f){if(b.point!==a){var g=b.cx-a.x,h=b.cy-a.y,i=1/Math.sqrt(g*g+h*h);if((e-c)*i<k){var j=b.charge*i*i;return a.px-=g*j,a.py-=h*j,!0}if(b.point&&isFinite(i)){var j=b.pointCharge*i*i;a.px-=g*j,a.py-=h*j}}return!b.charge}}function u(b){dL(dK=b),dJ=a}var a={},b=d3.dispatch("start","tick","end"),c=[1,1],d,e,f=.9,g=dQ,h=dR,i=-30,j=.1,k=.8,l,n=[],o=[],q,r,s;return a.tick=function(){if((e*=.99)<.005)return b.end({type:"end",alpha:e=0}),!0;var a=n.length,d=o.length,g,h,k,l,m,p,u,v,w;for(h=0;h<d;++h){k=o[h],l=k.source,m=k.target,v=m.x-l.x,w=m.y-l.y;if(p=v*v+w*w)p=e*r[h]*((p=Math.sqrt(p))-q[h])/p,v*=p,w*=p,m.x-=v*(u=l.weight/(m.weight+l.weight)),m.y-=w*u,l.x+=v*(u=1-u),l.y+=w*u}if(u=e*j){v=c[0]/2,w=c[1]/2,h=-1;if(u)while(++h<a)k=n[h],k.x+=(v-k.x)*u,k.y+=(w-k.y)*u}if(i){dP(g=d3.geom.quadtree(n),e,s),h=-1;while(++h<a)(k=n[h]).fixed||g.visit(t(k))}h=-1;while(++h<a)k=n[h],k.fixed?(k.x=k.px,k.y=k.py):(k.x-=(k.px-(k.px=k.x))*f,k.y-=(k.py-(k.py=k.y))*f);b.tick({type:"tick",alpha:e})},a.nodes=function(b){return arguments.length?(n=b,a):n},a.links=function(b){return arguments.length?(o=b,a):o},a.size=function(b){return arguments.length?(c=b,a):c},a.linkDistance=function(b){return arguments.length?(g=p(b),a):g},a.distance=a.linkDistance,a.linkStrength=function(b){return arguments.length?(h=p(b),a):h},a.friction=function(b){return arguments.length?(f=b,a):f},a.charge=function(b){return arguments.length?(i=typeof b=="function"?b:+b,a):i},a.gravity=function(b){return arguments.length?(j=b,a):j},a.theta=function(b){return arguments.length?(k=b,a):k},a.alpha=function(c){return arguments.length?(e?c>0?e=c:e=0:c>0&&(b.start({type:"start",alpha:e=c}),d3.timer(a.tick)),a):e},a.start=function(){function p(a,c){var d=t(b),e=-1,f=d.length,g;while(++e<f)if(!isNaN(g=d[e][a]))return g;return Math.random()*c}function t(){if(!l){l=[];for(d=0;d<e;++d)l[d]=[];for(d=0;d<f;++d){var a=o[d];l[a.source.index].push(a.target),l[a.target.index].push(a.source)}}return l[b]}var b,d,e=n.length,f=o.length,j=c[0],k=c[1],l,m;for(b=0;b<e;++b)(m=n[b]).index=b,m.weight=0;q=[],r=[];for(b=0;b<f;++b)m=o[b],typeof m.source=="number"&&(m.source=n[m.source]),typeof m.target=="number"&&(m.target=n[m.target]),q[b]=g.call(this,m,b),r[b]=h.call(this,m,b),++m.source.weight,++m.target.weight;for(b=0;b<e;++b)m=n[b],isNaN(m.x)&&(m.x=p("x",j)),isNaN(m.y)&&(m.y=p("y",k)),isNaN(m.px)&&(m.px=m.x),isNaN(m.py)&&(m.py=m.y);s=[];if(typeof i=="function")for(b=0;b<e;++b)s[b]=+i.call(this,n[b],b);else for(b=0;b<e;++b)s[b]=i;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){d||(d=d3.behavior.drag().origin(m).on("dragstart",u).on("drag",dO).on("dragend",dN)),this.on("mouseover.force",dL).on("mouseout.force",dM).call(d)},d3.rebind(a,b,"on")};var dJ,dK;d3.layout.partition=function(){function c(a,b,d,e){var f=a.children;a.x=b,a.y=a.depth*e,a.dx=d,a.dy=e;if(f&&(h=f.length)){var g=-1,h,i,j;d=a.value?d/a.value:0;while(++g<h)c(i=f[g],b,j=i.value*d,e),b+=j}}function d(a){var b=a.children,c=0;if(b&&(f=b.length)){var e=-1,f;while(++e<f)c=Math.max(c,d(b[e]))}return 1+c}function e(e,f){var g=a.call(this,e,f);return c(g[0],0,b[0],b[1]/d(g[0])),g}var a=d3.layout.hierarchy(),b=[1,1];return e.size=function(a){return arguments.length?(b=a,e):b},ee(e,a)},d3.layout.pie=function(){function e(f,g){var h=f.map(function(b,c){return+a.call(e,b,c)}),i=+(typeof c=="function"?c.apply(this,arguments):c),j=((typeof d=="function"?d.apply(this,arguments):d)-c)/d3.sum(h),k=d3.range(f.length);b!=null&&k.sort(b===dS?function(a,b){return h[b]-h[a]}:function(a,c){return b(f[a],f[c])});var l=[];return k.forEach(function(a){var b;l[a]={data:f[a],value:b=h[a],startAngle:i,endAngle:i+=b*j}}),l}var a=Number,b=dS,c=0,d=2*Math.PI;return e.value=function(b){return arguments.length?(a=b,e):a},e.sort=function(a){return arguments.length?(b=a,e):b},e.startAngle=function(a){return arguments.length?(c=a,e):c},e.endAngle=function(a){return arguments.length?(d=a,e):d},e};var dS={};d3.layout.stack=function(){function g(h,i){var j=h.map(function(b,c){return a.call(g,b,c)}),k=j.map(function(a,b){return a.map(function(a,b){return[e.call(g,a,b),f.call(g,a,b)]})}),l=b.call(g,k,i);j=d3.permute(j,l),k=d3.permute(k,l);var m=c.call(g,k,i),n=j.length,o=j[0].length,p,q,r;for(q=0;q<o;++q){d.call(g,j[0][q],r=m[q],k[0][q][1]);for(p=1;p<n;++p)d.call(g,j[p][q],r+=k[p-1][q][1],k[p][q][1])}return h}var a=m,b=dY,c=dZ,d=dV,e=dT,f=dU;return g.values=function(b){return arguments.length?(a=b,g):a},g.order=function(a){return arguments.length?(b=typeof a=="function"?a:dW.get(a)||dY,g):b},g.offset=function(a){return arguments.length?(c=typeof a=="function"?a:dX.get(a)||dZ,g):c},g.x=function(a){return arguments.length?(e=a,g):e},g.y=function(a){return arguments.length?(f=a,g):f},g.out=function(a){return arguments.length?(d=a,g):d},g};var dW=d3.map({"inside-out":function(a){var b=a.length,c,d,e=a.map(d$),f=a.map(d_),g=d3.range(b).sort(function(a,b){return e[a]-e[b]}),h=0,i=0,j=[],k=[];for(c=0;c<b;++c)d=g[c],h<i?(h+=f[d],j.push(d)):(i+=f[d],k.push(d));return k.reverse().concat(j)},reverse:function(a){return d3.range(a.length).reverse()},"default":dY}),dX=d3.map({silhouette:function(a){var b=a.length,c=a[0].length,d=[],e=0,f,g,h,i=[];for(g=0;g<c;++g){for(f=0,h=0;f<b;f++)h+=a[f][g][1];h>e&&(e=h),d.push(h)}for(g=0;g<c;++g)i[g]=(e-d[g])/2;return i},wiggle:function(a){var b=a.length,c=a[0],d=c.length,e=0,f,g,h,i,j,k,l,m,n,o=[];o[0]=m=n=0;for(g=1;g<d;++g){for(f=0,i=0;f<b;++f)i+=a[f][g][1];for(f=0,j=0,l=c[g][0]-c[g-1][0];f<b;++f){for(h=0,k=(a[f][g][1]-a[f][g-1][1])/(2*l);h<f;++h)k+=(a[h][g][1]-a[h][g-1][1])/l;j+=k*a[f][g][1]}o[g]=m-=i?j/i*l:0,m<n&&(n=m)}for(g=0;g<d;++g)o[g]-=n;return o},expand:function(a){var b=a.length,c=a[0].length,d=1/b,e,f,g,h=[];for(f=0;f<c;++f){for(e=0,g=0;e<b;e++)g+=a[e][f][1];if(g)for(e=0;e<b;e++)a[e][f][1]/=g;else for(e=0;e<b;e++)a[e][f][1]=d}for(f=0;f<c;++f)h[f]=0;return h},zero:dZ});d3.layout.histogram=function(){function e(e,f){var g=[],h=e.map(b,this),i=c.call(this,h,f),j=d.call(this,i,h,f),k,f=-1,l=h.length,m=j.length-1,n=a?1:1/l,o;while(++f<m)k=g[f]=[],k.dx=j[f+1]-(k.x=j[f]),k.y=0;if(m>0){f=-1;while(++f<l)o=h[f],o>=i[0]&&o<=i[1]&&(k=g[d3.bisect(j,o,1,m)-1],k.y+=n,k.push(e[f]))}return g}var a=!0,b=Number,c=ed,d=eb;return e.value=function(a){return arguments.length?(b=a,e):b},e.range=function(a){return arguments.length?(c=p(a),e):c},e.bins=function(a){return arguments.length?(d=typeof a=="number"?function(b){return ec(b,a)}:p(a),e):d},e.frequency=function(b){return arguments.length?(a=!!b,e):a},e},d3.layout.hierarchy=function(){function d(e,g,h){var i=b.call(f,e,g),j=ej?e:{data:e};j.depth=g,h.push(j);if(i&&(l=i.length)){var k=-1,l,m=j.children=[],n=0,o=g+1,p;while(++k<l)p=d(i[k],o,h),p.parent=j,m.push(p),n+=p.value;a&&m.sort(a),c&&(j.value=n)}else c&&(j.value=+c.call(f,e,g)||0);return j}function e(a,b){var d=a.children,g=0;if(d&&(i=d.length)){var h=-1,i,j=b+1;while(++h<i)g+=e(d[h],j)}else c&&(g=+c.call(f,ej?a:a.data,b)||0);return c&&(a.value=g),g}function f(a){var b=[];return d(a,0,b),b}var a=eh,b=ef,c=eg;return f.sort=function(b){return arguments.length?(a=b,f):a},f.children=function(a){return arguments.length?(b=a,f):b},f.value=function(a){return arguments.length?(c=a,f):c},f.revalue=function(a){return e(a,0),a},f};var ej=!1;d3.layout.pack=function(){function c(c,d){var e=a.call(this,c,d),f=e[0];f.x=0,f.y=0,er(f);var g=b[0],h=b[1],i=1/Math.max(2*f.r/g,2*f.r/h);return es(f,g/2,h/2,i),e}var a=d3.layout.hierarchy().sort(ek),b=[1,1];return c.size=function(a){return arguments.length?(b=a,c):b},ee(c,a)},d3.layout.cluster=function(){function d(d,e){var f=a.call(this,d,e),g=f[0],h,i=0,j,k;eF(g,function(a){var c=a.children;c&&c.length?(a.x=ev(c),a.y=eu(c)):(a.x=h?i+=b(a,h):0,a.y=0,h=a)});var l=ew(g),m=ex(g),n=l.x-b(l,m)/2,o=m.x+b(m,l)/2;return eF(g,function(a){a.x=(a.x-n)/(o-n)*c[0],a.y=(1-(g.y?a.y/g.y:1))*c[1]}),f}var a=d3.layout.hierarchy().sort(null).value(null),b=ey,c=[1,1];return d.separation=function(a){return arguments.length?(b=a,d):b},d.size=function(a){return arguments.length?(c=a,d):c},ee(d,a)},d3.layout.tree=function(){function d(d,e){function h(a,c){var d=a.children,e=a._tree;if(d&&(f=d.length)){var f,g=d[0],i,k=g,l,m=-1;while(++m<f)l=d[m],h(l,i),k=j(l,i,k),i=l;eG(a);var n=.5*(g._tree.prelim+l._tree.prelim);c?(e.prelim=c._tree.prelim+b(a,c),e.mod=e.prelim-n):e.prelim=n}else c&&(e.prelim=c._tree.prelim+b(a,c))}function i(a,b){a.x=a._tree.prelim+b;var c=a.children;if(c&&(e=c.length)){var d=-1,e;b+=a._tree.mod;while(++d<e)i(c[d],b)}}function j(a,c,d){if(c){var e=a,f=a,g=c,h=a.parent.children[0],i=e._tree.mod,j=f._tree.mod,k=g._tree.mod,l=h._tree.mod,m;while(g=eA(g),e=ez(e),g&&e)h=ez(h),f=eA(f),f._tree.ancestor=a,m=g._tree.prelim+k-e._tree.prelim-i+b(g,e),m>0&&(eH(eI(g,a,d),a,m),i+=m,j+=m),k+=g._tree.mod,i+=e._tree.mod,l+=h._tree.mod,j+=f._tree.mod;g&&!eA(f)&&(f._tree.thread=g,f._tree.mod+=k-j),e&&!ez(h)&&(h._tree.thread=e,h._tree.mod+=i-l,d=a)}return d}var f=a.call(this,d,e),g=f[0];eF(g,function(a,b){a._tree={ancestor:a,prelim:0,mod:0,change:0,shift:0,number:b?b._tree.number+1:0}}),h(g),i(g,-g._tree.prelim);var k=eB(g,eD),l=eB(g,eC),m=eB(g,eE),n=k.x-b(k,l)/2,o=l.x+b(l,k)/2,p=m.depth||1;return eF(g,function(a){a.x=(a.x-n)/(o-n)*c[0],a.y=a.depth/p*c[1],delete a._tree}),f}var a=d3.layout.hierarchy().sort(null).value(null),b=ey,c=[1,1];return d.separation=function(a){return arguments.length?(b=a,d):b},d.size=function(a){return arguments.length?(c=a,d):c},ee(d,a)},d3.layout.treemap=function(){function i(a,b){var c=-1,d=a.length,e,f;while(++c<d)f=(e=a[c]).value*(b<0?0:b),e.area=isNaN(f)||f<=0?0:f}function j(a){var b=a.children;if(b&&b.length){var c=e(a),d=[],f=b.slice(),g,h=Infinity,k,n=Math.min(c.dx,c.dy),o;i(f,c.dx*c.dy/a.value),d.area=0;while((o=f.length)>0)d.push(g=f[o-1]),d.area+=g.area,(k=l(d,n))<=h?(f.pop(),h=k):(d.area-=d.pop().area,m(d,n,c,!1),n=Math.min(c.dx,c.dy),d.length=d.area=0,h=Infinity);d.length&&(m(d,n,c,!0),d.length=d.area=0),b.forEach(j)}}function k(a){var b=a.children;if(b&&b.length){var c=e(a),d=b.slice(),f,g=[];i(d,c.dx*c.dy/a.value),g.area=0;while(f=d.pop())g.push(f),g.area+=f.area,f.z!=null&&(m(g,f.z?c.dx:c.dy,c,!d.length),g.length=g.area=0);b.forEach(k)}}function l(a,b){var c=a.area,d,e=0,f=Infinity,g=-1,i=a.length;while(++g<i){if(!(d=a[g].area))continue;d<f&&(f=d),d>e&&(e=d)}return c*=c,b*=b,c?Math.max(b*e*h/c,c/(b*f*h)):Infinity}function m(a,c,d,e){var f=-1,g=a.length,h=d.x,i=d.y,j=c?b(a.area/c):0,k;if(c==d.dx){if(e||j>d.dy)j=d.dy;while(++f<g)k=a[f],k.x=h,k.y=i,k.dy=j,h+=k.dx=Math.min(d.x+d.dx-h,j?b(k.area/j):0);k.z=!0,k.dx+=d.x+d.dx-h,d.y+=j,d.dy-=j}else{if(e||j>d.dx)j=d.dx;while(++f<g)k=a[f],k.x=h,k.y=i,k.dx=j,i+=k.dy=Math.min(d.y+d.dy-i,j?b(k.area/j):0);k.z=!1,k.dy+=d.y+d.dy-i,d.x+=j,d.dx-=j}}function n(b){var d=g||a(b),e=d[0];return e.x=0,e.y=0,e.dx=c[0],e.dy=c[1],g&&a.revalue(e),i([e],e.dx*e.dy/e.value),(g?k:j)(e),f&&(g=d),d}var a=d3.layout.hierarchy(),b=Math.round,c=[1,1],d=null,e=eJ,f=!1,g,h=.5*(1+Math.sqrt(5));return n.size=function(a){return arguments.length?(c=a,n):c},n.padding=function(a){function b(b){var c=a.call(n,b,b.depth);return c==null?eJ(b):eK(b,typeof c=="number"?[c,c,c,c]:c)}function c(b){return eK(b,a)}if(!arguments.length)return d;var f;return e=(d=a)==null?eJ:(f=typeof a)==="function"?b:f==="number"?(a=[a,a,a,a],c):c,n},n.round=function(a){return arguments.length?(b=a?Math.round:Number,n):b!=Number},n.sticky=function(a){return arguments.length?(f=a,g=null,n):f},n.ratio=function(a){return arguments.length?(h=a,n):h},ee(n,a)},d3.csv=function(a,b){d3.text(a,"text/csv",function(a){b(a&&d3.csv.parse(a))})},d3.csv.parse=function(a){var b;return d3.csv.parseRows(a,function(a,c){if(c){var d={},e=-1,f=b.length;while(++e<f)d[b[e]]=a[e];return d}return b=a,null})},d3.csv.parseRows=function(a,b){function j(){if(f.lastIndex>=a.length)return d;if(i)return i=!1,c;var b=f.lastIndex;if(a.charCodeAt(b)===34){var e=b;while(e++<a.length)if(a.charCodeAt(e)===34){if(a.charCodeAt(e+1)!==34)break;e++}f.lastIndex=e+2;var g=a.charCodeAt(e+1);return g===13?(i=!0,a.charCodeAt(e+2)===10&&f.lastIndex++):g===10&&(i=!0),a.substring(b+1,e).replace(/""/g,'"')}var h=f.exec(a);return h?(i=h[0].charCodeAt(0)!==44,a.substring(b,h.index)):(f.lastIndex=a.length,a.substring(b))}var c={},d={},e=[],f=/\r\n|[,\r\n]/g,g=0,h,i;f.lastIndex=0;while((h=j())!==d){var k=[];while(h!==c&&h!==d)k.push(h),h=j();if(b&&!(k=b(k,g++)))continue;e.push(k)}return e},d3.csv.format=function(a){return a.map(eL).join("\n")},d3.geo={};var eN=Math.PI/180;d3.geo.azimuthal=function(){function i(b){var f=b[0]*eN-e,i=b[1]*eN,j=Math.cos(f),k=Math.sin(f),l=Math.cos(i),m=Math.sin(i),n=a!=="orthographic"?h*m+g*l*j:null,o,p=a==="stereographic"?1/(1+n):a==="gnomonic"?1/n:a==="equidistant"?(o=Math.acos(n),o?o/Math.sin(o):0):a==="equalarea"?Math.sqrt(2/(1+n)):1,q=p*l*k,r=p*(h*l*j-g*m);return[c*q+d[0],c*r+d[1]]}var a="orthographic",b,c=200,d=[480,250],e,f,g,h;return i.invert=function(b){var f=(b[0]-d[0])/c,i=(b[1]-d[1])/c,j=Math.sqrt(f*f+i*i),k=a==="stereographic"?2*Math.atan(j):a==="gnomonic"?Math.atan(j):a==="equidistant"?j:a==="equalarea"?2*Math.asin(.5*j):Math.asin(j),l=Math.sin(k),m=Math.cos(k);return[(e+Math.atan2(f*l,j*g*m+i*h*l))/eN,Math.asin(m*h-(j?i*l*g/j:0))/eN]},i.mode=function(b){return arguments.length?(a=b+"",i):a},i.origin=function(a){return arguments.length?(b=a,e=b[0]*eN,f=b[1]*eN,g=Math.cos(f),h=Math.sin(f),i):b},i.scale=function(a){return arguments.length?(c=+a,i):c},i.translate=function(a){return arguments.length?(d=[+a[0],+a[1]],i):d},i.origin([0,0])},d3.geo.albers=function(){function i(a){var b=f*(eN*a[0]-e),i=Math.sqrt(g-2*f*Math.sin(eN*a[1]))/f;return[c*i*Math.sin(b)+d[0],c*(i*Math.cos(b)-h)+d[1]]}function j(){var c=eN*b[0],d=eN*b[1],j=eN*a[1],k=Math.sin(c),l=Math.cos(c);return e=eN*a[0],f=.5*(k+Math.sin(d)),g=l*l+2*f*k,h=Math.sqrt(g-2*f*Math.sin(j))/f,i}var a=[-98,38],b=[29.5,45.5],c=1e3,d=[480,250],e,f,g,h;return i.invert=function(a){var b=(a[0]-d[0])/c,i=(a[1]-d[1])/c,j=h+i,k=Math.atan2(b,j),l=Math.sqrt(b*b+j*j);return[(e+k/f)/eN,Math.asin((g-l*l*f*f)/(2*f))/eN]},i.origin=function(b){return arguments.length?(a=[+b[0],+b[1]],j()):a},i.parallels=function(a){return arguments.length?(b=[+a[0],+a[1]],j()):b},i.scale=function(a){return arguments.length?(c=+a,i):c},i.translate=function(a){return arguments.length?(d=[+a[0],+a[1]],i):d},j()},d3.geo.albersUsa=function(){function e(e){var f=e[0],g=e[1];return(g>50?b:f<-140?c:g<21?d:a)(e)}var a=d3.geo.albers(),b=d3.geo.albers().origin([-160,60]).parallels([55,65]),c=d3.geo.albers().origin([-160,20]).parallels([8,18]),d=d3.geo.albers().origin([-60,10]).parallels([8,18]);return e.scale=function(f){return arguments.length?(a.scale(f),b.scale(f*.6),c.scale(f),d.scale(f*1.5),e.translate(a.translate())):a.scale()},e.translate=function(f){if(!arguments.length)return a.translate();var g=a.scale()/1e3,h=f[0],i=f[1];return a.translate(f),b.translate([h-400*g,i+170*g]),c.translate([h-190*g,i+200*g]),d.translate([h+580*g,i+430*g]),e},e.scale(a.scale())},d3.geo.bonne=function(){function g(g){var h=g[0]*eN-c,i=g[1]*eN-d;if(e){var j=f+e-i,k=h*Math.cos(i)/j;h=j*Math.sin(k),i=j*Math.cos(k)-f}else h*=Math.cos(i),i*=-1;return[a*h+b[0],a*i+b[1]]}var a=200,b=[480,250],c,d,e,f;return g.invert=function(d){var g=(d[0]-b[0])/a,h=(d[1]-b[1])/a;if(e){var i=f+h,j=Math.sqrt(g*g+i*i);h=f+e-j,g=c+j*Math.atan2(g,i)/Math.cos(h)}else h*=-1,g/=Math.cos(h);return[g/eN,h/eN]},g.parallel=function(a){return arguments.length?(f=1/Math.tan(e=a*eN),g):e/eN},g.origin=function(a){return arguments.length?(c=a[0]*eN,d=a[1]*eN,g):[c/eN,d/eN]},g.scale=function(b){return arguments.length?(a=+b,g):a},g.translate=function(a){return arguments.length?(b=[+a[0],+a[1]],g):b},g.origin([0,0]).parallel(45)},d3.geo.equirectangular=function(){function c(c){var d=c[0]/360,e=-c[1]/360;return[a*d+b[0],a*e+b[1]]}var a=500,b=[480,250];return c.invert=function(c){var d=(c[0]-b[0])/a,e=(c[1]-b[1])/a;return[360*d,-360*e]},c.scale=function(b){return arguments.length?(a=+b,c):a},c.translate=function(a){return arguments.length?(b=[+a[0],+a[1]],c):b},c},d3.geo.mercator=function(){function c(c){var d=c[0]/360,e=-(Math.log(Math.tan(Math.PI/4+c[1]*eN/2))/eN)/360;return[a*d+b[0],a*Math.max(-0.5,Math.min(.5,e))+b[1]]}var a=500,b=[480,250];return c.invert=function(c){var d=(c[0]-b[0])/a,e=(c[1]-b[1])/a;return[360*d,2*Math.atan(Math.exp(-360*e*eN))/eN-90]},c.scale=function(b){return arguments.length?(a=+b,c):a},c.translate=function(a){return arguments.length?(b=[+a[0],+a[1]],c):b},c},d3.geo.path=function(){function e(c,e){typeof a=="function"&&(b=eP(a.apply(this,arguments))),g(c);var f=d.length?d.join(""):null;return d=[],f}function f(a){return c(a).join(",")}function i(a){var b=l(a[0]),c=0,d=a.length;while(++c<d)b-=l(a[c]);return b}function j(a){var b=d3.geom.polygon(a[0].map(c)),d=b.area(),e=b.centroid(d<0?(d*=-1,1):-1),f=e[0],g=e[1],h=d,i=0,j=a.length;while(++i<j)b=d3.geom.polygon(a[i].map(c)),d=b.area(),e=b.centroid(d<0?(d*=-1,1):-1),f-=e[0],g-=e[1],h-=d;return[f,g,6*h]}function l(a){return Math.abs(d3.geom.polygon(a.map(c)).area())}var a=4.5,b=eP(a),c=d3.geo.albersUsa(),d=[],g=eO({FeatureCollection:function(a){var b=a.features,c=-1,e=b.length;while(++c<e)d.push(g(b[c].geometry))},Feature:function(a){g(a.geometry)},Point:function(a){d.push("M",f(a.coordinates),b)},MultiPoint:function(a){var c=a.coordinates,e=-1,g=c.length;while(++e<g)d.push("M",f(c[e]),b)},LineString:function(a){var b=a.coordinates,c=-1,e=b.length;d.push("M");while(++c<e)d.push(f(b[c]),"L");d.pop()},MultiLineString:function(a){var b=a.coordinates,c=-1,e=b.length,g,h,i;while(++c<e){g=b[c],h=-1,i=g.length,d.push("M");while(++h<i)d.push(f(g[h]),"L");d.pop()}},Polygon:function(a){var b=a.coordinates,c=-1,e=b.length,g,h,i;while(++c<e){g=b[c],h=-1;if((i=g.length-1)>0){d.push("M");while(++h<i)d.push(f(g[h]),"L");d[d.length-1]="Z"}}},MultiPolygon:function(a){var b=a.coordinates,c=-1,e=b.length,g,h,i,j,k,l;while(++c<e){g=b[c],h=-1,i=g.length;while(++h<i){j=g[h],k=-1;if((l=j.length-1)>0){d.push("M");while(++k<l)d.push(f(j[k]),"L");d[d.length-1]="Z"}}}},GeometryCollection:function(a){var b=a.geometries,c=-1,e=b.length;while(++c<e)d.push(g(b[c]))}}),h=e.area=eO({FeatureCollection:function(a){var b=0,c=a.features,d=-1,e=c.length;while(++d<e)b+=h(c[d]);return b},Feature:function(a){return h(a.geometry)},Polygon:function(a){return i(a.coordinates)},MultiPolygon:function(a){var b=0,c=a.coordinates,d=-1,e=c.length;while(++d<e)b+=i(c[d]);return b},GeometryCollection:function(a){var b=0,c=a.geometries,d=-1,e=c.length;while(++d<e)b+=h(c[d]);return b}},0),k=e.centroid=eO({Feature:function(a){return k(a.geometry)},Polygon:function(a){var b=j(a.coordinates);return[b[0]/b[2],b[1]/b[2]]},MultiPolygon:function(a){var b=0,c=a.coordinates,d,e=0,f=0,g=0,h=-1,i=c.length;while(++h<i)d=j(c[h]),e+=d[0],f+=d[1],g+=d[2];return[e/g,f/g]}});return e.projection=function(a){return c=a,e},e.pointRadius=function(c){return typeof c=="function"?a=c:(a=+c,b=eP(a)),e},e},d3.geo.bounds=function(a){var b=Infinity,c=Infinity,d=-Infinity,e=-Infinity;return eQ(a,function(a,f){a<b&&(b=a),a>d&&(d=a),f<c&&(c=f),f>e&&(e=f)}),[[b,c],[d,e]]};var eR={Feature:eS,FeatureCollection:eT,GeometryCollection:eU,LineString:eV,MultiLineString:eW,MultiPoint:eV,MultiPolygon:eX,Point:eY,Polygon:eZ};d3.geo.circle=function(){function e(){}function f(a){return d.distance(a)<c}function h(a){var b=-1,e=a.length,f=[],g,h,j,k,l;while(++b<e)l=d.distance(j=a[b]),l<c?(h&&f.push(fb(h,j)((k-c)/(k-l))),f.push(j),g=h=null):(h=j,!g&&f.length&&(f.push(fb(f[f.length-1],h)((c-k)/(l-k))),g=h)),k=l;return g=a[0],h=f[0],h&&j[0]===g[0]&&j[1]===g[1]&&(j[0]!==h[0]||j[1]!==h[1])&&f.push(h),i(f)}function i(a){var b=0,c=a.length,e,f,g=c?[a[0]]:a,h,i=d.source();while(++b<c){h=d.source(a[b-1])(a[b]).coordinates;for(e=0,f=h.length;++e<f;)g.push(h[e])}return d.source(i),g}var a=[0,0],b=89.99,c=b*eN,d=d3.geo.greatArc().source(a).target(m);e.clip=function(b){return typeof a=="function"&&d.source(a.apply(this,arguments)),g(b)||null};var g=eO({FeatureCollection:function(a){var b=a.features.map(g)
.filter(m);return b&&(a=Object.create(a),a.features=b,a)},Feature:function(a){var b=g(a.geometry);return b&&(a=Object.create(a),a.geometry=b,a)},Point:function(a){return f(a.coordinates)&&a},MultiPoint:function(a){var b=a.coordinates.filter(f);return b.length&&{type:a.type,coordinates:b}},LineString:function(a){var b=h(a.coordinates);return b.length&&(a=Object.create(a),a.coordinates=b,a)},MultiLineString:function(a){var b=a.coordinates.map(h).filter(function(a){return a.length});return b.length&&(a=Object.create(a),a.coordinates=b,a)},Polygon:function(a){var b=a.coordinates.map(h);return b[0].length&&(a=Object.create(a),a.coordinates=b,a)},MultiPolygon:function(a){var b=a.coordinates.map(function(a){return a.map(h)}).filter(function(a){return a[0].length});return b.length&&(a=Object.create(a),a.coordinates=b,a)},GeometryCollection:function(a){var b=a.geometries.map(g).filter(m);return b.length&&(a=Object.create(a),a.geometries=b,a)}});return e.origin=function(b){return arguments.length?(a=b,typeof a!="function"&&d.source(a),e):a},e.angle=function(a){return arguments.length?(c=(b=+a)*eN,e):b},d3.rebind(e,d,"precision")},d3.geo.greatArc=function(){function g(){var a=g.distance.apply(this,arguments),c=0,h=e/a,i=[b];while((c+=h)<1)i.push(f(c));return i.push(d),{type:"LineString",coordinates:i}}var a=e$,b,c=e_,d,e=6*eN,f=fa();return g.distance=function(){return typeof a=="function"&&f.source(b=a.apply(this,arguments)),typeof c=="function"&&f.target(d=c.apply(this,arguments)),f.distance()},g.source=function(c){return arguments.length?(a=c,typeof a!="function"&&f.source(b=a),g):a},g.target=function(a){return arguments.length?(c=a,typeof c!="function"&&f.target(d=c),g):c},g.precision=function(a){return arguments.length?(e=a*eN,g):e/eN},g},d3.geo.greatCircle=d3.geo.circle,d3.geom={},d3.geom.contour=function(a,b){var c=b||fe(a),d=[],e=c[0],f=c[1],g=0,h=0,i=NaN,j=NaN,k=0;do k=0,a(e-1,f-1)&&(k+=1),a(e,f-1)&&(k+=2),a(e-1,f)&&(k+=4),a(e,f)&&(k+=8),k===6?(g=j===-1?-1:1,h=0):k===9?(g=0,h=i===1?-1:1):(g=fc[k],h=fd[k]),g!=i&&h!=j&&(d.push([e,f]),i=g,j=h),e+=g,f+=h;while(c[0]!=e||c[1]!=f);return d};var fc=[1,0,1,1,-1,0,-1,1,0,0,0,0,-1,0,-1,NaN],fd=[0,-1,0,0,0,-1,0,0,1,-1,1,1,0,-1,0,NaN];d3.geom.hull=function(a){if(a.length<3)return[];var b=a.length,c=b-1,d=[],e=[],f,g,h=0,i,j,k,l,m,n,o,p;for(f=1;f<b;++f)a[f][1]<a[h][1]?h=f:a[f][1]==a[h][1]&&(h=a[f][0]<a[h][0]?f:h);for(f=0;f<b;++f){if(f===h)continue;j=a[f][1]-a[h][1],i=a[f][0]-a[h][0],d.push({angle:Math.atan2(j,i),index:f})}d.sort(function(a,b){return a.angle-b.angle}),o=d[0].angle,n=d[0].index,m=0;for(f=1;f<c;++f)g=d[f].index,o==d[f].angle?(i=a[n][0]-a[h][0],j=a[n][1]-a[h][1],k=a[g][0]-a[h][0],l=a[g][1]-a[h][1],i*i+j*j>=k*k+l*l?d[f].index=-1:(d[m].index=-1,o=d[f].angle,m=f,n=g)):(o=d[f].angle,m=f,n=g);e.push(h);for(f=0,g=0;f<2;++g)d[g].index!==-1&&(e.push(d[g].index),f++);p=e.length;for(;g<c;++g){if(d[g].index===-1)continue;while(!ff(e[p-2],e[p-1],d[g].index,a))--p;e[p++]=d[g].index}var q=[];for(f=0;f<p;++f)q.push(a[e[f]]);return q},d3.geom.polygon=function(a){return a.area=function(){var b=0,c=a.length,d=a[c-1][0]*a[0][1],e=a[c-1][1]*a[0][0];while(++b<c)d+=a[b-1][0]*a[b][1],e+=a[b-1][1]*a[b][0];return(e-d)*.5},a.centroid=function(b){var c=-1,d=a.length,e=0,f=0,g,h=a[d-1],i;arguments.length||(b=-1/(6*a.area()));while(++c<d)g=h,h=a[c],i=g[0]*h[1]-h[0]*g[1],e+=(g[0]+h[0])*i,f+=(g[1]+h[1])*i;return[e*b,f*b]},a.clip=function(b){var c,d=-1,e=a.length,f,g,h=a[e-1],i,j,k;while(++d<e){c=b.slice(),b.length=0,i=a[d],j=c[(g=c.length)-1],f=-1;while(++f<g)k=c[f],fg(k,h,i)?(fg(j,h,i)||b.push(fh(j,k,h,i)),b.push(k)):fg(j,h,i)&&b.push(fh(j,k,h,i)),j=k;h=i}return b},a},d3.geom.voronoi=function(a){var b=a.map(function(){return[]});return fj(a,function(a){var c,d,e,f,g,h;a.a===1&&a.b>=0?(c=a.ep.r,d=a.ep.l):(c=a.ep.l,d=a.ep.r),a.a===1?(g=c?c.y:-1e6,e=a.c-a.b*g,h=d?d.y:1e6,f=a.c-a.b*h):(e=c?c.x:-1e6,g=a.c-a.a*e,f=d?d.x:1e6,h=a.c-a.a*f);var i=[e,g],j=[f,h];b[a.region.l.index].push(i,j),b[a.region.r.index].push(i,j)}),b.map(function(b,c){var d=a[c][0],e=a[c][1];return b.forEach(function(a){a.angle=Math.atan2(a[0]-d,a[1]-e)}),b.sort(function(a,b){return a.angle-b.angle}).filter(function(a,c){return!c||a.angle-b[c-1].angle>1e-10})})};var fi={l:"r",r:"l"};d3.geom.delaunay=function(a){var b=a.map(function(){return[]}),c=[];return fj(a,function(c){b[c.region.l.index].push(a[c.region.r.index])}),b.forEach(function(b,d){var e=a[d],f=e[0],g=e[1];b.forEach(function(a){a.angle=Math.atan2(a[0]-f,a[1]-g)}),b.sort(function(a,b){return a.angle-b.angle});for(var h=0,i=b.length-1;h<i;h++)c.push([e,b[h],b[h+1]])}),c},d3.geom.quadtree=function(a,b,c,d,e){function k(a,b,c,d,e,f){if(isNaN(b.x)||isNaN(b.y))return;if(a.leaf){var g=a.point;g?Math.abs(g.x-b.x)+Math.abs(g.y-b.y)<.01?l(a,b,c,d,e,f):(a.point=null,l(a,g,c,d,e,f),l(a,b,c,d,e,f)):a.point=b}else l(a,b,c,d,e,f)}function l(a,b,c,d,e,f){var g=(c+e)*.5,h=(d+f)*.5,i=b.x>=g,j=b.y>=h,l=(j<<1)+i;a.leaf=!1,a=a.nodes[l]||(a.nodes[l]=fk()),i?c=g:e=g,j?d=h:f=h,k(a,b,c,d,e,f)}var f,g=-1,h=a.length;h&&isNaN(a[0].x)&&(a=a.map(fm));if(arguments.length<5)if(arguments.length===3)e=d=c,c=b;else{b=c=Infinity,d=e=-Infinity;while(++g<h)f=a[g],f.x<b&&(b=f.x),f.y<c&&(c=f.y),f.x>d&&(d=f.x),f.y>e&&(e=f.y);var i=d-b,j=e-c;i>j?e=c+i:d=b+j}var m=fk();return m.add=function(a){k(m,a,b,c,d,e)},m.visit=function(a){fl(a,m,b,c,d,e)},a.forEach(m.add),m},d3.time={};var fn=Date;fo.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){fp.setUTCDate.apply(this._,arguments)},setDay:function(){fp.setUTCDay.apply(this._,arguments)},setFullYear:function(){fp.setUTCFullYear.apply(this._,arguments)},setHours:function(){fp.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){fp.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){fp.setUTCMinutes.apply(this._,arguments)},setMonth:function(){fp.setUTCMonth.apply(this._,arguments)},setSeconds:function(){fp.setUTCSeconds.apply(this._,arguments)},setTime:function(){fp.setTime.apply(this._,arguments)}};var fp=Date.prototype;d3.time.format=function(a){function c(c){var d=[],e=-1,f=0,g,h;while(++e<b)a.charCodeAt(e)==37&&(d.push(a.substring(f,e),(h=fv[g=a.charAt(++e)])?h(c):g),f=e+1);return d.push(a.substring(f,e)),d.join("")}var b=a.length;return c.parse=function(b){var c={y:1900,m:0,d:1,H:0,M:0,S:0,L:0},d=fq(c,a,b,0);if(d!=b.length)return null;"p"in c&&(c.H=c.H%12+c.p*12);var e=new fn;return e.setFullYear(c.y,c.m,c.d),e.setHours(c.H,c.M,c.S,c.L),e},c.toString=function(){return a},c};var fr=d3.format("02d"),fs=d3.format("03d"),ft=d3.format("04d"),fu=d3.format("2d"),fv={a:function(a){return fB[a.getDay()].substring(0,3)},A:function(a){return fB[a.getDay()]},b:function(a){return fH[a.getMonth()].substring(0,3)},B:function(a){return fH[a.getMonth()]},c:d3.time.format("%a %b %e %H:%M:%S %Y"),d:function(a){return fr(a.getDate())},e:function(a){return fu(a.getDate())},H:function(a){return fr(a.getHours())},I:function(a){return fr(a.getHours()%12||12)},j:function(a){return fs(1+d3.time.dayOfYear(a))},L:function(a){return fs(a.getMilliseconds())},m:function(a){return fr(a.getMonth()+1)},M:function(a){return fr(a.getMinutes())},p:function(a){return a.getHours()>=12?"PM":"AM"},S:function(a){return fr(a.getSeconds())},U:function(a){return fr(d3.time.sundayOfYear(a))},w:function(a){return a.getDay()},W:function(a){return fr(d3.time.mondayOfYear(a))},x:d3.time.format("%m/%d/%y"),X:d3.time.format("%H:%M:%S"),y:function(a){return fr(a.getFullYear()%100)},Y:function(a){return ft(a.getFullYear()%1e4)},Z:fX,"%":function(a){return"%"}},fw={a:fx,A:fy,b:fC,B:fE,c:fI,d:fP,e:fP,H:fQ,I:fQ,L:fT,m:fO,M:fR,p:fV,S:fS,x:fJ,X:fK,y:fM,Y:fL},fz=/^(?:sun|mon|tue|wed|thu|fri|sat)/i,fA=/^(?:Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday)/i,fB=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],fD=d3.map({jan:0,feb:1,mar:2,apr:3,may:4,jun:5,jul:6,aug:7,sep:8,oct:9,nov:10,dec:11}),fF=/^(?:January|February|March|April|May|June|July|August|September|October|November|December)/ig,fG=d3.map({january:0,february:1,march:2,april:3,may:4,june:5,july:6,august:7,september:8,october:9,november:10,december:11}),fH=["January","February","March","April","May","June","July","August","September","October","November","December"],fU=/\s*\d+/,fW=d3.map({am:0,pm:1});d3.time.format.utc=function(a){function c(a){try{fn=fo;var c=new fn;return c._=a,b(c)}finally{fn=Date}}var b=d3.time.format(a);return c.parse=function(a){try{fn=fo;var c=b.parse(a);return c&&c._}finally{fn=Date}},c.toString=b.toString,c};var fY=d3.time.format.utc("%Y-%m-%dT%H:%M:%S.%LZ");d3.time.format.iso=Date.prototype.toISOString?fZ:fY,fZ.parse=function(a){var b=new Date(a);return isNaN(b)?null:b},fZ.toString=fY.toString,d3.time.second=f$(function(a){return new fn(Math.floor(a/1e3)*1e3)},function(a,b){a.setTime(a.getTime()+Math.floor(b)*1e3)},function(a){return a.getSeconds()}),d3.time.seconds=d3.time.second.range,d3.time.seconds.utc=d3.time.second.utc.range,d3.time.minute=f$(function(a){return new fn(Math.floor(a/6e4)*6e4)},function(a,b){a.setTime(a.getTime()+Math.floor(b)*6e4)},function(a){return a.getMinutes()}),d3.time.minutes=d3.time.minute.range,d3.time.minutes.utc=d3.time.minute.utc.range,d3.time.hour=f$(function(a){var b=a.getTimezoneOffset()/60;return new fn((Math.floor(a/36e5-b)+b)*36e5)},function(a,b){a.setTime(a.getTime()+Math.floor(b)*36e5)},function(a){return a.getHours()}),d3.time.hours=d3.time.hour.range,d3.time.hours.utc=d3.time.hour.utc.range,d3.time.day=f$(function(a){return new fn(a.getFullYear(),a.getMonth(),a.getDate())},function(a,b){a.setDate(a.getDate()+b)},function(a){return a.getDate()-1}),d3.time.days=d3.time.day.range,d3.time.days.utc=d3.time.day.utc.range,d3.time.dayOfYear=function(a){var b=d3.time.year(a);return Math.floor((a-b)/864e5-(a.getTimezoneOffset()-b.getTimezoneOffset())/1440)},fB.forEach(function(a,b){a=a.toLowerCase(),b=7-b;var c=d3.time[a]=f$(function(a){return(a=d3.time.day(a)).setDate(a.getDate()-(a.getDay()+b)%7),a},function(a,b){a.setDate(a.getDate()+Math.floor(b)*7)},function(a){var c=d3.time.year(a).getDay();return Math.floor((d3.time.dayOfYear(a)+(c+b)%7)/7)-(c!==b)});d3.time[a+"s"]=c.range,d3.time[a+"s"].utc=c.utc.range,d3.time[a+"OfYear"]=function(a){var c=d3.time.year(a).getDay();return Math.floor((d3.time.dayOfYear(a)+(c+b)%7)/7)}}),d3.time.week=d3.time.sunday,d3.time.weeks=d3.time.sunday.range,d3.time.weeks.utc=d3.time.sunday.utc.range,d3.time.weekOfYear=d3.time.sundayOfYear,d3.time.month=f$(function(a){return new fn(a.getFullYear(),a.getMonth(),1)},function(a,b){a.setMonth(a.getMonth()+b)},function(a){return a.getMonth()}),d3.time.months=d3.time.month.range,d3.time.months.utc=d3.time.month.utc.range,d3.time.year=f$(function(a){return new fn(a.getFullYear(),0,1)},function(a,b){a.setFullYear(a.getFullYear()+b)},function(a){return a.getFullYear()}),d3.time.years=d3.time.year.range,d3.time.years.utc=d3.time.year.utc.range;var gg=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],gh=[[d3.time.second,1],[d3.time.second,5],[d3.time.second,15],[d3.time.second,30],[d3.time.minute,1],[d3.time.minute,5],[d3.time.minute,15],[d3.time.minute,30],[d3.time.hour,1],[d3.time.hour,3],[d3.time.hour,6],[d3.time.hour,12],[d3.time.day,1],[d3.time.day,2],[d3.time.week,1],[d3.time.month,1],[d3.time.month,3],[d3.time.year,1]],gi=[[d3.time.format("%Y"),function(a){return!0}],[d3.time.format("%B"),function(a){return a.getMonth()}],[d3.time.format("%b %d"),function(a){return a.getDate()!=1}],[d3.time.format("%a %d"),function(a){return a.getDay()&&a.getDate()!=1}],[d3.time.format("%I %p"),function(a){return a.getHours()}],[d3.time.format("%I:%M"),function(a){return a.getMinutes()}],[d3.time.format(":%S"),function(a){return a.getSeconds()}],[d3.time.format(".%L"),function(a){return a.getMilliseconds()}]],gj=d3.scale.linear(),gk=gd(gi);gh.year=function(a,b){return gj.domain(a.map(gf)).ticks(b).map(ge)},d3.time.scale=function(){return ga(d3.scale.linear(),gh,gk)};var gl=gh.map(function(a){return[a[0].utc,a[1]]}),gm=[[d3.time.format.utc("%Y"),function(a){return!0}],[d3.time.format.utc("%B"),function(a){return a.getUTCMonth()}],[d3.time.format.utc("%b %d"),function(a){return a.getUTCDate()!=1}],[d3.time.format.utc("%a %d"),function(a){return a.getUTCDay()&&a.getUTCDate()!=1}],[d3.time.format.utc("%I %p"),function(a){return a.getUTCHours()}],[d3.time.format.utc("%I:%M"),function(a){return a.getUTCMinutes()}],[d3.time.format.utc(":%S"),function(a){return a.getUTCSeconds()}],[d3.time.format.utc(".%L"),function(a){return a.getUTCMilliseconds()}]],gn=gd(gm);gl.year=function(a,b){return gj.domain(a.map(gp)).ticks(b).map(go)},d3.time.scale.utc=function(){return ga(d3.scale.linear(),gl,gn)}})();

/***/ }),
/* 10 */
/***/ (function(module, exports, __webpack_require__) {

var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! jQuery UI - v1.11.4 - 2015-03-11
* http://jqueryui.com
* Includes: core.js, widget.js, mouse.js, position.js, accordion.js, autocomplete.js, button.js, datepicker.js, dialog.js, draggable.js, droppable.js, effect.js, effect-blind.js, effect-bounce.js, effect-clip.js, effect-drop.js, effect-explode.js, effect-fade.js, effect-fold.js, effect-highlight.js, effect-puff.js, effect-pulsate.js, effect-scale.js, effect-shake.js, effect-size.js, effect-slide.js, effect-transfer.js, menu.js, progressbar.js, resizable.js, selectable.js, selectmenu.js, slider.js, sortable.js, spinner.js, tabs.js, tooltip.js
* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */

(function( factory ) {
	if ( true ) {

		// AMD. Register as an anonymous module.
		!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(0) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
				(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
	} else {

		// Browser globals
		factory( jQuery );
	}
}(function( $ ) {
/*!
 * jQuery UI Core 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/category/ui-core/
 */


// $.ui might exist from components with no dependencies, e.g., $.ui.position
$.ui = $.ui || {};

$.extend( $.ui, {
	version: "1.11.4",

	keyCode: {
		BACKSPACE: 8,
		COMMA: 188,
		DELETE: 46,
		DOWN: 40,
		END: 35,
		ENTER: 13,
		ESCAPE: 27,
		HOME: 36,
		LEFT: 37,
		PAGE_DOWN: 34,
		PAGE_UP: 33,
		PERIOD: 190,
		RIGHT: 39,
		SPACE: 32,
		TAB: 9,
		UP: 38
	}
});

// plugins
$.fn.extend({
	scrollParent: function( includeHidden ) {
		var position = this.css( "position" ),
			excludeStaticParent = position === "absolute",
			overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
			scrollParent = this.parents().filter( function() {
				var parent = $( this );
				if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
					return false;
				}
				return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) );
			}).eq( 0 );

		return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent;
	},

	uniqueId: (function() {
		var uuid = 0;

		return function() {
			return this.each(function() {
				if ( !this.id ) {
					this.id = "ui-id-" + ( ++uuid );
				}
			});
		};
	})(),

	removeUniqueId: function() {
		return this.each(function() {
			if ( /^ui-id-\d+$/.test( this.id ) ) {
				$( this ).removeAttr( "id" );
			}
		});
	}
});

// selectors
function focusable( element, isTabIndexNotNaN ) {
	var map, mapName, img,
		nodeName = element.nodeName.toLowerCase();
	if ( "area" === nodeName ) {
		map = element.parentNode;
		mapName = map.name;
		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
			return false;
		}
		img = $( "img[usemap='#" + mapName + "']" )[ 0 ];
		return !!img && visible( img );
	}
	return ( /^(input|select|textarea|button|object)$/.test( nodeName ) ?
		!element.disabled :
		"a" === nodeName ?
			element.href || isTabIndexNotNaN :
			isTabIndexNotNaN) &&
		// the element and all of its ancestors must be visible
		visible( element );
}

function visible( element ) {
	return $.expr.filters.visible( element ) &&
		!$( element ).parents().addBack().filter(function() {
			return $.css( this, "visibility" ) === "hidden";
		}).length;
}

$.extend( $.expr[ ":" ], {
	data: $.expr.createPseudo ?
		$.expr.createPseudo(function( dataName ) {
			return function( elem ) {
				return !!$.data( elem, dataName );
			};
		}) :
		// support: jQuery <1.8
		function( elem, i, match ) {
			return !!$.data( elem, match[ 3 ] );
		},

	focusable: function( element ) {
		return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
	},

	tabbable: function( element ) {
		var tabIndex = $.attr( element, "tabindex" ),
			isTabIndexNaN = isNaN( tabIndex );
		return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
	}
});

// support: jQuery <1.8
if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
	$.each( [ "Width", "Height" ], function( i, name ) {
		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
			type = name.toLowerCase(),
			orig = {
				innerWidth: $.fn.innerWidth,
				innerHeight: $.fn.innerHeight,
				outerWidth: $.fn.outerWidth,
				outerHeight: $.fn.outerHeight
			};

		function reduce( elem, size, border, margin ) {
			$.each( side, function() {
				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
				if ( border ) {
					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
				}
				if ( margin ) {
					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
				}
			});
			return size;
		}

		$.fn[ "inner" + name ] = function( size ) {
			if ( size === undefined ) {
				return orig[ "inner" + name ].call( this );
			}

			return this.each(function() {
				$( this ).css( type, reduce( this, size ) + "px" );
			});
		};

		$.fn[ "outer" + name] = function( size, margin ) {
			if ( typeof size !== "number" ) {
				return orig[ "outer" + name ].call( this, size );
			}

			return this.each(function() {
				$( this).css( type, reduce( this, size, true, margin ) + "px" );
			});
		};
	});
}

// support: jQuery <1.8
if ( !$.fn.addBack ) {
	$.fn.addBack = function( selector ) {
		return this.add( selector == null ?
			this.prevObject : this.prevObject.filter( selector )
		);
	};
}

// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
	$.fn.removeData = (function( removeData ) {
		return function( key ) {
			if ( arguments.length ) {
				return removeData.call( this, $.camelCase( key ) );
			} else {
				return removeData.call( this );
			}
		};
	})( $.fn.removeData );
}

// deprecated
$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );

$.fn.extend({
	focus: (function( orig ) {
		return function( delay, fn ) {
			return typeof delay === "number" ?
				this.each(function() {
					var elem = this;
					setTimeout(function() {
						$( elem ).focus();
						if ( fn ) {
							fn.call( elem );
						}
					}, delay );
				}) :
				orig.apply( this, arguments );
		};
	})( $.fn.focus ),

	disableSelection: (function() {
		var eventType = "onselectstart" in document.createElement( "div" ) ?
			"selectstart" :
			"mousedown";

		return function() {
			return this.bind( eventType + ".ui-disableSelection", function( event ) {
				event.preventDefault();
			});
		};
	})(),

	enableSelection: function() {
		return this.unbind( ".ui-disableSelection" );
	},

	zIndex: function( zIndex ) {
		if ( zIndex !== undefined ) {
			return this.css( "zIndex", zIndex );
		}

		if ( this.length ) {
			var elem = $( this[ 0 ] ), position, value;
			while ( elem.length && elem[ 0 ] !== document ) {
				// Ignore z-index if position is set to a value where z-index is ignored by the browser
				// This makes behavior of this function consistent across browsers
				// WebKit always returns auto if the element is positioned
				position = elem.css( "position" );
				if ( position === "absolute" || position === "relative" || position === "fixed" ) {
					// IE returns 0 when zIndex is not specified
					// other browsers return a string
					// we ignore the case of nested elements with an explicit value of 0
					// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
					value = parseInt( elem.css( "zIndex" ), 10 );
					if ( !isNaN( value ) && value !== 0 ) {
						return value;
					}
				}
				elem = elem.parent();
			}
		}

		return 0;
	}
});

// $.ui.plugin is deprecated. Use $.widget() extensions instead.
$.ui.plugin = {
	add: function( module, option, set ) {
		var i,
			proto = $.ui[ module ].prototype;
		for ( i in set ) {
			proto.plugins[ i ] = proto.plugins[ i ] || [];
			proto.plugins[ i ].push( [ option, set[ i ] ] );
		}
	},
	call: function( instance, name, args, allowDisconnected ) {
		var i,
			set = instance.plugins[ name ];

		if ( !set ) {
			return;
		}

		if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
			return;
		}

		for ( i = 0; i < set.length; i++ ) {
			if ( instance.options[ set[ i ][ 0 ] ] ) {
				set[ i ][ 1 ].apply( instance.element, args );
			}
		}
	}
};


/*!
 * jQuery UI Widget 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/jQuery.widget/
 */


var widget_uuid = 0,
	widget_slice = Array.prototype.slice;

$.cleanData = (function( orig ) {
	return function( elems ) {
		var events, elem, i;
		for ( i = 0; (elem = elems[i]) != null; i++ ) {
			try {

				// Only trigger remove when necessary to save time
				events = $._data( elem, "events" );
				if ( events && events.remove ) {
					$( elem ).triggerHandler( "remove" );
				}

			// http://bugs.jquery.com/ticket/8235
			} catch ( e ) {}
		}
		orig( elems );
	};
})( $.cleanData );

$.widget = function( name, base, prototype ) {
	var fullName, existingConstructor, constructor, basePrototype,
		// proxiedPrototype allows the provided prototype to remain unmodified
		// so that it can be used as a mixin for multiple widgets (#8876)
		proxiedPrototype = {},
		namespace = name.split( "." )[ 0 ];

	name = name.split( "." )[ 1 ];
	fullName = namespace + "-" + name;

	if ( !prototype ) {
		prototype = base;
		base = $.Widget;
	}

	// create selector for plugin
	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
		return !!$.data( elem, fullName );
	};

	$[ namespace ] = $[ namespace ] || {};
	existingConstructor = $[ namespace ][ name ];
	constructor = $[ namespace ][ name ] = function( options, element ) {
		// allow instantiation without "new" keyword
		if ( !this._createWidget ) {
			return new constructor( options, element );
		}

		// allow instantiation without initializing for simple inheritance
		// must use "new" keyword (the code above always passes args)
		if ( arguments.length ) {
			this._createWidget( options, element );
		}
	};
	// extend with the existing constructor to carry over any static properties
	$.extend( constructor, existingConstructor, {
		version: prototype.version,
		// copy the object used to create the prototype in case we need to
		// redefine the widget later
		_proto: $.extend( {}, prototype ),
		// track widgets that inherit from this widget in case this widget is
		// redefined after a widget inherits from it
		_childConstructors: []
	});

	basePrototype = new base();
	// we need to make the options hash a property directly on the new instance
	// otherwise we'll modify the options hash on the prototype that we're
	// inheriting from
	basePrototype.options = $.widget.extend( {}, basePrototype.options );
	$.each( prototype, function( prop, value ) {
		if ( !$.isFunction( value ) ) {
			proxiedPrototype[ prop ] = value;
			return;
		}
		proxiedPrototype[ prop ] = (function() {
			var _super = function() {
					return base.prototype[ prop ].apply( this, arguments );
				},
				_superApply = function( args ) {
					return base.prototype[ prop ].apply( this, args );
				};
			return function() {
				var __super = this._super,
					__superApply = this._superApply,
					returnValue;

				this._super = _super;
				this._superApply = _superApply;

				returnValue = value.apply( this, arguments );

				this._super = __super;
				this._superApply = __superApply;

				return returnValue;
			};
		})();
	});
	constructor.prototype = $.widget.extend( basePrototype, {
		// TODO: remove support for widgetEventPrefix
		// always use the name + a colon as the prefix, e.g., draggable:start
		// don't prefix for widgets that aren't DOM-based
		widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
	}, proxiedPrototype, {
		constructor: constructor,
		namespace: namespace,
		widgetName: name,
		widgetFullName: fullName
	});

	// If this widget is being redefined then we need to find all widgets that
	// are inheriting from it and redefine all of them so that they inherit from
	// the new version of this widget. We're essentially trying to replace one
	// level in the prototype chain.
	if ( existingConstructor ) {
		$.each( existingConstructor._childConstructors, function( i, child ) {
			var childPrototype = child.prototype;

			// redefine the child widget using the same prototype that was
			// originally used, but inherit from the new version of the base
			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
		});
		// remove the list of existing child constructors from the old constructor
		// so the old child constructors can be garbage collected
		delete existingConstructor._childConstructors;
	} else {
		base._childConstructors.push( constructor );
	}

	$.widget.bridge( name, constructor );

	return constructor;
};

$.widget.extend = function( target ) {
	var input = widget_slice.call( arguments, 1 ),
		inputIndex = 0,
		inputLength = input.length,
		key,
		value;
	for ( ; inputIndex < inputLength; inputIndex++ ) {
		for ( key in input[ inputIndex ] ) {
			value = input[ inputIndex ][ key ];
			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
				// Clone objects
				if ( $.isPlainObject( value ) ) {
					target[ key ] = $.isPlainObject( target[ key ] ) ?
						$.widget.extend( {}, target[ key ], value ) :
						// Don't extend strings, arrays, etc. with objects
						$.widget.extend( {}, value );
				// Copy everything else by reference
				} else {
					target[ key ] = value;
				}
			}
		}
	}
	return target;
};

$.widget.bridge = function( name, object ) {
	var fullName = object.prototype.widgetFullName || name;
	$.fn[ name ] = function( options ) {
		var isMethodCall = typeof options === "string",
			args = widget_slice.call( arguments, 1 ),
			returnValue = this;

		if ( isMethodCall ) {
			this.each(function() {
				var methodValue,
					instance = $.data( this, fullName );
				if ( options === "instance" ) {
					returnValue = instance;
					return false;
				}
				if ( !instance ) {
					return $.error( "cannot call methods on " + name + " prior to initialization; " +
						"attempted to call method '" + options + "'" );
				}
				if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
					return $.error( "no such method '" + options + "' for " + name + " widget instance" );
				}
				methodValue = instance[ options ].apply( instance, args );
				if ( methodValue !== instance && methodValue !== undefined ) {
					returnValue = methodValue && methodValue.jquery ?
						returnValue.pushStack( methodValue.get() ) :
						methodValue;
					return false;
				}
			});
		} else {

			// Allow multiple hashes to be passed on init
			if ( args.length ) {
				options = $.widget.extend.apply( null, [ options ].concat(args) );
			}

			this.each(function() {
				var instance = $.data( this, fullName );
				if ( instance ) {
					instance.option( options || {} );
					if ( instance._init ) {
						instance._init();
					}
				} else {
					$.data( this, fullName, new object( options, this ) );
				}
			});
		}

		return returnValue;
	};
};

$.Widget = function( /* options, element */ ) {};
$.Widget._childConstructors = [];

$.Widget.prototype = {
	widgetName: "widget",
	widgetEventPrefix: "",
	defaultElement: "<div>",
	options: {
		disabled: false,

		// callbacks
		create: null
	},
	_createWidget: function( options, element ) {
		element = $( element || this.defaultElement || this )[ 0 ];
		this.element = $( element );
		this.uuid = widget_uuid++;
		this.eventNamespace = "." + this.widgetName + this.uuid;

		this.bindings = $();
		this.hoverable = $();
		this.focusable = $();

		if ( element !== this ) {
			$.data( element, this.widgetFullName, this );
			this._on( true, this.element, {
				remove: function( event ) {
					if ( event.target === element ) {
						this.destroy();
					}
				}
			});
			this.document = $( element.style ?
				// element within the document
				element.ownerDocument :
				// element is window or document
				element.document || element );
			this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
		}

		this.options = $.widget.extend( {},
			this.options,
			this._getCreateOptions(),
			options );

		this._create();
		this._trigger( "create", null, this._getCreateEventData() );
		this._init();
	},
	_getCreateOptions: $.noop,
	_getCreateEventData: $.noop,
	_create: $.noop,
	_init: $.noop,

	destroy: function() {
		this._destroy();
		// we can probably remove the unbind calls in 2.0
		// all event bindings should go through this._on()
		this.element
			.unbind( this.eventNamespace )
			.removeData( this.widgetFullName )
			// support: jquery <1.6.3
			// http://bugs.jquery.com/ticket/9413
			.removeData( $.camelCase( this.widgetFullName ) );
		this.widget()
			.unbind( this.eventNamespace )
			.removeAttr( "aria-disabled" )
			.removeClass(
				this.widgetFullName + "-disabled " +
				"ui-state-disabled" );

		// clean up events and states
		this.bindings.unbind( this.eventNamespace );
		this.hoverable.removeClass( "ui-state-hover" );
		this.focusable.removeClass( "ui-state-focus" );
	},
	_destroy: $.noop,

	widget: function() {
		return this.element;
	},

	option: function( key, value ) {
		var options = key,
			parts,
			curOption,
			i;

		if ( arguments.length === 0 ) {
			// don't return a reference to the internal hash
			return $.widget.extend( {}, this.options );
		}

		if ( typeof key === "string" ) {
			// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
			options = {};
			parts = key.split( "." );
			key = parts.shift();
			if ( parts.length ) {
				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
				for ( i = 0; i < parts.length - 1; i++ ) {
					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
					curOption = curOption[ parts[ i ] ];
				}
				key = parts.pop();
				if ( arguments.length === 1 ) {
					return curOption[ key ] === undefined ? null : curOption[ key ];
				}
				curOption[ key ] = value;
			} else {
				if ( arguments.length === 1 ) {
					return this.options[ key ] === undefined ? null : this.options[ key ];
				}
				options[ key ] = value;
			}
		}

		this._setOptions( options );

		return this;
	},
	_setOptions: function( options ) {
		var key;

		for ( key in options ) {
			this._setOption( key, options[ key ] );
		}

		return this;
	},
	_setOption: function( key, value ) {
		this.options[ key ] = value;

		if ( key === "disabled" ) {
			this.widget()
				.toggleClass( this.widgetFullName + "-disabled", !!value );

			// If the widget is becoming disabled, then nothing is interactive
			if ( value ) {
				this.hoverable.removeClass( "ui-state-hover" );
				this.focusable.removeClass( "ui-state-focus" );
			}
		}

		return this;
	},

	enable: function() {
		return this._setOptions({ disabled: false });
	},
	disable: function() {
		return this._setOptions({ disabled: true });
	},

	_on: function( suppressDisabledCheck, element, handlers ) {
		var delegateElement,
			instance = this;

		// no suppressDisabledCheck flag, shuffle arguments
		if ( typeof suppressDisabledCheck !== "boolean" ) {
			handlers = element;
			element = suppressDisabledCheck;
			suppressDisabledCheck = false;
		}

		// no element argument, shuffle and use this.element
		if ( !handlers ) {
			handlers = element;
			element = this.element;
			delegateElement = this.widget();
		} else {
			element = delegateElement = $( element );
			this.bindings = this.bindings.add( element );
		}

		$.each( handlers, function( event, handler ) {
			function handlerProxy() {
				// allow widgets to customize the disabled handling
				// - disabled as an array instead of boolean
				// - disabled class as method for disabling individual parts
				if ( !suppressDisabledCheck &&
						( instance.options.disabled === true ||
							$( this ).hasClass( "ui-state-disabled" ) ) ) {
					return;
				}
				return ( typeof handler === "string" ? instance[ handler ] : handler )
					.apply( instance, arguments );
			}

			// copy the guid so direct unbinding works
			if ( typeof handler !== "string" ) {
				handlerProxy.guid = handler.guid =
					handler.guid || handlerProxy.guid || $.guid++;
			}

			var match = event.match( /^([\w:-]*)\s*(.*)$/ ),
				eventName = match[1] + instance.eventNamespace,
				selector = match[2];
			if ( selector ) {
				delegateElement.delegate( selector, eventName, handlerProxy );
			} else {
				element.bind( eventName, handlerProxy );
			}
		});
	},

	_off: function( element, eventName ) {
		eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) +
			this.eventNamespace;
		element.unbind( eventName ).undelegate( eventName );

		// Clear the stack to avoid memory leaks (#10056)
		this.bindings = $( this.bindings.not( element ).get() );
		this.focusable = $( this.focusable.not( element ).get() );
		this.hoverable = $( this.hoverable.not( element ).get() );
	},

	_delay: function( handler, delay ) {
		function handlerProxy() {
			return ( typeof handler === "string" ? instance[ handler ] : handler )
				.apply( instance, arguments );
		}
		var instance = this;
		return setTimeout( handlerProxy, delay || 0 );
	},

	_hoverable: function( element ) {
		this.hoverable = this.hoverable.add( element );
		this._on( element, {
			mouseenter: function( event ) {
				$( event.currentTarget ).addClass( "ui-state-hover" );
			},
			mouseleave: function( event ) {
				$( event.currentTarget ).removeClass( "ui-state-hover" );
			}
		});
	},

	_focusable: function( element ) {
		this.focusable = this.focusable.add( element );
		this._on( element, {
			focusin: function( event ) {
				$( event.currentTarget ).addClass( "ui-state-focus" );
			},
			focusout: function( event ) {
				$( event.currentTarget ).removeClass( "ui-state-focus" );
			}
		});
	},

	_trigger: function( type, event, data ) {
		var prop, orig,
			callback = this.options[ type ];

		data = data || {};
		event = $.Event( event );
		event.type = ( type === this.widgetEventPrefix ?
			type :
			this.widgetEventPrefix + type ).toLowerCase();
		// the original event may come from any element
		// so we need to reset the target on the new event
		event.target = this.element[ 0 ];

		// copy original event properties over to the new event
		orig = event.originalEvent;
		if ( orig ) {
			for ( prop in orig ) {
				if ( !( prop in event ) ) {
					event[ prop ] = orig[ prop ];
				}
			}
		}

		this.element.trigger( event, data );
		return !( $.isFunction( callback ) &&
			callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
			event.isDefaultPrevented() );
	}
};

$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
		if ( typeof options === "string" ) {
			options = { effect: options };
		}
		var hasOptions,
			effectName = !options ?
				method :
				options === true || typeof options === "number" ?
					defaultEffect :
					options.effect || defaultEffect;
		options = options || {};
		if ( typeof options === "number" ) {
			options = { duration: options };
		}
		hasOptions = !$.isEmptyObject( options );
		options.complete = callback;
		if ( options.delay ) {
			element.delay( options.delay );
		}
		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
			element[ method ]( options );
		} else if ( effectName !== method && element[ effectName ] ) {
			element[ effectName ]( options.duration, options.easing, callback );
		} else {
			element.queue(function( next ) {
				$( this )[ method ]();
				if ( callback ) {
					callback.call( element[ 0 ] );
				}
				next();
			});
		}
	};
});

var widget = $.widget;


/*!
 * jQuery UI Mouse 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/mouse/
 */


var mouseHandled = false;
$( document ).mouseup( function() {
	mouseHandled = false;
});

var mouse = $.widget("ui.mouse", {
	version: "1.11.4",
	options: {
		cancel: "input,textarea,button,select,option",
		distance: 1,
		delay: 0
	},
	_mouseInit: function() {
		var that = this;

		this.element
			.bind("mousedown." + this.widgetName, function(event) {
				return that._mouseDown(event);
			})
			.bind("click." + this.widgetName, function(event) {
				if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
					$.removeData(event.target, that.widgetName + ".preventClickEvent");
					event.stopImmediatePropagation();
					return false;
				}
			});

		this.started = false;
	},

	// TODO: make sure destroying one instance of mouse doesn't mess with
	// other instances of mouse
	_mouseDestroy: function() {
		this.element.unbind("." + this.widgetName);
		if ( this._mouseMoveDelegate ) {
			this.document
				.unbind("mousemove." + this.widgetName, this._mouseMoveDelegate)
				.unbind("mouseup." + this.widgetName, this._mouseUpDelegate);
		}
	},

	_mouseDown: function(event) {
		// don't let more than one widget handle mouseStart
		if ( mouseHandled ) {
			return;
		}

		this._mouseMoved = false;

		// we may have missed mouseup (out of window)
		(this._mouseStarted && this._mouseUp(event));

		this._mouseDownEvent = event;

		var that = this,
			btnIsLeft = (event.which === 1),
			// event.target.nodeName works around a bug in IE 8 with
			// disabled inputs (#7620)
			elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
		if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
			return true;
		}

		this.mouseDelayMet = !this.options.delay;
		if (!this.mouseDelayMet) {
			this._mouseDelayTimer = setTimeout(function() {
				that.mouseDelayMet = true;
			}, this.options.delay);
		}

		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
			this._mouseStarted = (this._mouseStart(event) !== false);
			if (!this._mouseStarted) {
				event.preventDefault();
				return true;
			}
		}

		// Click event may never have fired (Gecko & Opera)
		if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
			$.removeData(event.target, this.widgetName + ".preventClickEvent");
		}

		// these delegates are required to keep context
		this._mouseMoveDelegate = function(event) {
			return that._mouseMove(event);
		};
		this._mouseUpDelegate = function(event) {
			return that._mouseUp(event);
		};

		this.document
			.bind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
			.bind( "mouseup." + this.widgetName, this._mouseUpDelegate );

		event.preventDefault();

		mouseHandled = true;
		return true;
	},

	_mouseMove: function(event) {
		// Only check for mouseups outside the document if you've moved inside the document
		// at least once. This prevents the firing of mouseup in the case of IE<9, which will
		// fire a mousemove event if content is placed under the cursor. See #7778
		// Support: IE <9
		if ( this._mouseMoved ) {
			// IE mouseup check - mouseup happened when mouse was out of window
			if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
				return this._mouseUp(event);

			// Iframe mouseup check - mouseup occurred in another document
			} else if ( !event.which ) {
				return this._mouseUp( event );
			}
		}

		if ( event.which || event.button ) {
			this._mouseMoved = true;
		}

		if (this._mouseStarted) {
			this._mouseDrag(event);
			return event.preventDefault();
		}

		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
			this._mouseStarted =
				(this._mouseStart(this._mouseDownEvent, event) !== false);
			(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
		}

		return !this._mouseStarted;
	},

	_mouseUp: function(event) {
		this.document
			.unbind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
			.unbind( "mouseup." + this.widgetName, this._mouseUpDelegate );

		if (this._mouseStarted) {
			this._mouseStarted = false;

			if (event.target === this._mouseDownEvent.target) {
				$.data(event.target, this.widgetName + ".preventClickEvent", true);
			}

			this._mouseStop(event);
		}

		mouseHandled = false;
		return false;
	},

	_mouseDistanceMet: function(event) {
		return (Math.max(
				Math.abs(this._mouseDownEvent.pageX - event.pageX),
				Math.abs(this._mouseDownEvent.pageY - event.pageY)
			) >= this.options.distance
		);
	},

	_mouseDelayMet: function(/* event */) {
		return this.mouseDelayMet;
	},

	// These are placeholder methods, to be overriden by extending plugin
	_mouseStart: function(/* event */) {},
	_mouseDrag: function(/* event */) {},
	_mouseStop: function(/* event */) {},
	_mouseCapture: function(/* event */) { return true; }
});


/*!
 * jQuery UI Position 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/position/
 */

(function() {

$.ui = $.ui || {};

var cachedScrollbarWidth, supportsOffsetFractions,
	max = Math.max,
	abs = Math.abs,
	round = Math.round,
	rhorizontal = /left|center|right/,
	rvertical = /top|center|bottom/,
	roffset = /[\+\-]\d+(\.[\d]+)?%?/,
	rposition = /^\w+/,
	rpercent = /%$/,
	_position = $.fn.position;

function getOffsets( offsets, width, height ) {
	return [
		parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
		parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
	];
}

function parseCss( element, property ) {
	return parseInt( $.css( element, property ), 10 ) || 0;
}

function getDimensions( elem ) {
	var raw = elem[0];
	if ( raw.nodeType === 9 ) {
		return {
			width: elem.width(),
			height: elem.height(),
			offset: { top: 0, left: 0 }
		};
	}
	if ( $.isWindow( raw ) ) {
		return {
			width: elem.width(),
			height: elem.height(),
			offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
		};
	}
	if ( raw.preventDefault ) {
		return {
			width: 0,
			height: 0,
			offset: { top: raw.pageY, left: raw.pageX }
		};
	}
	return {
		width: elem.outerWidth(),
		height: elem.outerHeight(),
		offset: elem.offset()
	};
}

$.position = {
	scrollbarWidth: function() {
		if ( cachedScrollbarWidth !== undefined ) {
			return cachedScrollbarWidth;
		}
		var w1, w2,
			div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
			innerDiv = div.children()[0];

		$( "body" ).append( div );
		w1 = innerDiv.offsetWidth;
		div.css( "overflow", "scroll" );

		w2 = innerDiv.offsetWidth;

		if ( w1 === w2 ) {
			w2 = div[0].clientWidth;
		}

		div.remove();

		return (cachedScrollbarWidth = w1 - w2);
	},
	getScrollInfo: function( within ) {
		var overflowX = within.isWindow || within.isDocument ? "" :
				within.element.css( "overflow-x" ),
			overflowY = within.isWindow || within.isDocument ? "" :
				within.element.css( "overflow-y" ),
			hasOverflowX = overflowX === "scroll" ||
				( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
			hasOverflowY = overflowY === "scroll" ||
				( overflowY === "auto" && within.height < within.element[0].scrollHeight );
		return {
			width: hasOverflowY ? $.position.scrollbarWidth() : 0,
			height: hasOverflowX ? $.position.scrollbarWidth() : 0
		};
	},
	getWithinInfo: function( element ) {
		var withinElement = $( element || window ),
			isWindow = $.isWindow( withinElement[0] ),
			isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;
		return {
			element: withinElement,
			isWindow: isWindow,
			isDocument: isDocument,
			offset: withinElement.offset() || { left: 0, top: 0 },
			scrollLeft: withinElement.scrollLeft(),
			scrollTop: withinElement.scrollTop(),

			// support: jQuery 1.6.x
			// jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows
			width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(),
			height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight()
		};
	}
};

$.fn.position = function( options ) {
	if ( !options || !options.of ) {
		return _position.apply( this, arguments );
	}

	// make a copy, we don't want to modify arguments
	options = $.extend( {}, options );

	var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
		target = $( options.of ),
		within = $.position.getWithinInfo( options.within ),
		scrollInfo = $.position.getScrollInfo( within ),
		collision = ( options.collision || "flip" ).split( " " ),
		offsets = {};

	dimensions = getDimensions( target );
	if ( target[0].preventDefault ) {
		// force left top to allow flipping
		options.at = "left top";
	}
	targetWidth = dimensions.width;
	targetHeight = dimensions.height;
	targetOffset = dimensions.offset;
	// clone to reuse original targetOffset later
	basePosition = $.extend( {}, targetOffset );

	// force my and at to have valid horizontal and vertical positions
	// if a value is missing or invalid, it will be converted to center
	$.each( [ "my", "at" ], function() {
		var pos = ( options[ this ] || "" ).split( " " ),
			horizontalOffset,
			verticalOffset;

		if ( pos.length === 1) {
			pos = rhorizontal.test( pos[ 0 ] ) ?
				pos.concat( [ "center" ] ) :
				rvertical.test( pos[ 0 ] ) ?
					[ "center" ].concat( pos ) :
					[ "center", "center" ];
		}
		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";

		// calculate offsets
		horizontalOffset = roffset.exec( pos[ 0 ] );
		verticalOffset = roffset.exec( pos[ 1 ] );
		offsets[ this ] = [
			horizontalOffset ? horizontalOffset[ 0 ] : 0,
			verticalOffset ? verticalOffset[ 0 ] : 0
		];

		// reduce to just the positions without the offsets
		options[ this ] = [
			rposition.exec( pos[ 0 ] )[ 0 ],
			rposition.exec( pos[ 1 ] )[ 0 ]
		];
	});

	// normalize collision option
	if ( collision.length === 1 ) {
		collision[ 1 ] = collision[ 0 ];
	}

	if ( options.at[ 0 ] === "right" ) {
		basePosition.left += targetWidth;
	} else if ( options.at[ 0 ] === "center" ) {
		basePosition.left += targetWidth / 2;
	}

	if ( options.at[ 1 ] === "bottom" ) {
		basePosition.top += targetHeight;
	} else if ( options.at[ 1 ] === "center" ) {
		basePosition.top += targetHeight / 2;
	}

	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
	basePosition.left += atOffset[ 0 ];
	basePosition.top += atOffset[ 1 ];

	return this.each(function() {
		var collisionPosition, using,
			elem = $( this ),
			elemWidth = elem.outerWidth(),
			elemHeight = elem.outerHeight(),
			marginLeft = parseCss( this, "marginLeft" ),
			marginTop = parseCss( this, "marginTop" ),
			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
			position = $.extend( {}, basePosition ),
			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );

		if ( options.my[ 0 ] === "right" ) {
			position.left -= elemWidth;
		} else if ( options.my[ 0 ] === "center" ) {
			position.left -= elemWidth / 2;
		}

		if ( options.my[ 1 ] === "bottom" ) {
			position.top -= elemHeight;
		} else if ( options.my[ 1 ] === "center" ) {
			position.top -= elemHeight / 2;
		}

		position.left += myOffset[ 0 ];
		position.top += myOffset[ 1 ];

		// if the browser doesn't support fractions, then round for consistent results
		if ( !supportsOffsetFractions ) {
			position.left = round( position.left );
			position.top = round( position.top );
		}

		collisionPosition = {
			marginLeft: marginLeft,
			marginTop: marginTop
		};

		$.each( [ "left", "top" ], function( i, dir ) {
			if ( $.ui.position[ collision[ i ] ] ) {
				$.ui.position[ collision[ i ] ][ dir ]( position, {
					targetWidth: targetWidth,
					targetHeight: targetHeight,
					elemWidth: elemWidth,
					elemHeight: elemHeight,
					collisionPosition: collisionPosition,
					collisionWidth: collisionWidth,
					collisionHeight: collisionHeight,
					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
					my: options.my,
					at: options.at,
					within: within,
					elem: elem
				});
			}
		});

		if ( options.using ) {
			// adds feedback as second argument to using callback, if present
			using = function( props ) {
				var left = targetOffset.left - position.left,
					right = left + targetWidth - elemWidth,
					top = targetOffset.top - position.top,
					bottom = top + targetHeight - elemHeight,
					feedback = {
						target: {
							element: target,
							left: targetOffset.left,
							top: targetOffset.top,
							width: targetWidth,
							height: targetHeight
						},
						element: {
							element: elem,
							left: position.left,
							top: position.top,
							width: elemWidth,
							height: elemHeight
						},
						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
					};
				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
					feedback.horizontal = "center";
				}
				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
					feedback.vertical = "middle";
				}
				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
					feedback.important = "horizontal";
				} else {
					feedback.important = "vertical";
				}
				options.using.call( this, props, feedback );
			};
		}

		elem.offset( $.extend( position, { using: using } ) );
	});
};

$.ui.position = {
	fit: {
		left: function( position, data ) {
			var within = data.within,
				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
				outerWidth = within.width,
				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
				overLeft = withinOffset - collisionPosLeft,
				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
				newOverRight;

			// element is wider than within
			if ( data.collisionWidth > outerWidth ) {
				// element is initially over the left side of within
				if ( overLeft > 0 && overRight <= 0 ) {
					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
					position.left += overLeft - newOverRight;
				// element is initially over right side of within
				} else if ( overRight > 0 && overLeft <= 0 ) {
					position.left = withinOffset;
				// element is initially over both left and right sides of within
				} else {
					if ( overLeft > overRight ) {
						position.left = withinOffset + outerWidth - data.collisionWidth;
					} else {
						position.left = withinOffset;
					}
				}
			// too far left -> align with left edge
			} else if ( overLeft > 0 ) {
				position.left += overLeft;
			// too far right -> align with right edge
			} else if ( overRight > 0 ) {
				position.left -= overRight;
			// adjust based on position and margin
			} else {
				position.left = max( position.left - collisionPosLeft, position.left );
			}
		},
		top: function( position, data ) {
			var within = data.within,
				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
				outerHeight = data.within.height,
				collisionPosTop = position.top - data.collisionPosition.marginTop,
				overTop = withinOffset - collisionPosTop,
				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
				newOverBottom;

			// element is taller than within
			if ( data.collisionHeight > outerHeight ) {
				// element is initially over the top of within
				if ( overTop > 0 && overBottom <= 0 ) {
					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
					position.top += overTop - newOverBottom;
				// element is initially over bottom of within
				} else if ( overBottom > 0 && overTop <= 0 ) {
					position.top = withinOffset;
				// element is initially over both top and bottom of within
				} else {
					if ( overTop > overBottom ) {
						position.top = withinOffset + outerHeight - data.collisionHeight;
					} else {
						position.top = withinOffset;
					}
				}
			// too far up -> align with top
			} else if ( overTop > 0 ) {
				position.top += overTop;
			// too far down -> align with bottom edge
			} else if ( overBottom > 0 ) {
				position.top -= overBottom;
			// adjust based on position and margin
			} else {
				position.top = max( position.top - collisionPosTop, position.top );
			}
		}
	},
	flip: {
		left: function( position, data ) {
			var within = data.within,
				withinOffset = within.offset.left + within.scrollLeft,
				outerWidth = within.width,
				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
				overLeft = collisionPosLeft - offsetLeft,
				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
				myOffset = data.my[ 0 ] === "left" ?
					-data.elemWidth :
					data.my[ 0 ] === "right" ?
						data.elemWidth :
						0,
				atOffset = data.at[ 0 ] === "left" ?
					data.targetWidth :
					data.at[ 0 ] === "right" ?
						-data.targetWidth :
						0,
				offset = -2 * data.offset[ 0 ],
				newOverRight,
				newOverLeft;

			if ( overLeft < 0 ) {
				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
					position.left += myOffset + atOffset + offset;
				}
			} else if ( overRight > 0 ) {
				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
					position.left += myOffset + atOffset + offset;
				}
			}
		},
		top: function( position, data ) {
			var within = data.within,
				withinOffset = within.offset.top + within.scrollTop,
				outerHeight = within.height,
				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
				collisionPosTop = position.top - data.collisionPosition.marginTop,
				overTop = collisionPosTop - offsetTop,
				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
				top = data.my[ 1 ] === "top",
				myOffset = top ?
					-data.elemHeight :
					data.my[ 1 ] === "bottom" ?
						data.elemHeight :
						0,
				atOffset = data.at[ 1 ] === "top" ?
					data.targetHeight :
					data.at[ 1 ] === "bottom" ?
						-data.targetHeight :
						0,
				offset = -2 * data.offset[ 1 ],
				newOverTop,
				newOverBottom;
			if ( overTop < 0 ) {
				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
				if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
					position.top += myOffset + atOffset + offset;
				}
			} else if ( overBottom > 0 ) {
				newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
				if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
					position.top += myOffset + atOffset + offset;
				}
			}
		}
	},
	flipfit: {
		left: function() {
			$.ui.position.flip.left.apply( this, arguments );
			$.ui.position.fit.left.apply( this, arguments );
		},
		top: function() {
			$.ui.position.flip.top.apply( this, arguments );
			$.ui.position.fit.top.apply( this, arguments );
		}
	}
};

// fraction support test
(function() {
	var testElement, testElementParent, testElementStyle, offsetLeft, i,
		body = document.getElementsByTagName( "body" )[ 0 ],
		div = document.createElement( "div" );

	//Create a "fake body" for testing based on method used in jQuery.support
	testElement = document.createElement( body ? "div" : "body" );
	testElementStyle = {
		visibility: "hidden",
		width: 0,
		height: 0,
		border: 0,
		margin: 0,
		background: "none"
	};
	if ( body ) {
		$.extend( testElementStyle, {
			position: "absolute",
			left: "-1000px",
			top: "-1000px"
		});
	}
	for ( i in testElementStyle ) {
		testElement.style[ i ] = testElementStyle[ i ];
	}
	testElement.appendChild( div );
	testElementParent = body || document.documentElement;
	testElementParent.insertBefore( testElement, testElementParent.firstChild );

	div.style.cssText = "position: absolute; left: 10.7432222px;";

	offsetLeft = $( div ).offset().left;
	supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11;

	testElement.innerHTML = "";
	testElementParent.removeChild( testElement );
})();

})();

var position = $.ui.position;


/*!
 * jQuery UI Accordion 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/accordion/
 */


var accordion = $.widget( "ui.accordion", {
	version: "1.11.4",
	options: {
		active: 0,
		animate: {},
		collapsible: false,
		event: "click",
		header: "> li > :first-child,> :not(li):even",
		heightStyle: "auto",
		icons: {
			activeHeader: "ui-icon-triangle-1-s",
			header: "ui-icon-triangle-1-e"
		},

		// callbacks
		activate: null,
		beforeActivate: null
	},

	hideProps: {
		borderTopWidth: "hide",
		borderBottomWidth: "hide",
		paddingTop: "hide",
		paddingBottom: "hide",
		height: "hide"
	},

	showProps: {
		borderTopWidth: "show",
		borderBottomWidth: "show",
		paddingTop: "show",
		paddingBottom: "show",
		height: "show"
	},

	_create: function() {
		var options = this.options;
		this.prevShow = this.prevHide = $();
		this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
			// ARIA
			.attr( "role", "tablist" );

		// don't allow collapsible: false and active: false / null
		if ( !options.collapsible && (options.active === false || options.active == null) ) {
			options.active = 0;
		}

		this._processPanels();
		// handle negative values
		if ( options.active < 0 ) {
			options.active += this.headers.length;
		}
		this._refresh();
	},

	_getCreateEventData: function() {
		return {
			header: this.active,
			panel: !this.active.length ? $() : this.active.next()
		};
	},

	_createIcons: function() {
		var icons = this.options.icons;
		if ( icons ) {
			$( "<span>" )
				.addClass( "ui-accordion-header-icon ui-icon " + icons.header )
				.prependTo( this.headers );
			this.active.children( ".ui-accordion-header-icon" )
				.removeClass( icons.header )
				.addClass( icons.activeHeader );
			this.headers.addClass( "ui-accordion-icons" );
		}
	},

	_destroyIcons: function() {
		this.headers
			.removeClass( "ui-accordion-icons" )
			.children( ".ui-accordion-header-icon" )
				.remove();
	},

	_destroy: function() {
		var contents;

		// clean up main element
		this.element
			.removeClass( "ui-accordion ui-widget ui-helper-reset" )
			.removeAttr( "role" );

		// clean up headers
		this.headers
			.removeClass( "ui-accordion-header ui-accordion-header-active ui-state-default " +
				"ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
			.removeAttr( "role" )
			.removeAttr( "aria-expanded" )
			.removeAttr( "aria-selected" )
			.removeAttr( "aria-controls" )
			.removeAttr( "tabIndex" )
			.removeUniqueId();

		this._destroyIcons();

		// clean up content panels
		contents = this.headers.next()
			.removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom " +
				"ui-accordion-content ui-accordion-content-active ui-state-disabled" )
			.css( "display", "" )
			.removeAttr( "role" )
			.removeAttr( "aria-hidden" )
			.removeAttr( "aria-labelledby" )
			.removeUniqueId();

		if ( this.options.heightStyle !== "content" ) {
			contents.css( "height", "" );
		}
	},

	_setOption: function( key, value ) {
		if ( key === "active" ) {
			// _activate() will handle invalid values and update this.options
			this._activate( value );
			return;
		}

		if ( key === "event" ) {
			if ( this.options.event ) {
				this._off( this.headers, this.options.event );
			}
			this._setupEvents( value );
		}

		this._super( key, value );

		// setting collapsible: false while collapsed; open first panel
		if ( key === "collapsible" && !value && this.options.active === false ) {
			this._activate( 0 );
		}

		if ( key === "icons" ) {
			this._destroyIcons();
			if ( value ) {
				this._createIcons();
			}
		}

		// #5332 - opacity doesn't cascade to positioned elements in IE
		// so we need to add the disabled class to the headers and panels
		if ( key === "disabled" ) {
			this.element
				.toggleClass( "ui-state-disabled", !!value )
				.attr( "aria-disabled", value );
			this.headers.add( this.headers.next() )
				.toggleClass( "ui-state-disabled", !!value );
		}
	},

	_keydown: function( event ) {
		if ( event.altKey || event.ctrlKey ) {
			return;
		}

		var keyCode = $.ui.keyCode,
			length = this.headers.length,
			currentIndex = this.headers.index( event.target ),
			toFocus = false;

		switch ( event.keyCode ) {
			case keyCode.RIGHT:
			case keyCode.DOWN:
				toFocus = this.headers[ ( currentIndex + 1 ) % length ];
				break;
			case keyCode.LEFT:
			case keyCode.UP:
				toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
				break;
			case keyCode.SPACE:
			case keyCode.ENTER:
				this._eventHandler( event );
				break;
			case keyCode.HOME:
				toFocus = this.headers[ 0 ];
				break;
			case keyCode.END:
				toFocus = this.headers[ length - 1 ];
				break;
		}

		if ( toFocus ) {
			$( event.target ).attr( "tabIndex", -1 );
			$( toFocus ).attr( "tabIndex", 0 );
			toFocus.focus();
			event.preventDefault();
		}
	},

	_panelKeyDown: function( event ) {
		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
			$( event.currentTarget ).prev().focus();
		}
	},

	refresh: function() {
		var options = this.options;
		this._processPanels();

		// was collapsed or no panel
		if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
			options.active = false;
			this.active = $();
		// active false only when collapsible is true
		} else if ( options.active === false ) {
			this._activate( 0 );
		// was active, but active panel is gone
		} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
			// all remaining panel are disabled
			if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
				options.active = false;
				this.active = $();
			// activate previous panel
			} else {
				this._activate( Math.max( 0, options.active - 1 ) );
			}
		// was active, active panel still exists
		} else {
			// make sure active index is correct
			options.active = this.headers.index( this.active );
		}

		this._destroyIcons();

		this._refresh();
	},

	_processPanels: function() {
		var prevHeaders = this.headers,
			prevPanels = this.panels;

		this.headers = this.element.find( this.options.header )
			.addClass( "ui-accordion-header ui-state-default ui-corner-all" );

		this.panels = this.headers.next()
			.addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
			.filter( ":not(.ui-accordion-content-active)" )
			.hide();

		// Avoid memory leaks (#10056)
		if ( prevPanels ) {
			this._off( prevHeaders.not( this.headers ) );
			this._off( prevPanels.not( this.panels ) );
		}
	},

	_refresh: function() {
		var maxHeight,
			options = this.options,
			heightStyle = options.heightStyle,
			parent = this.element.parent();

		this.active = this._findActive( options.active )
			.addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
			.removeClass( "ui-corner-all" );
		this.active.next()
			.addClass( "ui-accordion-content-active" )
			.show();

		this.headers
			.attr( "role", "tab" )
			.each(function() {
				var header = $( this ),
					headerId = header.uniqueId().attr( "id" ),
					panel = header.next(),
					panelId = panel.uniqueId().attr( "id" );
				header.attr( "aria-controls", panelId );
				panel.attr( "aria-labelledby", headerId );
			})
			.next()
				.attr( "role", "tabpanel" );

		this.headers
			.not( this.active )
			.attr({
				"aria-selected": "false",
				"aria-expanded": "false",
				tabIndex: -1
			})
			.next()
				.attr({
					"aria-hidden": "true"
				})
				.hide();

		// make sure at least one header is in the tab order
		if ( !this.active.length ) {
			this.headers.eq( 0 ).attr( "tabIndex", 0 );
		} else {
			this.active.attr({
				"aria-selected": "true",
				"aria-expanded": "true",
				tabIndex: 0
			})
			.next()
				.attr({
					"aria-hidden": "false"
				});
		}

		this._createIcons();

		this._setupEvents( options.event );

		if ( heightStyle === "fill" ) {
			maxHeight = parent.height();
			this.element.siblings( ":visible" ).each(function() {
				var elem = $( this ),
					position = elem.css( "position" );

				if ( position === "absolute" || position === "fixed" ) {
					return;
				}
				maxHeight -= elem.outerHeight( true );
			});

			this.headers.each(function() {
				maxHeight -= $( this ).outerHeight( true );
			});

			this.headers.next()
				.each(function() {
					$( this ).height( Math.max( 0, maxHeight -
						$( this ).innerHeight() + $( this ).height() ) );
				})
				.css( "overflow", "auto" );
		} else if ( heightStyle === "auto" ) {
			maxHeight = 0;
			this.headers.next()
				.each(function() {
					maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
				})
				.height( maxHeight );
		}
	},

	_activate: function( index ) {
		var active = this._findActive( index )[ 0 ];

		// trying to activate the already active panel
		if ( active === this.active[ 0 ] ) {
			return;
		}

		// trying to collapse, simulate a click on the currently active header
		active = active || this.active[ 0 ];

		this._eventHandler({
			target: active,
			currentTarget: active,
			preventDefault: $.noop
		});
	},

	_findActive: function( selector ) {
		return typeof selector === "number" ? this.headers.eq( selector ) : $();
	},

	_setupEvents: function( event ) {
		var events = {
			keydown: "_keydown"
		};
		if ( event ) {
			$.each( event.split( " " ), function( index, eventName ) {
				events[ eventName ] = "_eventHandler";
			});
		}

		this._off( this.headers.add( this.headers.next() ) );
		this._on( this.headers, events );
		this._on( this.headers.next(), { keydown: "_panelKeyDown" });
		this._hoverable( this.headers );
		this._focusable( this.headers );
	},

	_eventHandler: function( event ) {
		var options = this.options,
			active = this.active,
			clicked = $( event.currentTarget ),
			clickedIsActive = clicked[ 0 ] === active[ 0 ],
			collapsing = clickedIsActive && options.collapsible,
			toShow = collapsing ? $() : clicked.next(),
			toHide = active.next(),
			eventData = {
				oldHeader: active,
				oldPanel: toHide,
				newHeader: collapsing ? $() : clicked,
				newPanel: toShow
			};

		event.preventDefault();

		if (
				// click on active header, but not collapsible
				( clickedIsActive && !options.collapsible ) ||
				// allow canceling activation
				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
			return;
		}

		options.active = collapsing ? false : this.headers.index( clicked );

		// when the call to ._toggle() comes after the class changes
		// it causes a very odd bug in IE 8 (see #6720)
		this.active = clickedIsActive ? $() : clicked;
		this._toggle( eventData );

		// switch classes
		// corner classes on the previously active header stay after the animation
		active.removeClass( "ui-accordion-header-active ui-state-active" );
		if ( options.icons ) {
			active.children( ".ui-accordion-header-icon" )
				.removeClass( options.icons.activeHeader )
				.addClass( options.icons.header );
		}

		if ( !clickedIsActive ) {
			clicked
				.removeClass( "ui-corner-all" )
				.addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
			if ( options.icons ) {
				clicked.children( ".ui-accordion-header-icon" )
					.removeClass( options.icons.header )
					.addClass( options.icons.activeHeader );
			}

			clicked
				.next()
				.addClass( "ui-accordion-content-active" );
		}
	},

	_toggle: function( data ) {
		var toShow = data.newPanel,
			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;

		// handle activating a panel during the animation for another activation
		this.prevShow.add( this.prevHide ).stop( true, true );
		this.prevShow = toShow;
		this.prevHide = toHide;

		if ( this.options.animate ) {
			this._animate( toShow, toHide, data );
		} else {
			toHide.hide();
			toShow.show();
			this._toggleComplete( data );
		}

		toHide.attr({
			"aria-hidden": "true"
		});
		toHide.prev().attr({
			"aria-selected": "false",
			"aria-expanded": "false"
		});
		// if we're switching panels, remove the old header from the tab order
		// if we're opening from collapsed state, remove the previous header from the tab order
		// if we're collapsing, then keep the collapsing header in the tab order
		if ( toShow.length && toHide.length ) {
			toHide.prev().attr({
				"tabIndex": -1,
				"aria-expanded": "false"
			});
		} else if ( toShow.length ) {
			this.headers.filter(function() {
				return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
			})
			.attr( "tabIndex", -1 );
		}

		toShow
			.attr( "aria-hidden", "false" )
			.prev()
				.attr({
					"aria-selected": "true",
					"aria-expanded": "true",
					tabIndex: 0
				});
	},

	_animate: function( toShow, toHide, data ) {
		var total, easing, duration,
			that = this,
			adjust = 0,
			boxSizing = toShow.css( "box-sizing" ),
			down = toShow.length &&
				( !toHide.length || ( toShow.index() < toHide.index() ) ),
			animate = this.options.animate || {},
			options = down && animate.down || animate,
			complete = function() {
				that._toggleComplete( data );
			};

		if ( typeof options === "number" ) {
			duration = options;
		}
		if ( typeof options === "string" ) {
			easing = options;
		}
		// fall back from options to animation in case of partial down settings
		easing = easing || options.easing || animate.easing;
		duration = duration || options.duration || animate.duration;

		if ( !toHide.length ) {
			return toShow.animate( this.showProps, duration, easing, complete );
		}
		if ( !toShow.length ) {
			return toHide.animate( this.hideProps, duration, easing, complete );
		}

		total = toShow.show().outerHeight();
		toHide.animate( this.hideProps, {
			duration: duration,
			easing: easing,
			step: function( now, fx ) {
				fx.now = Math.round( now );
			}
		});
		toShow
			.hide()
			.animate( this.showProps, {
				duration: duration,
				easing: easing,
				complete: complete,
				step: function( now, fx ) {
					fx.now = Math.round( now );
					if ( fx.prop !== "height" ) {
						if ( boxSizing === "content-box" ) {
							adjust += fx.now;
						}
					} else if ( that.options.heightStyle !== "content" ) {
						fx.now = Math.round( total - toHide.outerHeight() - adjust );
						adjust = 0;
					}
				}
			});
	},

	_toggleComplete: function( data ) {
		var toHide = data.oldPanel;

		toHide
			.removeClass( "ui-accordion-content-active" )
			.prev()
				.removeClass( "ui-corner-top" )
				.addClass( "ui-corner-all" );

		// Work around for rendering bug in IE (#5421)
		if ( toHide.length ) {
			toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
		}
		this._trigger( "activate", null, data );
	}
});


/*!
 * jQuery UI Menu 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/menu/
 */


var menu = $.widget( "ui.menu", {
	version: "1.11.4",
	defaultElement: "<ul>",
	delay: 300,
	options: {
		icons: {
			submenu: "ui-icon-carat-1-e"
		},
		items: "> *",
		menus: "ul",
		position: {
			my: "left-1 top",
			at: "right top"
		},
		role: "menu",

		// callbacks
		blur: null,
		focus: null,
		select: null
	},

	_create: function() {
		this.activeMenu = this.element;

		// Flag used to prevent firing of the click handler
		// as the event bubbles up through nested menus
		this.mouseHandled = false;
		this.element
			.uniqueId()
			.addClass( "ui-menu ui-widget ui-widget-content" )
			.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
			.attr({
				role: this.options.role,
				tabIndex: 0
			});

		if ( this.options.disabled ) {
			this.element
				.addClass( "ui-state-disabled" )
				.attr( "aria-disabled", "true" );
		}

		this._on({
			// Prevent focus from sticking to links inside menu after clicking
			// them (focus should always stay on UL during navigation).
			"mousedown .ui-menu-item": function( event ) {
				event.preventDefault();
			},
			"click .ui-menu-item": function( event ) {
				var target = $( event.target );
				if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
					this.select( event );

					// Only set the mouseHandled flag if the event will bubble, see #9469.
					if ( !event.isPropagationStopped() ) {
						this.mouseHandled = true;
					}

					// Open submenu on click
					if ( target.has( ".ui-menu" ).length ) {
						this.expand( event );
					} else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {

						// Redirect focus to the menu
						this.element.trigger( "focus", [ true ] );

						// If the active item is on the top level, let it stay active.
						// Otherwise, blur the active item since it is no longer visible.
						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
							clearTimeout( this.timer );
						}
					}
				}
			},
			"mouseenter .ui-menu-item": function( event ) {
				// Ignore mouse events while typeahead is active, see #10458.
				// Prevents focusing the wrong item when typeahead causes a scroll while the mouse
				// is over an item in the menu
				if ( this.previousFilter ) {
					return;
				}
				var target = $( event.currentTarget );
				// Remove ui-state-active class from siblings of the newly focused menu item
				// to avoid a jump caused by adjacent elements both having a class with a border
				target.siblings( ".ui-state-active" ).removeClass( "ui-state-active" );
				this.focus( event, target );
			},
			mouseleave: "collapseAll",
			"mouseleave .ui-menu": "collapseAll",
			focus: function( event, keepActiveItem ) {
				// If there's already an active item, keep it active
				// If not, activate the first item
				var item = this.active || this.element.find( this.options.items ).eq( 0 );

				if ( !keepActiveItem ) {
					this.focus( event, item );
				}
			},
			blur: function( event ) {
				this._delay(function() {
					if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
						this.collapseAll( event );
					}
				});
			},
			keydown: "_keydown"
		});

		this.refresh();

		// Clicks outside of a menu collapse any open menus
		this._on( this.document, {
			click: function( event ) {
				if ( this._closeOnDocumentClick( event ) ) {
					this.collapseAll( event );
				}

				// Reset the mouseHandled flag
				this.mouseHandled = false;
			}
		});
	},

	_destroy: function() {
		// Destroy (sub)menus
		this.element
			.removeAttr( "aria-activedescendant" )
			.find( ".ui-menu" ).addBack()
				.removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons ui-front" )
				.removeAttr( "role" )
				.removeAttr( "tabIndex" )
				.removeAttr( "aria-labelledby" )
				.removeAttr( "aria-expanded" )
				.removeAttr( "aria-hidden" )
				.removeAttr( "aria-disabled" )
				.removeUniqueId()
				.show();

		// Destroy menu items
		this.element.find( ".ui-menu-item" )
			.removeClass( "ui-menu-item" )
			.removeAttr( "role" )
			.removeAttr( "aria-disabled" )
			.removeUniqueId()
			.removeClass( "ui-state-hover" )
			.removeAttr( "tabIndex" )
			.removeAttr( "role" )
			.removeAttr( "aria-haspopup" )
			.children().each( function() {
				var elem = $( this );
				if ( elem.data( "ui-menu-submenu-carat" ) ) {
					elem.remove();
				}
			});

		// Destroy menu dividers
		this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
	},

	_keydown: function( event ) {
		var match, prev, character, skip,
			preventDefault = true;

		switch ( event.keyCode ) {
		case $.ui.keyCode.PAGE_UP:
			this.previousPage( event );
			break;
		case $.ui.keyCode.PAGE_DOWN:
			this.nextPage( event );
			break;
		case $.ui.keyCode.HOME:
			this._move( "first", "first", event );
			break;
		case $.ui.keyCode.END:
			this._move( "last", "last", event );
			break;
		case $.ui.keyCode.UP:
			this.previous( event );
			break;
		case $.ui.keyCode.DOWN:
			this.next( event );
			break;
		case $.ui.keyCode.LEFT:
			this.collapse( event );
			break;
		case $.ui.keyCode.RIGHT:
			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
				this.expand( event );
			}
			break;
		case $.ui.keyCode.ENTER:
		case $.ui.keyCode.SPACE:
			this._activate( event );
			break;
		case $.ui.keyCode.ESCAPE:
			this.collapse( event );
			break;
		default:
			preventDefault = false;
			prev = this.previousFilter || "";
			character = String.fromCharCode( event.keyCode );
			skip = false;

			clearTimeout( this.filterTimer );

			if ( character === prev ) {
				skip = true;
			} else {
				character = prev + character;
			}

			match = this._filterMenuItems( character );
			match = skip && match.index( this.active.next() ) !== -1 ?
				this.active.nextAll( ".ui-menu-item" ) :
				match;

			// If no matches on the current filter, reset to the last character pressed
			// to move down the menu to the first item that starts with that character
			if ( !match.length ) {
				character = String.fromCharCode( event.keyCode );
				match = this._filterMenuItems( character );
			}

			if ( match.length ) {
				this.focus( event, match );
				this.previousFilter = character;
				this.filterTimer = this._delay(function() {
					delete this.previousFilter;
				}, 1000 );
			} else {
				delete this.previousFilter;
			}
		}

		if ( preventDefault ) {
			event.preventDefault();
		}
	},

	_activate: function( event ) {
		if ( !this.active.is( ".ui-state-disabled" ) ) {
			if ( this.active.is( "[aria-haspopup='true']" ) ) {
				this.expand( event );
			} else {
				this.select( event );
			}
		}
	},

	refresh: function() {
		var menus, items,
			that = this,
			icon = this.options.icons.submenu,
			submenus = this.element.find( this.options.menus );

		this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length );

		// Initialize nested menus
		submenus.filter( ":not(.ui-menu)" )
			.addClass( "ui-menu ui-widget ui-widget-content ui-front" )
			.hide()
			.attr({
				role: this.options.role,
				"aria-hidden": "true",
				"aria-expanded": "false"
			})
			.each(function() {
				var menu = $( this ),
					item = menu.parent(),
					submenuCarat = $( "<span>" )
						.addClass( "ui-menu-icon ui-icon " + icon )
						.data( "ui-menu-submenu-carat", true );

				item
					.attr( "aria-haspopup", "true" )
					.prepend( submenuCarat );
				menu.attr( "aria-labelledby", item.attr( "id" ) );
			});

		menus = submenus.add( this.element );
		items = menus.find( this.options.items );

		// Initialize menu-items containing spaces and/or dashes only as dividers
		items.not( ".ui-menu-item" ).each(function() {
			var item = $( this );
			if ( that._isDivider( item ) ) {
				item.addClass( "ui-widget-content ui-menu-divider" );
			}
		});

		// Don't refresh list items that are already adapted
		items.not( ".ui-menu-item, .ui-menu-divider" )
			.addClass( "ui-menu-item" )
			.uniqueId()
			.attr({
				tabIndex: -1,
				role: this._itemRole()
			});

		// Add aria-disabled attribute to any disabled menu item
		items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );

		// If the active item has been removed, blur the menu
		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
			this.blur();
		}
	},

	_itemRole: function() {
		return {
			menu: "menuitem",
			listbox: "option"
		}[ this.options.role ];
	},

	_setOption: function( key, value ) {
		if ( key === "icons" ) {
			this.element.find( ".ui-menu-icon" )
				.removeClass( this.options.icons.submenu )
				.addClass( value.submenu );
		}
		if ( key === "disabled" ) {
			this.element
				.toggleClass( "ui-state-disabled", !!value )
				.attr( "aria-disabled", value );
		}
		this._super( key, value );
	},

	focus: function( event, item ) {
		var nested, focused;
		this.blur( event, event && event.type === "focus" );

		this._scrollIntoView( item );

		this.active = item.first();
		focused = this.active.addClass( "ui-state-focus" ).removeClass( "ui-state-active" );
		// Only update aria-activedescendant if there's a role
		// otherwise we assume focus is managed elsewhere
		if ( this.options.role ) {
			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
		}

		// Highlight active parent menu item, if any
		this.active
			.parent()
			.closest( ".ui-menu-item" )
			.addClass( "ui-state-active" );

		if ( event && event.type === "keydown" ) {
			this._close();
		} else {
			this.timer = this._delay(function() {
				this._close();
			}, this.delay );
		}

		nested = item.children( ".ui-menu" );
		if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
			this._startOpening(nested);
		}
		this.activeMenu = item.parent();

		this._trigger( "focus", event, { item: item } );
	},

	_scrollIntoView: function( item ) {
		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
		if ( this._hasScroll() ) {
			borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
			paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
			scroll = this.activeMenu.scrollTop();
			elementHeight = this.activeMenu.height();
			itemHeight = item.outerHeight();

			if ( offset < 0 ) {
				this.activeMenu.scrollTop( scroll + offset );
			} else if ( offset + itemHeight > elementHeight ) {
				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
			}
		}
	},

	blur: function( event, fromFocus ) {
		if ( !fromFocus ) {
			clearTimeout( this.timer );
		}

		if ( !this.active ) {
			return;
		}

		this.active.removeClass( "ui-state-focus" );
		this.active = null;

		this._trigger( "blur", event, { item: this.active } );
	},

	_startOpening: function( submenu ) {
		clearTimeout( this.timer );

		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
		// shift in the submenu position when mousing over the carat icon
		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
			return;
		}

		this.timer = this._delay(function() {
			this._close();
			this._open( submenu );
		}, this.delay );
	},

	_open: function( submenu ) {
		var position = $.extend({
			of: this.active
		}, this.options.position );

		clearTimeout( this.timer );
		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
			.hide()
			.attr( "aria-hidden", "true" );

		submenu
			.show()
			.removeAttr( "aria-hidden" )
			.attr( "aria-expanded", "true" )
			.position( position );
	},

	collapseAll: function( event, all ) {
		clearTimeout( this.timer );
		this.timer = this._delay(function() {
			// If we were passed an event, look for the submenu that contains the event
			var currentMenu = all ? this.element :
				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );

			// If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
			if ( !currentMenu.length ) {
				currentMenu = this.element;
			}

			this._close( currentMenu );

			this.blur( event );
			this.activeMenu = currentMenu;
		}, this.delay );
	},

	// With no arguments, closes the currently active menu - if nothing is active
	// it closes all menus.  If passed an argument, it will search for menus BELOW
	_close: function( startMenu ) {
		if ( !startMenu ) {
			startMenu = this.active ? this.active.parent() : this.element;
		}

		startMenu
			.find( ".ui-menu" )
				.hide()
				.attr( "aria-hidden", "true" )
				.attr( "aria-expanded", "false" )
			.end()
			.find( ".ui-state-active" ).not( ".ui-state-focus" )
				.removeClass( "ui-state-active" );
	},

	_closeOnDocumentClick: function( event ) {
		return !$( event.target ).closest( ".ui-menu" ).length;
	},

	_isDivider: function( item ) {

		// Match hyphen, em dash, en dash
		return !/[^\-\u2014\u2013\s]/.test( item.text() );
	},

	collapse: function( event ) {
		var newItem = this.active &&
			this.active.parent().closest( ".ui-menu-item", this.element );
		if ( newItem && newItem.length ) {
			this._close();
			this.focus( event, newItem );
		}
	},

	expand: function( event ) {
		var newItem = this.active &&
			this.active
				.children( ".ui-menu " )
				.find( this.options.items )
				.first();

		if ( newItem && newItem.length ) {
			this._open( newItem.parent() );

			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
			this._delay(function() {
				this.focus( event, newItem );
			});
		}
	},

	next: function( event ) {
		this._move( "next", "first", event );
	},

	previous: function( event ) {
		this._move( "prev", "last", event );
	},

	isFirstItem: function() {
		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
	},

	isLastItem: function() {
		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
	},

	_move: function( direction, filter, event ) {
		var next;
		if ( this.active ) {
			if ( direction === "first" || direction === "last" ) {
				next = this.active
					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
					.eq( -1 );
			} else {
				next = this.active
					[ direction + "All" ]( ".ui-menu-item" )
					.eq( 0 );
			}
		}
		if ( !next || !next.length || !this.active ) {
			next = this.activeMenu.find( this.options.items )[ filter ]();
		}

		this.focus( event, next );
	},

	nextPage: function( event ) {
		var item, base, height;

		if ( !this.active ) {
			this.next( event );
			return;
		}
		if ( this.isLastItem() ) {
			return;
		}
		if ( this._hasScroll() ) {
			base = this.active.offset().top;
			height = this.element.height();
			this.active.nextAll( ".ui-menu-item" ).each(function() {
				item = $( this );
				return item.offset().top - base - height < 0;
			});

			this.focus( event, item );
		} else {
			this.focus( event, this.activeMenu.find( this.options.items )
				[ !this.active ? "first" : "last" ]() );
		}
	},

	previousPage: function( event ) {
		var item, base, height;
		if ( !this.active ) {
			this.next( event );
			return;
		}
		if ( this.isFirstItem() ) {
			return;
		}
		if ( this._hasScroll() ) {
			base = this.active.offset().top;
			height = this.element.height();
			this.active.prevAll( ".ui-menu-item" ).each(function() {
				item = $( this );
				return item.offset().top - base + height > 0;
			});

			this.focus( event, item );
		} else {
			this.focus( event, this.activeMenu.find( this.options.items ).first() );
		}
	},

	_hasScroll: function() {
		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
	},

	select: function( event ) {
		// TODO: It should never be possible to not have an active item at this
		// point, but the tests don't trigger mouseenter before click.
		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
		var ui = { item: this.active };
		if ( !this.active.has( ".ui-menu" ).length ) {
			this.collapseAll( event, true );
		}
		this._trigger( "select", event, ui );
	},

	_filterMenuItems: function(character) {
		var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
			regex = new RegExp( "^" + escapedCharacter, "i" );

		return this.activeMenu
			.find( this.options.items )

			// Only match on items, not dividers or other content (#10571)
			.filter( ".ui-menu-item" )
			.filter(function() {
				return regex.test( $.trim( $( this ).text() ) );
			});
	}
});


/*!
 * jQuery UI Autocomplete 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/autocomplete/
 */


$.widget( "ui.autocomplete", {
	version: "1.11.4",
	defaultElement: "<input>",
	options: {
		appendTo: null,
		autoFocus: false,
		delay: 300,
		minLength: 1,
		position: {
			my: "left top",
			at: "left bottom",
			collision: "none"
		},
		source: null,

		// callbacks
		change: null,
		close: null,
		focus: null,
		open: null,
		response: null,
		search: null,
		select: null
	},

	requestIndex: 0,
	pending: 0,

	_create: function() {
		// Some browsers only repeat keydown events, not keypress events,
		// so we use the suppressKeyPress flag to determine if we've already
		// handled the keydown event. #7269
		// Unfortunately the code for & in keypress is the same as the up arrow,
		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
		// events when we know the keydown event was used to modify the
		// search term. #7799
		var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
			nodeName = this.element[ 0 ].nodeName.toLowerCase(),
			isTextarea = nodeName === "textarea",
			isInput = nodeName === "input";

		this.isMultiLine =
			// Textareas are always multi-line
			isTextarea ? true :
			// Inputs are always single-line, even if inside a contentEditable element
			// IE also treats inputs as contentEditable
			isInput ? false :
			// All other element types are determined by whether or not they're contentEditable
			this.element.prop( "isContentEditable" );

		this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
		this.isNewMenu = true;

		this.element
			.addClass( "ui-autocomplete-input" )
			.attr( "autocomplete", "off" );

		this._on( this.element, {
			keydown: function( event ) {
				if ( this.element.prop( "readOnly" ) ) {
					suppressKeyPress = true;
					suppressInput = true;
					suppressKeyPressRepeat = true;
					return;
				}

				suppressKeyPress = false;
				suppressInput = false;
				suppressKeyPressRepeat = false;
				var keyCode = $.ui.keyCode;
				switch ( event.keyCode ) {
				case keyCode.PAGE_UP:
					suppressKeyPress = true;
					this._move( "previousPage", event );
					break;
				case keyCode.PAGE_DOWN:
					suppressKeyPress = true;
					this._move( "nextPage", event );
					break;
				case keyCode.UP:
					suppressKeyPress = true;
					this._keyEvent( "previous", event );
					break;
				case keyCode.DOWN:
					suppressKeyPress = true;
					this._keyEvent( "next", event );
					break;
				case keyCode.ENTER:
					// when menu is open and has focus
					if ( this.menu.active ) {
						// #6055 - Opera still allows the keypress to occur
						// which causes forms to submit
						suppressKeyPress = true;
						event.preventDefault();
						this.menu.select( event );
					}
					break;
				case keyCode.TAB:
					if ( this.menu.active ) {
						this.menu.select( event );
					}
					break;
				case keyCode.ESCAPE:
					if ( this.menu.element.is( ":visible" ) ) {
						if ( !this.isMultiLine ) {
							this._value( this.term );
						}
						this.close( event );
						// Different browsers have different default behavior for escape
						// Single press can mean undo or clear
						// Double press in IE means clear the whole form
						event.preventDefault();
					}
					break;
				default:
					suppressKeyPressRepeat = true;
					// search timeout should be triggered before the input value is changed
					this._searchTimeout( event );
					break;
				}
			},
			keypress: function( event ) {
				if ( suppressKeyPress ) {
					suppressKeyPress = false;
					if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
						event.preventDefault();
					}
					return;
				}
				if ( suppressKeyPressRepeat ) {
					return;
				}

				// replicate some key handlers to allow them to repeat in Firefox and Opera
				var keyCode = $.ui.keyCode;
				switch ( event.keyCode ) {
				case keyCode.PAGE_UP:
					this._move( "previousPage", event );
					break;
				case keyCode.PAGE_DOWN:
					this._move( "nextPage", event );
					break;
				case keyCode.UP:
					this._keyEvent( "previous", event );
					break;
				case keyCode.DOWN:
					this._keyEvent( "next", event );
					break;
				}
			},
			input: function( event ) {
				if ( suppressInput ) {
					suppressInput = false;
					event.preventDefault();
					return;
				}
				this._searchTimeout( event );
			},
			focus: function() {
				this.selectedItem = null;
				this.previous = this._value();
			},
			blur: function( event ) {
				if ( this.cancelBlur ) {
					delete this.cancelBlur;
					return;
				}

				clearTimeout( this.searching );
				this.close( event );
				this._change( event );
			}
		});

		this._initSource();
		this.menu = $( "<ul>" )
			.addClass( "ui-autocomplete ui-front" )
			.appendTo( this._appendTo() )
			.menu({
				// disable ARIA support, the live region takes care of that
				role: null
			})
			.hide()
			.menu( "instance" );

		this._on( this.menu.element, {
			mousedown: function( event ) {
				// prevent moving focus out of the text field
				event.preventDefault();

				// IE doesn't prevent moving focus even with event.preventDefault()
				// so we set a flag to know when we should ignore the blur event
				this.cancelBlur = true;
				this._delay(function() {
					delete this.cancelBlur;
				});

				// clicking on the scrollbar causes focus to shift to the body
				// but we can't detect a mouseup or a click immediately afterward
				// so we have to track the next mousedown and close the menu if
				// the user clicks somewhere outside of the autocomplete
				var menuElement = this.menu.element[ 0 ];
				if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
					this._delay(function() {
						var that = this;
						this.document.one( "mousedown", function( event ) {
							if ( event.target !== that.element[ 0 ] &&
									event.target !== menuElement &&
									!$.contains( menuElement, event.target ) ) {
								that.close();
							}
						});
					});
				}
			},
			menufocus: function( event, ui ) {
				var label, item;
				// support: Firefox
				// Prevent accidental activation of menu items in Firefox (#7024 #9118)
				if ( this.isNewMenu ) {
					this.isNewMenu = false;
					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
						this.menu.blur();

						this.document.one( "mousemove", function() {
							$( event.target ).trigger( event.originalEvent );
						});

						return;
					}
				}

				item = ui.item.data( "ui-autocomplete-item" );
				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
					// use value to match what will end up in the input, if it was a key event
					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
						this._value( item.value );
					}
				}

				// Announce the value in the liveRegion
				label = ui.item.attr( "aria-label" ) || item.value;
				if ( label && $.trim( label ).length ) {
					this.liveRegion.children().hide();
					$( "<div>" ).text( label ).appendTo( this.liveRegion );
				}
			},
			menuselect: function( event, ui ) {
				var item = ui.item.data( "ui-autocomplete-item" ),
					previous = this.previous;

				// only trigger when focus was lost (click on menu)
				if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) {
					this.element.focus();
					this.previous = previous;
					// #6109 - IE triggers two focus events and the second
					// is asynchronous, so we need to reset the previous
					// term synchronously and asynchronously :-(
					this._delay(function() {
						this.previous = previous;
						this.selectedItem = item;
					});
				}

				if ( false !== this._trigger( "select", event, { item: item } ) ) {
					this._value( item.value );
				}
				// reset the term after the select event
				// this allows custom select handling to work properly
				this.term = this._value();

				this.close( event );
				this.selectedItem = item;
			}
		});

		this.liveRegion = $( "<span>", {
				role: "status",
				"aria-live": "assertive",
				"aria-relevant": "additions"
			})
			.addClass( "ui-helper-hidden-accessible" )
			.appendTo( this.document[ 0 ].body );

		// turning off autocomplete prevents the browser from remembering the
		// value when navigating through history, so we re-enable autocomplete
		// if the page is unloaded before the widget is destroyed. #7790
		this._on( this.window, {
			beforeunload: function() {
				this.element.removeAttr( "autocomplete" );
			}
		});
	},

	_destroy: function() {
		clearTimeout( this.searching );
		this.element
			.removeClass( "ui-autocomplete-input" )
			.removeAttr( "autocomplete" );
		this.menu.element.remove();
		this.liveRegion.remove();
	},

	_setOption: function( key, value ) {
		this._super( key, value );
		if ( key === "source" ) {
			this._initSource();
		}
		if ( key === "appendTo" ) {
			this.menu.element.appendTo( this._appendTo() );
		}
		if ( key === "disabled" && value && this.xhr ) {
			this.xhr.abort();
		}
	},

	_appendTo: function() {
		var element = this.options.appendTo;

		if ( element ) {
			element = element.jquery || element.nodeType ?
				$( element ) :
				this.document.find( element ).eq( 0 );
		}

		if ( !element || !element[ 0 ] ) {
			element = this.element.closest( ".ui-front" );
		}

		if ( !element.length ) {
			element = this.document[ 0 ].body;
		}

		return element;
	},

	_initSource: function() {
		var array, url,
			that = this;
		if ( $.isArray( this.options.source ) ) {
			array = this.options.source;
			this.source = function( request, response ) {
				response( $.ui.autocomplete.filter( array, request.term ) );
			};
		} else if ( typeof this.options.source === "string" ) {
			url = this.options.source;
			this.source = function( request, response ) {
				if ( that.xhr ) {
					that.xhr.abort();
				}
				that.xhr = $.ajax({
					url: url,
					data: request,
					dataType: "json",
					success: function( data ) {
						response( data );
					},
					error: function() {
						response([]);
					}
				});
			};
		} else {
			this.source = this.options.source;
		}
	},

	_searchTimeout: function( event ) {
		clearTimeout( this.searching );
		this.searching = this._delay(function() {

			// Search if the value has changed, or if the user retypes the same value (see #7434)
			var equalValues = this.term === this._value(),
				menuVisible = this.menu.element.is( ":visible" ),
				modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;

			if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
				this.selectedItem = null;
				this.search( null, event );
			}
		}, this.options.delay );
	},

	search: function( value, event ) {
		value = value != null ? value : this._value();

		// always save the actual value, not the one passed as an argument
		this.term = this._value();

		if ( value.length < this.options.minLength ) {
			return this.close( event );
		}

		if ( this._trigger( "search", event ) === false ) {
			return;
		}

		return this._search( value );
	},

	_search: function( value ) {
		this.pending++;
		this.element.addClass( "ui-autocomplete-loading" );
		this.cancelSearch = false;

		this.source( { term: value }, this._response() );
	},

	_response: function() {
		var index = ++this.requestIndex;

		return $.proxy(function( content ) {
			if ( index === this.requestIndex ) {
				this.__response( content );
			}

			this.pending--;
			if ( !this.pending ) {
				this.element.removeClass( "ui-autocomplete-loading" );
			}
		}, this );
	},

	__response: function( content ) {
		if ( content ) {
			content = this._normalize( content );
		}
		this._trigger( "response", null, { content: content } );
		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
			this._suggest( content );
			this._trigger( "open" );
		} else {
			// use ._close() instead of .close() so we don't cancel future searches
			this._close();
		}
	},

	close: function( event ) {
		this.cancelSearch = true;
		this._close( event );
	},

	_close: function( event ) {
		if ( this.menu.element.is( ":visible" ) ) {
			this.menu.element.hide();
			this.menu.blur();
			this.isNewMenu = true;
			this._trigger( "close", event );
		}
	},

	_change: function( event ) {
		if ( this.previous !== this._value() ) {
			this._trigger( "change", event, { item: this.selectedItem } );
		}
	},

	_normalize: function( items ) {
		// assume all items have the right format when the first item is complete
		if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
			return items;
		}
		return $.map( items, function( item ) {
			if ( typeof item === "string" ) {
				return {
					label: item,
					value: item
				};
			}
			return $.extend( {}, item, {
				label: item.label || item.value,
				value: item.value || item.label
			});
		});
	},

	_suggest: function( items ) {
		var ul = this.menu.element.empty();
		this._renderMenu( ul, items );
		this.isNewMenu = true;
		this.menu.refresh();

		// size and position menu
		ul.show();
		this._resizeMenu();
		ul.position( $.extend({
			of: this.element
		}, this.options.position ) );

		if ( this.options.autoFocus ) {
			this.menu.next();
		}
	},

	_resizeMenu: function() {
		var ul = this.menu.element;
		ul.outerWidth( Math.max(
			// Firefox wraps long text (possibly a rounding bug)
			// so we add 1px to avoid the wrapping (#7513)
			ul.width( "" ).outerWidth() + 1,
			this.element.outerWidth()
		) );
	},

	_renderMenu: function( ul, items ) {
		var that = this;
		$.each( items, function( index, item ) {
			that._renderItemData( ul, item );
		});
	},

	_renderItemData: function( ul, item ) {
		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
	},

	_renderItem: function( ul, item ) {
		return $( "<li>" ).text( item.label ).appendTo( ul );
	},

	_move: function( direction, event ) {
		if ( !this.menu.element.is( ":visible" ) ) {
			this.search( null, event );
			return;
		}
		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
				this.menu.isLastItem() && /^next/.test( direction ) ) {

			if ( !this.isMultiLine ) {
				this._value( this.term );
			}

			this.menu.blur();
			return;
		}
		this.menu[ direction ]( event );
	},

	widget: function() {
		return this.menu.element;
	},

	_value: function() {
		return this.valueMethod.apply( this.element, arguments );
	},

	_keyEvent: function( keyEvent, event ) {
		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
			this._move( keyEvent, event );

			// prevents moving cursor to beginning/end of the text field in some browsers
			event.preventDefault();
		}
	}
});

$.extend( $.ui.autocomplete, {
	escapeRegex: function( value ) {
		return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
	},
	filter: function( array, term ) {
		var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
		return $.grep( array, function( value ) {
			return matcher.test( value.label || value.value || value );
		});
	}
});

// live region extension, adding a `messages` option
// NOTE: This is an experimental API. We are still investigating
// a full solution for string manipulation and internationalization.
$.widget( "ui.autocomplete", $.ui.autocomplete, {
	options: {
		messages: {
			noResults: "No search results.",
			results: function( amount ) {
				return amount + ( amount > 1 ? " results are" : " result is" ) +
					" available, use up and down arrow keys to navigate.";
			}
		}
	},

	__response: function( content ) {
		var message;
		this._superApply( arguments );
		if ( this.options.disabled || this.cancelSearch ) {
			return;
		}
		if ( content && content.length ) {
			message = this.options.messages.results( content.length );
		} else {
			message = this.options.messages.noResults;
		}
		this.liveRegion.children().hide();
		$( "<div>" ).text( message ).appendTo( this.liveRegion );
	}
});

var autocomplete = $.ui.autocomplete;


/*!
 * jQuery UI Button 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/button/
 */


var lastActive,
	baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
	typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
	formResetHandler = function() {
		var form = $( this );
		setTimeout(function() {
			form.find( ":ui-button" ).button( "refresh" );
		}, 1 );
	},
	radioGroup = function( radio ) {
		var name = radio.name,
			form = radio.form,
			radios = $( [] );
		if ( name ) {
			name = name.replace( /'/g, "\\'" );
			if ( form ) {
				radios = $( form ).find( "[name='" + name + "'][type=radio]" );
			} else {
				radios = $( "[name='" + name + "'][type=radio]", radio.ownerDocument )
					.filter(function() {
						return !this.form;
					});
			}
		}
		return radios;
	};

$.widget( "ui.button", {
	version: "1.11.4",
	defaultElement: "<button>",
	options: {
		disabled: null,
		text: true,
		label: null,
		icons: {
			primary: null,
			secondary: null
		}
	},
	_create: function() {
		this.element.closest( "form" )
			.unbind( "reset" + this.eventNamespace )
			.bind( "reset" + this.eventNamespace, formResetHandler );

		if ( typeof this.options.disabled !== "boolean" ) {
			this.options.disabled = !!this.element.prop( "disabled" );
		} else {
			this.element.prop( "disabled", this.options.disabled );
		}

		this._determineButtonType();
		this.hasTitle = !!this.buttonElement.attr( "title" );

		var that = this,
			options = this.options,
			toggleButton = this.type === "checkbox" || this.type === "radio",
			activeClass = !toggleButton ? "ui-state-active" : "";

		if ( options.label === null ) {
			options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
		}

		this._hoverable( this.buttonElement );

		this.buttonElement
			.addClass( baseClasses )
			.attr( "role", "button" )
			.bind( "mouseenter" + this.eventNamespace, function() {
				if ( options.disabled ) {
					return;
				}
				if ( this === lastActive ) {
					$( this ).addClass( "ui-state-active" );
				}
			})
			.bind( "mouseleave" + this.eventNamespace, function() {
				if ( options.disabled ) {
					return;
				}
				$( this ).removeClass( activeClass );
			})
			.bind( "click" + this.eventNamespace, function( event ) {
				if ( options.disabled ) {
					event.preventDefault();
					event.stopImmediatePropagation();
				}
			});

		// Can't use _focusable() because the element that receives focus
		// and the element that gets the ui-state-focus class are different
		this._on({
			focus: function() {
				this.buttonElement.addClass( "ui-state-focus" );
			},
			blur: function() {
				this.buttonElement.removeClass( "ui-state-focus" );
			}
		});

		if ( toggleButton ) {
			this.element.bind( "change" + this.eventNamespace, function() {
				that.refresh();
			});
		}

		if ( this.type === "checkbox" ) {
			this.buttonElement.bind( "click" + this.eventNamespace, function() {
				if ( options.disabled ) {
					return false;
				}
			});
		} else if ( this.type === "radio" ) {
			this.buttonElement.bind( "click" + this.eventNamespace, function() {
				if ( options.disabled ) {
					return false;
				}
				$( this ).addClass( "ui-state-active" );
				that.buttonElement.attr( "aria-pressed", "true" );

				var radio = that.element[ 0 ];
				radioGroup( radio )
					.not( radio )
					.map(function() {
						return $( this ).button( "widget" )[ 0 ];
					})
					.removeClass( "ui-state-active" )
					.attr( "aria-pressed", "false" );
			});
		} else {
			this.buttonElement
				.bind( "mousedown" + this.eventNamespace, function() {
					if ( options.disabled ) {
						return false;
					}
					$( this ).addClass( "ui-state-active" );
					lastActive = this;
					that.document.one( "mouseup", function() {
						lastActive = null;
					});
				})
				.bind( "mouseup" + this.eventNamespace, function() {
					if ( options.disabled ) {
						return false;
					}
					$( this ).removeClass( "ui-state-active" );
				})
				.bind( "keydown" + this.eventNamespace, function(event) {
					if ( options.disabled ) {
						return false;
					}
					if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
						$( this ).addClass( "ui-state-active" );
					}
				})
				// see #8559, we bind to blur here in case the button element loses
				// focus between keydown and keyup, it would be left in an "active" state
				.bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
					$( this ).removeClass( "ui-state-active" );
				});

			if ( this.buttonElement.is("a") ) {
				this.buttonElement.keyup(function(event) {
					if ( event.keyCode === $.ui.keyCode.SPACE ) {
						// TODO pass through original event correctly (just as 2nd argument doesn't work)
						$( this ).click();
					}
				});
			}
		}

		this._setOption( "disabled", options.disabled );
		this._resetButton();
	},

	_determineButtonType: function() {
		var ancestor, labelSelector, checked;

		if ( this.element.is("[type=checkbox]") ) {
			this.type = "checkbox";
		} else if ( this.element.is("[type=radio]") ) {
			this.type = "radio";
		} else if ( this.element.is("input") ) {
			this.type = "input";
		} else {
			this.type = "button";
		}

		if ( this.type === "checkbox" || this.type === "radio" ) {
			// we don't search against the document in case the element
			// is disconnected from the DOM
			ancestor = this.element.parents().last();
			labelSelector = "label[for='" + this.element.attr("id") + "']";
			this.buttonElement = ancestor.find( labelSelector );
			if ( !this.buttonElement.length ) {
				ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
				this.buttonElement = ancestor.filter( labelSelector );
				if ( !this.buttonElement.length ) {
					this.buttonElement = ancestor.find( labelSelector );
				}
			}
			this.element.addClass( "ui-helper-hidden-accessible" );

			checked = this.element.is( ":checked" );
			if ( checked ) {
				this.buttonElement.addClass( "ui-state-active" );
			}
			this.buttonElement.prop( "aria-pressed", checked );
		} else {
			this.buttonElement = this.element;
		}
	},

	widget: function() {
		return this.buttonElement;
	},

	_destroy: function() {
		this.element
			.removeClass( "ui-helper-hidden-accessible" );
		this.buttonElement
			.removeClass( baseClasses + " ui-state-active " + typeClasses )
			.removeAttr( "role" )
			.removeAttr( "aria-pressed" )
			.html( this.buttonElement.find(".ui-button-text").html() );

		if ( !this.hasTitle ) {
			this.buttonElement.removeAttr( "title" );
		}
	},

	_setOption: function( key, value ) {
		this._super( key, value );
		if ( key === "disabled" ) {
			this.widget().toggleClass( "ui-state-disabled", !!value );
			this.element.prop( "disabled", !!value );
			if ( value ) {
				if ( this.type === "checkbox" || this.type === "radio" ) {
					this.buttonElement.removeClass( "ui-state-focus" );
				} else {
					this.buttonElement.removeClass( "ui-state-focus ui-state-active" );
				}
			}
			return;
		}
		this._resetButton();
	},

	refresh: function() {
		//See #8237 & #8828
		var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );

		if ( isDisabled !== this.options.disabled ) {
			this._setOption( "disabled", isDisabled );
		}
		if ( this.type === "radio" ) {
			radioGroup( this.element[0] ).each(function() {
				if ( $( this ).is( ":checked" ) ) {
					$( this ).button( "widget" )
						.addClass( "ui-state-active" )
						.attr( "aria-pressed", "true" );
				} else {
					$( this ).button( "widget" )
						.removeClass( "ui-state-active" )
						.attr( "aria-pressed", "false" );
				}
			});
		} else if ( this.type === "checkbox" ) {
			if ( this.element.is( ":checked" ) ) {
				this.buttonElement
					.addClass( "ui-state-active" )
					.attr( "aria-pressed", "true" );
			} else {
				this.buttonElement
					.removeClass( "ui-state-active" )
					.attr( "aria-pressed", "false" );
			}
		}
	},

	_resetButton: function() {
		if ( this.type === "input" ) {
			if ( this.options.label ) {
				this.element.val( this.options.label );
			}
			return;
		}
		var buttonElement = this.buttonElement.removeClass( typeClasses ),
			buttonText = $( "<span></span>", this.document[0] )
				.addClass( "ui-button-text" )
				.html( this.options.label )
				.appendTo( buttonElement.empty() )
				.text(),
			icons = this.options.icons,
			multipleIcons = icons.primary && icons.secondary,
			buttonClasses = [];

		if ( icons.primary || icons.secondary ) {
			if ( this.options.text ) {
				buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
			}

			if ( icons.primary ) {
				buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
			}

			if ( icons.secondary ) {
				buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
			}

			if ( !this.options.text ) {
				buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );

				if ( !this.hasTitle ) {
					buttonElement.attr( "title", $.trim( buttonText ) );
				}
			}
		} else {
			buttonClasses.push( "ui-button-text-only" );
		}
		buttonElement.addClass( buttonClasses.join( " " ) );
	}
});

$.widget( "ui.buttonset", {
	version: "1.11.4",
	options: {
		items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
	},

	_create: function() {
		this.element.addClass( "ui-buttonset" );
	},

	_init: function() {
		this.refresh();
	},

	_setOption: function( key, value ) {
		if ( key === "disabled" ) {
			this.buttons.button( "option", key, value );
		}

		this._super( key, value );
	},

	refresh: function() {
		var rtl = this.element.css( "direction" ) === "rtl",
			allButtons = this.element.find( this.options.items ),
			existingButtons = allButtons.filter( ":ui-button" );

		// Initialize new buttons
		allButtons.not( ":ui-button" ).button();

		// Refresh existing buttons
		existingButtons.button( "refresh" );

		this.buttons = allButtons
			.map(function() {
				return $( this ).button( "widget" )[ 0 ];
			})
				.removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
				.filter( ":first" )
					.addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
				.end()
				.filter( ":last" )
					.addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
				.end()
			.end();
	},

	_destroy: function() {
		this.element.removeClass( "ui-buttonset" );
		this.buttons
			.map(function() {
				return $( this ).button( "widget" )[ 0 ];
			})
				.removeClass( "ui-corner-left ui-corner-right" )
			.end()
			.button( "destroy" );
	}
});

var button = $.ui.button;


/*!
 * jQuery UI Datepicker 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/datepicker/
 */


$.extend($.ui, { datepicker: { version: "1.11.4" } });

var datepicker_instActive;

function datepicker_getZindex( elem ) {
	var position, value;
	while ( elem.length && elem[ 0 ] !== document ) {
		// Ignore z-index if position is set to a value where z-index is ignored by the browser
		// This makes behavior of this function consistent across browsers
		// WebKit always returns auto if the element is positioned
		position = elem.css( "position" );
		if ( position === "absolute" || position === "relative" || position === "fixed" ) {
			// IE returns 0 when zIndex is not specified
			// other browsers return a string
			// we ignore the case of nested elements with an explicit value of 0
			// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
			value = parseInt( elem.css( "zIndex" ), 10 );
			if ( !isNaN( value ) && value !== 0 ) {
				return value;
			}
		}
		elem = elem.parent();
	}

	return 0;
}
/* Date picker manager.
   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
   Settings for (groups of) date pickers are maintained in an instance object,
   allowing multiple different settings on the same page. */

function Datepicker() {
	this._curInst = null; // The current instance in use
	this._keyEvent = false; // If the last event was a key event
	this._disabledInputs = []; // List of date picker inputs that have been disabled
	this._datepickerShowing = false; // True if the popup picker is showing , false if not
	this._inDialog = false; // True if showing within a "dialog", false if not
	this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
	this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
	this._appendClass = "ui-datepicker-append"; // The name of the append marker class
	this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
	this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
	this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
	this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
	this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
	this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
	this.regional = []; // Available regional settings, indexed by language code
	this.regional[""] = { // Default regional settings
		closeText: "Done", // Display text for close link
		prevText: "Prev", // Display text for previous month link
		nextText: "Next", // Display text for next month link
		currentText: "Today", // Display text for current month link
		monthNames: ["January","February","March","April","May","June",
			"July","August","September","October","November","December"], // Names of months for drop-down and formatting
		monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
		dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
		dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
		dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
		weekHeader: "Wk", // Column header for week of the year
		dateFormat: "mm/dd/yy", // See format options on parseDate
		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
		isRTL: false, // True if right-to-left language, false if left-to-right
		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
		yearSuffix: "" // Additional text to append to the year in the month headers
	};
	this._defaults = { // Global defaults for all the date picker instances
		showOn: "focus", // "focus" for popup on focus,
			// "button" for trigger button, or "both" for either
		showAnim: "fadeIn", // Name of jQuery animation for popup
		showOptions: {}, // Options for enhanced animations
		defaultDate: null, // Used when field is blank: actual date,
			// +/-number for offset from today, null for today
		appendText: "", // Display text following the input box, e.g. showing the format
		buttonText: "...", // Text for trigger button
		buttonImage: "", // URL for trigger button image
		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
		hideIfNoPrevNext: false, // True to hide next/previous month links
			// if not applicable, false to just disable them
		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
		gotoCurrent: false, // True if today link goes back to current selection instead
		changeMonth: false, // True if month can be selected directly, false if only prev/next
		changeYear: false, // True if year can be selected directly, false if only prev/next
		yearRange: "c-10:c+10", // Range of years to display in drop-down,
			// either relative to today's year (-nn:+nn), relative to currently displayed year
			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
		showOtherMonths: false, // True to show dates in other months, false to leave blank
		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
		showWeek: false, // True to show week of the year, false to not show it
		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
			// takes a Date and returns the number of the week for it
		shortYearCutoff: "+10", // Short year values < this are in the current century,
			// > this are in the previous century,
			// string value starting with "+" for current year + value
		minDate: null, // The earliest selectable date, or null for no limit
		maxDate: null, // The latest selectable date, or null for no limit
		duration: "fast", // Duration of display/closure
		beforeShowDay: null, // Function that takes a date and returns an array with
			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
		beforeShow: null, // Function that takes an input field and
			// returns a set of custom settings for the date picker
		onSelect: null, // Define a callback function when a date is selected
		onChangeMonthYear: null, // Define a callback function when the month or year is changed
		onClose: null, // Define a callback function when the datepicker is closed
		numberOfMonths: 1, // Number of months to show at a time
		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
		stepMonths: 1, // Number of months to step back/forward
		stepBigMonths: 12, // Number of months to step back/forward for the big links
		altField: "", // Selector for an alternate field to store selected dates into
		altFormat: "", // The date format to use for the alternate field
		constrainInput: true, // The input is constrained by the current date format
		showButtonPanel: false, // True to show button panel, false to not show it
		autoSize: false, // True to size the input for the date format, false to leave as is
		disabled: false // The initial disabled state
	};
	$.extend(this._defaults, this.regional[""]);
	this.regional.en = $.extend( true, {}, this.regional[ "" ]);
	this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
	this.dpDiv = datepicker_bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
}

$.extend(Datepicker.prototype, {
	/* Class name added to elements to indicate already configured with a date picker. */
	markerClassName: "hasDatepicker",

	//Keep track of the maximum number of rows displayed (see #7043)
	maxRows: 4,

	// TODO rename to "widget" when switching to widget factory
	_widgetDatepicker: function() {
		return this.dpDiv;
	},

	/* Override the default settings for all instances of the date picker.
	 * @param  settings  object - the new settings to use as defaults (anonymous object)
	 * @return the manager object
	 */
	setDefaults: function(settings) {
		datepicker_extendRemove(this._defaults, settings || {});
		return this;
	},

	/* Attach the date picker to a jQuery selection.
	 * @param  target	element - the target input field or division or span
	 * @param  settings  object - the new settings to use for this date picker instance (anonymous)
	 */
	_attachDatepicker: function(target, settings) {
		var nodeName, inline, inst;
		nodeName = target.nodeName.toLowerCase();
		inline = (nodeName === "div" || nodeName === "span");
		if (!target.id) {
			this.uuid += 1;
			target.id = "dp" + this.uuid;
		}
		inst = this._newInst($(target), inline);
		inst.settings = $.extend({}, settings || {});
		if (nodeName === "input") {
			this._connectDatepicker(target, inst);
		} else if (inline) {
			this._inlineDatepicker(target, inst);
		}
	},

	/* Create a new instance object. */
	_newInst: function(target, inline) {
		var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
		return {id: id, input: target, // associated target
			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
			drawMonth: 0, drawYear: 0, // month being drawn
			inline: inline, // is datepicker inline or not
			dpDiv: (!inline ? this.dpDiv : // presentation div
			datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
	},

	/* Attach the date picker to an input field. */
	_connectDatepicker: function(target, inst) {
		var input = $(target);
		inst.append = $([]);
		inst.trigger = $([]);
		if (input.hasClass(this.markerClassName)) {
			return;
		}
		this._attachments(input, inst);
		input.addClass(this.markerClassName).keydown(this._doKeyDown).
			keypress(this._doKeyPress).keyup(this._doKeyUp);
		this._autoSize(inst);
		$.data(target, "datepicker", inst);
		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
		if( inst.settings.disabled ) {
			this._disableDatepicker( target );
		}
	},

	/* Make attachments based on settings. */
	_attachments: function(input, inst) {
		var showOn, buttonText, buttonImage,
			appendText = this._get(inst, "appendText"),
			isRTL = this._get(inst, "isRTL");

		if (inst.append) {
			inst.append.remove();
		}
		if (appendText) {
			inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
			input[isRTL ? "before" : "after"](inst.append);
		}

		input.unbind("focus", this._showDatepicker);

		if (inst.trigger) {
			inst.trigger.remove();
		}

		showOn = this._get(inst, "showOn");
		if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
			input.focus(this._showDatepicker);
		}
		if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
			buttonText = this._get(inst, "buttonText");
			buttonImage = this._get(inst, "buttonImage");
			inst.trigger = $(this._get(inst, "buttonImageOnly") ?
				$("<img/>").addClass(this._triggerClass).
					attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
				$("<button type='button'></button>").addClass(this._triggerClass).
					html(!buttonImage ? buttonText : $("<img/>").attr(
					{ src:buttonImage, alt:buttonText, title:buttonText })));
			input[isRTL ? "before" : "after"](inst.trigger);
			inst.trigger.click(function() {
				if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
					$.datepicker._hideDatepicker();
				} else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
					$.datepicker._hideDatepicker();
					$.datepicker._showDatepicker(input[0]);
				} else {
					$.datepicker._showDatepicker(input[0]);
				}
				return false;
			});
		}
	},

	/* Apply the maximum length for the date format. */
	_autoSize: function(inst) {
		if (this._get(inst, "autoSize") && !inst.inline) {
			var findMax, max, maxI, i,
				date = new Date(2009, 12 - 1, 20), // Ensure double digits
				dateFormat = this._get(inst, "dateFormat");

			if (dateFormat.match(/[DM]/)) {
				findMax = function(names) {
					max = 0;
					maxI = 0;
					for (i = 0; i < names.length; i++) {
						if (names[i].length > max) {
							max = names[i].length;
							maxI = i;
						}
					}
					return maxI;
				};
				date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
					"monthNames" : "monthNamesShort"))));
				date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
					"dayNames" : "dayNamesShort"))) + 20 - date.getDay());
			}
			inst.input.attr("size", this._formatDate(inst, date).length);
		}
	},

	/* Attach an inline date picker to a div. */
	_inlineDatepicker: function(target, inst) {
		var divSpan = $(target);
		if (divSpan.hasClass(this.markerClassName)) {
			return;
		}
		divSpan.addClass(this.markerClassName).append(inst.dpDiv);
		$.data(target, "datepicker", inst);
		this._setDate(inst, this._getDefaultDate(inst), true);
		this._updateDatepicker(inst);
		this._updateAlternate(inst);
		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
		if( inst.settings.disabled ) {
			this._disableDatepicker( target );
		}
		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
		// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
		inst.dpDiv.css( "display", "block" );
	},

	/* Pop-up the date picker in a "dialog" box.
	 * @param  input element - ignored
	 * @param  date	string or Date - the initial date to display
	 * @param  onSelect  function - the function to call when a date is selected
	 * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
	 * @param  pos int[2] - coordinates for the dialog's position within the screen or
	 *					event - with x/y coordinates or
	 *					leave empty for default (screen centre)
	 * @return the manager object
	 */
	_dialogDatepicker: function(input, date, onSelect, settings, pos) {
		var id, browserWidth, browserHeight, scrollX, scrollY,
			inst = this._dialogInst; // internal instance

		if (!inst) {
			this.uuid += 1;
			id = "dp" + this.uuid;
			this._dialogInput = $("<input type='text' id='" + id +
				"' style='position: absolute; top: -100px; width: 0px;'/>");
			this._dialogInput.keydown(this._doKeyDown);
			$("body").append(this._dialogInput);
			inst = this._dialogInst = this._newInst(this._dialogInput, false);
			inst.settings = {};
			$.data(this._dialogInput[0], "datepicker", inst);
		}
		datepicker_extendRemove(inst.settings, settings || {});
		date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
		this._dialogInput.val(date);

		this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
		if (!this._pos) {
			browserWidth = document.documentElement.clientWidth;
			browserHeight = document.documentElement.clientHeight;
			scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
			scrollY = document.documentElement.scrollTop || document.body.scrollTop;
			this._pos = // should use actual width/height below
				[(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
		}

		// move input on screen for focus, but hidden behind dialog
		this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
		inst.settings.onSelect = onSelect;
		this._inDialog = true;
		this.dpDiv.addClass(this._dialogClass);
		this._showDatepicker(this._dialogInput[0]);
		if ($.blockUI) {
			$.blockUI(this.dpDiv);
		}
		$.data(this._dialogInput[0], "datepicker", inst);
		return this;
	},

	/* Detach a datepicker from its control.
	 * @param  target	element - the target input field or division or span
	 */
	_destroyDatepicker: function(target) {
		var nodeName,
			$target = $(target),
			inst = $.data(target, "datepicker");

		if (!$target.hasClass(this.markerClassName)) {
			return;
		}

		nodeName = target.nodeName.toLowerCase();
		$.removeData(target, "datepicker");
		if (nodeName === "input") {
			inst.append.remove();
			inst.trigger.remove();
			$target.removeClass(this.markerClassName).
				unbind("focus", this._showDatepicker).
				unbind("keydown", this._doKeyDown).
				unbind("keypress", this._doKeyPress).
				unbind("keyup", this._doKeyUp);
		} else if (nodeName === "div" || nodeName === "span") {
			$target.removeClass(this.markerClassName).empty();
		}

		if ( datepicker_instActive === inst ) {
			datepicker_instActive = null;
		}
	},

	/* Enable the date picker to a jQuery selection.
	 * @param  target	element - the target input field or division or span
	 */
	_enableDatepicker: function(target) {
		var nodeName, inline,
			$target = $(target),
			inst = $.data(target, "datepicker");

		if (!$target.hasClass(this.markerClassName)) {
			return;
		}

		nodeName = target.nodeName.toLowerCase();
		if (nodeName === "input") {
			target.disabled = false;
			inst.trigger.filter("button").
				each(function() { this.disabled = false; }).end().
				filter("img").css({opacity: "1.0", cursor: ""});
		} else if (nodeName === "div" || nodeName === "span") {
			inline = $target.children("." + this._inlineClass);
			inline.children().removeClass("ui-state-disabled");
			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
				prop("disabled", false);
		}
		this._disabledInputs = $.map(this._disabledInputs,
			function(value) { return (value === target ? null : value); }); // delete entry
	},

	/* Disable the date picker to a jQuery selection.
	 * @param  target	element - the target input field or division or span
	 */
	_disableDatepicker: function(target) {
		var nodeName, inline,
			$target = $(target),
			inst = $.data(target, "datepicker");

		if (!$target.hasClass(this.markerClassName)) {
			return;
		}

		nodeName = target.nodeName.toLowerCase();
		if (nodeName === "input") {
			target.disabled = true;
			inst.trigger.filter("button").
				each(function() { this.disabled = true; }).end().
				filter("img").css({opacity: "0.5", cursor: "default"});
		} else if (nodeName === "div" || nodeName === "span") {
			inline = $target.children("." + this._inlineClass);
			inline.children().addClass("ui-state-disabled");
			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
				prop("disabled", true);
		}
		this._disabledInputs = $.map(this._disabledInputs,
			function(value) { return (value === target ? null : value); }); // delete entry
		this._disabledInputs[this._disabledInputs.length] = target;
	},

	/* Is the first field in a jQuery collection disabled as a datepicker?
	 * @param  target	element - the target input field or division or span
	 * @return boolean - true if disabled, false if enabled
	 */
	_isDisabledDatepicker: function(target) {
		if (!target) {
			return false;
		}
		for (var i = 0; i < this._disabledInputs.length; i++) {
			if (this._disabledInputs[i] === target) {
				return true;
			}
		}
		return false;
	},

	/* Retrieve the instance data for the target control.
	 * @param  target  element - the target input field or division or span
	 * @return  object - the associated instance data
	 * @throws  error if a jQuery problem getting data
	 */
	_getInst: function(target) {
		try {
			return $.data(target, "datepicker");
		}
		catch (err) {
			throw "Missing instance data for this datepicker";
		}
	},

	/* Update or retrieve the settings for a date picker attached to an input field or division.
	 * @param  target  element - the target input field or division or span
	 * @param  name	object - the new settings to update or
	 *				string - the name of the setting to change or retrieve,
	 *				when retrieving also "all" for all instance settings or
	 *				"defaults" for all global defaults
	 * @param  value   any - the new value for the setting
	 *				(omit if above is an object or to retrieve a value)
	 */
	_optionDatepicker: function(target, name, value) {
		var settings, date, minDate, maxDate,
			inst = this._getInst(target);

		if (arguments.length === 2 && typeof name === "string") {
			return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
				(inst ? (name === "all" ? $.extend({}, inst.settings) :
				this._get(inst, name)) : null));
		}

		settings = name || {};
		if (typeof name === "string") {
			settings = {};
			settings[name] = value;
		}

		if (inst) {
			if (this._curInst === inst) {
				this._hideDatepicker();
			}

			date = this._getDateDatepicker(target, true);
			minDate = this._getMinMaxDate(inst, "min");
			maxDate = this._getMinMaxDate(inst, "max");
			datepicker_extendRemove(inst.settings, settings);
			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
			if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
				inst.settings.minDate = this._formatDate(inst, minDate);
			}
			if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
				inst.settings.maxDate = this._formatDate(inst, maxDate);
			}
			if ( "disabled" in settings ) {
				if ( settings.disabled ) {
					this._disableDatepicker(target);
				} else {
					this._enableDatepicker(target);
				}
			}
			this._attachments($(target), inst);
			this._autoSize(inst);
			this._setDate(inst, date);
			this._updateAlternate(inst);
			this._updateDatepicker(inst);
		}
	},

	// change method deprecated
	_changeDatepicker: function(target, name, value) {
		this._optionDatepicker(target, name, value);
	},

	/* Redraw the date picker attached to an input field or division.
	 * @param  target  element - the target input field or division or span
	 */
	_refreshDatepicker: function(target) {
		var inst = this._getInst(target);
		if (inst) {
			this._updateDatepicker(inst);
		}
	},

	/* Set the dates for a jQuery selection.
	 * @param  target element - the target input field or division or span
	 * @param  date	Date - the new date
	 */
	_setDateDatepicker: function(target, date) {
		var inst = this._getInst(target);
		if (inst) {
			this._setDate(inst, date);
			this._updateDatepicker(inst);
			this._updateAlternate(inst);
		}
	},

	/* Get the date(s) for the first entry in a jQuery selection.
	 * @param  target element - the target input field or division or span
	 * @param  noDefault boolean - true if no default date is to be used
	 * @return Date - the current date
	 */
	_getDateDatepicker: function(target, noDefault) {
		var inst = this._getInst(target);
		if (inst && !inst.inline) {
			this._setDateFromField(inst, noDefault);
		}
		return (inst ? this._getDate(inst) : null);
	},

	/* Handle keystrokes. */
	_doKeyDown: function(event) {
		var onSelect, dateStr, sel,
			inst = $.datepicker._getInst(event.target),
			handled = true,
			isRTL = inst.dpDiv.is(".ui-datepicker-rtl");

		inst._keyEvent = true;
		if ($.datepicker._datepickerShowing) {
			switch (event.keyCode) {
				case 9: $.datepicker._hideDatepicker();
						handled = false;
						break; // hide on tab out
				case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
									$.datepicker._currentClass + ")", inst.dpDiv);
						if (sel[0]) {
							$.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
						}

						onSelect = $.datepicker._get(inst, "onSelect");
						if (onSelect) {
							dateStr = $.datepicker._formatDate(inst);

							// trigger custom callback
							onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
						} else {
							$.datepicker._hideDatepicker();
						}

						return false; // don't submit the form
				case 27: $.datepicker._hideDatepicker();
						break; // hide on escape
				case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
							-$.datepicker._get(inst, "stepBigMonths") :
							-$.datepicker._get(inst, "stepMonths")), "M");
						break; // previous month/year on page up/+ ctrl
				case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
							+$.datepicker._get(inst, "stepBigMonths") :
							+$.datepicker._get(inst, "stepMonths")), "M");
						break; // next month/year on page down/+ ctrl
				case 35: if (event.ctrlKey || event.metaKey) {
							$.datepicker._clearDate(event.target);
						}
						handled = event.ctrlKey || event.metaKey;
						break; // clear on ctrl or command +end
				case 36: if (event.ctrlKey || event.metaKey) {
							$.datepicker._gotoToday(event.target);
						}
						handled = event.ctrlKey || event.metaKey;
						break; // current on ctrl or command +home
				case 37: if (event.ctrlKey || event.metaKey) {
							$.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
						}
						handled = event.ctrlKey || event.metaKey;
						// -1 day on ctrl or command +left
						if (event.originalEvent.altKey) {
							$.datepicker._adjustDate(event.target, (event.ctrlKey ?
								-$.datepicker._get(inst, "stepBigMonths") :
								-$.datepicker._get(inst, "stepMonths")), "M");
						}
						// next month/year on alt +left on Mac
						break;
				case 38: if (event.ctrlKey || event.metaKey) {
							$.datepicker._adjustDate(event.target, -7, "D");
						}
						handled = event.ctrlKey || event.metaKey;
						break; // -1 week on ctrl or command +up
				case 39: if (event.ctrlKey || event.metaKey) {
							$.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
						}
						handled = event.ctrlKey || event.metaKey;
						// +1 day on ctrl or command +right
						if (event.originalEvent.altKey) {
							$.datepicker._adjustDate(event.target, (event.ctrlKey ?
								+$.datepicker._get(inst, "stepBigMonths") :
								+$.datepicker._get(inst, "stepMonths")), "M");
						}
						// next month/year on alt +right
						break;
				case 40: if (event.ctrlKey || event.metaKey) {
							$.datepicker._adjustDate(event.target, +7, "D");
						}
						handled = event.ctrlKey || event.metaKey;
						break; // +1 week on ctrl or command +down
				default: handled = false;
			}
		} else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
			$.datepicker._showDatepicker(this);
		} else {
			handled = false;
		}

		if (handled) {
			event.preventDefault();
			event.stopPropagation();
		}
	},

	/* Filter entered characters - based on date format. */
	_doKeyPress: function(event) {
		var chars, chr,
			inst = $.datepicker._getInst(event.target);

		if ($.datepicker._get(inst, "constrainInput")) {
			chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
			chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
			return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
		}
	},

	/* Synchronise manual entry and field/alternate field. */
	_doKeyUp: function(event) {
		var date,
			inst = $.datepicker._getInst(event.target);

		if (inst.input.val() !== inst.lastVal) {
			try {
				date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
					(inst.input ? inst.input.val() : null),
					$.datepicker._getFormatConfig(inst));

				if (date) { // only if valid
					$.datepicker._setDateFromField(inst);
					$.datepicker._updateAlternate(inst);
					$.datepicker._updateDatepicker(inst);
				}
			}
			catch (err) {
			}
		}
		return true;
	},

	/* Pop-up the date picker for a given input field.
	 * If false returned from beforeShow event handler do not show.
	 * @param  input  element - the input field attached to the date picker or
	 *					event - if triggered by focus
	 */
	_showDatepicker: function(input) {
		input = input.target || input;
		if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
			input = $("input", input.parentNode)[0];
		}

		if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
			return;
		}

		var inst, beforeShow, beforeShowSettings, isFixed,
			offset, showAnim, duration;

		inst = $.datepicker._getInst(input);
		if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
			$.datepicker._curInst.dpDiv.stop(true, true);
			if ( inst && $.datepicker._datepickerShowing ) {
				$.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
			}
		}

		beforeShow = $.datepicker._get(inst, "beforeShow");
		beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
		if(beforeShowSettings === false){
			return;
		}
		datepicker_extendRemove(inst.settings, beforeShowSettings);

		inst.lastVal = null;
		$.datepicker._lastInput = input;
		$.datepicker._setDateFromField(inst);

		if ($.datepicker._inDialog) { // hide cursor
			input.value = "";
		}
		if (!$.datepicker._pos) { // position below input
			$.datepicker._pos = $.datepicker._findPos(input);
			$.datepicker._pos[1] += input.offsetHeight; // add the height
		}

		isFixed = false;
		$(input).parents().each(function() {
			isFixed |= $(this).css("position") === "fixed";
			return !isFixed;
		});

		offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
		$.datepicker._pos = null;
		//to avoid flashes on Firefox
		inst.dpDiv.empty();
		// determine sizing offscreen
		inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
		$.datepicker._updateDatepicker(inst);
		// fix width for dynamic number of date pickers
		// and adjust position before showing
		offset = $.datepicker._checkOffset(inst, offset, isFixed);
		inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
			"static" : (isFixed ? "fixed" : "absolute")), display: "none",
			left: offset.left + "px", top: offset.top + "px"});

		if (!inst.inline) {
			showAnim = $.datepicker._get(inst, "showAnim");
			duration = $.datepicker._get(inst, "duration");
			inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
			$.datepicker._datepickerShowing = true;

			if ( $.effects && $.effects.effect[ showAnim ] ) {
				inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
			} else {
				inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
			}

			if ( $.datepicker._shouldFocusInput( inst ) ) {
				inst.input.focus();
			}

			$.datepicker._curInst = inst;
		}
	},

	/* Generate the date picker content. */
	_updateDatepicker: function(inst) {
		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
		datepicker_instActive = inst; // for delegate hover events
		inst.dpDiv.empty().append(this._generateHTML(inst));
		this._attachHandlers(inst);

		var origyearshtml,
			numMonths = this._getNumberOfMonths(inst),
			cols = numMonths[1],
			width = 17,
			activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );

		if ( activeCell.length > 0 ) {
			datepicker_handleMouseover.apply( activeCell.get( 0 ) );
		}

		inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
		if (cols > 1) {
			inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
		}
		inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
			"Class"]("ui-datepicker-multi");
		inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
			"Class"]("ui-datepicker-rtl");

		if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
			inst.input.focus();
		}

		// deffered render of the years select (to avoid flashes on Firefox)
		if( inst.yearshtml ){
			origyearshtml = inst.yearshtml;
			setTimeout(function(){
				//assure that inst.yearshtml didn't change.
				if( origyearshtml === inst.yearshtml && inst.yearshtml ){
					inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
				}
				origyearshtml = inst.yearshtml = null;
			}, 0);
		}
	},

	// #6694 - don't focus the input if it's already focused
	// this breaks the change event in IE
	// Support: IE and jQuery <1.9
	_shouldFocusInput: function( inst ) {
		return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
	},

	/* Check positioning to remain on screen. */
	_checkOffset: function(inst, offset, isFixed) {
		var dpWidth = inst.dpDiv.outerWidth(),
			dpHeight = inst.dpDiv.outerHeight(),
			inputWidth = inst.input ? inst.input.outerWidth() : 0,
			inputHeight = inst.input ? inst.input.outerHeight() : 0,
			viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
			viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());

		offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
		offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
		offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;

		// now check if datepicker is showing outside window viewport - move to a better place if so.
		offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
			Math.abs(offset.left + dpWidth - viewWidth) : 0);
		offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
			Math.abs(dpHeight + inputHeight) : 0);

		return offset;
	},

	/* Find an object's position on the screen. */
	_findPos: function(obj) {
		var position,
			inst = this._getInst(obj),
			isRTL = this._get(inst, "isRTL");

		while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
			obj = obj[isRTL ? "previousSibling" : "nextSibling"];
		}

		position = $(obj).offset();
		return [position.left, position.top];
	},

	/* Hide the date picker from view.
	 * @param  input  element - the input field attached to the date picker
	 */
	_hideDatepicker: function(input) {
		var showAnim, duration, postProcess, onClose,
			inst = this._curInst;

		if (!inst || (input && inst !== $.data(input, "datepicker"))) {
			return;
		}

		if (this._datepickerShowing) {
			showAnim = this._get(inst, "showAnim");
			duration = this._get(inst, "duration");
			postProcess = function() {
				$.datepicker._tidyDialog(inst);
			};

			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
				inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
			} else {
				inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
					(showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
			}

			if (!showAnim) {
				postProcess();
			}
			this._datepickerShowing = false;

			onClose = this._get(inst, "onClose");
			if (onClose) {
				onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
			}

			this._lastInput = null;
			if (this._inDialog) {
				this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
				if ($.blockUI) {
					$.unblockUI();
					$("body").append(this.dpDiv);
				}
			}
			this._inDialog = false;
		}
	},

	/* Tidy up after a dialog display. */
	_tidyDialog: function(inst) {
		inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
	},

	/* Close date picker if clicked elsewhere. */
	_checkExternalClick: function(event) {
		if (!$.datepicker._curInst) {
			return;
		}

		var $target = $(event.target),
			inst = $.datepicker._getInst($target[0]);

		if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
				$target.parents("#" + $.datepicker._mainDivId).length === 0 &&
				!$target.hasClass($.datepicker.markerClassName) &&
				!$target.closest("." + $.datepicker._triggerClass).length &&
				$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
			( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
				$.datepicker._hideDatepicker();
		}
	},

	/* Adjust one of the date sub-fields. */
	_adjustDate: function(id, offset, period) {
		var target = $(id),
			inst = this._getInst(target[0]);

		if (this._isDisabledDatepicker(target[0])) {
			return;
		}
		this._adjustInstDate(inst, offset +
			(period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
			period);
		this._updateDatepicker(inst);
	},

	/* Action for current link. */
	_gotoToday: function(id) {
		var date,
			target = $(id),
			inst = this._getInst(target[0]);

		if (this._get(inst, "gotoCurrent") && inst.currentDay) {
			inst.selectedDay = inst.currentDay;
			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
			inst.drawYear = inst.selectedYear = inst.currentYear;
		} else {
			date = new Date();
			inst.selectedDay = date.getDate();
			inst.drawMonth = inst.selectedMonth = date.getMonth();
			inst.drawYear = inst.selectedYear = date.getFullYear();
		}
		this._notifyChange(inst);
		this._adjustDate(target);
	},

	/* Action for selecting a new month/year. */
	_selectMonthYear: function(id, select, period) {
		var target = $(id),
			inst = this._getInst(target[0]);

		inst["selected" + (period === "M" ? "Month" : "Year")] =
		inst["draw" + (period === "M" ? "Month" : "Year")] =
			parseInt(select.options[select.selectedIndex].value,10);

		this._notifyChange(inst);
		this._adjustDate(target);
	},

	/* Action for selecting a day. */
	_selectDay: function(id, month, year, td) {
		var inst,
			target = $(id);

		if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
			return;
		}

		inst = this._getInst(target[0]);
		inst.selectedDay = inst.currentDay = $("a", td).html();
		inst.selectedMonth = inst.currentMonth = month;
		inst.selectedYear = inst.currentYear = year;
		this._selectDate(id, this._formatDate(inst,
			inst.currentDay, inst.currentMonth, inst.currentYear));
	},

	/* Erase the input field and hide the date picker. */
	_clearDate: function(id) {
		var target = $(id);
		this._selectDate(target, "");
	},

	/* Update the input field with the selected date. */
	_selectDate: function(id, dateStr) {
		var onSelect,
			target = $(id),
			inst = this._getInst(target[0]);

		dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
		if (inst.input) {
			inst.input.val(dateStr);
		}
		this._updateAlternate(inst);

		onSelect = this._get(inst, "onSelect");
		if (onSelect) {
			onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
		} else if (inst.input) {
			inst.input.trigger("change"); // fire the change event
		}

		if (inst.inline){
			this._updateDatepicker(inst);
		} else {
			this._hideDatepicker();
			this._lastInput = inst.input[0];
			if (typeof(inst.input[0]) !== "object") {
				inst.input.focus(); // restore focus
			}
			this._lastInput = null;
		}
	},

	/* Update any alternate field to synchronise with the main field. */
	_updateAlternate: function(inst) {
		var altFormat, date, dateStr,
			altField = this._get(inst, "altField");

		if (altField) { // update alternate field too
			altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
			date = this._getDate(inst);
			dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
			$(altField).each(function() { $(this).val(dateStr); });
		}
	},

	/* Set as beforeShowDay function to prevent selection of weekends.
	 * @param  date  Date - the date to customise
	 * @return [boolean, string] - is this date selectable?, what is its CSS class?
	 */
	noWeekends: function(date) {
		var day = date.getDay();
		return [(day > 0 && day < 6), ""];
	},

	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
	 * @param  date  Date - the date to get the week for
	 * @return  number - the number of the week within the year that contains this date
	 */
	iso8601Week: function(date) {
		var time,
			checkDate = new Date(date.getTime());

		// Find Thursday of this week starting on Monday
		checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));

		time = checkDate.getTime();
		checkDate.setMonth(0); // Compare with Jan 1
		checkDate.setDate(1);
		return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
	},

	/* Parse a string value into a date object.
	 * See formatDate below for the possible formats.
	 *
	 * @param  format string - the expected format of the date
	 * @param  value string - the date in the above format
	 * @param  settings Object - attributes include:
	 *					shortYearCutoff  number - the cutoff year for determining the century (optional)
	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
	 *					dayNames		string[7] - names of the days from Sunday (optional)
	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
	 *					monthNames		string[12] - names of the months (optional)
	 * @return  Date - the extracted date value or null if value is blank
	 */
	parseDate: function (format, value, settings) {
		if (format == null || value == null) {
			throw "Invalid arguments";
		}

		value = (typeof value === "object" ? value.toString() : value + "");
		if (value === "") {
			return null;
		}

		var iFormat, dim, extra,
			iValue = 0,
			shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
			shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
				new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
			dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
			dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
			monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
			monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
			year = -1,
			month = -1,
			day = -1,
			doy = -1,
			literal = false,
			date,
			// Check whether a format character is doubled
			lookAhead = function(match) {
				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
				if (matches) {
					iFormat++;
				}
				return matches;
			},
			// Extract a number from the string value
			getNumber = function(match) {
				var isDoubled = lookAhead(match),
					size = (match === "@" ? 14 : (match === "!" ? 20 :
					(match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
					minSize = (match === "y" ? size : 1),
					digits = new RegExp("^\\d{" + minSize + "," + size + "}"),
					num = value.substring(iValue).match(digits);
				if (!num) {
					throw "Missing number at position " + iValue;
				}
				iValue += num[0].length;
				return parseInt(num[0], 10);
			},
			// Extract a name from the string value and convert to an index
			getName = function(match, shortNames, longNames) {
				var index = -1,
					names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
						return [ [k, v] ];
					}).sort(function (a, b) {
						return -(a[1].length - b[1].length);
					});

				$.each(names, function (i, pair) {
					var name = pair[1];
					if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
						index = pair[0];
						iValue += name.length;
						return false;
					}
				});
				if (index !== -1) {
					return index + 1;
				} else {
					throw "Unknown name at position " + iValue;
				}
			},
			// Confirm that a literal character matches the string value
			checkLiteral = function() {
				if (value.charAt(iValue) !== format.charAt(iFormat)) {
					throw "Unexpected literal at position " + iValue;
				}
				iValue++;
			};

		for (iFormat = 0; iFormat < format.length; iFormat++) {
			if (literal) {
				if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
					literal = false;
				} else {
					checkLiteral();
				}
			} else {
				switch (format.charAt(iFormat)) {
					case "d":
						day = getNumber("d");
						break;
					case "D":
						getName("D", dayNamesShort, dayNames);
						break;
					case "o":
						doy = getNumber("o");
						break;
					case "m":
						month = getNumber("m");
						break;
					case "M":
						month = getName("M", monthNamesShort, monthNames);
						break;
					case "y":
						year = getNumber("y");
						break;
					case "@":
						date = new Date(getNumber("@"));
						year = date.getFullYear();
						month = date.getMonth() + 1;
						day = date.getDate();
						break;
					case "!":
						date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
						year = date.getFullYear();
						month = date.getMonth() + 1;
						day = date.getDate();
						break;
					case "'":
						if (lookAhead("'")){
							checkLiteral();
						} else {
							literal = true;
						}
						break;
					default:
						checkLiteral();
				}
			}
		}

		if (iValue < value.length){
			extra = value.substr(iValue);
			if (!/^\s+/.test(extra)) {
				throw "Extra/unparsed characters found in date: " + extra;
			}
		}

		if (year === -1) {
			year = new Date().getFullYear();
		} else if (year < 100) {
			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
				(year <= shortYearCutoff ? 0 : -100);
		}

		if (doy > -1) {
			month = 1;
			day = doy;
			do {
				dim = this._getDaysInMonth(year, month - 1);
				if (day <= dim) {
					break;
				}
				month++;
				day -= dim;
			} while (true);
		}

		date = this._daylightSavingAdjust(new Date(year, month - 1, day));
		if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
			throw "Invalid date"; // E.g. 31/02/00
		}
		return date;
	},

	/* Standard date formats. */
	ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
	COOKIE: "D, dd M yy",
	ISO_8601: "yy-mm-dd",
	RFC_822: "D, d M y",
	RFC_850: "DD, dd-M-y",
	RFC_1036: "D, d M y",
	RFC_1123: "D, d M yy",
	RFC_2822: "D, d M yy",
	RSS: "D, d M y", // RFC 822
	TICKS: "!",
	TIMESTAMP: "@",
	W3C: "yy-mm-dd", // ISO 8601

	_ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
		Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),

	/* Format a date object into a string value.
	 * The format can be combinations of the following:
	 * d  - day of month (no leading zero)
	 * dd - day of month (two digit)
	 * o  - day of year (no leading zeros)
	 * oo - day of year (three digit)
	 * D  - day name short
	 * DD - day name long
	 * m  - month of year (no leading zero)
	 * mm - month of year (two digit)
	 * M  - month name short
	 * MM - month name long
	 * y  - year (two digit)
	 * yy - year (four digit)
	 * @ - Unix timestamp (ms since 01/01/1970)
	 * ! - Windows ticks (100ns since 01/01/0001)
	 * "..." - literal text
	 * '' - single quote
	 *
	 * @param  format string - the desired format of the date
	 * @param  date Date - the date value to format
	 * @param  settings Object - attributes include:
	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
	 *					dayNames		string[7] - names of the days from Sunday (optional)
	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
	 *					monthNames		string[12] - names of the months (optional)
	 * @return  string - the date in the above format
	 */
	formatDate: function (format, date, settings) {
		if (!date) {
			return "";
		}

		var iFormat,
			dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
			dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
			monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
			monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
			// Check whether a format character is doubled
			lookAhead = function(match) {
				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
				if (matches) {
					iFormat++;
				}
				return matches;
			},
			// Format a number, with leading zero if necessary
			formatNumber = function(match, value, len) {
				var num = "" + value;
				if (lookAhead(match)) {
					while (num.length < len) {
						num = "0" + num;
					}
				}
				return num;
			},
			// Format a name, short or long as requested
			formatName = function(match, value, shortNames, longNames) {
				return (lookAhead(match) ? longNames[value] : shortNames[value]);
			},
			output = "",
			literal = false;

		if (date) {
			for (iFormat = 0; iFormat < format.length; iFormat++) {
				if (literal) {
					if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
						literal = false;
					} else {
						output += format.charAt(iFormat);
					}
				} else {
					switch (format.charAt(iFormat)) {
						case "d":
							output += formatNumber("d", date.getDate(), 2);
							break;
						case "D":
							output += formatName("D", date.getDay(), dayNamesShort, dayNames);
							break;
						case "o":
							output += formatNumber("o",
								Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
							break;
						case "m":
							output += formatNumber("m", date.getMonth() + 1, 2);
							break;
						case "M":
							output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
							break;
						case "y":
							output += (lookAhead("y") ? date.getFullYear() :
								(date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
							break;
						case "@":
							output += date.getTime();
							break;
						case "!":
							output += date.getTime() * 10000 + this._ticksTo1970;
							break;
						case "'":
							if (lookAhead("'")) {
								output += "'";
							} else {
								literal = true;
							}
							break;
						default:
							output += format.charAt(iFormat);
					}
				}
			}
		}
		return output;
	},

	/* Extract all possible characters from the date format. */
	_possibleChars: function (format) {
		var iFormat,
			chars = "",
			literal = false,
			// Check whether a format character is doubled
			lookAhead = function(match) {
				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
				if (matches) {
					iFormat++;
				}
				return matches;
			};

		for (iFormat = 0; iFormat < format.length; iFormat++) {
			if (literal) {
				if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
					literal = false;
				} else {
					chars += format.charAt(iFormat);
				}
			} else {
				switch (format.charAt(iFormat)) {
					case "d": case "m": case "y": case "@":
						chars += "0123456789";
						break;
					case "D": case "M":
						return null; // Accept anything
					case "'":
						if (lookAhead("'")) {
							chars += "'";
						} else {
							literal = true;
						}
						break;
					default:
						chars += format.charAt(iFormat);
				}
			}
		}
		return chars;
	},

	/* Get a setting value, defaulting if necessary. */
	_get: function(inst, name) {
		return inst.settings[name] !== undefined ?
			inst.settings[name] : this._defaults[name];
	},

	/* Parse existing date and initialise date picker. */
	_setDateFromField: function(inst, noDefault) {
		if (inst.input.val() === inst.lastVal) {
			return;
		}

		var dateFormat = this._get(inst, "dateFormat"),
			dates = inst.lastVal = inst.input ? inst.input.val() : null,
			defaultDate = this._getDefaultDate(inst),
			date = defaultDate,
			settings = this._getFormatConfig(inst);

		try {
			date = this.parseDate(dateFormat, dates, settings) || defaultDate;
		} catch (event) {
			dates = (noDefault ? "" : dates);
		}
		inst.selectedDay = date.getDate();
		inst.drawMonth = inst.selectedMonth = date.getMonth();
		inst.drawYear = inst.selectedYear = date.getFullYear();
		inst.currentDay = (dates ? date.getDate() : 0);
		inst.currentMonth = (dates ? date.getMonth() : 0);
		inst.currentYear = (dates ? date.getFullYear() : 0);
		this._adjustInstDate(inst);
	},

	/* Retrieve the default date shown on opening. */
	_getDefaultDate: function(inst) {
		return this._restrictMinMax(inst,
			this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
	},

	/* A date may be specified as an exact value or a relative one. */
	_determineDate: function(inst, date, defaultDate) {
		var offsetNumeric = function(offset) {
				var date = new Date();
				date.setDate(date.getDate() + offset);
				return date;
			},
			offsetString = function(offset) {
				try {
					return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
						offset, $.datepicker._getFormatConfig(inst));
				}
				catch (e) {
					// Ignore
				}

				var date = (offset.toLowerCase().match(/^c/) ?
					$.datepicker._getDate(inst) : null) || new Date(),
					year = date.getFullYear(),
					month = date.getMonth(),
					day = date.getDate(),
					pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
					matches = pattern.exec(offset);

				while (matches) {
					switch (matches[2] || "d") {
						case "d" : case "D" :
							day += parseInt(matches[1],10); break;
						case "w" : case "W" :
							day += parseInt(matches[1],10) * 7; break;
						case "m" : case "M" :
							month += parseInt(matches[1],10);
							day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
							break;
						case "y": case "Y" :
							year += parseInt(matches[1],10);
							day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
							break;
					}
					matches = pattern.exec(offset);
				}
				return new Date(year, month, day);
			},
			newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
				(typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));

		newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
		if (newDate) {
			newDate.setHours(0);
			newDate.setMinutes(0);
			newDate.setSeconds(0);
			newDate.setMilliseconds(0);
		}
		return this._daylightSavingAdjust(newDate);
	},

	/* Handle switch to/from daylight saving.
	 * Hours may be non-zero on daylight saving cut-over:
	 * > 12 when midnight changeover, but then cannot generate
	 * midnight datetime, so jump to 1AM, otherwise reset.
	 * @param  date  (Date) the date to check
	 * @return  (Date) the corrected date
	 */
	_daylightSavingAdjust: function(date) {
		if (!date) {
			return null;
		}
		date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
		return date;
	},

	/* Set the date(s) directly. */
	_setDate: function(inst, date, noChange) {
		var clear = !date,
			origMonth = inst.selectedMonth,
			origYear = inst.selectedYear,
			newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));

		inst.selectedDay = inst.currentDay = newDate.getDate();
		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
		if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
			this._notifyChange(inst);
		}
		this._adjustInstDate(inst);
		if (inst.input) {
			inst.input.val(clear ? "" : this._formatDate(inst));
		}
	},

	/* Retrieve the date(s) directly. */
	_getDate: function(inst) {
		var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
			this._daylightSavingAdjust(new Date(
			inst.currentYear, inst.currentMonth, inst.currentDay)));
			return startDate;
	},

	/* Attach the onxxx handlers.  These are declared statically so
	 * they work with static code transformers like Caja.
	 */
	_attachHandlers: function(inst) {
		var stepMonths = this._get(inst, "stepMonths"),
			id = "#" + inst.id.replace( /\\\\/g, "\\" );
		inst.dpDiv.find("[data-handler]").map(function () {
			var handler = {
				prev: function () {
					$.datepicker._adjustDate(id, -stepMonths, "M");
				},
				next: function () {
					$.datepicker._adjustDate(id, +stepMonths, "M");
				},
				hide: function () {
					$.datepicker._hideDatepicker();
				},
				today: function () {
					$.datepicker._gotoToday(id);
				},
				selectDay: function () {
					$.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
					return false;
				},
				selectMonth: function () {
					$.datepicker._selectMonthYear(id, this, "M");
					return false;
				},
				selectYear: function () {
					$.datepicker._selectMonthYear(id, this, "Y");
					return false;
				}
			};
			$(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
		});
	},

	/* Generate the HTML for the current state of the date picker. */
	_generateHTML: function(inst) {
		var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
			controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
			monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
			selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
			cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
			printDate, dRow, tbody, daySettings, otherMonth, unselectable,
			tempDate = new Date(),
			today = this._daylightSavingAdjust(
				new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
			isRTL = this._get(inst, "isRTL"),
			showButtonPanel = this._get(inst, "showButtonPanel"),
			hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
			navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
			numMonths = this._getNumberOfMonths(inst),
			showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
			stepMonths = this._get(inst, "stepMonths"),
			isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
			currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
				new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
			minDate = this._getMinMaxDate(inst, "min"),
			maxDate = this._getMinMaxDate(inst, "max"),
			drawMonth = inst.drawMonth - showCurrentAtPos,
			drawYear = inst.drawYear;

		if (drawMonth < 0) {
			drawMonth += 12;
			drawYear--;
		}
		if (maxDate) {
			maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
				maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
			maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
			while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
				drawMonth--;
				if (drawMonth < 0) {
					drawMonth = 11;
					drawYear--;
				}
			}
		}
		inst.drawMonth = drawMonth;
		inst.drawYear = drawYear;

		prevText = this._get(inst, "prevText");
		prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
			this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
			this._getFormatConfig(inst)));

		prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
			"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
			" title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
			(hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+ prevText +"'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>"));

		nextText = this._get(inst, "nextText");
		nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
			this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
			this._getFormatConfig(inst)));

		next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
			"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
			" title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
			(hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+ nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>"));

		currentText = this._get(inst, "currentText");
		gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
		currentText = (!navigationAsDateFormat ? currentText :
			this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));

		controls = (!inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" +
			this._get(inst, "closeText") + "</button>" : "");

		buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
			(this._isInRange(inst, gotoDate) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" +
			">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";

		firstDay = parseInt(this._get(inst, "firstDay"),10);
		firstDay = (isNaN(firstDay) ? 0 : firstDay);

		showWeek = this._get(inst, "showWeek");
		dayNames = this._get(inst, "dayNames");
		dayNamesMin = this._get(inst, "dayNamesMin");
		monthNames = this._get(inst, "monthNames");
		monthNamesShort = this._get(inst, "monthNamesShort");
		beforeShowDay = this._get(inst, "beforeShowDay");
		showOtherMonths = this._get(inst, "showOtherMonths");
		selectOtherMonths = this._get(inst, "selectOtherMonths");
		defaultDate = this._getDefaultDate(inst);
		html = "";
		dow;
		for (row = 0; row < numMonths[0]; row++) {
			group = "";
			this.maxRows = 4;
			for (col = 0; col < numMonths[1]; col++) {
				selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
				cornerClass = " ui-corner-all";
				calender = "";
				if (isMultiMonth) {
					calender += "<div class='ui-datepicker-group";
					if (numMonths[1] > 1) {
						switch (col) {
							case 0: calender += " ui-datepicker-group-first";
								cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
							case numMonths[1]-1: calender += " ui-datepicker-group-last";
								cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
							default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
						}
					}
					calender += "'>";
				}
				calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
					(/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
					(/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
					this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
					row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
					"</div><table class='ui-datepicker-calendar'><thead>" +
					"<tr>";
				thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
				for (dow = 0; dow < 7; dow++) { // days of the week
					day = (dow + firstDay) % 7;
					thead += "<th scope='col'" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
						"<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
				}
				calender += thead + "</tr></thead><tbody>";
				daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
				if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
					inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
				}
				leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
				curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
				numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
				this.maxRows = numRows;
				printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
				for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
					calender += "<tr>";
					tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
						this._get(inst, "calculateWeek")(printDate) + "</td>");
					for (dow = 0; dow < 7; dow++) { // create date picker days
						daySettings = (beforeShowDay ?
							beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
						otherMonth = (printDate.getMonth() !== drawMonth);
						unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
							(minDate && printDate < minDate) || (maxDate && printDate > maxDate);
						tbody += "<td class='" +
							((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
							(otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
							((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
							(defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
							// or defaultDate is current printedDate and defaultDate is selectedDate
							" " + this._dayOverClass : "") + // highlight selected day
							(unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") +  // highlight unselectable days
							(otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
							(printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
							(printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
							((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
							(unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
							(otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
							(unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
							(printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
							(printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
							(otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
							"' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
						printDate.setDate(printDate.getDate() + 1);
						printDate = this._daylightSavingAdjust(printDate);
					}
					calender += tbody + "</tr>";
				}
				drawMonth++;
				if (drawMonth > 11) {
					drawMonth = 0;
					drawYear++;
				}
				calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
							((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
				group += calender;
			}
			html += group;
		}
		html += buttonPanel;
		inst._keyEvent = false;
		return html;
	},

	/* Generate the month and year header. */
	_generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
			secondary, monthNames, monthNamesShort) {

		var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
			changeMonth = this._get(inst, "changeMonth"),
			changeYear = this._get(inst, "changeYear"),
			showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
			html = "<div class='ui-datepicker-title'>",
			monthHtml = "";

		// month selection
		if (secondary || !changeMonth) {
			monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
		} else {
			inMinYear = (minDate && minDate.getFullYear() === drawYear);
			inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
			monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
			for ( month = 0; month < 12; month++) {
				if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
					monthHtml += "<option value='" + month + "'" +
						(month === drawMonth ? " selected='selected'" : "") +
						">" + monthNamesShort[month] + "</option>";
				}
			}
			monthHtml += "</select>";
		}

		if (!showMonthAfterYear) {
			html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
		}

		// year selection
		if ( !inst.yearshtml ) {
			inst.yearshtml = "";
			if (secondary || !changeYear) {
				html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
			} else {
				// determine range of years to display
				years = this._get(inst, "yearRange").split(":");
				thisYear = new Date().getFullYear();
				determineYear = function(value) {
					var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
						(value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
						parseInt(value, 10)));
					return (isNaN(year) ? thisYear : year);
				};
				year = determineYear(years[0]);
				endYear = Math.max(year, determineYear(years[1] || ""));
				year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
				endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
				inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
				for (; year <= endYear; year++) {
					inst.yearshtml += "<option value='" + year + "'" +
						(year === drawYear ? " selected='selected'" : "") +
						">" + year + "</option>";
				}
				inst.yearshtml += "</select>";

				html += inst.yearshtml;
				inst.yearshtml = null;
			}
		}

		html += this._get(inst, "yearSuffix");
		if (showMonthAfterYear) {
			html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
		}
		html += "</div>"; // Close datepicker_header
		return html;
	},

	/* Adjust one of the date sub-fields. */
	_adjustInstDate: function(inst, offset, period) {
		var year = inst.drawYear + (period === "Y" ? offset : 0),
			month = inst.drawMonth + (period === "M" ? offset : 0),
			day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
			date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));

		inst.selectedDay = date.getDate();
		inst.drawMonth = inst.selectedMonth = date.getMonth();
		inst.drawYear = inst.selectedYear = date.getFullYear();
		if (period === "M" || period === "Y") {
			this._notifyChange(inst);
		}
	},

	/* Ensure a date is within any min/max bounds. */
	_restrictMinMax: function(inst, date) {
		var minDate = this._getMinMaxDate(inst, "min"),
			maxDate = this._getMinMaxDate(inst, "max"),
			newDate = (minDate && date < minDate ? minDate : date);
		return (maxDate && newDate > maxDate ? maxDate : newDate);
	},

	/* Notify change of month/year. */
	_notifyChange: function(inst) {
		var onChange = this._get(inst, "onChangeMonthYear");
		if (onChange) {
			onChange.apply((inst.input ? inst.input[0] : null),
				[inst.selectedYear, inst.selectedMonth + 1, inst]);
		}
	},

	/* Determine the number of months to show. */
	_getNumberOfMonths: function(inst) {
		var numMonths = this._get(inst, "numberOfMonths");
		return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
	},

	/* Determine the current maximum date - ensure no time components are set. */
	_getMinMaxDate: function(inst, minMax) {
		return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
	},

	/* Find the number of days in a given month. */
	_getDaysInMonth: function(year, month) {
		return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
	},

	/* Find the day of the week of the first of a month. */
	_getFirstDayOfMonth: function(year, month) {
		return new Date(year, month, 1).getDay();
	},

	/* Determines if we should allow a "next/prev" month display change. */
	_canAdjustMonth: function(inst, offset, curYear, curMonth) {
		var numMonths = this._getNumberOfMonths(inst),
			date = this._daylightSavingAdjust(new Date(curYear,
			curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));

		if (offset < 0) {
			date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
		}
		return this._isInRange(inst, date);
	},

	/* Is the given date in the accepted range? */
	_isInRange: function(inst, date) {
		var yearSplit, currentYear,
			minDate = this._getMinMaxDate(inst, "min"),
			maxDate = this._getMinMaxDate(inst, "max"),
			minYear = null,
			maxYear = null,
			years = this._get(inst, "yearRange");
			if (years){
				yearSplit = years.split(":");
				currentYear = new Date().getFullYear();
				minYear = parseInt(yearSplit[0], 10);
				maxYear = parseInt(yearSplit[1], 10);
				if ( yearSplit[0].match(/[+\-].*/) ) {
					minYear += currentYear;
				}
				if ( yearSplit[1].match(/[+\-].*/) ) {
					maxYear += currentYear;
				}
			}

		return ((!minDate || date.getTime() >= minDate.getTime()) &&
			(!maxDate || date.getTime() <= maxDate.getTime()) &&
			(!minYear || date.getFullYear() >= minYear) &&
			(!maxYear || date.getFullYear() <= maxYear));
	},

	/* Provide the configuration settings for formatting/parsing. */
	_getFormatConfig: function(inst) {
		var shortYearCutoff = this._get(inst, "shortYearCutoff");
		shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
			new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
		return {shortYearCutoff: shortYearCutoff,
			dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
			monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
	},

	/* Format the given date for display. */
	_formatDate: function(inst, day, month, year) {
		if (!day) {
			inst.currentDay = inst.selectedDay;
			inst.currentMonth = inst.selectedMonth;
			inst.currentYear = inst.selectedYear;
		}
		var date = (day ? (typeof day === "object" ? day :
			this._daylightSavingAdjust(new Date(year, month, day))) :
			this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
		return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
	}
});

/*
 * Bind hover events for datepicker elements.
 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
 */
function datepicker_bindHover(dpDiv) {
	var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
	return dpDiv.delegate(selector, "mouseout", function() {
			$(this).removeClass("ui-state-hover");
			if (this.className.indexOf("ui-datepicker-prev") !== -1) {
				$(this).removeClass("ui-datepicker-prev-hover");
			}
			if (this.className.indexOf("ui-datepicker-next") !== -1) {
				$(this).removeClass("ui-datepicker-next-hover");
			}
		})
		.delegate( selector, "mouseover", datepicker_handleMouseover );
}

function datepicker_handleMouseover() {
	if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) {
		$(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
		$(this).addClass("ui-state-hover");
		if (this.className.indexOf("ui-datepicker-prev") !== -1) {
			$(this).addClass("ui-datepicker-prev-hover");
		}
		if (this.className.indexOf("ui-datepicker-next") !== -1) {
			$(this).addClass("ui-datepicker-next-hover");
		}
	}
}

/* jQuery extend now ignores nulls! */
function datepicker_extendRemove(target, props) {
	$.extend(target, props);
	for (var name in props) {
		if (props[name] == null) {
			target[name] = props[name];
		}
	}
	return target;
}

/* Invoke the datepicker functionality.
   @param  options  string - a command, optionally followed by additional parameters or
					Object - settings for attaching new datepicker functionality
   @return  jQuery object */
$.fn.datepicker = function(options){

	/* Verify an empty collection wasn't passed - Fixes #6976 */
	if ( !this.length ) {
		return this;
	}

	/* Initialise the date picker. */
	if (!$.datepicker.initialized) {
		$(document).mousedown($.datepicker._checkExternalClick);
		$.datepicker.initialized = true;
	}

	/* Append datepicker main container to body if not exist. */
	if ($("#"+$.datepicker._mainDivId).length === 0) {
		$("body").append($.datepicker.dpDiv);
	}

	var otherArgs = Array.prototype.slice.call(arguments, 1);
	if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
		return $.datepicker["_" + options + "Datepicker"].
			apply($.datepicker, [this[0]].concat(otherArgs));
	}
	if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
		return $.datepicker["_" + options + "Datepicker"].
			apply($.datepicker, [this[0]].concat(otherArgs));
	}
	return this.each(function() {
		typeof options === "string" ?
			$.datepicker["_" + options + "Datepicker"].
				apply($.datepicker, [this].concat(otherArgs)) :
			$.datepicker._attachDatepicker(this, options);
	});
};

$.datepicker = new Datepicker(); // singleton instance
$.datepicker.initialized = false;
$.datepicker.uuid = new Date().getTime();
$.datepicker.version = "1.11.4";

var datepicker = $.datepicker;


/*!
 * jQuery UI Draggable 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/draggable/
 */


$.widget("ui.draggable", $.ui.mouse, {
	version: "1.11.4",
	widgetEventPrefix: "drag",
	options: {
		addClasses: true,
		appendTo: "parent",
		axis: false,
		connectToSortable: false,
		containment: false,
		cursor: "auto",
		cursorAt: false,
		grid: false,
		handle: false,
		helper: "original",
		iframeFix: false,
		opacity: false,
		refreshPositions: false,
		revert: false,
		revertDuration: 500,
		scope: "default",
		scroll: true,
		scrollSensitivity: 20,
		scrollSpeed: 20,
		snap: false,
		snapMode: "both",
		snapTolerance: 20,
		stack: false,
		zIndex: false,

		// callbacks
		drag: null,
		start: null,
		stop: null
	},
	_create: function() {

		if ( this.options.helper === "original" ) {
			this._setPositionRelative();
		}
		if (this.options.addClasses){
			this.element.addClass("ui-draggable");
		}
		if (this.options.disabled){
			this.element.addClass("ui-draggable-disabled");
		}
		this._setHandleClassName();

		this._mouseInit();
	},

	_setOption: function( key, value ) {
		this._super( key, value );
		if ( key === "handle" ) {
			this._removeHandleClassName();
			this._setHandleClassName();
		}
	},

	_destroy: function() {
		if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
			this.destroyOnClear = true;
			return;
		}
		this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
		this._removeHandleClassName();
		this._mouseDestroy();
	},

	_mouseCapture: function(event) {
		var o = this.options;

		this._blurActiveElement( event );

		// among others, prevent a drag on a resizable-handle
		if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
			return false;
		}

		//Quit if we're not on a valid handle
		this.handle = this._getHandle(event);
		if (!this.handle) {
			return false;
		}

		this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );

		return true;

	},

	_blockFrames: function( selector ) {
		this.iframeBlocks = this.document.find( selector ).map(function() {
			var iframe = $( this );

			return $( "<div>" )
				.css( "position", "absolute" )
				.appendTo( iframe.parent() )
				.outerWidth( iframe.outerWidth() )
				.outerHeight( iframe.outerHeight() )
				.offset( iframe.offset() )[ 0 ];
		});
	},

	_unblockFrames: function() {
		if ( this.iframeBlocks ) {
			this.iframeBlocks.remove();
			delete this.iframeBlocks;
		}
	},

	_blurActiveElement: function( event ) {
		var document = this.document[ 0 ];

		// Only need to blur if the event occurred on the draggable itself, see #10527
		if ( !this.handleElement.is( event.target ) ) {
			return;
		}

		// support: IE9
		// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
		try {

			// Support: IE9, IE10
			// If the <body> is blurred, IE will switch windows, see #9520
			if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) {

				// Blur any element that currently has focus, see #4261
				$( document.activeElement ).blur();
			}
		} catch ( error ) {}
	},

	_mouseStart: function(event) {

		var o = this.options;

		//Create and append the visible helper
		this.helper = this._createHelper(event);

		this.helper.addClass("ui-draggable-dragging");

		//Cache the helper size
		this._cacheHelperProportions();

		//If ddmanager is used for droppables, set the global draggable
		if ($.ui.ddmanager) {
			$.ui.ddmanager.current = this;
		}

		/*
		 * - Position generation -
		 * This block generates everything position related - it's the core of draggables.
		 */

		//Cache the margins of the original element
		this._cacheMargins();

		//Store the helper's css position
		this.cssPosition = this.helper.css( "position" );
		this.scrollParent = this.helper.scrollParent( true );
		this.offsetParent = this.helper.offsetParent();
		this.hasFixedAncestor = this.helper.parents().filter(function() {
				return $( this ).css( "position" ) === "fixed";
			}).length > 0;

		//The element's absolute position on the page minus margins
		this.positionAbs = this.element.offset();
		this._refreshOffsets( event );

		//Generate the original position
		this.originalPosition = this.position = this._generatePosition( event, false );
		this.originalPageX = event.pageX;
		this.originalPageY = event.pageY;

		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));

		//Set a containment if given in the options
		this._setContainment();

		//Trigger event + callbacks
		if (this._trigger("start", event) === false) {
			this._clear();
			return false;
		}

		//Recache the helper size
		this._cacheHelperProportions();

		//Prepare the droppable offsets
		if ($.ui.ddmanager && !o.dropBehaviour) {
			$.ui.ddmanager.prepareOffsets(this, event);
		}

		// Reset helper's right/bottom css if they're set and set explicit width/height instead
		// as this prevents resizing of elements with right/bottom set (see #7772)
		this._normalizeRightBottom();

		this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position

		//If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
		if ( $.ui.ddmanager ) {
			$.ui.ddmanager.dragStart(this, event);
		}

		return true;
	},

	_refreshOffsets: function( event ) {
		this.offset = {
			top: this.positionAbs.top - this.margins.top,
			left: this.positionAbs.left - this.margins.left,
			scroll: false,
			parent: this._getParentOffset(),
			relative: this._getRelativeOffset()
		};

		this.offset.click = {
			left: event.pageX - this.offset.left,
			top: event.pageY - this.offset.top
		};
	},

	_mouseDrag: function(event, noPropagation) {
		// reset any necessary cached properties (see #5009)
		if ( this.hasFixedAncestor ) {
			this.offset.parent = this._getParentOffset();
		}

		//Compute the helpers position
		this.position = this._generatePosition( event, true );
		this.positionAbs = this._convertPositionTo("absolute");

		//Call plugins and callbacks and use the resulting position if something is returned
		if (!noPropagation) {
			var ui = this._uiHash();
			if (this._trigger("drag", event, ui) === false) {
				this._mouseUp({});
				return false;
			}
			this.position = ui.position;
		}

		this.helper[ 0 ].style.left = this.position.left + "px";
		this.helper[ 0 ].style.top = this.position.top + "px";

		if ($.ui.ddmanager) {
			$.ui.ddmanager.drag(this, event);
		}

		return false;
	},

	_mouseStop: function(event) {

		//If we are using droppables, inform the manager about the drop
		var that = this,
			dropped = false;
		if ($.ui.ddmanager && !this.options.dropBehaviour) {
			dropped = $.ui.ddmanager.drop(this, event);
		}

		//if a drop comes from outside (a sortable)
		if (this.dropped) {
			dropped = this.dropped;
			this.dropped = false;
		}

		if ((this.options.revert === "invalid" && !dropped) || (this.options.revert === "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
			$(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
				if (that._trigger("stop", event) !== false) {
					that._clear();
				}
			});
		} else {
			if (this._trigger("stop", event) !== false) {
				this._clear();
			}
		}

		return false;
	},

	_mouseUp: function( event ) {
		this._unblockFrames();

		//If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
		if ( $.ui.ddmanager ) {
			$.ui.ddmanager.dragStop(this, event);
		}

		// Only need to focus if the event occurred on the draggable itself, see #10527
		if ( this.handleElement.is( event.target ) ) {
			// The interaction is over; whether or not the click resulted in a drag, focus the element
			this.element.focus();
		}

		return $.ui.mouse.prototype._mouseUp.call(this, event);
	},

	cancel: function() {

		if (this.helper.is(".ui-draggable-dragging")) {
			this._mouseUp({});
		} else {
			this._clear();
		}

		return this;

	},

	_getHandle: function(event) {
		return this.options.handle ?
			!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
			true;
	},

	_setHandleClassName: function() {
		this.handleElement = this.options.handle ?
			this.element.find( this.options.handle ) : this.element;
		this.handleElement.addClass( "ui-draggable-handle" );
	},

	_removeHandleClassName: function() {
		this.handleElement.removeClass( "ui-draggable-handle" );
	},

	_createHelper: function(event) {

		var o = this.options,
			helperIsFunction = $.isFunction( o.helper ),
			helper = helperIsFunction ?
				$( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
				( o.helper === "clone" ?
					this.element.clone().removeAttr( "id" ) :
					this.element );

		if (!helper.parents("body").length) {
			helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
		}

		// http://bugs.jqueryui.com/ticket/9446
		// a helper function can return the original element
		// which wouldn't have been set to relative in _create
		if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
			this._setPositionRelative();
		}

		if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
			helper.css("position", "absolute");
		}

		return helper;

	},

	_setPositionRelative: function() {
		if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
			this.element[ 0 ].style.position = "relative";
		}
	},

	_adjustOffsetFromHelper: function(obj) {
		if (typeof obj === "string") {
			obj = obj.split(" ");
		}
		if ($.isArray(obj)) {
			obj = { left: +obj[0], top: +obj[1] || 0 };
		}
		if ("left" in obj) {
			this.offset.click.left = obj.left + this.margins.left;
		}
		if ("right" in obj) {
			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
		}
		if ("top" in obj) {
			this.offset.click.top = obj.top + this.margins.top;
		}
		if ("bottom" in obj) {
			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
		}
	},

	_isRootNode: function( element ) {
		return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
	},

	_getParentOffset: function() {

		//Get the offsetParent and cache its position
		var po = this.offsetParent.offset(),
			document = this.document[ 0 ];

		// This is a special case where we need to modify a offset calculated on start, since the following happened:
		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
		if (this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
			po.left += this.scrollParent.scrollLeft();
			po.top += this.scrollParent.scrollTop();
		}

		if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
			po = { top: 0, left: 0 };
		}

		return {
			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0),
			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0)
		};

	},

	_getRelativeOffset: function() {
		if ( this.cssPosition !== "relative" ) {
			return { top: 0, left: 0 };
		}

		var p = this.element.position(),
			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );

		return {
			top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
			left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
		};

	},

	_cacheMargins: function() {
		this.margins = {
			left: (parseInt(this.element.css("marginLeft"), 10) || 0),
			top: (parseInt(this.element.css("marginTop"), 10) || 0),
			right: (parseInt(this.element.css("marginRight"), 10) || 0),
			bottom: (parseInt(this.element.css("marginBottom"), 10) || 0)
		};
	},

	_cacheHelperProportions: function() {
		this.helperProportions = {
			width: this.helper.outerWidth(),
			height: this.helper.outerHeight()
		};
	},

	_setContainment: function() {

		var isUserScrollable, c, ce,
			o = this.options,
			document = this.document[ 0 ];

		this.relativeContainer = null;

		if ( !o.containment ) {
			this.containment = null;
			return;
		}

		if ( o.containment === "window" ) {
			this.containment = [
				$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
				$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
				$( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
				$( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
			];
			return;
		}

		if ( o.containment === "document") {
			this.containment = [
				0,
				0,
				$( document ).width() - this.helperProportions.width - this.margins.left,
				( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
			];
			return;
		}

		if ( o.containment.constructor === Array ) {
			this.containment = o.containment;
			return;
		}

		if ( o.containment === "parent" ) {
			o.containment = this.helper[ 0 ].parentNode;
		}

		c = $( o.containment );
		ce = c[ 0 ];

		if ( !ce ) {
			return;
		}

		isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );

		this.containment = [
			( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
			( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
			( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
				( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
				( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
				this.helperProportions.width -
				this.margins.left -
				this.margins.right,
			( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
				( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
				( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
				this.helperProportions.height -
				this.margins.top -
				this.margins.bottom
		];
		this.relativeContainer = c;
	},

	_convertPositionTo: function(d, pos) {

		if (!pos) {
			pos = this.position;
		}

		var mod = d === "absolute" ? 1 : -1,
			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );

		return {
			top: (
				pos.top	+																// The absolute mouse position
				this.offset.relative.top * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
				this.offset.parent.top * mod -										// The offsetParent's offset without borders (offset + border)
				( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod)
			),
			left: (
				pos.left +																// The absolute mouse position
				this.offset.relative.left * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
				this.offset.parent.left * mod	-										// The offsetParent's offset without borders (offset + border)
				( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod)
			)
		};

	},

	_generatePosition: function( event, constrainPosition ) {

		var containment, co, top, left,
			o = this.options,
			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
			pageX = event.pageX,
			pageY = event.pageY;

		// Cache the scroll
		if ( !scrollIsRootNode || !this.offset.scroll ) {
			this.offset.scroll = {
				top: this.scrollParent.scrollTop(),
				left: this.scrollParent.scrollLeft()
			};
		}

		/*
		 * - Position constraining -
		 * Constrain the position to a mix of grid, containment.
		 */

		// If we are not dragging yet, we won't check for options
		if ( constrainPosition ) {
			if ( this.containment ) {
				if ( this.relativeContainer ){
					co = this.relativeContainer.offset();
					containment = [
						this.containment[ 0 ] + co.left,
						this.containment[ 1 ] + co.top,
						this.containment[ 2 ] + co.left,
						this.containment[ 3 ] + co.top
					];
				} else {
					containment = this.containment;
				}

				if (event.pageX - this.offset.click.left < containment[0]) {
					pageX = containment[0] + this.offset.click.left;
				}
				if (event.pageY - this.offset.click.top < containment[1]) {
					pageY = containment[1] + this.offset.click.top;
				}
				if (event.pageX - this.offset.click.left > containment[2]) {
					pageX = containment[2] + this.offset.click.left;
				}
				if (event.pageY - this.offset.click.top > containment[3]) {
					pageY = containment[3] + this.offset.click.top;
				}
			}

			if (o.grid) {
				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
				top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
				pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;

				left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
				pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
			}

			if ( o.axis === "y" ) {
				pageX = this.originalPageX;
			}

			if ( o.axis === "x" ) {
				pageY = this.originalPageY;
			}
		}

		return {
			top: (
				pageY -																	// The absolute mouse position
				this.offset.click.top	-												// Click offset (relative to the element)
				this.offset.relative.top -												// Only for relative positioned nodes: Relative offset from element to offset parent
				this.offset.parent.top +												// The offsetParent's offset without borders (offset + border)
				( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
			),
			left: (
				pageX -																	// The absolute mouse position
				this.offset.click.left -												// Click offset (relative to the element)
				this.offset.relative.left -												// Only for relative positioned nodes: Relative offset from element to offset parent
				this.offset.parent.left +												// The offsetParent's offset without borders (offset + border)
				( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
			)
		};

	},

	_clear: function() {
		this.helper.removeClass("ui-draggable-dragging");
		if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
			this.helper.remove();
		}
		this.helper = null;
		this.cancelHelperRemoval = false;
		if ( this.destroyOnClear ) {
			this.destroy();
		}
	},

	_normalizeRightBottom: function() {
		if ( this.options.axis !== "y" && this.helper.css( "right" ) !== "auto" ) {
			this.helper.width( this.helper.width() );
			this.helper.css( "right", "auto" );
		}
		if ( this.options.axis !== "x" && this.helper.css( "bottom" ) !== "auto" ) {
			this.helper.height( this.helper.height() );
			this.helper.css( "bottom", "auto" );
		}
	},

	// From now on bulk stuff - mainly helpers

	_trigger: function( type, event, ui ) {
		ui = ui || this._uiHash();
		$.ui.plugin.call( this, type, [ event, ui, this ], true );

		// Absolute position and offset (see #6884 ) have to be recalculated after plugins
		if ( /^(drag|start|stop)/.test( type ) ) {
			this.positionAbs = this._convertPositionTo( "absolute" );
			ui.offset = this.positionAbs;
		}
		return $.Widget.prototype._trigger.call( this, type, event, ui );
	},

	plugins: {},

	_uiHash: function() {
		return {
			helper: this.helper,
			position: this.position,
			originalPosition: this.originalPosition,
			offset: this.positionAbs
		};
	}

});

$.ui.plugin.add( "draggable", "connectToSortable", {
	start: function( event, ui, draggable ) {
		var uiSortable = $.extend( {}, ui, {
			item: draggable.element
		});

		draggable.sortables = [];
		$( draggable.options.connectToSortable ).each(function() {
			var sortable = $( this ).sortable( "instance" );

			if ( sortable && !sortable.options.disabled ) {
				draggable.sortables.push( sortable );

				// refreshPositions is called at drag start to refresh the containerCache
				// which is used in drag. This ensures it's initialized and synchronized
				// with any changes that might have happened on the page since initialization.
				sortable.refreshPositions();
				sortable._trigger("activate", event, uiSortable);
			}
		});
	},
	stop: function( event, ui, draggable ) {
		var uiSortable = $.extend( {}, ui, {
			item: draggable.element
		});

		draggable.cancelHelperRemoval = false;

		$.each( draggable.sortables, function() {
			var sortable = this;

			if ( sortable.isOver ) {
				sortable.isOver = 0;

				// Allow this sortable to handle removing the helper
				draggable.cancelHelperRemoval = true;
				sortable.cancelHelperRemoval = false;

				// Use _storedCSS To restore properties in the sortable,
				// as this also handles revert (#9675) since the draggable
				// may have modified them in unexpected ways (#8809)
				sortable._storedCSS = {
					position: sortable.placeholder.css( "position" ),
					top: sortable.placeholder.css( "top" ),
					left: sortable.placeholder.css( "left" )
				};

				sortable._mouseStop(event);

				// Once drag has ended, the sortable should return to using
				// its original helper, not the shared helper from draggable
				sortable.options.helper = sortable.options._helper;
			} else {
				// Prevent this Sortable from removing the helper.
				// However, don't set the draggable to remove the helper
				// either as another connected Sortable may yet handle the removal.
				sortable.cancelHelperRemoval = true;

				sortable._trigger( "deactivate", event, uiSortable );
			}
		});
	},
	drag: function( event, ui, draggable ) {
		$.each( draggable.sortables, function() {
			var innermostIntersecting = false,
				sortable = this;

			// Copy over variables that sortable's _intersectsWith uses
			sortable.positionAbs = draggable.positionAbs;
			sortable.helperProportions = draggable.helperProportions;
			sortable.offset.click = draggable.offset.click;

			if ( sortable._intersectsWith( sortable.containerCache ) ) {
				innermostIntersecting = true;

				$.each( draggable.sortables, function() {
					// Copy over variables that sortable's _intersectsWith uses
					this.positionAbs = draggable.positionAbs;
					this.helperProportions = draggable.helperProportions;
					this.offset.click = draggable.offset.click;

					if ( this !== sortable &&
							this._intersectsWith( this.containerCache ) &&
							$.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
						innermostIntersecting = false;
					}

					return innermostIntersecting;
				});
			}

			if ( innermostIntersecting ) {
				// If it intersects, we use a little isOver variable and set it once,
				// so that the move-in stuff gets fired only once.
				if ( !sortable.isOver ) {
					sortable.isOver = 1;

					// Store draggable's parent in case we need to reappend to it later.
					draggable._parent = ui.helper.parent();

					sortable.currentItem = ui.helper
						.appendTo( sortable.element )
						.data( "ui-sortable-item", true );

					// Store helper option to later restore it
					sortable.options._helper = sortable.options.helper;

					sortable.options.helper = function() {
						return ui.helper[ 0 ];
					};

					// Fire the start events of the sortable with our passed browser event,
					// and our own helper (so it doesn't create a new one)
					event.target = sortable.currentItem[ 0 ];
					sortable._mouseCapture( event, true );
					sortable._mouseStart( event, true, true );

					// Because the browser event is way off the new appended portlet,
					// modify necessary variables to reflect the changes
					sortable.offset.click.top = draggable.offset.click.top;
					sortable.offset.click.left = draggable.offset.click.left;
					sortable.offset.parent.left -= draggable.offset.parent.left -
						sortable.offset.parent.left;
					sortable.offset.parent.top -= draggable.offset.parent.top -
						sortable.offset.parent.top;

					draggable._trigger( "toSortable", event );

					// Inform draggable that the helper is in a valid drop zone,
					// used solely in the revert option to handle "valid/invalid".
					draggable.dropped = sortable.element;

					// Need to refreshPositions of all sortables in the case that
					// adding to one sortable changes the location of the other sortables (#9675)
					$.each( draggable.sortables, function() {
						this.refreshPositions();
					});

					// hack so receive/update callbacks work (mostly)
					draggable.currentItem = draggable.element;
					sortable.fromOutside = draggable;
				}

				if ( sortable.currentItem ) {
					sortable._mouseDrag( event );
					// Copy the sortable's position because the draggable's can potentially reflect
					// a relative position, while sortable is always absolute, which the dragged
					// element has now become. (#8809)
					ui.position = sortable.position;
				}
			} else {
				// If it doesn't intersect with the sortable, and it intersected before,
				// we fake the drag stop of the sortable, but make sure it doesn't remove
				// the helper by using cancelHelperRemoval.
				if ( sortable.isOver ) {

					sortable.isOver = 0;
					sortable.cancelHelperRemoval = true;

					// Calling sortable's mouseStop would trigger a revert,
					// so revert must be temporarily false until after mouseStop is called.
					sortable.options._revert = sortable.options.revert;
					sortable.options.revert = false;

					sortable._trigger( "out", event, sortable._uiHash( sortable ) );
					sortable._mouseStop( event, true );

					// restore sortable behaviors that were modfied
					// when the draggable entered the sortable area (#9481)
					sortable.options.revert = sortable.options._revert;
					sortable.options.helper = sortable.options._helper;

					if ( sortable.placeholder ) {
						sortable.placeholder.remove();
					}

					// Restore and recalculate the draggable's offset considering the sortable
					// may have modified them in unexpected ways. (#8809, #10669)
					ui.helper.appendTo( draggable._parent );
					draggable._refreshOffsets( event );
					ui.position = draggable._generatePosition( event, true );

					draggable._trigger( "fromSortable", event );

					// Inform draggable that the helper is no longer in a valid drop zone
					draggable.dropped = false;

					// Need to refreshPositions of all sortables just in case removing
					// from one sortable changes the location of other sortables (#9675)
					$.each( draggable.sortables, function() {
						this.refreshPositions();
					});
				}
			}
		});
	}
});

$.ui.plugin.add("draggable", "cursor", {
	start: function( event, ui, instance ) {
		var t = $( "body" ),
			o = instance.options;

		if (t.css("cursor")) {
			o._cursor = t.css("cursor");
		}
		t.css("cursor", o.cursor);
	},
	stop: function( event, ui, instance ) {
		var o = instance.options;
		if (o._cursor) {
			$("body").css("cursor", o._cursor);
		}
	}
});

$.ui.plugin.add("draggable", "opacity", {
	start: function( event, ui, instance ) {
		var t = $( ui.helper ),
			o = instance.options;
		if (t.css("opacity")) {
			o._opacity = t.css("opacity");
		}
		t.css("opacity", o.opacity);
	},
	stop: function( event, ui, instance ) {
		var o = instance.options;
		if (o._opacity) {
			$(ui.helper).css("opacity", o._opacity);
		}
	}
});

$.ui.plugin.add("draggable", "scroll", {
	start: function( event, ui, i ) {
		if ( !i.scrollParentNotHidden ) {
			i.scrollParentNotHidden = i.helper.scrollParent( false );
		}

		if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
			i.overflowOffset = i.scrollParentNotHidden.offset();
		}
	},
	drag: function( event, ui, i  ) {

		var o = i.options,
			scrolled = false,
			scrollParent = i.scrollParentNotHidden[ 0 ],
			document = i.document[ 0 ];

		if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
			if ( !o.axis || o.axis !== "x" ) {
				if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) {
					scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
				} else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
					scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
				}
			}

			if ( !o.axis || o.axis !== "y" ) {
				if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) {
					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
				} else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
				}
			}

		} else {

			if (!o.axis || o.axis !== "x") {
				if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
				} else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
				}
			}

			if (!o.axis || o.axis !== "y") {
				if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
				} else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
				}
			}

		}

		if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
			$.ui.ddmanager.prepareOffsets(i, event);
		}

	}
});

$.ui.plugin.add("draggable", "snap", {
	start: function( event, ui, i ) {

		var o = i.options;

		i.snapElements = [];

		$(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
			var $t = $(this),
				$o = $t.offset();
			if (this !== i.element[0]) {
				i.snapElements.push({
					item: this,
					width: $t.outerWidth(), height: $t.outerHeight(),
					top: $o.top, left: $o.left
				});
			}
		});

	},
	drag: function( event, ui, inst ) {

		var ts, bs, ls, rs, l, r, t, b, i, first,
			o = inst.options,
			d = o.snapTolerance,
			x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;

		for (i = inst.snapElements.length - 1; i >= 0; i--){

			l = inst.snapElements[i].left - inst.margins.left;
			r = l + inst.snapElements[i].width;
			t = inst.snapElements[i].top - inst.margins.top;
			b = t + inst.snapElements[i].height;

			if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
				if (inst.snapElements[i].snapping) {
					(inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
				}
				inst.snapElements[i].snapping = false;
				continue;
			}

			if (o.snapMode !== "inner") {
				ts = Math.abs(t - y2) <= d;
				bs = Math.abs(b - y1) <= d;
				ls = Math.abs(l - x2) <= d;
				rs = Math.abs(r - x1) <= d;
				if (ts) {
					ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top;
				}
				if (bs) {
					ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top;
				}
				if (ls) {
					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left;
				}
				if (rs) {
					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left;
				}
			}

			first = (ts || bs || ls || rs);

			if (o.snapMode !== "outer") {
				ts = Math.abs(t - y1) <= d;
				bs = Math.abs(b - y2) <= d;
				ls = Math.abs(l - x1) <= d;
				rs = Math.abs(r - x2) <= d;
				if (ts) {
					ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top;
				}
				if (bs) {
					ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top;
				}
				if (ls) {
					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left;
				}
				if (rs) {
					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left;
				}
			}

			if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
				(inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
			}
			inst.snapElements[i].snapping = (ts || bs || ls || rs || first);

		}

	}
});

$.ui.plugin.add("draggable", "stack", {
	start: function( event, ui, instance ) {
		var min,
			o = instance.options,
			group = $.makeArray($(o.stack)).sort(function(a, b) {
				return (parseInt($(a).css("zIndex"), 10) || 0) - (parseInt($(b).css("zIndex"), 10) || 0);
			});

		if (!group.length) { return; }

		min = parseInt($(group[0]).css("zIndex"), 10) || 0;
		$(group).each(function(i) {
			$(this).css("zIndex", min + i);
		});
		this.css("zIndex", (min + group.length));
	}
});

$.ui.plugin.add("draggable", "zIndex", {
	start: function( event, ui, instance ) {
		var t = $( ui.helper ),
			o = instance.options;

		if (t.css("zIndex")) {
			o._zIndex = t.css("zIndex");
		}
		t.css("zIndex", o.zIndex);
	},
	stop: function( event, ui, instance ) {
		var o = instance.options;

		if (o._zIndex) {
			$(ui.helper).css("zIndex", o._zIndex);
		}
	}
});

var draggable = $.ui.draggable;


/*!
 * jQuery UI Resizable 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/resizable/
 */


$.widget("ui.resizable", $.ui.mouse, {
	version: "1.11.4",
	widgetEventPrefix: "resize",
	options: {
		alsoResize: false,
		animate: false,
		animateDuration: "slow",
		animateEasing: "swing",
		aspectRatio: false,
		autoHide: false,
		containment: false,
		ghost: false,
		grid: false,
		handles: "e,s,se",
		helper: false,
		maxHeight: null,
		maxWidth: null,
		minHeight: 10,
		minWidth: 10,
		// See #7960
		zIndex: 90,

		// callbacks
		resize: null,
		start: null,
		stop: null
	},

	_num: function( value ) {
		return parseInt( value, 10 ) || 0;
	},

	_isNumber: function( value ) {
		return !isNaN( parseInt( value, 10 ) );
	},

	_hasScroll: function( el, a ) {

		if ( $( el ).css( "overflow" ) === "hidden") {
			return false;
		}

		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
			has = false;

		if ( el[ scroll ] > 0 ) {
			return true;
		}

		// TODO: determine which cases actually cause this to happen
		// if the element doesn't have the scroll set, see if it's possible to
		// set the scroll
		el[ scroll ] = 1;
		has = ( el[ scroll ] > 0 );
		el[ scroll ] = 0;
		return has;
	},

	_create: function() {

		var n, i, handle, axis, hname,
			that = this,
			o = this.options;
		this.element.addClass("ui-resizable");

		$.extend(this, {
			_aspectRatio: !!(o.aspectRatio),
			aspectRatio: o.aspectRatio,
			originalElement: this.element,
			_proportionallyResizeElements: [],
			_helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
		});

		// Wrap the element if it cannot hold child nodes
		if (this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)) {

			this.element.wrap(
				$("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
					position: this.element.css("position"),
					width: this.element.outerWidth(),
					height: this.element.outerHeight(),
					top: this.element.css("top"),
					left: this.element.css("left")
				})
			);

			this.element = this.element.parent().data(
				"ui-resizable", this.element.resizable( "instance" )
			);

			this.elementIsWrapper = true;

			this.element.css({
				marginLeft: this.originalElement.css("marginLeft"),
				marginTop: this.originalElement.css("marginTop"),
				marginRight: this.originalElement.css("marginRight"),
				marginBottom: this.originalElement.css("marginBottom")
			});
			this.originalElement.css({
				marginLeft: 0,
				marginTop: 0,
				marginRight: 0,
				marginBottom: 0
			});
			// support: Safari
			// Prevent Safari textarea resize
			this.originalResizeStyle = this.originalElement.css("resize");
			this.originalElement.css("resize", "none");

			this._proportionallyResizeElements.push( this.originalElement.css({
				position: "static",
				zoom: 1,
				display: "block"
			}) );

			// support: IE9
			// avoid IE jump (hard set the margin)
			this.originalElement.css({ margin: this.originalElement.css("margin") });

			this._proportionallyResize();
		}

		this.handles = o.handles ||
			( !$(".ui-resizable-handle", this.element).length ?
				"e,s,se" : {
					n: ".ui-resizable-n",
					e: ".ui-resizable-e",
					s: ".ui-resizable-s",
					w: ".ui-resizable-w",
					se: ".ui-resizable-se",
					sw: ".ui-resizable-sw",
					ne: ".ui-resizable-ne",
					nw: ".ui-resizable-nw"
				} );

		this._handles = $();
		if ( this.handles.constructor === String ) {

			if ( this.handles === "all") {
				this.handles = "n,e,s,w,se,sw,ne,nw";
			}

			n = this.handles.split(",");
			this.handles = {};

			for (i = 0; i < n.length; i++) {

				handle = $.trim(n[i]);
				hname = "ui-resizable-" + handle;
				axis = $("<div class='ui-resizable-handle " + hname + "'></div>");

				axis.css({ zIndex: o.zIndex });

				// TODO : What's going on here?
				if ("se" === handle) {
					axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
				}

				this.handles[handle] = ".ui-resizable-" + handle;
				this.element.append(axis);
			}

		}

		this._renderAxis = function(target) {

			var i, axis, padPos, padWrapper;

			target = target || this.element;

			for (i in this.handles) {

				if (this.handles[i].constructor === String) {
					this.handles[i] = this.element.children( this.handles[ i ] ).first().show();
				} else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
					this.handles[ i ] = $( this.handles[ i ] );
					this._on( this.handles[ i ], { "mousedown": that._mouseDown });
				}

				if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)) {

					axis = $(this.handles[i], this.element);

					padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();

					padPos = [ "padding",
						/ne|nw|n/.test(i) ? "Top" :
						/se|sw|s/.test(i) ? "Bottom" :
						/^e$/.test(i) ? "Right" : "Left" ].join("");

					target.css(padPos, padWrapper);

					this._proportionallyResize();
				}

				this._handles = this._handles.add( this.handles[ i ] );
			}
		};

		// TODO: make renderAxis a prototype function
		this._renderAxis(this.element);

		this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
		this._handles.disableSelection();

		this._handles.mouseover(function() {
			if (!that.resizing) {
				if (this.className) {
					axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
				}
				that.axis = axis && axis[1] ? axis[1] : "se";
			}
		});

		if (o.autoHide) {
			this._handles.hide();
			$(this.element)
				.addClass("ui-resizable-autohide")
				.mouseenter(function() {
					if (o.disabled) {
						return;
					}
					$(this).removeClass("ui-resizable-autohide");
					that._handles.show();
				})
				.mouseleave(function() {
					if (o.disabled) {
						return;
					}
					if (!that.resizing) {
						$(this).addClass("ui-resizable-autohide");
						that._handles.hide();
					}
				});
		}

		this._mouseInit();
	},

	_destroy: function() {

		this._mouseDestroy();

		var wrapper,
			_destroy = function(exp) {
				$(exp)
					.removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
					.removeData("resizable")
					.removeData("ui-resizable")
					.unbind(".resizable")
					.find(".ui-resizable-handle")
						.remove();
			};

		// TODO: Unwrap at same DOM position
		if (this.elementIsWrapper) {
			_destroy(this.element);
			wrapper = this.element;
			this.originalElement.css({
				position: wrapper.css("position"),
				width: wrapper.outerWidth(),
				height: wrapper.outerHeight(),
				top: wrapper.css("top"),
				left: wrapper.css("left")
			}).insertAfter( wrapper );
			wrapper.remove();
		}

		this.originalElement.css("resize", this.originalResizeStyle);
		_destroy(this.originalElement);

		return this;
	},

	_mouseCapture: function(event) {
		var i, handle,
			capture = false;

		for (i in this.handles) {
			handle = $(this.handles[i])[0];
			if (handle === event.target || $.contains(handle, event.target)) {
				capture = true;
			}
		}

		return !this.options.disabled && capture;
	},

	_mouseStart: function(event) {

		var curleft, curtop, cursor,
			o = this.options,
			el = this.element;

		this.resizing = true;

		this._renderProxy();

		curleft = this._num(this.helper.css("left"));
		curtop = this._num(this.helper.css("top"));

		if (o.containment) {
			curleft += $(o.containment).scrollLeft() || 0;
			curtop += $(o.containment).scrollTop() || 0;
		}

		this.offset = this.helper.offset();
		this.position = { left: curleft, top: curtop };

		this.size = this._helper ? {
				width: this.helper.width(),
				height: this.helper.height()
			} : {
				width: el.width(),
				height: el.height()
			};

		this.originalSize = this._helper ? {
				width: el.outerWidth(),
				height: el.outerHeight()
			} : {
				width: el.width(),
				height: el.height()
			};

		this.sizeDiff = {
			width: el.outerWidth() - el.width(),
			height: el.outerHeight() - el.height()
		};

		this.originalPosition = { left: curleft, top: curtop };
		this.originalMousePosition = { left: event.pageX, top: event.pageY };

		this.aspectRatio = (typeof o.aspectRatio === "number") ?
			o.aspectRatio :
			((this.originalSize.width / this.originalSize.height) || 1);

		cursor = $(".ui-resizable-" + this.axis).css("cursor");
		$("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);

		el.addClass("ui-resizable-resizing");
		this._propagate("start", event);
		return true;
	},

	_mouseDrag: function(event) {

		var data, props,
			smp = this.originalMousePosition,
			a = this.axis,
			dx = (event.pageX - smp.left) || 0,
			dy = (event.pageY - smp.top) || 0,
			trigger = this._change[a];

		this._updatePrevProperties();

		if (!trigger) {
			return false;
		}

		data = trigger.apply(this, [ event, dx, dy ]);

		this._updateVirtualBoundaries(event.shiftKey);
		if (this._aspectRatio || event.shiftKey) {
			data = this._updateRatio(data, event);
		}

		data = this._respectSize(data, event);

		this._updateCache(data);

		this._propagate("resize", event);

		props = this._applyChanges();

		if ( !this._helper && this._proportionallyResizeElements.length ) {
			this._proportionallyResize();
		}

		if ( !$.isEmptyObject( props ) ) {
			this._updatePrevProperties();
			this._trigger( "resize", event, this.ui() );
			this._applyChanges();
		}

		return false;
	},

	_mouseStop: function(event) {

		this.resizing = false;
		var pr, ista, soffseth, soffsetw, s, left, top,
			o = this.options, that = this;

		if (this._helper) {

			pr = this._proportionallyResizeElements;
			ista = pr.length && (/textarea/i).test(pr[0].nodeName);
			soffseth = ista && this._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height;
			soffsetw = ista ? 0 : that.sizeDiff.width;

			s = {
				width: (that.helper.width()  - soffsetw),
				height: (that.helper.height() - soffseth)
			};
			left = (parseInt(that.element.css("left"), 10) +
				(that.position.left - that.originalPosition.left)) || null;
			top = (parseInt(that.element.css("top"), 10) +
				(that.position.top - that.originalPosition.top)) || null;

			if (!o.animate) {
				this.element.css($.extend(s, { top: top, left: left }));
			}

			that.helper.height(that.size.height);
			that.helper.width(that.size.width);

			if (this._helper && !o.animate) {
				this._proportionallyResize();
			}
		}

		$("body").css("cursor", "auto");

		this.element.removeClass("ui-resizable-resizing");

		this._propagate("stop", event);

		if (this._helper) {
			this.helper.remove();
		}

		return false;

	},

	_updatePrevProperties: function() {
		this.prevPosition = {
			top: this.position.top,
			left: this.position.left
		};
		this.prevSize = {
			width: this.size.width,
			height: this.size.height
		};
	},

	_applyChanges: function() {
		var props = {};

		if ( this.position.top !== this.prevPosition.top ) {
			props.top = this.position.top + "px";
		}
		if ( this.position.left !== this.prevPosition.left ) {
			props.left = this.position.left + "px";
		}
		if ( this.size.width !== this.prevSize.width ) {
			props.width = this.size.width + "px";
		}
		if ( this.size.height !== this.prevSize.height ) {
			props.height = this.size.height + "px";
		}

		this.helper.css( props );

		return props;
	},

	_updateVirtualBoundaries: function(forceAspectRatio) {
		var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
			o = this.options;

		b = {
			minWidth: this._isNumber(o.minWidth) ? o.minWidth : 0,
			maxWidth: this._isNumber(o.maxWidth) ? o.maxWidth : Infinity,
			minHeight: this._isNumber(o.minHeight) ? o.minHeight : 0,
			maxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity
		};

		if (this._aspectRatio || forceAspectRatio) {
			pMinWidth = b.minHeight * this.aspectRatio;
			pMinHeight = b.minWidth / this.aspectRatio;
			pMaxWidth = b.maxHeight * this.aspectRatio;
			pMaxHeight = b.maxWidth / this.aspectRatio;

			if (pMinWidth > b.minWidth) {
				b.minWidth = pMinWidth;
			}
			if (pMinHeight > b.minHeight) {
				b.minHeight = pMinHeight;
			}
			if (pMaxWidth < b.maxWidth) {
				b.maxWidth = pMaxWidth;
			}
			if (pMaxHeight < b.maxHeight) {
				b.maxHeight = pMaxHeight;
			}
		}
		this._vBoundaries = b;
	},

	_updateCache: function(data) {
		this.offset = this.helper.offset();
		if (this._isNumber(data.left)) {
			this.position.left = data.left;
		}
		if (this._isNumber(data.top)) {
			this.position.top = data.top;
		}
		if (this._isNumber(data.height)) {
			this.size.height = data.height;
		}
		if (this._isNumber(data.width)) {
			this.size.width = data.width;
		}
	},

	_updateRatio: function( data ) {

		var cpos = this.position,
			csize = this.size,
			a = this.axis;

		if (this._isNumber(data.height)) {
			data.width = (data.height * this.aspectRatio);
		} else if (this._isNumber(data.width)) {
			data.height = (data.width / this.aspectRatio);
		}

		if (a === "sw") {
			data.left = cpos.left + (csize.width - data.width);
			data.top = null;
		}
		if (a === "nw") {
			data.top = cpos.top + (csize.height - data.height);
			data.left = cpos.left + (csize.width - data.width);
		}

		return data;
	},

	_respectSize: function( data ) {

		var o = this._vBoundaries,
			a = this.axis,
			ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width),
			ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
			isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width),
			isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
			dw = this.originalPosition.left + this.originalSize.width,
			dh = this.position.top + this.size.height,
			cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
		if (isminw) {
			data.width = o.minWidth;
		}
		if (isminh) {
			data.height = o.minHeight;
		}
		if (ismaxw) {
			data.width = o.maxWidth;
		}
		if (ismaxh) {
			data.height = o.maxHeight;
		}

		if (isminw && cw) {
			data.left = dw - o.minWidth;
		}
		if (ismaxw && cw) {
			data.left = dw - o.maxWidth;
		}
		if (isminh && ch) {
			data.top = dh - o.minHeight;
		}
		if (ismaxh && ch) {
			data.top = dh - o.maxHeight;
		}

		// Fixing jump error on top/left - bug #2330
		if (!data.width && !data.height && !data.left && data.top) {
			data.top = null;
		} else if (!data.width && !data.height && !data.top && data.left) {
			data.left = null;
		}

		return data;
	},

	_getPaddingPlusBorderDimensions: function( element ) {
		var i = 0,
			widths = [],
			borders = [
				element.css( "borderTopWidth" ),
				element.css( "borderRightWidth" ),
				element.css( "borderBottomWidth" ),
				element.css( "borderLeftWidth" )
			],
			paddings = [
				element.css( "paddingTop" ),
				element.css( "paddingRight" ),
				element.css( "paddingBottom" ),
				element.css( "paddingLeft" )
			];

		for ( ; i < 4; i++ ) {
			widths[ i ] = ( parseInt( borders[ i ], 10 ) || 0 );
			widths[ i ] += ( parseInt( paddings[ i ], 10 ) || 0 );
		}

		return {
			height: widths[ 0 ] + widths[ 2 ],
			width: widths[ 1 ] + widths[ 3 ]
		};
	},

	_proportionallyResize: function() {

		if (!this._proportionallyResizeElements.length) {
			return;
		}

		var prel,
			i = 0,
			element = this.helper || this.element;

		for ( ; i < this._proportionallyResizeElements.length; i++) {

			prel = this._proportionallyResizeElements[i];

			// TODO: Seems like a bug to cache this.outerDimensions
			// considering that we are in a loop.
			if (!this.outerDimensions) {
				this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
			}

			prel.css({
				height: (element.height() - this.outerDimensions.height) || 0,
				width: (element.width() - this.outerDimensions.width) || 0
			});

		}

	},

	_renderProxy: function() {

		var el = this.element, o = this.options;
		this.elementOffset = el.offset();

		if (this._helper) {

			this.helper = this.helper || $("<div style='overflow:hidden;'></div>");

			this.helper.addClass(this._helper).css({
				width: this.element.outerWidth() - 1,
				height: this.element.outerHeight() - 1,
				position: "absolute",
				left: this.elementOffset.left + "px",
				top: this.elementOffset.top + "px",
				zIndex: ++o.zIndex //TODO: Don't modify option
			});

			this.helper
				.appendTo("body")
				.disableSelection();

		} else {
			this.helper = this.element;
		}

	},

	_change: {
		e: function(event, dx) {
			return { width: this.originalSize.width + dx };
		},
		w: function(event, dx) {
			var cs = this.originalSize, sp = this.originalPosition;
			return { left: sp.left + dx, width: cs.width - dx };
		},
		n: function(event, dx, dy) {
			var cs = this.originalSize, sp = this.originalPosition;
			return { top: sp.top + dy, height: cs.height - dy };
		},
		s: function(event, dx, dy) {
			return { height: this.originalSize.height + dy };
		},
		se: function(event, dx, dy) {
			return $.extend(this._change.s.apply(this, arguments),
				this._change.e.apply(this, [ event, dx, dy ]));
		},
		sw: function(event, dx, dy) {
			return $.extend(this._change.s.apply(this, arguments),
				this._change.w.apply(this, [ event, dx, dy ]));
		},
		ne: function(event, dx, dy) {
			return $.extend(this._change.n.apply(this, arguments),
				this._change.e.apply(this, [ event, dx, dy ]));
		},
		nw: function(event, dx, dy) {
			return $.extend(this._change.n.apply(this, arguments),
				this._change.w.apply(this, [ event, dx, dy ]));
		}
	},

	_propagate: function(n, event) {
		$.ui.plugin.call(this, n, [ event, this.ui() ]);
		(n !== "resize" && this._trigger(n, event, this.ui()));
	},

	plugins: {},

	ui: function() {
		return {
			originalElement: this.originalElement,
			element: this.element,
			helper: this.helper,
			position: this.position,
			size: this.size,
			originalSize: this.originalSize,
			originalPosition: this.originalPosition
		};
	}

});

/*
 * Resizable Extensions
 */

$.ui.plugin.add("resizable", "animate", {

	stop: function( event ) {
		var that = $(this).resizable( "instance" ),
			o = that.options,
			pr = that._proportionallyResizeElements,
			ista = pr.length && (/textarea/i).test(pr[0].nodeName),
			soffseth = ista && that._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height,
			soffsetw = ista ? 0 : that.sizeDiff.width,
			style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
			left = (parseInt(that.element.css("left"), 10) +
				(that.position.left - that.originalPosition.left)) || null,
			top = (parseInt(that.element.css("top"), 10) +
				(that.position.top - that.originalPosition.top)) || null;

		that.element.animate(
			$.extend(style, top && left ? { top: top, left: left } : {}), {
				duration: o.animateDuration,
				easing: o.animateEasing,
				step: function() {

					var data = {
						width: parseInt(that.element.css("width"), 10),
						height: parseInt(that.element.css("height"), 10),
						top: parseInt(that.element.css("top"), 10),
						left: parseInt(that.element.css("left"), 10)
					};

					if (pr && pr.length) {
						$(pr[0]).css({ width: data.width, height: data.height });
					}

					// propagating resize, and updating values for each animation step
					that._updateCache(data);
					that._propagate("resize", event);

				}
			}
		);
	}

});

$.ui.plugin.add( "resizable", "containment", {

	start: function() {
		var element, p, co, ch, cw, width, height,
			that = $( this ).resizable( "instance" ),
			o = that.options,
			el = that.element,
			oc = o.containment,
			ce = ( oc instanceof $ ) ? oc.get( 0 ) : ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;

		if ( !ce ) {
			return;
		}

		that.containerElement = $( ce );

		if ( /document/.test( oc ) || oc === document ) {
			that.containerOffset = {
				left: 0,
				top: 0
			};
			that.containerPosition = {
				left: 0,
				top: 0
			};

			that.parentData = {
				element: $( document ),
				left: 0,
				top: 0,
				width: $( document ).width(),
				height: $( document ).height() || document.body.parentNode.scrollHeight
			};
		} else {
			element = $( ce );
			p = [];
			$([ "Top", "Right", "Left", "Bottom" ]).each(function( i, name ) {
				p[ i ] = that._num( element.css( "padding" + name ) );
			});

			that.containerOffset = element.offset();
			that.containerPosition = element.position();
			that.containerSize = {
				height: ( element.innerHeight() - p[ 3 ] ),
				width: ( element.innerWidth() - p[ 1 ] )
			};

			co = that.containerOffset;
			ch = that.containerSize.height;
			cw = that.containerSize.width;
			width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
			height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;

			that.parentData = {
				element: ce,
				left: co.left,
				top: co.top,
				width: width,
				height: height
			};
		}
	},

	resize: function( event ) {
		var woset, hoset, isParent, isOffsetRelative,
			that = $( this ).resizable( "instance" ),
			o = that.options,
			co = that.containerOffset,
			cp = that.position,
			pRatio = that._aspectRatio || event.shiftKey,
			cop = {
				top: 0,
				left: 0
			},
			ce = that.containerElement,
			continueResize = true;

		if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
			cop = co;
		}

		if ( cp.left < ( that._helper ? co.left : 0 ) ) {
			that.size.width = that.size.width +
				( that._helper ?
					( that.position.left - co.left ) :
					( that.position.left - cop.left ) );

			if ( pRatio ) {
				that.size.height = that.size.width / that.aspectRatio;
				continueResize = false;
			}
			that.position.left = o.helper ? co.left : 0;
		}

		if ( cp.top < ( that._helper ? co.top : 0 ) ) {
			that.size.height = that.size.height +
				( that._helper ?
					( that.position.top - co.top ) :
					that.position.top );

			if ( pRatio ) {
				that.size.width = that.size.height * that.aspectRatio;
				continueResize = false;
			}
			that.position.top = that._helper ? co.top : 0;
		}

		isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
		isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );

		if ( isParent && isOffsetRelative ) {
			that.offset.left = that.parentData.left + that.position.left;
			that.offset.top = that.parentData.top + that.position.top;
		} else {
			that.offset.left = that.element.offset().left;
			that.offset.top = that.element.offset().top;
		}

		woset = Math.abs( that.sizeDiff.width +
			(that._helper ?
				that.offset.left - cop.left :
				(that.offset.left - co.left)) );

		hoset = Math.abs( that.sizeDiff.height +
			(that._helper ?
				that.offset.top - cop.top :
				(that.offset.top - co.top)) );

		if ( woset + that.size.width >= that.parentData.width ) {
			that.size.width = that.parentData.width - woset;
			if ( pRatio ) {
				that.size.height = that.size.width / that.aspectRatio;
				continueResize = false;
			}
		}

		if ( hoset + that.size.height >= that.parentData.height ) {
			that.size.height = that.parentData.height - hoset;
			if ( pRatio ) {
				that.size.width = that.size.height * that.aspectRatio;
				continueResize = false;
			}
		}

		if ( !continueResize ) {
			that.position.left = that.prevPosition.left;
			that.position.top = that.prevPosition.top;
			that.size.width = that.prevSize.width;
			that.size.height = that.prevSize.height;
		}
	},

	stop: function() {
		var that = $( this ).resizable( "instance" ),
			o = that.options,
			co = that.containerOffset,
			cop = that.containerPosition,
			ce = that.containerElement,
			helper = $( that.helper ),
			ho = helper.offset(),
			w = helper.outerWidth() - that.sizeDiff.width,
			h = helper.outerHeight() - that.sizeDiff.height;

		if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
			$( this ).css({
				left: ho.left - cop.left - co.left,
				width: w,
				height: h
			});
		}

		if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
			$( this ).css({
				left: ho.left - cop.left - co.left,
				width: w,
				height: h
			});
		}
	}
});

$.ui.plugin.add("resizable", "alsoResize", {

	start: function() {
		var that = $(this).resizable( "instance" ),
			o = that.options;

		$(o.alsoResize).each(function() {
			var el = $(this);
			el.data("ui-resizable-alsoresize", {
				width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
				left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
			});
		});
	},

	resize: function(event, ui) {
		var that = $(this).resizable( "instance" ),
			o = that.options,
			os = that.originalSize,
			op = that.originalPosition,
			delta = {
				height: (that.size.height - os.height) || 0,
				width: (that.size.width - os.width) || 0,
				top: (that.position.top - op.top) || 0,
				left: (that.position.left - op.left) || 0
			};

			$(o.alsoResize).each(function() {
				var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
					css = el.parents(ui.originalElement[0]).length ?
							[ "width", "height" ] :
							[ "width", "height", "top", "left" ];

				$.each(css, function(i, prop) {
					var sum = (start[prop] || 0) + (delta[prop] || 0);
					if (sum && sum >= 0) {
						style[prop] = sum || null;
					}
				});

				el.css(style);
			});
	},

	stop: function() {
		$(this).removeData("resizable-alsoresize");
	}
});

$.ui.plugin.add("resizable", "ghost", {

	start: function() {

		var that = $(this).resizable( "instance" ), o = that.options, cs = that.size;

		that.ghost = that.originalElement.clone();
		that.ghost
			.css({
				opacity: 0.25,
				display: "block",
				position: "relative",
				height: cs.height,
				width: cs.width,
				margin: 0,
				left: 0,
				top: 0
			})
			.addClass("ui-resizable-ghost")
			.addClass(typeof o.ghost === "string" ? o.ghost : "");

		that.ghost.appendTo(that.helper);

	},

	resize: function() {
		var that = $(this).resizable( "instance" );
		if (that.ghost) {
			that.ghost.css({
				position: "relative",
				height: that.size.height,
				width: that.size.width
			});
		}
	},

	stop: function() {
		var that = $(this).resizable( "instance" );
		if (that.ghost && that.helper) {
			that.helper.get(0).removeChild(that.ghost.get(0));
		}
	}

});

$.ui.plugin.add("resizable", "grid", {

	resize: function() {
		var outerDimensions,
			that = $(this).resizable( "instance" ),
			o = that.options,
			cs = that.size,
			os = that.originalSize,
			op = that.originalPosition,
			a = that.axis,
			grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
			gridX = (grid[0] || 1),
			gridY = (grid[1] || 1),
			ox = Math.round((cs.width - os.width) / gridX) * gridX,
			oy = Math.round((cs.height - os.height) / gridY) * gridY,
			newWidth = os.width + ox,
			newHeight = os.height + oy,
			isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
			isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
			isMinWidth = o.minWidth && (o.minWidth > newWidth),
			isMinHeight = o.minHeight && (o.minHeight > newHeight);

		o.grid = grid;

		if (isMinWidth) {
			newWidth += gridX;
		}
		if (isMinHeight) {
			newHeight += gridY;
		}
		if (isMaxWidth) {
			newWidth -= gridX;
		}
		if (isMaxHeight) {
			newHeight -= gridY;
		}

		if (/^(se|s|e)$/.test(a)) {
			that.size.width = newWidth;
			that.size.height = newHeight;
		} else if (/^(ne)$/.test(a)) {
			that.size.width = newWidth;
			that.size.height = newHeight;
			that.position.top = op.top - oy;
		} else if (/^(sw)$/.test(a)) {
			that.size.width = newWidth;
			that.size.height = newHeight;
			that.position.left = op.left - ox;
		} else {
			if ( newHeight - gridY <= 0 || newWidth - gridX <= 0) {
				outerDimensions = that._getPaddingPlusBorderDimensions( this );
			}

			if ( newHeight - gridY > 0 ) {
				that.size.height = newHeight;
				that.position.top = op.top - oy;
			} else {
				newHeight = gridY - outerDimensions.height;
				that.size.height = newHeight;
				that.position.top = op.top + os.height - newHeight;
			}
			if ( newWidth - gridX > 0 ) {
				that.size.width = newWidth;
				that.position.left = op.left - ox;
			} else {
				newWidth = gridX - outerDimensions.width;
				that.size.width = newWidth;
				that.position.left = op.left + os.width - newWidth;
			}
		}
	}

});

var resizable = $.ui.resizable;


/*!
 * jQuery UI Dialog 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/dialog/
 */


var dialog = $.widget( "ui.dialog", {
	version: "1.11.4",
	options: {
		appendTo: "body",
		autoOpen: true,
		buttons: [],
		closeOnEscape: true,
		closeText: "Close",
		dialogClass: "",
		draggable: true,
		hide: null,
		height: "auto",
		maxHeight: null,
		maxWidth: null,
		minHeight: 150,
		minWidth: 150,
		modal: false,
		position: {
			my: "center",
			at: "center",
			of: window,
			collision: "fit",
			// Ensure the titlebar is always visible
			using: function( pos ) {
				var topOffset = $( this ).css( pos ).offset().top;
				if ( topOffset < 0 ) {
					$( this ).css( "top", pos.top - topOffset );
				}
			}
		},
		resizable: true,
		show: null,
		title: null,
		width: 300,

		// callbacks
		beforeClose: null,
		close: null,
		drag: null,
		dragStart: null,
		dragStop: null,
		focus: null,
		open: null,
		resize: null,
		resizeStart: null,
		resizeStop: null
	},

	sizeRelatedOptions: {
		buttons: true,
		height: true,
		maxHeight: true,
		maxWidth: true,
		minHeight: true,
		minWidth: true,
		width: true
	},

	resizableRelatedOptions: {
		maxHeight: true,
		maxWidth: true,
		minHeight: true,
		minWidth: true
	},

	_create: function() {
		this.originalCss = {
			display: this.element[ 0 ].style.display,
			width: this.element[ 0 ].style.width,
			minHeight: this.element[ 0 ].style.minHeight,
			maxHeight: this.element[ 0 ].style.maxHeight,
			height: this.element[ 0 ].style.height
		};
		this.originalPosition = {
			parent: this.element.parent(),
			index: this.element.parent().children().index( this.element )
		};
		this.originalTitle = this.element.attr( "title" );
		this.options.title = this.options.title || this.originalTitle;

		this._createWrapper();

		this.element
			.show()
			.removeAttr( "title" )
			.addClass( "ui-dialog-content ui-widget-content" )
			.appendTo( this.uiDialog );

		this._createTitlebar();
		this._createButtonPane();

		if ( this.options.draggable && $.fn.draggable ) {
			this._makeDraggable();
		}
		if ( this.options.resizable && $.fn.resizable ) {
			this._makeResizable();
		}

		this._isOpen = false;

		this._trackFocus();
	},

	_init: function() {
		if ( this.options.autoOpen ) {
			this.open();
		}
	},

	_appendTo: function() {
		var element = this.options.appendTo;
		if ( element && (element.jquery || element.nodeType) ) {
			return $( element );
		}
		return this.document.find( element || "body" ).eq( 0 );
	},

	_destroy: function() {
		var next,
			originalPosition = this.originalPosition;

		this._untrackInstance();
		this._destroyOverlay();

		this.element
			.removeUniqueId()
			.removeClass( "ui-dialog-content ui-widget-content" )
			.css( this.originalCss )
			// Without detaching first, the following becomes really slow
			.detach();

		this.uiDialog.stop( true, true ).remove();

		if ( this.originalTitle ) {
			this.element.attr( "title", this.originalTitle );
		}

		next = originalPosition.parent.children().eq( originalPosition.index );
		// Don't try to place the dialog next to itself (#8613)
		if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
			next.before( this.element );
		} else {
			originalPosition.parent.append( this.element );
		}
	},

	widget: function() {
		return this.uiDialog;
	},

	disable: $.noop,
	enable: $.noop,

	close: function( event ) {
		var activeElement,
			that = this;

		if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
			return;
		}

		this._isOpen = false;
		this._focusedElement = null;
		this._destroyOverlay();
		this._untrackInstance();

		if ( !this.opener.filter( ":focusable" ).focus().length ) {

			// support: IE9
			// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
			try {
				activeElement = this.document[ 0 ].activeElement;

				// Support: IE9, IE10
				// If the <body> is blurred, IE will switch windows, see #4520
				if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) {

					// Hiding a focused element doesn't trigger blur in WebKit
					// so in case we have nothing to focus on, explicitly blur the active element
					// https://bugs.webkit.org/show_bug.cgi?id=47182
					$( activeElement ).blur();
				}
			} catch ( error ) {}
		}

		this._hide( this.uiDialog, this.options.hide, function() {
			that._trigger( "close", event );
		});
	},

	isOpen: function() {
		return this._isOpen;
	},

	moveToTop: function() {
		this._moveToTop();
	},

	_moveToTop: function( event, silent ) {
		var moved = false,
			zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map(function() {
				return +$( this ).css( "z-index" );
			}).get(),
			zIndexMax = Math.max.apply( null, zIndices );

		if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
			this.uiDialog.css( "z-index", zIndexMax + 1 );
			moved = true;
		}

		if ( moved && !silent ) {
			this._trigger( "focus", event );
		}
		return moved;
	},

	open: function() {
		var that = this;
		if ( this._isOpen ) {
			if ( this._moveToTop() ) {
				this._focusTabbable();
			}
			return;
		}

		this._isOpen = true;
		this.opener = $( this.document[ 0 ].activeElement );

		this._size();
		this._position();
		this._createOverlay();
		this._moveToTop( null, true );

		// Ensure the overlay is moved to the top with the dialog, but only when
		// opening. The overlay shouldn't move after the dialog is open so that
		// modeless dialogs opened after the modal dialog stack properly.
		if ( this.overlay ) {
			this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
		}

		this._show( this.uiDialog, this.options.show, function() {
			that._focusTabbable();
			that._trigger( "focus" );
		});

		// Track the dialog immediately upon openening in case a focus event
		// somehow occurs outside of the dialog before an element inside the
		// dialog is focused (#10152)
		this._makeFocusTarget();

		this._trigger( "open" );
	},

	_focusTabbable: function() {
		// Set focus to the first match:
		// 1. An element that was focused previously
		// 2. First element inside the dialog matching [autofocus]
		// 3. Tabbable element inside the content element
		// 4. Tabbable element inside the buttonpane
		// 5. The close button
		// 6. The dialog itself
		var hasFocus = this._focusedElement;
		if ( !hasFocus ) {
			hasFocus = this.element.find( "[autofocus]" );
		}
		if ( !hasFocus.length ) {
			hasFocus = this.element.find( ":tabbable" );
		}
		if ( !hasFocus.length ) {
			hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
		}
		if ( !hasFocus.length ) {
			hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
		}
		if ( !hasFocus.length ) {
			hasFocus = this.uiDialog;
		}
		hasFocus.eq( 0 ).focus();
	},

	_keepFocus: function( event ) {
		function checkFocus() {
			var activeElement = this.document[0].activeElement,
				isActive = this.uiDialog[0] === activeElement ||
					$.contains( this.uiDialog[0], activeElement );
			if ( !isActive ) {
				this._focusTabbable();
			}
		}
		event.preventDefault();
		checkFocus.call( this );
		// support: IE
		// IE <= 8 doesn't prevent moving focus even with event.preventDefault()
		// so we check again later
		this._delay( checkFocus );
	},

	_createWrapper: function() {
		this.uiDialog = $("<div>")
			.addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
				this.options.dialogClass )
			.hide()
			.attr({
				// Setting tabIndex makes the div focusable
				tabIndex: -1,
				role: "dialog"
			})
			.appendTo( this._appendTo() );

		this._on( this.uiDialog, {
			keydown: function( event ) {
				if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
						event.keyCode === $.ui.keyCode.ESCAPE ) {
					event.preventDefault();
					this.close( event );
					return;
				}

				// prevent tabbing out of dialogs
				if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
					return;
				}
				var tabbables = this.uiDialog.find( ":tabbable" ),
					first = tabbables.filter( ":first" ),
					last = tabbables.filter( ":last" );

				if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
					this._delay(function() {
						first.focus();
					});
					event.preventDefault();
				} else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
					this._delay(function() {
						last.focus();
					});
					event.preventDefault();
				}
			},
			mousedown: function( event ) {
				if ( this._moveToTop( event ) ) {
					this._focusTabbable();
				}
			}
		});

		// We assume that any existing aria-describedby attribute means
		// that the dialog content is marked up properly
		// otherwise we brute force the content as the description
		if ( !this.element.find( "[aria-describedby]" ).length ) {
			this.uiDialog.attr({
				"aria-describedby": this.element.uniqueId().attr( "id" )
			});
		}
	},

	_createTitlebar: function() {
		var uiDialogTitle;

		this.uiDialogTitlebar = $( "<div>" )
			.addClass( "ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix" )
			.prependTo( this.uiDialog );
		this._on( this.uiDialogTitlebar, {
			mousedown: function( event ) {
				// Don't prevent click on close button (#8838)
				// Focusing a dialog that is partially scrolled out of view
				// causes the browser to scroll it into view, preventing the click event
				if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
					// Dialog isn't getting focus when dragging (#8063)
					this.uiDialog.focus();
				}
			}
		});

		// support: IE
		// Use type="button" to prevent enter keypresses in textboxes from closing the
		// dialog in IE (#9312)
		this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
			.button({
				label: this.options.closeText,
				icons: {
					primary: "ui-icon-closethick"
				},
				text: false
			})
			.addClass( "ui-dialog-titlebar-close" )
			.appendTo( this.uiDialogTitlebar );
		this._on( this.uiDialogTitlebarClose, {
			click: function( event ) {
				event.preventDefault();
				this.close( event );
			}
		});

		uiDialogTitle = $( "<span>" )
			.uniqueId()
			.addClass( "ui-dialog-title" )
			.prependTo( this.uiDialogTitlebar );
		this._title( uiDialogTitle );

		this.uiDialog.attr({
			"aria-labelledby": uiDialogTitle.attr( "id" )
		});
	},

	_title: function( title ) {
		if ( !this.options.title ) {
			title.html( "&#160;" );
		}
		title.text( this.options.title );
	},

	_createButtonPane: function() {
		this.uiDialogButtonPane = $( "<div>" )
			.addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" );

		this.uiButtonSet = $( "<div>" )
			.addClass( "ui-dialog-buttonset" )
			.appendTo( this.uiDialogButtonPane );

		this._createButtons();
	},

	_createButtons: function() {
		var that = this,
			buttons = this.options.buttons;

		// if we already have a button pane, remove it
		this.uiDialogButtonPane.remove();
		this.uiButtonSet.empty();

		if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
			this.uiDialog.removeClass( "ui-dialog-buttons" );
			return;
		}

		$.each( buttons, function( name, props ) {
			var click, buttonOptions;
			props = $.isFunction( props ) ?
				{ click: props, text: name } :
				props;
			// Default to a non-submitting button
			props = $.extend( { type: "button" }, props );
			// Change the context for the click callback to be the main element
			click = props.click;
			props.click = function() {
				click.apply( that.element[ 0 ], arguments );
			};
			buttonOptions = {
				icons: props.icons,
				text: props.showText
			};
			delete props.icons;
			delete props.showText;
			$( "<button></button>", props )
				.button( buttonOptions )
				.appendTo( that.uiButtonSet );
		});
		this.uiDialog.addClass( "ui-dialog-buttons" );
		this.uiDialogButtonPane.appendTo( this.uiDialog );
	},

	_makeDraggable: function() {
		var that = this,
			options = this.options;

		function filteredUi( ui ) {
			return {
				position: ui.position,
				offset: ui.offset
			};
		}

		this.uiDialog.draggable({
			cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
			handle: ".ui-dialog-titlebar",
			containment: "document",
			start: function( event, ui ) {
				$( this ).addClass( "ui-dialog-dragging" );
				that._blockFrames();
				that._trigger( "dragStart", event, filteredUi( ui ) );
			},
			drag: function( event, ui ) {
				that._trigger( "drag", event, filteredUi( ui ) );
			},
			stop: function( event, ui ) {
				var left = ui.offset.left - that.document.scrollLeft(),
					top = ui.offset.top - that.document.scrollTop();

				options.position = {
					my: "left top",
					at: "left" + (left >= 0 ? "+" : "") + left + " " +
						"top" + (top >= 0 ? "+" : "") + top,
					of: that.window
				};
				$( this ).removeClass( "ui-dialog-dragging" );
				that._unblockFrames();
				that._trigger( "dragStop", event, filteredUi( ui ) );
			}
		});
	},

	_makeResizable: function() {
		var that = this,
			options = this.options,
			handles = options.resizable,
			// .ui-resizable has position: relative defined in the stylesheet
			// but dialogs have to use absolute or fixed positioning
			position = this.uiDialog.css("position"),
			resizeHandles = typeof handles === "string" ?
				handles	:
				"n,e,s,w,se,sw,ne,nw";

		function filteredUi( ui ) {
			return {
				originalPosition: ui.originalPosition,
				originalSize: ui.originalSize,
				position: ui.position,
				size: ui.size
			};
		}

		this.uiDialog.resizable({
			cancel: ".ui-dialog-content",
			containment: "document",
			alsoResize: this.element,
			maxWidth: options.maxWidth,
			maxHeight: options.maxHeight,
			minWidth: options.minWidth,
			minHeight: this._minHeight(),
			handles: resizeHandles,
			start: function( event, ui ) {
				$( this ).addClass( "ui-dialog-resizing" );
				that._blockFrames();
				that._trigger( "resizeStart", event, filteredUi( ui ) );
			},
			resize: function( event, ui ) {
				that._trigger( "resize", event, filteredUi( ui ) );
			},
			stop: function( event, ui ) {
				var offset = that.uiDialog.offset(),
					left = offset.left - that.document.scrollLeft(),
					top = offset.top - that.document.scrollTop();

				options.height = that.uiDialog.height();
				options.width = that.uiDialog.width();
				options.position = {
					my: "left top",
					at: "left" + (left >= 0 ? "+" : "") + left + " " +
						"top" + (top >= 0 ? "+" : "") + top,
					of: that.window
				};
				$( this ).removeClass( "ui-dialog-resizing" );
				that._unblockFrames();
				that._trigger( "resizeStop", event, filteredUi( ui ) );
			}
		})
		.css( "position", position );
	},

	_trackFocus: function() {
		this._on( this.widget(), {
			focusin: function( event ) {
				this._makeFocusTarget();
				this._focusedElement = $( event.target );
			}
		});
	},

	_makeFocusTarget: function() {
		this._untrackInstance();
		this._trackingInstances().unshift( this );
	},

	_untrackInstance: function() {
		var instances = this._trackingInstances(),
			exists = $.inArray( this, instances );
		if ( exists !== -1 ) {
			instances.splice( exists, 1 );
		}
	},

	_trackingInstances: function() {
		var instances = this.document.data( "ui-dialog-instances" );
		if ( !instances ) {
			instances = [];
			this.document.data( "ui-dialog-instances", instances );
		}
		return instances;
	},

	_minHeight: function() {
		var options = this.options;

		return options.height === "auto" ?
			options.minHeight :
			Math.min( options.minHeight, options.height );
	},

	_position: function() {
		// Need to show the dialog to get the actual offset in the position plugin
		var isVisible = this.uiDialog.is( ":visible" );
		if ( !isVisible ) {
			this.uiDialog.show();
		}
		this.uiDialog.position( this.options.position );
		if ( !isVisible ) {
			this.uiDialog.hide();
		}
	},

	_setOptions: function( options ) {
		var that = this,
			resize = false,
			resizableOptions = {};

		$.each( options, function( key, value ) {
			that._setOption( key, value );

			if ( key in that.sizeRelatedOptions ) {
				resize = true;
			}
			if ( key in that.resizableRelatedOptions ) {
				resizableOptions[ key ] = value;
			}
		});

		if ( resize ) {
			this._size();
			this._position();
		}
		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
			this.uiDialog.resizable( "option", resizableOptions );
		}
	},

	_setOption: function( key, value ) {
		var isDraggable, isResizable,
			uiDialog = this.uiDialog;

		if ( key === "dialogClass" ) {
			uiDialog
				.removeClass( this.options.dialogClass )
				.addClass( value );
		}

		if ( key === "disabled" ) {
			return;
		}

		this._super( key, value );

		if ( key === "appendTo" ) {
			this.uiDialog.appendTo( this._appendTo() );
		}

		if ( key === "buttons" ) {
			this._createButtons();
		}

		if ( key === "closeText" ) {
			this.uiDialogTitlebarClose.button({
				// Ensure that we always pass a string
				label: "" + value
			});
		}

		if ( key === "draggable" ) {
			isDraggable = uiDialog.is( ":data(ui-draggable)" );
			if ( isDraggable && !value ) {
				uiDialog.draggable( "destroy" );
			}

			if ( !isDraggable && value ) {
				this._makeDraggable();
			}
		}

		if ( key === "position" ) {
			this._position();
		}

		if ( key === "resizable" ) {
			// currently resizable, becoming non-resizable
			isResizable = uiDialog.is( ":data(ui-resizable)" );
			if ( isResizable && !value ) {
				uiDialog.resizable( "destroy" );
			}

			// currently resizable, changing handles
			if ( isResizable && typeof value === "string" ) {
				uiDialog.resizable( "option", "handles", value );
			}

			// currently non-resizable, becoming resizable
			if ( !isResizable && value !== false ) {
				this._makeResizable();
			}
		}

		if ( key === "title" ) {
			this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
		}
	},

	_size: function() {
		// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
		// divs will both have width and height set, so we need to reset them
		var nonContentHeight, minContentHeight, maxContentHeight,
			options = this.options;

		// Reset content sizing
		this.element.show().css({
			width: "auto",
			minHeight: 0,
			maxHeight: "none",
			height: 0
		});

		if ( options.minWidth > options.width ) {
			options.width = options.minWidth;
		}

		// reset wrapper sizing
		// determine the height of all the non-content elements
		nonContentHeight = this.uiDialog.css({
				height: "auto",
				width: options.width
			})
			.outerHeight();
		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
		maxContentHeight = typeof options.maxHeight === "number" ?
			Math.max( 0, options.maxHeight - nonContentHeight ) :
			"none";

		if ( options.height === "auto" ) {
			this.element.css({
				minHeight: minContentHeight,
				maxHeight: maxContentHeight,
				height: "auto"
			});
		} else {
			this.element.height( Math.max( 0, options.height - nonContentHeight ) );
		}

		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
			this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
		}
	},

	_blockFrames: function() {
		this.iframeBlocks = this.document.find( "iframe" ).map(function() {
			var iframe = $( this );

			return $( "<div>" )
				.css({
					position: "absolute",
					width: iframe.outerWidth(),
					height: iframe.outerHeight()
				})
				.appendTo( iframe.parent() )
				.offset( iframe.offset() )[0];
		});
	},

	_unblockFrames: function() {
		if ( this.iframeBlocks ) {
			this.iframeBlocks.remove();
			delete this.iframeBlocks;
		}
	},

	_allowInteraction: function( event ) {
		if ( $( event.target ).closest( ".ui-dialog" ).length ) {
			return true;
		}

		// TODO: Remove hack when datepicker implements
		// the .ui-front logic (#8989)
		return !!$( event.target ).closest( ".ui-datepicker" ).length;
	},

	_createOverlay: function() {
		if ( !this.options.modal ) {
			return;
		}

		// We use a delay in case the overlay is created from an
		// event that we're going to be cancelling (#2804)
		var isOpening = true;
		this._delay(function() {
			isOpening = false;
		});

		if ( !this.document.data( "ui-dialog-overlays" ) ) {

			// Prevent use of anchors and inputs
			// Using _on() for an event handler shared across many instances is
			// safe because the dialogs stack and must be closed in reverse order
			this._on( this.document, {
				focusin: function( event ) {
					if ( isOpening ) {
						return;
					}

					if ( !this._allowInteraction( event ) ) {
						event.preventDefault();
						this._trackingInstances()[ 0 ]._focusTabbable();
					}
				}
			});
		}

		this.overlay = $( "<div>" )
			.addClass( "ui-widget-overlay ui-front" )
			.appendTo( this._appendTo() );
		this._on( this.overlay, {
			mousedown: "_keepFocus"
		});
		this.document.data( "ui-dialog-overlays",
			(this.document.data( "ui-dialog-overlays" ) || 0) + 1 );
	},

	_destroyOverlay: function() {
		if ( !this.options.modal ) {
			return;
		}

		if ( this.overlay ) {
			var overlays = this.document.data( "ui-dialog-overlays" ) - 1;

			if ( !overlays ) {
				this.document
					.unbind( "focusin" )
					.removeData( "ui-dialog-overlays" );
			} else {
				this.document.data( "ui-dialog-overlays", overlays );
			}

			this.overlay.remove();
			this.overlay = null;
		}
	}
});


/*!
 * jQuery UI Droppable 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/droppable/
 */


$.widget( "ui.droppable", {
	version: "1.11.4",
	widgetEventPrefix: "drop",
	options: {
		accept: "*",
		activeClass: false,
		addClasses: true,
		greedy: false,
		hoverClass: false,
		scope: "default",
		tolerance: "intersect",

		// callbacks
		activate: null,
		deactivate: null,
		drop: null,
		out: null,
		over: null
	},
	_create: function() {

		var proportions,
			o = this.options,
			accept = o.accept;

		this.isover = false;
		this.isout = true;

		this.accept = $.isFunction( accept ) ? accept : function( d ) {
			return d.is( accept );
		};

		this.proportions = function( /* valueToWrite */ ) {
			if ( arguments.length ) {
				// Store the droppable's proportions
				proportions = arguments[ 0 ];
			} else {
				// Retrieve or derive the droppable's proportions
				return proportions ?
					proportions :
					proportions = {
						width: this.element[ 0 ].offsetWidth,
						height: this.element[ 0 ].offsetHeight
					};
			}
		};

		this._addToManager( o.scope );

		o.addClasses && this.element.addClass( "ui-droppable" );

	},

	_addToManager: function( scope ) {
		// Add the reference and positions to the manager
		$.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
		$.ui.ddmanager.droppables[ scope ].push( this );
	},

	_splice: function( drop ) {
		var i = 0;
		for ( ; i < drop.length; i++ ) {
			if ( drop[ i ] === this ) {
				drop.splice( i, 1 );
			}
		}
	},

	_destroy: function() {
		var drop = $.ui.ddmanager.droppables[ this.options.scope ];

		this._splice( drop );

		this.element.removeClass( "ui-droppable ui-droppable-disabled" );
	},

	_setOption: function( key, value ) {

		if ( key === "accept" ) {
			this.accept = $.isFunction( value ) ? value : function( d ) {
				return d.is( value );
			};
		} else if ( key === "scope" ) {
			var drop = $.ui.ddmanager.droppables[ this.options.scope ];

			this._splice( drop );
			this._addToManager( value );
		}

		this._super( key, value );
	},

	_activate: function( event ) {
		var draggable = $.ui.ddmanager.current;
		if ( this.options.activeClass ) {
			this.element.addClass( this.options.activeClass );
		}
		if ( draggable ){
			this._trigger( "activate", event, this.ui( draggable ) );
		}
	},

	_deactivate: function( event ) {
		var draggable = $.ui.ddmanager.current;
		if ( this.options.activeClass ) {
			this.element.removeClass( this.options.activeClass );
		}
		if ( draggable ){
			this._trigger( "deactivate", event, this.ui( draggable ) );
		}
	},

	_over: function( event ) {

		var draggable = $.ui.ddmanager.current;

		// Bail if draggable and droppable are same element
		if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
			return;
		}

		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
			if ( this.options.hoverClass ) {
				this.element.addClass( this.options.hoverClass );
			}
			this._trigger( "over", event, this.ui( draggable ) );
		}

	},

	_out: function( event ) {

		var draggable = $.ui.ddmanager.current;

		// Bail if draggable and droppable are same element
		if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
			return;
		}

		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
			if ( this.options.hoverClass ) {
				this.element.removeClass( this.options.hoverClass );
			}
			this._trigger( "out", event, this.ui( draggable ) );
		}

	},

	_drop: function( event, custom ) {

		var draggable = custom || $.ui.ddmanager.current,
			childrenIntersection = false;

		// Bail if draggable and droppable are same element
		if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
			return false;
		}

		this.element.find( ":data(ui-droppable)" ).not( ".ui-draggable-dragging" ).each(function() {
			var inst = $( this ).droppable( "instance" );
			if (
				inst.options.greedy &&
				!inst.options.disabled &&
				inst.options.scope === draggable.options.scope &&
				inst.accept.call( inst.element[ 0 ], ( draggable.currentItem || draggable.element ) ) &&
				$.ui.intersect( draggable, $.extend( inst, { offset: inst.element.offset() } ), inst.options.tolerance, event )
			) { childrenIntersection = true; return false; }
		});
		if ( childrenIntersection ) {
			return false;
		}

		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
			if ( this.options.activeClass ) {
				this.element.removeClass( this.options.activeClass );
			}
			if ( this.options.hoverClass ) {
				this.element.removeClass( this.options.hoverClass );
			}
			this._trigger( "drop", event, this.ui( draggable ) );
			return this.element;
		}

		return false;

	},

	ui: function( c ) {
		return {
			draggable: ( c.currentItem || c.element ),
			helper: c.helper,
			position: c.position,
			offset: c.positionAbs
		};
	}

});

$.ui.intersect = (function() {
	function isOverAxis( x, reference, size ) {
		return ( x >= reference ) && ( x < ( reference + size ) );
	}

	return function( draggable, droppable, toleranceMode, event ) {

		if ( !droppable.offset ) {
			return false;
		}

		var x1 = ( draggable.positionAbs || draggable.position.absolute ).left + draggable.margins.left,
			y1 = ( draggable.positionAbs || draggable.position.absolute ).top + draggable.margins.top,
			x2 = x1 + draggable.helperProportions.width,
			y2 = y1 + draggable.helperProportions.height,
			l = droppable.offset.left,
			t = droppable.offset.top,
			r = l + droppable.proportions().width,
			b = t + droppable.proportions().height;

		switch ( toleranceMode ) {
		case "fit":
			return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
		case "intersect":
			return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
				x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
				t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
				y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
		case "pointer":
			return isOverAxis( event.pageY, t, droppable.proportions().height ) && isOverAxis( event.pageX, l, droppable.proportions().width );
		case "touch":
			return (
				( y1 >= t && y1 <= b ) || // Top edge touching
				( y2 >= t && y2 <= b ) || // Bottom edge touching
				( y1 < t && y2 > b ) // Surrounded vertically
			) && (
				( x1 >= l && x1 <= r ) || // Left edge touching
				( x2 >= l && x2 <= r ) || // Right edge touching
				( x1 < l && x2 > r ) // Surrounded horizontally
			);
		default:
			return false;
		}
	};
})();

/*
	This manager tracks offsets of draggables and droppables
*/
$.ui.ddmanager = {
	current: null,
	droppables: { "default": [] },
	prepareOffsets: function( t, event ) {

		var i, j,
			m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
			type = event ? event.type : null, // workaround for #2317
			list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();

		droppablesLoop: for ( i = 0; i < m.length; i++ ) {

			// No disabled and non-accepted
			if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) {
				continue;
			}

			// Filter out elements in the current dragged item
			for ( j = 0; j < list.length; j++ ) {
				if ( list[ j ] === m[ i ].element[ 0 ] ) {
					m[ i ].proportions().height = 0;
					continue droppablesLoop;
				}
			}

			m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
			if ( !m[ i ].visible ) {
				continue;
			}

			// Activate the droppable if used directly from draggables
			if ( type === "mousedown" ) {
				m[ i ]._activate.call( m[ i ], event );
			}

			m[ i ].offset = m[ i ].element.offset();
			m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });

		}

	},
	drop: function( draggable, event ) {

		var dropped = false;
		// Create a copy of the droppables in case the list changes during the drop (#9116)
		$.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {

			if ( !this.options ) {
				return;
			}
			if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance, event ) ) {
				dropped = this._drop.call( this, event ) || dropped;
			}

			if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
				this.isout = true;
				this.isover = false;
				this._deactivate.call( this, event );
			}

		});
		return dropped;

	},
	dragStart: function( draggable, event ) {
		// Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
		draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
			if ( !draggable.options.refreshPositions ) {
				$.ui.ddmanager.prepareOffsets( draggable, event );
			}
		});
	},
	drag: function( draggable, event ) {

		// If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
		if ( draggable.options.refreshPositions ) {
			$.ui.ddmanager.prepareOffsets( draggable, event );
		}

		// Run through all droppables and check their positions based on specific tolerance options
		$.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {

			if ( this.options.disabled || this.greedyChild || !this.visible ) {
				return;
			}

			var parentInstance, scope, parent,
				intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ),
				c = !intersects && this.isover ? "isout" : ( intersects && !this.isover ? "isover" : null );
			if ( !c ) {
				return;
			}

			if ( this.options.greedy ) {
				// find droppable parents with same scope
				scope = this.options.scope;
				parent = this.element.parents( ":data(ui-droppable)" ).filter(function() {
					return $( this ).droppable( "instance" ).options.scope === scope;
				});

				if ( parent.length ) {
					parentInstance = $( parent[ 0 ] ).droppable( "instance" );
					parentInstance.greedyChild = ( c === "isover" );
				}
			}

			// we just moved into a greedy child
			if ( parentInstance && c === "isover" ) {
				parentInstance.isover = false;
				parentInstance.isout = true;
				parentInstance._out.call( parentInstance, event );
			}

			this[ c ] = true;
			this[c === "isout" ? "isover" : "isout"] = false;
			this[c === "isover" ? "_over" : "_out"].call( this, event );

			// we just moved out of a greedy child
			if ( parentInstance && c === "isout" ) {
				parentInstance.isout = false;
				parentInstance.isover = true;
				parentInstance._over.call( parentInstance, event );
			}
		});

	},
	dragStop: function( draggable, event ) {
		draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
		// Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
		if ( !draggable.options.refreshPositions ) {
			$.ui.ddmanager.prepareOffsets( draggable, event );
		}
	}
};

var droppable = $.ui.droppable;


/*!
 * jQuery UI Effects 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/category/effects-core/
 */


var dataSpace = "ui-effects-",

	// Create a local jQuery because jQuery Color relies on it and the
	// global may not exist with AMD and a custom build (#10199)
	jQuery = $;

$.effects = {
	effect: {}
};

/*!
 * jQuery Color Animations v2.1.2
 * https://github.com/jquery/jquery-color
 *
 * Copyright 2014 jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * Date: Wed Jan 16 08:47:09 2013 -0600
 */
(function( jQuery, undefined ) {

	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",

	// plusequals test for += 100 -= 100
	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
	// a set of RE's that can match strings and generate color tuples.
	stringParsers = [ {
			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
			parse: function( execResult ) {
				return [
					execResult[ 1 ],
					execResult[ 2 ],
					execResult[ 3 ],
					execResult[ 4 ]
				];
			}
		}, {
			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
			parse: function( execResult ) {
				return [
					execResult[ 1 ] * 2.55,
					execResult[ 2 ] * 2.55,
					execResult[ 3 ] * 2.55,
					execResult[ 4 ]
				];
			}
		}, {
			// this regex ignores A-F because it's compared against an already lowercased string
			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
			parse: function( execResult ) {
				return [
					parseInt( execResult[ 1 ], 16 ),
					parseInt( execResult[ 2 ], 16 ),
					parseInt( execResult[ 3 ], 16 )
				];
			}
		}, {
			// this regex ignores A-F because it's compared against an already lowercased string
			re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
			parse: function( execResult ) {
				return [
					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
				];
			}
		}, {
			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
			space: "hsla",
			parse: function( execResult ) {
				return [
					execResult[ 1 ],
					execResult[ 2 ] / 100,
					execResult[ 3 ] / 100,
					execResult[ 4 ]
				];
			}
		} ],

	// jQuery.Color( )
	color = jQuery.Color = function( color, green, blue, alpha ) {
		return new jQuery.Color.fn.parse( color, green, blue, alpha );
	},
	spaces = {
		rgba: {
			props: {
				red: {
					idx: 0,
					type: "byte"
				},
				green: {
					idx: 1,
					type: "byte"
				},
				blue: {
					idx: 2,
					type: "byte"
				}
			}
		},

		hsla: {
			props: {
				hue: {
					idx: 0,
					type: "degrees"
				},
				saturation: {
					idx: 1,
					type: "percent"
				},
				lightness: {
					idx: 2,
					type: "percent"
				}
			}
		}
	},
	propTypes = {
		"byte": {
			floor: true,
			max: 255
		},
		"percent": {
			max: 1
		},
		"degrees": {
			mod: 360,
			floor: true
		}
	},
	support = color.support = {},

	// element for support tests
	supportElem = jQuery( "<p>" )[ 0 ],

	// colors = jQuery.Color.names
	colors,

	// local aliases of functions called often
	each = jQuery.each;

// determine rgba support immediately
supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;

// define cache name and alpha properties
// for rgba and hsla spaces
each( spaces, function( spaceName, space ) {
	space.cache = "_" + spaceName;
	space.props.alpha = {
		idx: 3,
		type: "percent",
		def: 1
	};
});

function clamp( value, prop, allowEmpty ) {
	var type = propTypes[ prop.type ] || {};

	if ( value == null ) {
		return (allowEmpty || !prop.def) ? null : prop.def;
	}

	// ~~ is an short way of doing floor for positive numbers
	value = type.floor ? ~~value : parseFloat( value );

	// IE will pass in empty strings as value for alpha,
	// which will hit this case
	if ( isNaN( value ) ) {
		return prop.def;
	}

	if ( type.mod ) {
		// we add mod before modding to make sure that negatives values
		// get converted properly: -10 -> 350
		return (value + type.mod) % type.mod;
	}

	// for now all property types without mod have min and max
	return 0 > value ? 0 : type.max < value ? type.max : value;
}

function stringParse( string ) {
	var inst = color(),
		rgba = inst._rgba = [];

	string = string.toLowerCase();

	each( stringParsers, function( i, parser ) {
		var parsed,
			match = parser.re.exec( string ),
			values = match && parser.parse( match ),
			spaceName = parser.space || "rgba";

		if ( values ) {
			parsed = inst[ spaceName ]( values );

			// if this was an rgba parse the assignment might happen twice
			// oh well....
			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
			rgba = inst._rgba = parsed._rgba;

			// exit each( stringParsers ) here because we matched
			return false;
		}
	});

	// Found a stringParser that handled it
	if ( rgba.length ) {

		// if this came from a parsed string, force "transparent" when alpha is 0
		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
		if ( rgba.join() === "0,0,0,0" ) {
			jQuery.extend( rgba, colors.transparent );
		}
		return inst;
	}

	// named colors
	return colors[ string ];
}

color.fn = jQuery.extend( color.prototype, {
	parse: function( red, green, blue, alpha ) {
		if ( red === undefined ) {
			this._rgba = [ null, null, null, null ];
			return this;
		}
		if ( red.jquery || red.nodeType ) {
			red = jQuery( red ).css( green );
			green = undefined;
		}

		var inst = this,
			type = jQuery.type( red ),
			rgba = this._rgba = [];

		// more than 1 argument specified - assume ( red, green, blue, alpha )
		if ( green !== undefined ) {
			red = [ red, green, blue, alpha ];
			type = "array";
		}

		if ( type === "string" ) {
			return this.parse( stringParse( red ) || colors._default );
		}

		if ( type === "array" ) {
			each( spaces.rgba.props, function( key, prop ) {
				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
			});
			return this;
		}

		if ( type === "object" ) {
			if ( red instanceof color ) {
				each( spaces, function( spaceName, space ) {
					if ( red[ space.cache ] ) {
						inst[ space.cache ] = red[ space.cache ].slice();
					}
				});
			} else {
				each( spaces, function( spaceName, space ) {
					var cache = space.cache;
					each( space.props, function( key, prop ) {

						// if the cache doesn't exist, and we know how to convert
						if ( !inst[ cache ] && space.to ) {

							// if the value was null, we don't need to copy it
							// if the key was alpha, we don't need to copy it either
							if ( key === "alpha" || red[ key ] == null ) {
								return;
							}
							inst[ cache ] = space.to( inst._rgba );
						}

						// this is the only case where we allow nulls for ALL properties.
						// call clamp with alwaysAllowEmpty
						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
					});

					// everything defined but alpha?
					if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
						// use the default of 1
						inst[ cache ][ 3 ] = 1;
						if ( space.from ) {
							inst._rgba = space.from( inst[ cache ] );
						}
					}
				});
			}
			return this;
		}
	},
	is: function( compare ) {
		var is = color( compare ),
			same = true,
			inst = this;

		each( spaces, function( _, space ) {
			var localCache,
				isCache = is[ space.cache ];
			if (isCache) {
				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
				each( space.props, function( _, prop ) {
					if ( isCache[ prop.idx ] != null ) {
						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
						return same;
					}
				});
			}
			return same;
		});
		return same;
	},
	_space: function() {
		var used = [],
			inst = this;
		each( spaces, function( spaceName, space ) {
			if ( inst[ space.cache ] ) {
				used.push( spaceName );
			}
		});
		return used.pop();
	},
	transition: function( other, distance ) {
		var end = color( other ),
			spaceName = end._space(),
			space = spaces[ spaceName ],
			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
			start = startColor[ space.cache ] || space.to( startColor._rgba ),
			result = start.slice();

		end = end[ space.cache ];
		each( space.props, function( key, prop ) {
			var index = prop.idx,
				startValue = start[ index ],
				endValue = end[ index ],
				type = propTypes[ prop.type ] || {};

			// if null, don't override start value
			if ( endValue === null ) {
				return;
			}
			// if null - use end
			if ( startValue === null ) {
				result[ index ] = endValue;
			} else {
				if ( type.mod ) {
					if ( endValue - startValue > type.mod / 2 ) {
						startValue += type.mod;
					} else if ( startValue - endValue > type.mod / 2 ) {
						startValue -= type.mod;
					}
				}
				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
			}
		});
		return this[ spaceName ]( result );
	},
	blend: function( opaque ) {
		// if we are already opaque - return ourself
		if ( this._rgba[ 3 ] === 1 ) {
			return this;
		}

		var rgb = this._rgba.slice(),
			a = rgb.pop(),
			blend = color( opaque )._rgba;

		return color( jQuery.map( rgb, function( v, i ) {
			return ( 1 - a ) * blend[ i ] + a * v;
		}));
	},
	toRgbaString: function() {
		var prefix = "rgba(",
			rgba = jQuery.map( this._rgba, function( v, i ) {
				return v == null ? ( i > 2 ? 1 : 0 ) : v;
			});

		if ( rgba[ 3 ] === 1 ) {
			rgba.pop();
			prefix = "rgb(";
		}

		return prefix + rgba.join() + ")";
	},
	toHslaString: function() {
		var prefix = "hsla(",
			hsla = jQuery.map( this.hsla(), function( v, i ) {
				if ( v == null ) {
					v = i > 2 ? 1 : 0;
				}

				// catch 1 and 2
				if ( i && i < 3 ) {
					v = Math.round( v * 100 ) + "%";
				}
				return v;
			});

		if ( hsla[ 3 ] === 1 ) {
			hsla.pop();
			prefix = "hsl(";
		}
		return prefix + hsla.join() + ")";
	},
	toHexString: function( includeAlpha ) {
		var rgba = this._rgba.slice(),
			alpha = rgba.pop();

		if ( includeAlpha ) {
			rgba.push( ~~( alpha * 255 ) );
		}

		return "#" + jQuery.map( rgba, function( v ) {

			// default to 0 when nulls exist
			v = ( v || 0 ).toString( 16 );
			return v.length === 1 ? "0" + v : v;
		}).join("");
	},
	toString: function() {
		return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
	}
});
color.fn.parse.prototype = color.fn;

// hsla conversions adapted from:
// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021

function hue2rgb( p, q, h ) {
	h = ( h + 1 ) % 1;
	if ( h * 6 < 1 ) {
		return p + ( q - p ) * h * 6;
	}
	if ( h * 2 < 1) {
		return q;
	}
	if ( h * 3 < 2 ) {
		return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
	}
	return p;
}

spaces.hsla.to = function( rgba ) {
	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
		return [ null, null, null, rgba[ 3 ] ];
	}
	var r = rgba[ 0 ] / 255,
		g = rgba[ 1 ] / 255,
		b = rgba[ 2 ] / 255,
		a = rgba[ 3 ],
		max = Math.max( r, g, b ),
		min = Math.min( r, g, b ),
		diff = max - min,
		add = max + min,
		l = add * 0.5,
		h, s;

	if ( min === max ) {
		h = 0;
	} else if ( r === max ) {
		h = ( 60 * ( g - b ) / diff ) + 360;
	} else if ( g === max ) {
		h = ( 60 * ( b - r ) / diff ) + 120;
	} else {
		h = ( 60 * ( r - g ) / diff ) + 240;
	}

	// chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
	// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
	if ( diff === 0 ) {
		s = 0;
	} else if ( l <= 0.5 ) {
		s = diff / add;
	} else {
		s = diff / ( 2 - add );
	}
	return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
};

spaces.hsla.from = function( hsla ) {
	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
		return [ null, null, null, hsla[ 3 ] ];
	}
	var h = hsla[ 0 ] / 360,
		s = hsla[ 1 ],
		l = hsla[ 2 ],
		a = hsla[ 3 ],
		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
		p = 2 * l - q;

	return [
		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
		Math.round( hue2rgb( p, q, h ) * 255 ),
		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
		a
	];
};

each( spaces, function( spaceName, space ) {
	var props = space.props,
		cache = space.cache,
		to = space.to,
		from = space.from;

	// makes rgba() and hsla()
	color.fn[ spaceName ] = function( value ) {

		// generate a cache for this space if it doesn't exist
		if ( to && !this[ cache ] ) {
			this[ cache ] = to( this._rgba );
		}
		if ( value === undefined ) {
			return this[ cache ].slice();
		}

		var ret,
			type = jQuery.type( value ),
			arr = ( type === "array" || type === "object" ) ? value : arguments,
			local = this[ cache ].slice();

		each( props, function( key, prop ) {
			var val = arr[ type === "object" ? key : prop.idx ];
			if ( val == null ) {
				val = local[ prop.idx ];
			}
			local[ prop.idx ] = clamp( val, prop );
		});

		if ( from ) {
			ret = color( from( local ) );
			ret[ cache ] = local;
			return ret;
		} else {
			return color( local );
		}
	};

	// makes red() green() blue() alpha() hue() saturation() lightness()
	each( props, function( key, prop ) {
		// alpha is included in more than one space
		if ( color.fn[ key ] ) {
			return;
		}
		color.fn[ key ] = function( value ) {
			var vtype = jQuery.type( value ),
				fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
				local = this[ fn ](),
				cur = local[ prop.idx ],
				match;

			if ( vtype === "undefined" ) {
				return cur;
			}

			if ( vtype === "function" ) {
				value = value.call( this, cur );
				vtype = jQuery.type( value );
			}
			if ( value == null && prop.empty ) {
				return this;
			}
			if ( vtype === "string" ) {
				match = rplusequals.exec( value );
				if ( match ) {
					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
				}
			}
			local[ prop.idx ] = value;
			return this[ fn ]( local );
		};
	});
});

// add cssHook and .fx.step function for each named hook.
// accept a space separated string of properties
color.hook = function( hook ) {
	var hooks = hook.split( " " );
	each( hooks, function( i, hook ) {
		jQuery.cssHooks[ hook ] = {
			set: function( elem, value ) {
				var parsed, curElem,
					backgroundColor = "";

				if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
					value = color( parsed || value );
					if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
						curElem = hook === "backgroundColor" ? elem.parentNode : elem;
						while (
							(backgroundColor === "" || backgroundColor === "transparent") &&
							curElem && curElem.style
						) {
							try {
								backgroundColor = jQuery.css( curElem, "backgroundColor" );
								curElem = curElem.parentNode;
							} catch ( e ) {
							}
						}

						value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
							backgroundColor :
							"_default" );
					}

					value = value.toRgbaString();
				}
				try {
					elem.style[ hook ] = value;
				} catch ( e ) {
					// wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
				}
			}
		};
		jQuery.fx.step[ hook ] = function( fx ) {
			if ( !fx.colorInit ) {
				fx.start = color( fx.elem, hook );
				fx.end = color( fx.end );
				fx.colorInit = true;
			}
			jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
		};
	});

};

color.hook( stepHooks );

jQuery.cssHooks.borderColor = {
	expand: function( value ) {
		var expanded = {};

		each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
			expanded[ "border" + part + "Color" ] = value;
		});
		return expanded;
	}
};

// Basic color names only.
// Usage of any of the other color names requires adding yourself or including
// jquery.color.svg-names.js.
colors = jQuery.Color.names = {
	// 4.1. Basic color keywords
	aqua: "#00ffff",
	black: "#000000",
	blue: "#0000ff",
	fuchsia: "#ff00ff",
	gray: "#808080",
	green: "#008000",
	lime: "#00ff00",
	maroon: "#800000",
	navy: "#000080",
	olive: "#808000",
	purple: "#800080",
	red: "#ff0000",
	silver: "#c0c0c0",
	teal: "#008080",
	white: "#ffffff",
	yellow: "#ffff00",

	// 4.2.3. "transparent" color keyword
	transparent: [ null, null, null, 0 ],

	_default: "#ffffff"
};

})( jQuery );

/******************************************************************************/
/****************************** CLASS ANIMATIONS ******************************/
/******************************************************************************/
(function() {

var classAnimationActions = [ "add", "remove", "toggle" ],
	shorthandStyles = {
		border: 1,
		borderBottom: 1,
		borderColor: 1,
		borderLeft: 1,
		borderRight: 1,
		borderTop: 1,
		borderWidth: 1,
		margin: 1,
		padding: 1
	};

$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
	$.fx.step[ prop ] = function( fx ) {
		if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
			jQuery.style( fx.elem, prop, fx.end );
			fx.setAttr = true;
		}
	};
});

function getElementStyles( elem ) {
	var key, len,
		style = elem.ownerDocument.defaultView ?
			elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
			elem.currentStyle,
		styles = {};

	if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
		len = style.length;
		while ( len-- ) {
			key = style[ len ];
			if ( typeof style[ key ] === "string" ) {
				styles[ $.camelCase( key ) ] = style[ key ];
			}
		}
	// support: Opera, IE <9
	} else {
		for ( key in style ) {
			if ( typeof style[ key ] === "string" ) {
				styles[ key ] = style[ key ];
			}
		}
	}

	return styles;
}

function styleDifference( oldStyle, newStyle ) {
	var diff = {},
		name, value;

	for ( name in newStyle ) {
		value = newStyle[ name ];
		if ( oldStyle[ name ] !== value ) {
			if ( !shorthandStyles[ name ] ) {
				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
					diff[ name ] = value;
				}
			}
		}
	}

	return diff;
}

// support: jQuery <1.8
if ( !$.fn.addBack ) {
	$.fn.addBack = function( selector ) {
		return this.add( selector == null ?
			this.prevObject : this.prevObject.filter( selector )
		);
	};
}

$.effects.animateClass = function( value, duration, easing, callback ) {
	var o = $.speed( duration, easing, callback );

	return this.queue( function() {
		var animated = $( this ),
			baseClass = animated.attr( "class" ) || "",
			applyClassChange,
			allAnimations = o.children ? animated.find( "*" ).addBack() : animated;

		// map the animated objects to store the original styles.
		allAnimations = allAnimations.map(function() {
			var el = $( this );
			return {
				el: el,
				start: getElementStyles( this )
			};
		});

		// apply class change
		applyClassChange = function() {
			$.each( classAnimationActions, function(i, action) {
				if ( value[ action ] ) {
					animated[ action + "Class" ]( value[ action ] );
				}
			});
		};
		applyClassChange();

		// map all animated objects again - calculate new styles and diff
		allAnimations = allAnimations.map(function() {
			this.end = getElementStyles( this.el[ 0 ] );
			this.diff = styleDifference( this.start, this.end );
			return this;
		});

		// apply original class
		animated.attr( "class", baseClass );

		// map all animated objects again - this time collecting a promise
		allAnimations = allAnimations.map(function() {
			var styleInfo = this,
				dfd = $.Deferred(),
				opts = $.extend({}, o, {
					queue: false,
					complete: function() {
						dfd.resolve( styleInfo );
					}
				});

			this.el.animate( this.diff, opts );
			return dfd.promise();
		});

		// once all animations have completed:
		$.when.apply( $, allAnimations.get() ).done(function() {

			// set the final class
			applyClassChange();

			// for each animated element,
			// clear all css properties that were animated
			$.each( arguments, function() {
				var el = this.el;
				$.each( this.diff, function(key) {
					el.css( key, "" );
				});
			});

			// this is guarnteed to be there if you use jQuery.speed()
			// it also handles dequeuing the next anim...
			o.complete.call( animated[ 0 ] );
		});
	});
};

$.fn.extend({
	addClass: (function( orig ) {
		return function( classNames, speed, easing, callback ) {
			return speed ?
				$.effects.animateClass.call( this,
					{ add: classNames }, speed, easing, callback ) :
				orig.apply( this, arguments );
		};
	})( $.fn.addClass ),

	removeClass: (function( orig ) {
		return function( classNames, speed, easing, callback ) {
			return arguments.length > 1 ?
				$.effects.animateClass.call( this,
					{ remove: classNames }, speed, easing, callback ) :
				orig.apply( this, arguments );
		};
	})( $.fn.removeClass ),

	toggleClass: (function( orig ) {
		return function( classNames, force, speed, easing, callback ) {
			if ( typeof force === "boolean" || force === undefined ) {
				if ( !speed ) {
					// without speed parameter
					return orig.apply( this, arguments );
				} else {
					return $.effects.animateClass.call( this,
						(force ? { add: classNames } : { remove: classNames }),
						speed, easing, callback );
				}
			} else {
				// without force parameter
				return $.effects.animateClass.call( this,
					{ toggle: classNames }, force, speed, easing );
			}
		};
	})( $.fn.toggleClass ),

	switchClass: function( remove, add, speed, easing, callback) {
		return $.effects.animateClass.call( this, {
			add: add,
			remove: remove
		}, speed, easing, callback );
	}
});

})();

/******************************************************************************/
/*********************************** EFFECTS **********************************/
/******************************************************************************/

(function() {

$.extend( $.effects, {
	version: "1.11.4",

	// Saves a set of properties in a data storage
	save: function( element, set ) {
		for ( var i = 0; i < set.length; i++ ) {
			if ( set[ i ] !== null ) {
				element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
			}
		}
	},

	// Restores a set of previously saved properties from a data storage
	restore: function( element, set ) {
		var val, i;
		for ( i = 0; i < set.length; i++ ) {
			if ( set[ i ] !== null ) {
				val = element.data( dataSpace + set[ i ] );
				// support: jQuery 1.6.2
				// http://bugs.jquery.com/ticket/9917
				// jQuery 1.6.2 incorrectly returns undefined for any falsy value.
				// We can't differentiate between "" and 0 here, so we just assume
				// empty string since it's likely to be a more common value...
				if ( val === undefined ) {
					val = "";
				}
				element.css( set[ i ], val );
			}
		}
	},

	setMode: function( el, mode ) {
		if (mode === "toggle") {
			mode = el.is( ":hidden" ) ? "show" : "hide";
		}
		return mode;
	},

	// Translates a [top,left] array into a baseline value
	// this should be a little more flexible in the future to handle a string & hash
	getBaseline: function( origin, original ) {
		var y, x;
		switch ( origin[ 0 ] ) {
			case "top": y = 0; break;
			case "middle": y = 0.5; break;
			case "bottom": y = 1; break;
			default: y = origin[ 0 ] / original.height;
		}
		switch ( origin[ 1 ] ) {
			case "left": x = 0; break;
			case "center": x = 0.5; break;
			case "right": x = 1; break;
			default: x = origin[ 1 ] / original.width;
		}
		return {
			x: x,
			y: y
		};
	},

	// Wraps the element around a wrapper that copies position properties
	createWrapper: function( element ) {

		// if the element is already wrapped, return it
		if ( element.parent().is( ".ui-effects-wrapper" )) {
			return element.parent();
		}

		// wrap the element
		var props = {
				width: element.outerWidth(true),
				height: element.outerHeight(true),
				"float": element.css( "float" )
			},
			wrapper = $( "<div></div>" )
				.addClass( "ui-effects-wrapper" )
				.css({
					fontSize: "100%",
					background: "transparent",
					border: "none",
					margin: 0,
					padding: 0
				}),
			// Store the size in case width/height are defined in % - Fixes #5245
			size = {
				width: element.width(),
				height: element.height()
			},
			active = document.activeElement;

		// support: Firefox
		// Firefox incorrectly exposes anonymous content
		// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
		try {
			active.id;
		} catch ( e ) {
			active = document.body;
		}

		element.wrap( wrapper );

		// Fixes #7595 - Elements lose focus when wrapped.
		if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
			$( active ).focus();
		}

		wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element

		// transfer positioning properties to the wrapper
		if ( element.css( "position" ) === "static" ) {
			wrapper.css({ position: "relative" });
			element.css({ position: "relative" });
		} else {
			$.extend( props, {
				position: element.css( "position" ),
				zIndex: element.css( "z-index" )
			});
			$.each([ "top", "left", "bottom", "right" ], function(i, pos) {
				props[ pos ] = element.css( pos );
				if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
					props[ pos ] = "auto";
				}
			});
			element.css({
				position: "relative",
				top: 0,
				left: 0,
				right: "auto",
				bottom: "auto"
			});
		}
		element.css(size);

		return wrapper.css( props ).show();
	},

	removeWrapper: function( element ) {
		var active = document.activeElement;

		if ( element.parent().is( ".ui-effects-wrapper" ) ) {
			element.parent().replaceWith( element );

			// Fixes #7595 - Elements lose focus when wrapped.
			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
				$( active ).focus();
			}
		}

		return element;
	},

	setTransition: function( element, list, factor, value ) {
		value = value || {};
		$.each( list, function( i, x ) {
			var unit = element.cssUnit( x );
			if ( unit[ 0 ] > 0 ) {
				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
			}
		});
		return value;
	}
});

// return an effect options object for the given parameters:
function _normalizeArguments( effect, options, speed, callback ) {

	// allow passing all options as the first parameter
	if ( $.isPlainObject( effect ) ) {
		options = effect;
		effect = effect.effect;
	}

	// convert to an object
	effect = { effect: effect };

	// catch (effect, null, ...)
	if ( options == null ) {
		options = {};
	}

	// catch (effect, callback)
	if ( $.isFunction( options ) ) {
		callback = options;
		speed = null;
		options = {};
	}

	// catch (effect, speed, ?)
	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
		callback = speed;
		speed = options;
		options = {};
	}

	// catch (effect, options, callback)
	if ( $.isFunction( speed ) ) {
		callback = speed;
		speed = null;
	}

	// add options to effect
	if ( options ) {
		$.extend( effect, options );
	}

	speed = speed || options.duration;
	effect.duration = $.fx.off ? 0 :
		typeof speed === "number" ? speed :
		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
		$.fx.speeds._default;

	effect.complete = callback || options.complete;

	return effect;
}

function standardAnimationOption( option ) {
	// Valid standard speeds (nothing, number, named speed)
	if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
		return true;
	}

	// Invalid strings - treat as "normal" speed
	if ( typeof option === "string" && !$.effects.effect[ option ] ) {
		return true;
	}

	// Complete callback
	if ( $.isFunction( option ) ) {
		return true;
	}

	// Options hash (but not naming an effect)
	if ( typeof option === "object" && !option.effect ) {
		return true;
	}

	// Didn't match any standard API
	return false;
}

$.fn.extend({
	effect: function( /* effect, options, speed, callback */ ) {
		var args = _normalizeArguments.apply( this, arguments ),
			mode = args.mode,
			queue = args.queue,
			effectMethod = $.effects.effect[ args.effect ];

		if ( $.fx.off || !effectMethod ) {
			// delegate to the original method (e.g., .show()) if possible
			if ( mode ) {
				return this[ mode ]( args.duration, args.complete );
			} else {
				return this.each( function() {
					if ( args.complete ) {
						args.complete.call( this );
					}
				});
			}
		}

		function run( next ) {
			var elem = $( this ),
				complete = args.complete,
				mode = args.mode;

			function done() {
				if ( $.isFunction( complete ) ) {
					complete.call( elem[0] );
				}
				if ( $.isFunction( next ) ) {
					next();
				}
			}

			// If the element already has the correct final state, delegate to
			// the core methods so the internal tracking of "olddisplay" works.
			if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
				elem[ mode ]();
				done();
			} else {
				effectMethod.call( elem[0], args, done );
			}
		}

		return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
	},

	show: (function( orig ) {
		return function( option ) {
			if ( standardAnimationOption( option ) ) {
				return orig.apply( this, arguments );
			} else {
				var args = _normalizeArguments.apply( this, arguments );
				args.mode = "show";
				return this.effect.call( this, args );
			}
		};
	})( $.fn.show ),

	hide: (function( orig ) {
		return function( option ) {
			if ( standardAnimationOption( option ) ) {
				return orig.apply( this, arguments );
			} else {
				var args = _normalizeArguments.apply( this, arguments );
				args.mode = "hide";
				return this.effect.call( this, args );
			}
		};
	})( $.fn.hide ),

	toggle: (function( orig ) {
		return function( option ) {
			if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
				return orig.apply( this, arguments );
			} else {
				var args = _normalizeArguments.apply( this, arguments );
				args.mode = "toggle";
				return this.effect.call( this, args );
			}
		};
	})( $.fn.toggle ),

	// helper functions
	cssUnit: function(key) {
		var style = this.css( key ),
			val = [];

		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
			if ( style.indexOf( unit ) > 0 ) {
				val = [ parseFloat( style ), unit ];
			}
		});
		return val;
	}
});

})();

/******************************************************************************/
/*********************************** EASING ***********************************/
/******************************************************************************/

(function() {

// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)

var baseEasings = {};

$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
	baseEasings[ name ] = function( p ) {
		return Math.pow( p, i + 2 );
	};
});

$.extend( baseEasings, {
	Sine: function( p ) {
		return 1 - Math.cos( p * Math.PI / 2 );
	},
	Circ: function( p ) {
		return 1 - Math.sqrt( 1 - p * p );
	},
	Elastic: function( p ) {
		return p === 0 || p === 1 ? p :
			-Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
	},
	Back: function( p ) {
		return p * p * ( 3 * p - 2 );
	},
	Bounce: function( p ) {
		var pow2,
			bounce = 4;

		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
	}
});

$.each( baseEasings, function( name, easeIn ) {
	$.easing[ "easeIn" + name ] = easeIn;
	$.easing[ "easeOut" + name ] = function( p ) {
		return 1 - easeIn( 1 - p );
	};
	$.easing[ "easeInOut" + name ] = function( p ) {
		return p < 0.5 ?
			easeIn( p * 2 ) / 2 :
			1 - easeIn( p * -2 + 2 ) / 2;
	};
});

})();

var effect = $.effects;


/*!
 * jQuery UI Effects Blind 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/blind-effect/
 */


var effectBlind = $.effects.effect.blind = function( o, done ) {
	// Create element
	var el = $( this ),
		rvertical = /up|down|vertical/,
		rpositivemotion = /up|left|vertical|horizontal/,
		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
		mode = $.effects.setMode( el, o.mode || "hide" ),
		direction = o.direction || "up",
		vertical = rvertical.test( direction ),
		ref = vertical ? "height" : "width",
		ref2 = vertical ? "top" : "left",
		motion = rpositivemotion.test( direction ),
		animation = {},
		show = mode === "show",
		wrapper, distance, margin;

	// if already wrapped, the wrapper's properties are my property. #6245
	if ( el.parent().is( ".ui-effects-wrapper" ) ) {
		$.effects.save( el.parent(), props );
	} else {
		$.effects.save( el, props );
	}
	el.show();
	wrapper = $.effects.createWrapper( el ).css({
		overflow: "hidden"
	});

	distance = wrapper[ ref ]();
	margin = parseFloat( wrapper.css( ref2 ) ) || 0;

	animation[ ref ] = show ? distance : 0;
	if ( !motion ) {
		el
			.css( vertical ? "bottom" : "right", 0 )
			.css( vertical ? "top" : "left", "auto" )
			.css({ position: "absolute" });

		animation[ ref2 ] = show ? margin : distance + margin;
	}

	// start at 0 if we are showing
	if ( show ) {
		wrapper.css( ref, 0 );
		if ( !motion ) {
			wrapper.css( ref2, margin + distance );
		}
	}

	// Animate
	wrapper.animate( animation, {
		duration: o.duration,
		easing: o.easing,
		queue: false,
		complete: function() {
			if ( mode === "hide" ) {
				el.hide();
			}
			$.effects.restore( el, props );
			$.effects.removeWrapper( el );
			done();
		}
	});
};


/*!
 * jQuery UI Effects Bounce 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/bounce-effect/
 */


var effectBounce = $.effects.effect.bounce = function( o, done ) {
	var el = $( this ),
		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],

		// defaults:
		mode = $.effects.setMode( el, o.mode || "effect" ),
		hide = mode === "hide",
		show = mode === "show",
		direction = o.direction || "up",
		distance = o.distance,
		times = o.times || 5,

		// number of internal animations
		anims = times * 2 + ( show || hide ? 1 : 0 ),
		speed = o.duration / anims,
		easing = o.easing,

		// utility:
		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
		motion = ( direction === "up" || direction === "left" ),
		i,
		upAnim,
		downAnim,

		// we will need to re-assemble the queue to stack our animations in place
		queue = el.queue(),
		queuelen = queue.length;

	// Avoid touching opacity to prevent clearType and PNG issues in IE
	if ( show || hide ) {
		props.push( "opacity" );
	}

	$.effects.save( el, props );
	el.show();
	$.effects.createWrapper( el ); // Create Wrapper

	// default distance for the BIGGEST bounce is the outer Distance / 3
	if ( !distance ) {
		distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
	}

	if ( show ) {
		downAnim = { opacity: 1 };
		downAnim[ ref ] = 0;

		// if we are showing, force opacity 0 and set the initial position
		// then do the "first" animation
		el.css( "opacity", 0 )
			.css( ref, motion ? -distance * 2 : distance * 2 )
			.animate( downAnim, speed, easing );
	}

	// start at the smallest distance if we are hiding
	if ( hide ) {
		distance = distance / Math.pow( 2, times - 1 );
	}

	downAnim = {};
	downAnim[ ref ] = 0;
	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
	for ( i = 0; i < times; i++ ) {
		upAnim = {};
		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;

		el.animate( upAnim, speed, easing )
			.animate( downAnim, speed, easing );

		distance = hide ? distance * 2 : distance / 2;
	}

	// Last Bounce when Hiding
	if ( hide ) {
		upAnim = { opacity: 0 };
		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;

		el.animate( upAnim, speed, easing );
	}

	el.queue(function() {
		if ( hide ) {
			el.hide();
		}
		$.effects.restore( el, props );
		$.effects.removeWrapper( el );
		done();
	});

	// inject all the animations we just queued to be first in line (after "inprogress")
	if ( queuelen > 1) {
		queue.splice.apply( queue,
			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
	}
	el.dequeue();

};


/*!
 * jQuery UI Effects Clip 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/clip-effect/
 */


var effectClip = $.effects.effect.clip = function( o, done ) {
	// Create element
	var el = $( this ),
		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
		mode = $.effects.setMode( el, o.mode || "hide" ),
		show = mode === "show",
		direction = o.direction || "vertical",
		vert = direction === "vertical",
		size = vert ? "height" : "width",
		position = vert ? "top" : "left",
		animation = {},
		wrapper, animate, distance;

	// Save & Show
	$.effects.save( el, props );
	el.show();

	// Create Wrapper
	wrapper = $.effects.createWrapper( el ).css({
		overflow: "hidden"
	});
	animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
	distance = animate[ size ]();

	// Shift
	if ( show ) {
		animate.css( size, 0 );
		animate.css( position, distance / 2 );
	}

	// Create Animation Object:
	animation[ size ] = show ? distance : 0;
	animation[ position ] = show ? 0 : distance / 2;

	// Animate
	animate.animate( animation, {
		queue: false,
		duration: o.duration,
		easing: o.easing,
		complete: function() {
			if ( !show ) {
				el.hide();
			}
			$.effects.restore( el, props );
			$.effects.removeWrapper( el );
			done();
		}
	});

};


/*!
 * jQuery UI Effects Drop 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/drop-effect/
 */


var effectDrop = $.effects.effect.drop = function( o, done ) {

	var el = $( this ),
		props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
		mode = $.effects.setMode( el, o.mode || "hide" ),
		show = mode === "show",
		direction = o.direction || "left",
		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
		motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
		animation = {
			opacity: show ? 1 : 0
		},
		distance;

	// Adjust
	$.effects.save( el, props );
	el.show();
	$.effects.createWrapper( el );

	distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;

	if ( show ) {
		el
			.css( "opacity", 0 )
			.css( ref, motion === "pos" ? -distance : distance );
	}

	// Animation
	animation[ ref ] = ( show ?
		( motion === "pos" ? "+=" : "-=" ) :
		( motion === "pos" ? "-=" : "+=" ) ) +
		distance;

	// Animate
	el.animate( animation, {
		queue: false,
		duration: o.duration,
		easing: o.easing,
		complete: function() {
			if ( mode === "hide" ) {
				el.hide();
			}
			$.effects.restore( el, props );
			$.effects.removeWrapper( el );
			done();
		}
	});
};


/*!
 * jQuery UI Effects Explode 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/explode-effect/
 */


var effectExplode = $.effects.effect.explode = function( o, done ) {

	var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
		cells = rows,
		el = $( this ),
		mode = $.effects.setMode( el, o.mode || "hide" ),
		show = mode === "show",

		// show and then visibility:hidden the element before calculating offset
		offset = el.show().css( "visibility", "hidden" ).offset(),

		// width and height of a piece
		width = Math.ceil( el.outerWidth() / cells ),
		height = Math.ceil( el.outerHeight() / rows ),
		pieces = [],

		// loop
		i, j, left, top, mx, my;

	// children animate complete:
	function childComplete() {
		pieces.push( this );
		if ( pieces.length === rows * cells ) {
			animComplete();
		}
	}

	// clone the element for each row and cell.
	for ( i = 0; i < rows ; i++ ) { // ===>
		top = offset.top + i * height;
		my = i - ( rows - 1 ) / 2 ;

		for ( j = 0; j < cells ; j++ ) { // |||
			left = offset.left + j * width;
			mx = j - ( cells - 1 ) / 2 ;

			// Create a clone of the now hidden main element that will be absolute positioned
			// within a wrapper div off the -left and -top equal to size of our pieces
			el
				.clone()
				.appendTo( "body" )
				.wrap( "<div></div>" )
				.css({
					position: "absolute",
					visibility: "visible",
					left: -j * width,
					top: -i * height
				})

			// select the wrapper - make it overflow: hidden and absolute positioned based on
			// where the original was located +left and +top equal to the size of pieces
				.parent()
				.addClass( "ui-effects-explode" )
				.css({
					position: "absolute",
					overflow: "hidden",
					width: width,
					height: height,
					left: left + ( show ? mx * width : 0 ),
					top: top + ( show ? my * height : 0 ),
					opacity: show ? 0 : 1
				}).animate({
					left: left + ( show ? 0 : mx * width ),
					top: top + ( show ? 0 : my * height ),
					opacity: show ? 1 : 0
				}, o.duration || 500, o.easing, childComplete );
		}
	}

	function animComplete() {
		el.css({
			visibility: "visible"
		});
		$( pieces ).remove();
		if ( !show ) {
			el.hide();
		}
		done();
	}
};


/*!
 * jQuery UI Effects Fade 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/fade-effect/
 */


var effectFade = $.effects.effect.fade = function( o, done ) {
	var el = $( this ),
		mode = $.effects.setMode( el, o.mode || "toggle" );

	el.animate({
		opacity: mode
	}, {
		queue: false,
		duration: o.duration,
		easing: o.easing,
		complete: done
	});
};


/*!
 * jQuery UI Effects Fold 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/fold-effect/
 */


var effectFold = $.effects.effect.fold = function( o, done ) {

	// Create element
	var el = $( this ),
		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
		mode = $.effects.setMode( el, o.mode || "hide" ),
		show = mode === "show",
		hide = mode === "hide",
		size = o.size || 15,
		percent = /([0-9]+)%/.exec( size ),
		horizFirst = !!o.horizFirst,
		widthFirst = show !== horizFirst,
		ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
		duration = o.duration / 2,
		wrapper, distance,
		animation1 = {},
		animation2 = {};

	$.effects.save( el, props );
	el.show();

	// Create Wrapper
	wrapper = $.effects.createWrapper( el ).css({
		overflow: "hidden"
	});
	distance = widthFirst ?
		[ wrapper.width(), wrapper.height() ] :
		[ wrapper.height(), wrapper.width() ];

	if ( percent ) {
		size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
	}
	if ( show ) {
		wrapper.css( horizFirst ? {
			height: 0,
			width: size
		} : {
			height: size,
			width: 0
		});
	}

	// Animation
	animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
	animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;

	// Animate
	wrapper
		.animate( animation1, duration, o.easing )
		.animate( animation2, duration, o.easing, function() {
			if ( hide ) {
				el.hide();
			}
			$.effects.restore( el, props );
			$.effects.removeWrapper( el );
			done();
		});

};


/*!
 * jQuery UI Effects Highlight 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/highlight-effect/
 */


var effectHighlight = $.effects.effect.highlight = function( o, done ) {
	var elem = $( this ),
		props = [ "backgroundImage", "backgroundColor", "opacity" ],
		mode = $.effects.setMode( elem, o.mode || "show" ),
		animation = {
			backgroundColor: elem.css( "backgroundColor" )
		};

	if (mode === "hide") {
		animation.opacity = 0;
	}

	$.effects.save( elem, props );

	elem
		.show()
		.css({
			backgroundImage: "none",
			backgroundColor: o.color || "#ffff99"
		})
		.animate( animation, {
			queue: false,
			duration: o.duration,
			easing: o.easing,
			complete: function() {
				if ( mode === "hide" ) {
					elem.hide();
				}
				$.effects.restore( elem, props );
				done();
			}
		});
};


/*!
 * jQuery UI Effects Size 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/size-effect/
 */


var effectSize = $.effects.effect.size = function( o, done ) {

	// Create element
	var original, baseline, factor,
		el = $( this ),
		props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],

		// Always restore
		props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],

		// Copy for children
		props2 = [ "width", "height", "overflow" ],
		cProps = [ "fontSize" ],
		vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
		hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],

		// Set options
		mode = $.effects.setMode( el, o.mode || "effect" ),
		restore = o.restore || mode !== "effect",
		scale = o.scale || "both",
		origin = o.origin || [ "middle", "center" ],
		position = el.css( "position" ),
		props = restore ? props0 : props1,
		zero = {
			height: 0,
			width: 0,
			outerHeight: 0,
			outerWidth: 0
		};

	if ( mode === "show" ) {
		el.show();
	}
	original = {
		height: el.height(),
		width: el.width(),
		outerHeight: el.outerHeight(),
		outerWidth: el.outerWidth()
	};

	if ( o.mode === "toggle" && mode === "show" ) {
		el.from = o.to || zero;
		el.to = o.from || original;
	} else {
		el.from = o.from || ( mode === "show" ? zero : original );
		el.to = o.to || ( mode === "hide" ? zero : original );
	}

	// Set scaling factor
	factor = {
		from: {
			y: el.from.height / original.height,
			x: el.from.width / original.width
		},
		to: {
			y: el.to.height / original.height,
			x: el.to.width / original.width
		}
	};

	// Scale the css box
	if ( scale === "box" || scale === "both" ) {

		// Vertical props scaling
		if ( factor.from.y !== factor.to.y ) {
			props = props.concat( vProps );
			el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
			el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
		}

		// Horizontal props scaling
		if ( factor.from.x !== factor.to.x ) {
			props = props.concat( hProps );
			el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
			el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
		}
	}

	// Scale the content
	if ( scale === "content" || scale === "both" ) {

		// Vertical props scaling
		if ( factor.from.y !== factor.to.y ) {
			props = props.concat( cProps ).concat( props2 );
			el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
			el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
		}
	}

	$.effects.save( el, props );
	el.show();
	$.effects.createWrapper( el );
	el.css( "overflow", "hidden" ).css( el.from );

	// Adjust
	if (origin) { // Calculate baseline shifts
		baseline = $.effects.getBaseline( origin, original );
		el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
		el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
		el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
		el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
	}
	el.css( el.from ); // set top & left

	// Animate
	if ( scale === "content" || scale === "both" ) { // Scale the children

		// Add margins/font-size
		vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
		hProps = hProps.concat([ "marginLeft", "marginRight" ]);
		props2 = props0.concat(vProps).concat(hProps);

		el.find( "*[width]" ).each( function() {
			var child = $( this ),
				c_original = {
					height: child.height(),
					width: child.width(),
					outerHeight: child.outerHeight(),
					outerWidth: child.outerWidth()
				};
			if (restore) {
				$.effects.save(child, props2);
			}

			child.from = {
				height: c_original.height * factor.from.y,
				width: c_original.width * factor.from.x,
				outerHeight: c_original.outerHeight * factor.from.y,
				outerWidth: c_original.outerWidth * factor.from.x
			};
			child.to = {
				height: c_original.height * factor.to.y,
				width: c_original.width * factor.to.x,
				outerHeight: c_original.height * factor.to.y,
				outerWidth: c_original.width * factor.to.x
			};

			// Vertical props scaling
			if ( factor.from.y !== factor.to.y ) {
				child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
				child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
			}

			// Horizontal props scaling
			if ( factor.from.x !== factor.to.x ) {
				child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
				child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
			}

			// Animate children
			child.css( child.from );
			child.animate( child.to, o.duration, o.easing, function() {

				// Restore children
				if ( restore ) {
					$.effects.restore( child, props2 );
				}
			});
		});
	}

	// Animate
	el.animate( el.to, {
		queue: false,
		duration: o.duration,
		easing: o.easing,
		complete: function() {
			if ( el.to.opacity === 0 ) {
				el.css( "opacity", el.from.opacity );
			}
			if ( mode === "hide" ) {
				el.hide();
			}
			$.effects.restore( el, props );
			if ( !restore ) {

				// we need to calculate our new positioning based on the scaling
				if ( position === "static" ) {
					el.css({
						position: "relative",
						top: el.to.top,
						left: el.to.left
					});
				} else {
					$.each([ "top", "left" ], function( idx, pos ) {
						el.css( pos, function( _, str ) {
							var val = parseInt( str, 10 ),
								toRef = idx ? el.to.left : el.to.top;

							// if original was "auto", recalculate the new value from wrapper
							if ( str === "auto" ) {
								return toRef + "px";
							}

							return val + toRef + "px";
						});
					});
				}
			}

			$.effects.removeWrapper( el );
			done();
		}
	});

};


/*!
 * jQuery UI Effects Scale 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/scale-effect/
 */


var effectScale = $.effects.effect.scale = function( o, done ) {

	// Create element
	var el = $( this ),
		options = $.extend( true, {}, o ),
		mode = $.effects.setMode( el, o.mode || "effect" ),
		percent = parseInt( o.percent, 10 ) ||
			( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
		direction = o.direction || "both",
		origin = o.origin,
		original = {
			height: el.height(),
			width: el.width(),
			outerHeight: el.outerHeight(),
			outerWidth: el.outerWidth()
		},
		factor = {
			y: direction !== "horizontal" ? (percent / 100) : 1,
			x: direction !== "vertical" ? (percent / 100) : 1
		};

	// We are going to pass this effect to the size effect:
	options.effect = "size";
	options.queue = false;
	options.complete = done;

	// Set default origin and restore for show/hide
	if ( mode !== "effect" ) {
		options.origin = origin || [ "middle", "center" ];
		options.restore = true;
	}

	options.from = o.from || ( mode === "show" ? {
		height: 0,
		width: 0,
		outerHeight: 0,
		outerWidth: 0
	} : original );
	options.to = {
		height: original.height * factor.y,
		width: original.width * factor.x,
		outerHeight: original.outerHeight * factor.y,
		outerWidth: original.outerWidth * factor.x
	};

	// Fade option to support puff
	if ( options.fade ) {
		if ( mode === "show" ) {
			options.from.opacity = 0;
			options.to.opacity = 1;
		}
		if ( mode === "hide" ) {
			options.from.opacity = 1;
			options.to.opacity = 0;
		}
	}

	// Animate
	el.effect( options );

};


/*!
 * jQuery UI Effects Puff 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/puff-effect/
 */


var effectPuff = $.effects.effect.puff = function( o, done ) {
	var elem = $( this ),
		mode = $.effects.setMode( elem, o.mode || "hide" ),
		hide = mode === "hide",
		percent = parseInt( o.percent, 10 ) || 150,
		factor = percent / 100,
		original = {
			height: elem.height(),
			width: elem.width(),
			outerHeight: elem.outerHeight(),
			outerWidth: elem.outerWidth()
		};

	$.extend( o, {
		effect: "scale",
		queue: false,
		fade: true,
		mode: mode,
		complete: done,
		percent: hide ? percent : 100,
		from: hide ?
			original :
			{
				height: original.height * factor,
				width: original.width * factor,
				outerHeight: original.outerHeight * factor,
				outerWidth: original.outerWidth * factor
			}
	});

	elem.effect( o );
};


/*!
 * jQuery UI Effects Pulsate 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/pulsate-effect/
 */


var effectPulsate = $.effects.effect.pulsate = function( o, done ) {
	var elem = $( this ),
		mode = $.effects.setMode( elem, o.mode || "show" ),
		show = mode === "show",
		hide = mode === "hide",
		showhide = ( show || mode === "hide" ),

		// showing or hiding leaves of the "last" animation
		anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
		duration = o.duration / anims,
		animateTo = 0,
		queue = elem.queue(),
		queuelen = queue.length,
		i;

	if ( show || !elem.is(":visible")) {
		elem.css( "opacity", 0 ).show();
		animateTo = 1;
	}

	// anims - 1 opacity "toggles"
	for ( i = 1; i < anims; i++ ) {
		elem.animate({
			opacity: animateTo
		}, duration, o.easing );
		animateTo = 1 - animateTo;
	}

	elem.animate({
		opacity: animateTo
	}, duration, o.easing);

	elem.queue(function() {
		if ( hide ) {
			elem.hide();
		}
		done();
	});

	// We just queued up "anims" animations, we need to put them next in the queue
	if ( queuelen > 1 ) {
		queue.splice.apply( queue,
			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
	}
	elem.dequeue();
};


/*!
 * jQuery UI Effects Shake 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/shake-effect/
 */


var effectShake = $.effects.effect.shake = function( o, done ) {

	var el = $( this ),
		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
		mode = $.effects.setMode( el, o.mode || "effect" ),
		direction = o.direction || "left",
		distance = o.distance || 20,
		times = o.times || 3,
		anims = times * 2 + 1,
		speed = Math.round( o.duration / anims ),
		ref = (direction === "up" || direction === "down") ? "top" : "left",
		positiveMotion = (direction === "up" || direction === "left"),
		animation = {},
		animation1 = {},
		animation2 = {},
		i,

		// we will need to re-assemble the queue to stack our animations in place
		queue = el.queue(),
		queuelen = queue.length;

	$.effects.save( el, props );
	el.show();
	$.effects.createWrapper( el );

	// Animation
	animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
	animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
	animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;

	// Animate
	el.animate( animation, speed, o.easing );

	// Shakes
	for ( i = 1; i < times; i++ ) {
		el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
	}
	el
		.animate( animation1, speed, o.easing )
		.animate( animation, speed / 2, o.easing )
		.queue(function() {
			if ( mode === "hide" ) {
				el.hide();
			}
			$.effects.restore( el, props );
			$.effects.removeWrapper( el );
			done();
		});

	// inject all the animations we just queued to be first in line (after "inprogress")
	if ( queuelen > 1) {
		queue.splice.apply( queue,
			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
	}
	el.dequeue();

};


/*!
 * jQuery UI Effects Slide 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/slide-effect/
 */


var effectSlide = $.effects.effect.slide = function( o, done ) {

	// Create element
	var el = $( this ),
		props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
		mode = $.effects.setMode( el, o.mode || "show" ),
		show = mode === "show",
		direction = o.direction || "left",
		ref = (direction === "up" || direction === "down") ? "top" : "left",
		positiveMotion = (direction === "up" || direction === "left"),
		distance,
		animation = {};

	// Adjust
	$.effects.save( el, props );
	el.show();
	distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );

	$.effects.createWrapper( el ).css({
		overflow: "hidden"
	});

	if ( show ) {
		el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
	}

	// Animation
	animation[ ref ] = ( show ?
		( positiveMotion ? "+=" : "-=") :
		( positiveMotion ? "-=" : "+=")) +
		distance;

	// Animate
	el.animate( animation, {
		queue: false,
		duration: o.duration,
		easing: o.easing,
		complete: function() {
			if ( mode === "hide" ) {
				el.hide();
			}
			$.effects.restore( el, props );
			$.effects.removeWrapper( el );
			done();
		}
	});
};


/*!
 * jQuery UI Effects Transfer 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/transfer-effect/
 */


var effectTransfer = $.effects.effect.transfer = function( o, done ) {
	var elem = $( this ),
		target = $( o.to ),
		targetFixed = target.css( "position" ) === "fixed",
		body = $("body"),
		fixTop = targetFixed ? body.scrollTop() : 0,
		fixLeft = targetFixed ? body.scrollLeft() : 0,
		endPosition = target.offset(),
		animation = {
			top: endPosition.top - fixTop,
			left: endPosition.left - fixLeft,
			height: target.innerHeight(),
			width: target.innerWidth()
		},
		startPosition = elem.offset(),
		transfer = $( "<div class='ui-effects-transfer'></div>" )
			.appendTo( document.body )
			.addClass( o.className )
			.css({
				top: startPosition.top - fixTop,
				left: startPosition.left - fixLeft,
				height: elem.innerHeight(),
				width: elem.innerWidth(),
				position: targetFixed ? "fixed" : "absolute"
			})
			.animate( animation, o.duration, o.easing, function() {
				transfer.remove();
				done();
			});
};


/*!
 * jQuery UI Progressbar 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/progressbar/
 */


var progressbar = $.widget( "ui.progressbar", {
	version: "1.11.4",
	options: {
		max: 100,
		value: 0,

		change: null,
		complete: null
	},

	min: 0,

	_create: function() {
		// Constrain initial value
		this.oldValue = this.options.value = this._constrainedValue();

		this.element
			.addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
			.attr({
				// Only set static values, aria-valuenow and aria-valuemax are
				// set inside _refreshValue()
				role: "progressbar",
				"aria-valuemin": this.min
			});

		this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
			.appendTo( this.element );

		this._refreshValue();
	},

	_destroy: function() {
		this.element
			.removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
			.removeAttr( "role" )
			.removeAttr( "aria-valuemin" )
			.removeAttr( "aria-valuemax" )
			.removeAttr( "aria-valuenow" );

		this.valueDiv.remove();
	},

	value: function( newValue ) {
		if ( newValue === undefined ) {
			return this.options.value;
		}

		this.options.value = this._constrainedValue( newValue );
		this._refreshValue();
	},

	_constrainedValue: function( newValue ) {
		if ( newValue === undefined ) {
			newValue = this.options.value;
		}

		this.indeterminate = newValue === false;

		// sanitize value
		if ( typeof newValue !== "number" ) {
			newValue = 0;
		}

		return this.indeterminate ? false :
			Math.min( this.options.max, Math.max( this.min, newValue ) );
	},

	_setOptions: function( options ) {
		// Ensure "value" option is set after other values (like max)
		var value = options.value;
		delete options.value;

		this._super( options );

		this.options.value = this._constrainedValue( value );
		this._refreshValue();
	},

	_setOption: function( key, value ) {
		if ( key === "max" ) {
			// Don't allow a max less than min
			value = Math.max( this.min, value );
		}
		if ( key === "disabled" ) {
			this.element
				.toggleClass( "ui-state-disabled", !!value )
				.attr( "aria-disabled", value );
		}
		this._super( key, value );
	},

	_percentage: function() {
		return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
	},

	_refreshValue: function() {
		var value = this.options.value,
			percentage = this._percentage();

		this.valueDiv
			.toggle( this.indeterminate || value > this.min )
			.toggleClass( "ui-corner-right", value === this.options.max )
			.width( percentage.toFixed(0) + "%" );

		this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );

		if ( this.indeterminate ) {
			this.element.removeAttr( "aria-valuenow" );
			if ( !this.overlayDiv ) {
				this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv );
			}
		} else {
			this.element.attr({
				"aria-valuemax": this.options.max,
				"aria-valuenow": value
			});
			if ( this.overlayDiv ) {
				this.overlayDiv.remove();
				this.overlayDiv = null;
			}
		}

		if ( this.oldValue !== value ) {
			this.oldValue = value;
			this._trigger( "change" );
		}
		if ( value === this.options.max ) {
			this._trigger( "complete" );
		}
	}
});


/*!
 * jQuery UI Selectable 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/selectable/
 */


var selectable = $.widget("ui.selectable", $.ui.mouse, {
	version: "1.11.4",
	options: {
		appendTo: "body",
		autoRefresh: true,
		distance: 0,
		filter: "*",
		tolerance: "touch",

		// callbacks
		selected: null,
		selecting: null,
		start: null,
		stop: null,
		unselected: null,
		unselecting: null
	},
	_create: function() {
		var selectees,
			that = this;

		this.element.addClass("ui-selectable");

		this.dragged = false;

		// cache selectee children based on filter
		this.refresh = function() {
			selectees = $(that.options.filter, that.element[0]);
			selectees.addClass("ui-selectee");
			selectees.each(function() {
				var $this = $(this),
					pos = $this.offset();
				$.data(this, "selectable-item", {
					element: this,
					$element: $this,
					left: pos.left,
					top: pos.top,
					right: pos.left + $this.outerWidth(),
					bottom: pos.top + $this.outerHeight(),
					startselected: false,
					selected: $this.hasClass("ui-selected"),
					selecting: $this.hasClass("ui-selecting"),
					unselecting: $this.hasClass("ui-unselecting")
				});
			});
		};
		this.refresh();

		this.selectees = selectees.addClass("ui-selectee");

		this._mouseInit();

		this.helper = $("<div class='ui-selectable-helper'></div>");
	},

	_destroy: function() {
		this.selectees
			.removeClass("ui-selectee")
			.removeData("selectable-item");
		this.element
			.removeClass("ui-selectable ui-selectable-disabled");
		this._mouseDestroy();
	},

	_mouseStart: function(event) {
		var that = this,
			options = this.options;

		this.opos = [ event.pageX, event.pageY ];

		if (this.options.disabled) {
			return;
		}

		this.selectees = $(options.filter, this.element[0]);

		this._trigger("start", event);

		$(options.appendTo).append(this.helper);
		// position helper (lasso)
		this.helper.css({
			"left": event.pageX,
			"top": event.pageY,
			"width": 0,
			"height": 0
		});

		if (options.autoRefresh) {
			this.refresh();
		}

		this.selectees.filter(".ui-selected").each(function() {
			var selectee = $.data(this, "selectable-item");
			selectee.startselected = true;
			if (!event.metaKey && !event.ctrlKey) {
				selectee.$element.removeClass("ui-selected");
				selectee.selected = false;
				selectee.$element.addClass("ui-unselecting");
				selectee.unselecting = true;
				// selectable UNSELECTING callback
				that._trigger("unselecting", event, {
					unselecting: selectee.element
				});
			}
		});

		$(event.target).parents().addBack().each(function() {
			var doSelect,
				selectee = $.data(this, "selectable-item");
			if (selectee) {
				doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
				selectee.$element
					.removeClass(doSelect ? "ui-unselecting" : "ui-selected")
					.addClass(doSelect ? "ui-selecting" : "ui-unselecting");
				selectee.unselecting = !doSelect;
				selectee.selecting = doSelect;
				selectee.selected = doSelect;
				// selectable (UN)SELECTING callback
				if (doSelect) {
					that._trigger("selecting", event, {
						selecting: selectee.element
					});
				} else {
					that._trigger("unselecting", event, {
						unselecting: selectee.element
					});
				}
				return false;
			}
		});

	},

	_mouseDrag: function(event) {

		this.dragged = true;

		if (this.options.disabled) {
			return;
		}

		var tmp,
			that = this,
			options = this.options,
			x1 = this.opos[0],
			y1 = this.opos[1],
			x2 = event.pageX,
			y2 = event.pageY;

		if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
		if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
		this.helper.css({ left: x1, top: y1, width: x2 - x1, height: y2 - y1 });

		this.selectees.each(function() {
			var selectee = $.data(this, "selectable-item"),
				hit = false;

			//prevent helper from being selected if appendTo: selectable
			if (!selectee || selectee.element === that.element[0]) {
				return;
			}

			if (options.tolerance === "touch") {
				hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
			} else if (options.tolerance === "fit") {
				hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
			}

			if (hit) {
				// SELECT
				if (selectee.selected) {
					selectee.$element.removeClass("ui-selected");
					selectee.selected = false;
				}
				if (selectee.unselecting) {
					selectee.$element.removeClass("ui-unselecting");
					selectee.unselecting = false;
				}
				if (!selectee.selecting) {
					selectee.$element.addClass("ui-selecting");
					selectee.selecting = true;
					// selectable SELECTING callback
					that._trigger("selecting", event, {
						selecting: selectee.element
					});
				}
			} else {
				// UNSELECT
				if (selectee.selecting) {
					if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
						selectee.$element.removeClass("ui-selecting");
						selectee.selecting = false;
						selectee.$element.addClass("ui-selected");
						selectee.selected = true;
					} else {
						selectee.$element.removeClass("ui-selecting");
						selectee.selecting = false;
						if (selectee.startselected) {
							selectee.$element.addClass("ui-unselecting");
							selectee.unselecting = true;
						}
						// selectable UNSELECTING callback
						that._trigger("unselecting", event, {
							unselecting: selectee.element
						});
					}
				}
				if (selectee.selected) {
					if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
						selectee.$element.removeClass("ui-selected");
						selectee.selected = false;

						selectee.$element.addClass("ui-unselecting");
						selectee.unselecting = true;
						// selectable UNSELECTING callback
						that._trigger("unselecting", event, {
							unselecting: selectee.element
						});
					}
				}
			}
		});

		return false;
	},

	_mouseStop: function(event) {
		var that = this;

		this.dragged = false;

		$(".ui-unselecting", this.element[0]).each(function() {
			var selectee = $.data(this, "selectable-item");
			selectee.$element.removeClass("ui-unselecting");
			selectee.unselecting = false;
			selectee.startselected = false;
			that._trigger("unselected", event, {
				unselected: selectee.element
			});
		});
		$(".ui-selecting", this.element[0]).each(function() {
			var selectee = $.data(this, "selectable-item");
			selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
			selectee.selecting = false;
			selectee.selected = true;
			selectee.startselected = true;
			that._trigger("selected", event, {
				selected: selectee.element
			});
		});
		this._trigger("stop", event);

		this.helper.remove();

		return false;
	}

});


/*!
 * jQuery UI Selectmenu 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/selectmenu
 */


var selectmenu = $.widget( "ui.selectmenu", {
	version: "1.11.4",
	defaultElement: "<select>",
	options: {
		appendTo: null,
		disabled: null,
		icons: {
			button: "ui-icon-triangle-1-s"
		},
		position: {
			my: "left top",
			at: "left bottom",
			collision: "none"
		},
		width: null,

		// callbacks
		change: null,
		close: null,
		focus: null,
		open: null,
		select: null
	},

	_create: function() {
		var selectmenuId = this.element.uniqueId().attr( "id" );
		this.ids = {
			element: selectmenuId,
			button: selectmenuId + "-button",
			menu: selectmenuId + "-menu"
		};

		this._drawButton();
		this._drawMenu();

		if ( this.options.disabled ) {
			this.disable();
		}
	},

	_drawButton: function() {
		var that = this;

		// Associate existing label with the new button
		this.label = $( "label[for='" + this.ids.element + "']" ).attr( "for", this.ids.button );
		this._on( this.label, {
			click: function( event ) {
				this.button.focus();
				event.preventDefault();
			}
		});

		// Hide original select element
		this.element.hide();

		// Create button
		this.button = $( "<span>", {
			"class": "ui-selectmenu-button ui-widget ui-state-default ui-corner-all",
			tabindex: this.options.disabled ? -1 : 0,
			id: this.ids.button,
			role: "combobox",
			"aria-expanded": "false",
			"aria-autocomplete": "list",
			"aria-owns": this.ids.menu,
			"aria-haspopup": "true"
		})
			.insertAfter( this.element );

		$( "<span>", {
			"class": "ui-icon " + this.options.icons.button
		})
			.prependTo( this.button );

		this.buttonText = $( "<span>", {
			"class": "ui-selectmenu-text"
		})
			.appendTo( this.button );

		this._setText( this.buttonText, this.element.find( "option:selected" ).text() );
		this._resizeButton();

		this._on( this.button, this._buttonEvents );
		this.button.one( "focusin", function() {

			// Delay rendering the menu items until the button receives focus.
			// The menu may have already been rendered via a programmatic open.
			if ( !that.menuItems ) {
				that._refreshMenu();
			}
		});
		this._hoverable( this.button );
		this._focusable( this.button );
	},

	_drawMenu: function() {
		var that = this;

		// Create menu
		this.menu = $( "<ul>", {
			"aria-hidden": "true",
			"aria-labelledby": this.ids.button,
			id: this.ids.menu
		});

		// Wrap menu
		this.menuWrap = $( "<div>", {
			"class": "ui-selectmenu-menu ui-front"
		})
			.append( this.menu )
			.appendTo( this._appendTo() );

		// Initialize menu widget
		this.menuInstance = this.menu
			.menu({
				role: "listbox",
				select: function( event, ui ) {
					event.preventDefault();

					// support: IE8
					// If the item was selected via a click, the text selection
					// will be destroyed in IE
					that._setSelection();

					that._select( ui.item.data( "ui-selectmenu-item" ), event );
				},
				focus: function( event, ui ) {
					var item = ui.item.data( "ui-selectmenu-item" );

					// Prevent inital focus from firing and check if its a newly focused item
					if ( that.focusIndex != null && item.index !== that.focusIndex ) {
						that._trigger( "focus", event, { item: item } );
						if ( !that.isOpen ) {
							that._select( item, event );
						}
					}
					that.focusIndex = item.index;

					that.button.attr( "aria-activedescendant",
						that.menuItems.eq( item.index ).attr( "id" ) );
				}
			})
			.menu( "instance" );

		// Adjust menu styles to dropdown
		this.menu
			.addClass( "ui-corner-bottom" )
			.removeClass( "ui-corner-all" );

		// Don't close the menu on mouseleave
		this.menuInstance._off( this.menu, "mouseleave" );

		// Cancel the menu's collapseAll on document click
		this.menuInstance._closeOnDocumentClick = function() {
			return false;
		};

		// Selects often contain empty items, but never contain dividers
		this.menuInstance._isDivider = function() {
			return false;
		};
	},

	refresh: function() {
		this._refreshMenu();
		this._setText( this.buttonText, this._getSelectedItem().text() );
		if ( !this.options.width ) {
			this._resizeButton();
		}
	},

	_refreshMenu: function() {
		this.menu.empty();

		var item,
			options = this.element.find( "option" );

		if ( !options.length ) {
			return;
		}

		this._parseOptions( options );
		this._renderMenu( this.menu, this.items );

		this.menuInstance.refresh();
		this.menuItems = this.menu.find( "li" ).not( ".ui-selectmenu-optgroup" );

		item = this._getSelectedItem();

		// Update the menu to have the correct item focused
		this.menuInstance.focus( null, item );
		this._setAria( item.data( "ui-selectmenu-item" ) );

		// Set disabled state
		this._setOption( "disabled", this.element.prop( "disabled" ) );
	},

	open: function( event ) {
		if ( this.options.disabled ) {
			return;
		}

		// If this is the first time the menu is being opened, render the items
		if ( !this.menuItems ) {
			this._refreshMenu();
		} else {

			// Menu clears focus on close, reset focus to selected item
			this.menu.find( ".ui-state-focus" ).removeClass( "ui-state-focus" );
			this.menuInstance.focus( null, this._getSelectedItem() );
		}

		this.isOpen = true;
		this._toggleAttr();
		this._resizeMenu();
		this._position();

		this._on( this.document, this._documentClick );

		this._trigger( "open", event );
	},

	_position: function() {
		this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
	},

	close: function( event ) {
		if ( !this.isOpen ) {
			return;
		}

		this.isOpen = false;
		this._toggleAttr();

		this.range = null;
		this._off( this.document );

		this._trigger( "close", event );
	},

	widget: function() {
		return this.button;
	},

	menuWidget: function() {
		return this.menu;
	},

	_renderMenu: function( ul, items ) {
		var that = this,
			currentOptgroup = "";

		$.each( items, function( index, item ) {
			if ( item.optgroup !== currentOptgroup ) {
				$( "<li>", {
					"class": "ui-selectmenu-optgroup ui-menu-divider" +
						( item.element.parent( "optgroup" ).prop( "disabled" ) ?
							" ui-state-disabled" :
							"" ),
					text: item.optgroup
				})
					.appendTo( ul );

				currentOptgroup = item.optgroup;
			}

			that._renderItemData( ul, item );
		});
	},

	_renderItemData: function( ul, item ) {
		return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
	},

	_renderItem: function( ul, item ) {
		var li = $( "<li>" );

		if ( item.disabled ) {
			li.addClass( "ui-state-disabled" );
		}
		this._setText( li, item.label );

		return li.appendTo( ul );
	},

	_setText: function( element, value ) {
		if ( value ) {
			element.text( value );
		} else {
			element.html( "&#160;" );
		}
	},

	_move: function( direction, event ) {
		var item, next,
			filter = ".ui-menu-item";

		if ( this.isOpen ) {
			item = this.menuItems.eq( this.focusIndex );
		} else {
			item = this.menuItems.eq( this.element[ 0 ].selectedIndex );
			filter += ":not(.ui-state-disabled)";
		}

		if ( direction === "first" || direction === "last" ) {
			next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
		} else {
			next = item[ direction + "All" ]( filter ).eq( 0 );
		}

		if ( next.length ) {
			this.menuInstance.focus( event, next );
		}
	},

	_getSelectedItem: function() {
		return this.menuItems.eq( this.element[ 0 ].selectedIndex );
	},

	_toggle: function( event ) {
		this[ this.isOpen ? "close" : "open" ]( event );
	},

	_setSelection: function() {
		var selection;

		if ( !this.range ) {
			return;
		}

		if ( window.getSelection ) {
			selection = window.getSelection();
			selection.removeAllRanges();
			selection.addRange( this.range );

		// support: IE8
		} else {
			this.range.select();
		}

		// support: IE
		// Setting the text selection kills the button focus in IE, but
		// restoring the focus doesn't kill the selection.
		this.button.focus();
	},

	_documentClick: {
		mousedown: function( event ) {
			if ( !this.isOpen ) {
				return;
			}

			if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + this.ids.button ).length ) {
				this.close( event );
			}
		}
	},

	_buttonEvents: {

		// Prevent text selection from being reset when interacting with the selectmenu (#10144)
		mousedown: function() {
			var selection;

			if ( window.getSelection ) {
				selection = window.getSelection();
				if ( selection.rangeCount ) {
					this.range = selection.getRangeAt( 0 );
				}

			// support: IE8
			} else {
				this.range = document.selection.createRange();
			}
		},

		click: function( event ) {
			this._setSelection();
			this._toggle( event );
		},

		keydown: function( event ) {
			var preventDefault = true;
			switch ( event.keyCode ) {
				case $.ui.keyCode.TAB:
				case $.ui.keyCode.ESCAPE:
					this.close( event );
					preventDefault = false;
					break;
				case $.ui.keyCode.ENTER:
					if ( this.isOpen ) {
						this._selectFocusedItem( event );
					}
					break;
				case $.ui.keyCode.UP:
					if ( event.altKey ) {
						this._toggle( event );
					} else {
						this._move( "prev", event );
					}
					break;
				case $.ui.keyCode.DOWN:
					if ( event.altKey ) {
						this._toggle( event );
					} else {
						this._move( "next", event );
					}
					break;
				case $.ui.keyCode.SPACE:
					if ( this.isOpen ) {
						this._selectFocusedItem( event );
					} else {
						this._toggle( event );
					}
					break;
				case $.ui.keyCode.LEFT:
					this._move( "prev", event );
					break;
				case $.ui.keyCode.RIGHT:
					this._move( "next", event );
					break;
				case $.ui.keyCode.HOME:
				case $.ui.keyCode.PAGE_UP:
					this._move( "first", event );
					break;
				case $.ui.keyCode.END:
				case $.ui.keyCode.PAGE_DOWN:
					this._move( "last", event );
					break;
				default:
					this.menu.trigger( event );
					preventDefault = false;
			}

			if ( preventDefault ) {
				event.preventDefault();
			}
		}
	},

	_selectFocusedItem: function( event ) {
		var item = this.menuItems.eq( this.focusIndex );
		if ( !item.hasClass( "ui-state-disabled" ) ) {
			this._select( item.data( "ui-selectmenu-item" ), event );
		}
	},

	_select: function( item, event ) {
		var oldIndex = this.element[ 0 ].selectedIndex;

		// Change native select element
		this.element[ 0 ].selectedIndex = item.index;
		this._setText( this.buttonText, item.label );
		this._setAria( item );
		this._trigger( "select", event, { item: item } );

		if ( item.index !== oldIndex ) {
			this._trigger( "change", event, { item: item } );
		}

		this.close( event );
	},

	_setAria: function( item ) {
		var id = this.menuItems.eq( item.index ).attr( "id" );

		this.button.attr({
			"aria-labelledby": id,
			"aria-activedescendant": id
		});
		this.menu.attr( "aria-activedescendant", id );
	},

	_setOption: function( key, value ) {
		if ( key === "icons" ) {
			this.button.find( "span.ui-icon" )
				.removeClass( this.options.icons.button )
				.addClass( value.button );
		}

		this._super( key, value );

		if ( key === "appendTo" ) {
			this.menuWrap.appendTo( this._appendTo() );
		}

		if ( key === "disabled" ) {
			this.menuInstance.option( "disabled", value );
			this.button
				.toggleClass( "ui-state-disabled", value )
				.attr( "aria-disabled", value );

			this.element.prop( "disabled", value );
			if ( value ) {
				this.button.attr( "tabindex", -1 );
				this.close();
			} else {
				this.button.attr( "tabindex", 0 );
			}
		}

		if ( key === "width" ) {
			this._resizeButton();
		}
	},

	_appendTo: function() {
		var element = this.options.appendTo;

		if ( element ) {
			element = element.jquery || element.nodeType ?
				$( element ) :
				this.document.find( element ).eq( 0 );
		}

		if ( !element || !element[ 0 ] ) {
			element = this.element.closest( ".ui-front" );
		}

		if ( !element.length ) {
			element = this.document[ 0 ].body;
		}

		return element;
	},

	_toggleAttr: function() {
		this.button
			.toggleClass( "ui-corner-top", this.isOpen )
			.toggleClass( "ui-corner-all", !this.isOpen )
			.attr( "aria-expanded", this.isOpen );
		this.menuWrap.toggleClass( "ui-selectmenu-open", this.isOpen );
		this.menu.attr( "aria-hidden", !this.isOpen );
	},

	_resizeButton: function() {
		var width = this.options.width;

		if ( !width ) {
			width = this.element.show().outerWidth();
			this.element.hide();
		}

		this.button.outerWidth( width );
	},

	_resizeMenu: function() {
		this.menu.outerWidth( Math.max(
			this.button.outerWidth(),

			// support: IE10
			// IE10 wraps long text (possibly a rounding bug)
			// so we add 1px to avoid the wrapping
			this.menu.width( "" ).outerWidth() + 1
		) );
	},

	_getCreateOptions: function() {
		return { disabled: this.element.prop( "disabled" ) };
	},

	_parseOptions: function( options ) {
		var data = [];
		options.each(function( index, item ) {
			var option = $( item ),
				optgroup = option.parent( "optgroup" );
			data.push({
				element: option,
				index: index,
				value: option.val(),
				label: option.text(),
				optgroup: optgroup.attr( "label" ) || "",
				disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
			});
		});
		this.items = data;
	},

	_destroy: function() {
		this.menuWrap.remove();
		this.button.remove();
		this.element.show();
		this.element.removeUniqueId();
		this.label.attr( "for", this.ids.element );
	}
});


/*!
 * jQuery UI Slider 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/slider/
 */


var slider = $.widget( "ui.slider", $.ui.mouse, {
	version: "1.11.4",
	widgetEventPrefix: "slide",

	options: {
		animate: false,
		distance: 0,
		max: 100,
		min: 0,
		orientation: "horizontal",
		range: false,
		step: 1,
		value: 0,
		values: null,

		// callbacks
		change: null,
		slide: null,
		start: null,
		stop: null
	},

	// number of pages in a slider
	// (how many times can you page up/down to go through the whole range)
	numPages: 5,

	_create: function() {
		this._keySliding = false;
		this._mouseSliding = false;
		this._animateOff = true;
		this._handleIndex = null;
		this._detectOrientation();
		this._mouseInit();
		this._calculateNewMax();

		this.element
			.addClass( "ui-slider" +
				" ui-slider-" + this.orientation +
				" ui-widget" +
				" ui-widget-content" +
				" ui-corner-all");

		this._refresh();
		this._setOption( "disabled", this.options.disabled );

		this._animateOff = false;
	},

	_refresh: function() {
		this._createRange();
		this._createHandles();
		this._setupEvents();
		this._refreshValue();
	},

	_createHandles: function() {
		var i, handleCount,
			options = this.options,
			existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
			handle = "<span class='ui-slider-handle ui-state-default ui-corner-all' tabindex='0'></span>",
			handles = [];

		handleCount = ( options.values && options.values.length ) || 1;

		if ( existingHandles.length > handleCount ) {
			existingHandles.slice( handleCount ).remove();
			existingHandles = existingHandles.slice( 0, handleCount );
		}

		for ( i = existingHandles.length; i < handleCount; i++ ) {
			handles.push( handle );
		}

		this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );

		this.handle = this.handles.eq( 0 );

		this.handles.each(function( i ) {
			$( this ).data( "ui-slider-handle-index", i );
		});
	},

	_createRange: function() {
		var options = this.options,
			classes = "";

		if ( options.range ) {
			if ( options.range === true ) {
				if ( !options.values ) {
					options.values = [ this._valueMin(), this._valueMin() ];
				} else if ( options.values.length && options.values.length !== 2 ) {
					options.values = [ options.values[0], options.values[0] ];
				} else if ( $.isArray( options.values ) ) {
					options.values = options.values.slice(0);
				}
			}

			if ( !this.range || !this.range.length ) {
				this.range = $( "<div></div>" )
					.appendTo( this.element );

				classes = "ui-slider-range" +
				// note: this isn't the most fittingly semantic framework class for this element,
				// but worked best visually with a variety of themes
				" ui-widget-header ui-corner-all";
			} else {
				this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
					// Handle range switching from true to min/max
					.css({
						"left": "",
						"bottom": ""
					});
			}

			this.range.addClass( classes +
				( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
		} else {
			if ( this.range ) {
				this.range.remove();
			}
			this.range = null;
		}
	},

	_setupEvents: function() {
		this._off( this.handles );
		this._on( this.handles, this._handleEvents );
		this._hoverable( this.handles );
		this._focusable( this.handles );
	},

	_destroy: function() {
		this.handles.remove();
		if ( this.range ) {
			this.range.remove();
		}

		this.element
			.removeClass( "ui-slider" +
				" ui-slider-horizontal" +
				" ui-slider-vertical" +
				" ui-widget" +
				" ui-widget-content" +
				" ui-corner-all" );

		this._mouseDestroy();
	},

	_mouseCapture: function( event ) {
		var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
			that = this,
			o = this.options;

		if ( o.disabled ) {
			return false;
		}

		this.elementSize = {
			width: this.element.outerWidth(),
			height: this.element.outerHeight()
		};
		this.elementOffset = this.element.offset();

		position = { x: event.pageX, y: event.pageY };
		normValue = this._normValueFromMouse( position );
		distance = this._valueMax() - this._valueMin() + 1;
		this.handles.each(function( i ) {
			var thisDistance = Math.abs( normValue - that.values(i) );
			if (( distance > thisDistance ) ||
				( distance === thisDistance &&
					(i === that._lastChangedValue || that.values(i) === o.min ))) {
				distance = thisDistance;
				closestHandle = $( this );
				index = i;
			}
		});

		allowed = this._start( event, index );
		if ( allowed === false ) {
			return false;
		}
		this._mouseSliding = true;

		this._handleIndex = index;

		closestHandle
			.addClass( "ui-state-active" )
			.focus();

		offset = closestHandle.offset();
		mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
			left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
			top: event.pageY - offset.top -
				( closestHandle.height() / 2 ) -
				( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
				( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
				( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
		};

		if ( !this.handles.hasClass( "ui-state-hover" ) ) {
			this._slide( event, index, normValue );
		}
		this._animateOff = true;
		return true;
	},

	_mouseStart: function() {
		return true;
	},

	_mouseDrag: function( event ) {
		var position = { x: event.pageX, y: event.pageY },
			normValue = this._normValueFromMouse( position );

		this._slide( event, this._handleIndex, normValue );

		return false;
	},

	_mouseStop: function( event ) {
		this.handles.removeClass( "ui-state-active" );
		this._mouseSliding = false;

		this._stop( event, this._handleIndex );
		this._change( event, this._handleIndex );

		this._handleIndex = null;
		this._clickOffset = null;
		this._animateOff = false;

		return false;
	},

	_detectOrientation: function() {
		this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
	},

	_normValueFromMouse: function( position ) {
		var pixelTotal,
			pixelMouse,
			percentMouse,
			valueTotal,
			valueMouse;

		if ( this.orientation === "horizontal" ) {
			pixelTotal = this.elementSize.width;
			pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
		} else {
			pixelTotal = this.elementSize.height;
			pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
		}

		percentMouse = ( pixelMouse / pixelTotal );
		if ( percentMouse > 1 ) {
			percentMouse = 1;
		}
		if ( percentMouse < 0 ) {
			percentMouse = 0;
		}
		if ( this.orientation === "vertical" ) {
			percentMouse = 1 - percentMouse;
		}

		valueTotal = this._valueMax() - this._valueMin();
		valueMouse = this._valueMin() + percentMouse * valueTotal;

		return this._trimAlignValue( valueMouse );
	},

	_start: function( event, index ) {
		var uiHash = {
			handle: this.handles[ index ],
			value: this.value()
		};
		if ( this.options.values && this.options.values.length ) {
			uiHash.value = this.values( index );
			uiHash.values = this.values();
		}
		return this._trigger( "start", event, uiHash );
	},

	_slide: function( event, index, newVal ) {
		var otherVal,
			newValues,
			allowed;

		if ( this.options.values && this.options.values.length ) {
			otherVal = this.values( index ? 0 : 1 );

			if ( ( this.options.values.length === 2 && this.options.range === true ) &&
					( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
				) {
				newVal = otherVal;
			}

			if ( newVal !== this.values( index ) ) {
				newValues = this.values();
				newValues[ index ] = newVal;
				// A slide can be canceled by returning false from the slide callback
				allowed = this._trigger( "slide", event, {
					handle: this.handles[ index ],
					value: newVal,
					values: newValues
				} );
				otherVal = this.values( index ? 0 : 1 );
				if ( allowed !== false ) {
					this.values( index, newVal );
				}
			}
		} else {
			if ( newVal !== this.value() ) {
				// A slide can be canceled by returning false from the slide callback
				allowed = this._trigger( "slide", event, {
					handle: this.handles[ index ],
					value: newVal
				} );
				if ( allowed !== false ) {
					this.value( newVal );
				}
			}
		}
	},

	_stop: function( event, index ) {
		var uiHash = {
			handle: this.handles[ index ],
			value: this.value()
		};
		if ( this.options.values && this.options.values.length ) {
			uiHash.value = this.values( index );
			uiHash.values = this.values();
		}

		this._trigger( "stop", event, uiHash );
	},

	_change: function( event, index ) {
		if ( !this._keySliding && !this._mouseSliding ) {
			var uiHash = {
				handle: this.handles[ index ],
				value: this.value()
			};
			if ( this.options.values && this.options.values.length ) {
				uiHash.value = this.values( index );
				uiHash.values = this.values();
			}

			//store the last changed value index for reference when handles overlap
			this._lastChangedValue = index;

			this._trigger( "change", event, uiHash );
		}
	},

	value: function( newValue ) {
		if ( arguments.length ) {
			this.options.value = this._trimAlignValue( newValue );
			this._refreshValue();
			this._change( null, 0 );
			return;
		}

		return this._value();
	},

	values: function( index, newValue ) {
		var vals,
			newValues,
			i;

		if ( arguments.length > 1 ) {
			this.options.values[ index ] = this._trimAlignValue( newValue );
			this._refreshValue();
			this._change( null, index );
			return;
		}

		if ( arguments.length ) {
			if ( $.isArray( arguments[ 0 ] ) ) {
				vals = this.options.values;
				newValues = arguments[ 0 ];
				for ( i = 0; i < vals.length; i += 1 ) {
					vals[ i ] = this._trimAlignValue( newValues[ i ] );
					this._change( null, i );
				}
				this._refreshValue();
			} else {
				if ( this.options.values && this.options.values.length ) {
					return this._values( index );
				} else {
					return this.value();
				}
			}
		} else {
			return this._values();
		}
	},

	_setOption: function( key, value ) {
		var i,
			valsLength = 0;

		if ( key === "range" && this.options.range === true ) {
			if ( value === "min" ) {
				this.options.value = this._values( 0 );
				this.options.values = null;
			} else if ( value === "max" ) {
				this.options.value = this._values( this.options.values.length - 1 );
				this.options.values = null;
			}
		}

		if ( $.isArray( this.options.values ) ) {
			valsLength = this.options.values.length;
		}

		if ( key === "disabled" ) {
			this.element.toggleClass( "ui-state-disabled", !!value );
		}

		this._super( key, value );

		switch ( key ) {
			case "orientation":
				this._detectOrientation();
				this.element
					.removeClass( "ui-slider-horizontal ui-slider-vertical" )
					.addClass( "ui-slider-" + this.orientation );
				this._refreshValue();

				// Reset positioning from previous orientation
				this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
				break;
			case "value":
				this._animateOff = true;
				this._refreshValue();
				this._change( null, 0 );
				this._animateOff = false;
				break;
			case "values":
				this._animateOff = true;
				this._refreshValue();
				for ( i = 0; i < valsLength; i += 1 ) {
					this._change( null, i );
				}
				this._animateOff = false;
				break;
			case "step":
			case "min":
			case "max":
				this._animateOff = true;
				this._calculateNewMax();
				this._refreshValue();
				this._animateOff = false;
				break;
			case "range":
				this._animateOff = true;
				this._refresh();
				this._animateOff = false;
				break;
		}
	},

	//internal value getter
	// _value() returns value trimmed by min and max, aligned by step
	_value: function() {
		var val = this.options.value;
		val = this._trimAlignValue( val );

		return val;
	},

	//internal values getter
	// _values() returns array of values trimmed by min and max, aligned by step
	// _values( index ) returns single value trimmed by min and max, aligned by step
	_values: function( index ) {
		var val,
			vals,
			i;

		if ( arguments.length ) {
			val = this.options.values[ index ];
			val = this._trimAlignValue( val );

			return val;
		} else if ( this.options.values && this.options.values.length ) {
			// .slice() creates a copy of the array
			// this copy gets trimmed by min and max and then returned
			vals = this.options.values.slice();
			for ( i = 0; i < vals.length; i += 1) {
				vals[ i ] = this._trimAlignValue( vals[ i ] );
			}

			return vals;
		} else {
			return [];
		}
	},

	// returns the step-aligned value that val is closest to, between (inclusive) min and max
	_trimAlignValue: function( val ) {
		if ( val <= this._valueMin() ) {
			return this._valueMin();
		}
		if ( val >= this._valueMax() ) {
			return this._valueMax();
		}
		var step = ( this.options.step > 0 ) ? this.options.step : 1,
			valModStep = (val - this._valueMin()) % step,
			alignValue = val - valModStep;

		if ( Math.abs(valModStep) * 2 >= step ) {
			alignValue += ( valModStep > 0 ) ? step : ( -step );
		}

		// Since JavaScript has problems with large floats, round
		// the final value to 5 digits after the decimal point (see #4124)
		return parseFloat( alignValue.toFixed(5) );
	},

	_calculateNewMax: function() {
		var max = this.options.max,
			min = this._valueMin(),
			step = this.options.step,
			aboveMin = Math.floor( ( +( max - min ).toFixed( this._precision() ) ) / step ) * step;
		max = aboveMin + min;
		this.max = parseFloat( max.toFixed( this._precision() ) );
	},

	_precision: function() {
		var precision = this._precisionOf( this.options.step );
		if ( this.options.min !== null ) {
			precision = Math.max( precision, this._precisionOf( this.options.min ) );
		}
		return precision;
	},

	_precisionOf: function( num ) {
		var str = num.toString(),
			decimal = str.indexOf( "." );
		return decimal === -1 ? 0 : str.length - decimal - 1;
	},

	_valueMin: function() {
		return this.options.min;
	},

	_valueMax: function() {
		return this.max;
	},

	_refreshValue: function() {
		var lastValPercent, valPercent, value, valueMin, valueMax,
			oRange = this.options.range,
			o = this.options,
			that = this,
			animate = ( !this._animateOff ) ? o.animate : false,
			_set = {};

		if ( this.options.values && this.options.values.length ) {
			this.handles.each(function( i ) {
				valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
				_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
				$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
				if ( that.options.range === true ) {
					if ( that.orientation === "horizontal" ) {
						if ( i === 0 ) {
							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
						}
						if ( i === 1 ) {
							that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
						}
					} else {
						if ( i === 0 ) {
							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
						}
						if ( i === 1 ) {
							that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
						}
					}
				}
				lastValPercent = valPercent;
			});
		} else {
			value = this.value();
			valueMin = this._valueMin();
			valueMax = this._valueMax();
			valPercent = ( valueMax !== valueMin ) ?
					( value - valueMin ) / ( valueMax - valueMin ) * 100 :
					0;
			_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
			this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );

			if ( oRange === "min" && this.orientation === "horizontal" ) {
				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
			}
			if ( oRange === "max" && this.orientation === "horizontal" ) {
				this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
			}
			if ( oRange === "min" && this.orientation === "vertical" ) {
				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
			}
			if ( oRange === "max" && this.orientation === "vertical" ) {
				this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
			}
		}
	},

	_handleEvents: {
		keydown: function( event ) {
			var allowed, curVal, newVal, step,
				index = $( event.target ).data( "ui-slider-handle-index" );

			switch ( event.keyCode ) {
				case $.ui.keyCode.HOME:
				case $.ui.keyCode.END:
				case $.ui.keyCode.PAGE_UP:
				case $.ui.keyCode.PAGE_DOWN:
				case $.ui.keyCode.UP:
				case $.ui.keyCode.RIGHT:
				case $.ui.keyCode.DOWN:
				case $.ui.keyCode.LEFT:
					event.preventDefault();
					if ( !this._keySliding ) {
						this._keySliding = true;
						$( event.target ).addClass( "ui-state-active" );
						allowed = this._start( event, index );
						if ( allowed === false ) {
							return;
						}
					}
					break;
			}

			step = this.options.step;
			if ( this.options.values && this.options.values.length ) {
				curVal = newVal = this.values( index );
			} else {
				curVal = newVal = this.value();
			}

			switch ( event.keyCode ) {
				case $.ui.keyCode.HOME:
					newVal = this._valueMin();
					break;
				case $.ui.keyCode.END:
					newVal = this._valueMax();
					break;
				case $.ui.keyCode.PAGE_UP:
					newVal = this._trimAlignValue(
						curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
					);
					break;
				case $.ui.keyCode.PAGE_DOWN:
					newVal = this._trimAlignValue(
						curVal - ( (this._valueMax() - this._valueMin()) / this.numPages ) );
					break;
				case $.ui.keyCode.UP:
				case $.ui.keyCode.RIGHT:
					if ( curVal === this._valueMax() ) {
						return;
					}
					newVal = this._trimAlignValue( curVal + step );
					break;
				case $.ui.keyCode.DOWN:
				case $.ui.keyCode.LEFT:
					if ( curVal === this._valueMin() ) {
						return;
					}
					newVal = this._trimAlignValue( curVal - step );
					break;
			}

			this._slide( event, index, newVal );
		},
		keyup: function( event ) {
			var index = $( event.target ).data( "ui-slider-handle-index" );

			if ( this._keySliding ) {
				this._keySliding = false;
				this._stop( event, index );
				this._change( event, index );
				$( event.target ).removeClass( "ui-state-active" );
			}
		}
	}
});


/*!
 * jQuery UI Sortable 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/sortable/
 */


var sortable = $.widget("ui.sortable", $.ui.mouse, {
	version: "1.11.4",
	widgetEventPrefix: "sort",
	ready: false,
	options: {
		appendTo: "parent",
		axis: false,
		connectWith: false,
		containment: false,
		cursor: "auto",
		cursorAt: false,
		dropOnEmpty: true,
		forcePlaceholderSize: false,
		forceHelperSize: false,
		grid: false,
		handle: false,
		helper: "original",
		items: "> *",
		opacity: false,
		placeholder: false,
		revert: false,
		scroll: true,
		scrollSensitivity: 20,
		scrollSpeed: 20,
		scope: "default",
		tolerance: "intersect",
		zIndex: 1000,

		// callbacks
		activate: null,
		beforeStop: null,
		change: null,
		deactivate: null,
		out: null,
		over: null,
		receive: null,
		remove: null,
		sort: null,
		start: null,
		stop: null,
		update: null
	},

	_isOverAxis: function( x, reference, size ) {
		return ( x >= reference ) && ( x < ( reference + size ) );
	},

	_isFloating: function( item ) {
		return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
	},

	_create: function() {
		this.containerCache = {};
		this.element.addClass("ui-sortable");

		//Get the items
		this.refresh();

		//Let's determine the parent's offset
		this.offset = this.element.offset();

		//Initialize mouse events for interaction
		this._mouseInit();

		this._setHandleClassName();

		//We're ready to go
		this.ready = true;

	},

	_setOption: function( key, value ) {
		this._super( key, value );

		if ( key === "handle" ) {
			this._setHandleClassName();
		}
	},

	_setHandleClassName: function() {
		this.element.find( ".ui-sortable-handle" ).removeClass( "ui-sortable-handle" );
		$.each( this.items, function() {
			( this.instance.options.handle ?
				this.item.find( this.instance.options.handle ) : this.item )
				.addClass( "ui-sortable-handle" );
		});
	},

	_destroy: function() {
		this.element
			.removeClass( "ui-sortable ui-sortable-disabled" )
			.find( ".ui-sortable-handle" )
				.removeClass( "ui-sortable-handle" );
		this._mouseDestroy();

		for ( var i = this.items.length - 1; i >= 0; i-- ) {
			this.items[i].item.removeData(this.widgetName + "-item");
		}

		return this;
	},

	_mouseCapture: function(event, overrideHandle) {
		var currentItem = null,
			validHandle = false,
			that = this;

		if (this.reverting) {
			return false;
		}

		if(this.options.disabled || this.options.type === "static") {
			return false;
		}

		//We have to refresh the items data once first
		this._refreshItems(event);

		//Find out if the clicked node (or one of its parents) is a actual item in this.items
		$(event.target).parents().each(function() {
			if($.data(this, that.widgetName + "-item") === that) {
				currentItem = $(this);
				return false;
			}
		});
		if($.data(event.target, that.widgetName + "-item") === that) {
			currentItem = $(event.target);
		}

		if(!currentItem) {
			return false;
		}
		if(this.options.handle && !overrideHandle) {
			$(this.options.handle, currentItem).find("*").addBack().each(function() {
				if(this === event.target) {
					validHandle = true;
				}
			});
			if(!validHandle) {
				return false;
			}
		}

		this.currentItem = currentItem;
		this._removeCurrentsFromItems();
		return true;

	},

	_mouseStart: function(event, overrideHandle, noActivation) {

		var i, body,
			o = this.options;

		this.currentContainer = this;

		//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
		this.refreshPositions();

		//Create and append the visible helper
		this.helper = this._createHelper(event);

		//Cache the helper size
		this._cacheHelperProportions();

		/*
		 * - Position generation -
		 * This block generates everything position related - it's the core of draggables.
		 */

		//Cache the margins of the original element
		this._cacheMargins();

		//Get the next scrolling parent
		this.scrollParent = this.helper.scrollParent();

		//The element's absolute position on the page minus margins
		this.offset = this.currentItem.offset();
		this.offset = {
			top: this.offset.top - this.margins.top,
			left: this.offset.left - this.margins.left
		};

		$.extend(this.offset, {
			click: { //Where the click happened, relative to the element
				left: event.pageX - this.offset.left,
				top: event.pageY - this.offset.top
			},
			parent: this._getParentOffset(),
			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
		});

		// Only after we got the offset, we can change the helper's position to absolute
		// TODO: Still need to figure out a way to make relative sorting possible
		this.helper.css("position", "absolute");
		this.cssPosition = this.helper.css("position");

		//Generate the original position
		this.originalPosition = this._generatePosition(event);
		this.originalPageX = event.pageX;
		this.originalPageY = event.pageY;

		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));

		//Cache the former DOM position
		this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };

		//If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
		if(this.helper[0] !== this.currentItem[0]) {
			this.currentItem.hide();
		}

		//Create the placeholder
		this._createPlaceholder();

		//Set a containment if given in the options
		if(o.containment) {
			this._setContainment();
		}

		if( o.cursor && o.cursor !== "auto" ) { // cursor option
			body = this.document.find( "body" );

			// support: IE
			this.storedCursor = body.css( "cursor" );
			body.css( "cursor", o.cursor );

			this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
		}

		if(o.opacity) { // opacity option
			if (this.helper.css("opacity")) {
				this._storedOpacity = this.helper.css("opacity");
			}
			this.helper.css("opacity", o.opacity);
		}

		if(o.zIndex) { // zIndex option
			if (this.helper.css("zIndex")) {
				this._storedZIndex = this.helper.css("zIndex");
			}
			this.helper.css("zIndex", o.zIndex);
		}

		//Prepare scrolling
		if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
			this.overflowOffset = this.scrollParent.offset();
		}

		//Call callbacks
		this._trigger("start", event, this._uiHash());

		//Recache the helper size
		if(!this._preserveHelperProportions) {
			this._cacheHelperProportions();
		}


		//Post "activate" events to possible containers
		if( !noActivation ) {
			for ( i = this.containers.length - 1; i >= 0; i-- ) {
				this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
			}
		}

		//Prepare possible droppables
		if($.ui.ddmanager) {
			$.ui.ddmanager.current = this;
		}

		if ($.ui.ddmanager && !o.dropBehaviour) {
			$.ui.ddmanager.prepareOffsets(this, event);
		}

		this.dragging = true;

		this.helper.addClass("ui-sortable-helper");
		this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
		return true;

	},

	_mouseDrag: function(event) {
		var i, item, itemElement, intersection,
			o = this.options,
			scrolled = false;

		//Compute the helpers position
		this.position = this._generatePosition(event);
		this.positionAbs = this._convertPositionTo("absolute");

		if (!this.lastPositionAbs) {
			this.lastPositionAbs = this.positionAbs;
		}

		//Do scrolling
		if(this.options.scroll) {
			if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {

				if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
				} else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
				}

				if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
				} else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
				}

			} else {

				if(event.pageY - this.document.scrollTop() < o.scrollSensitivity) {
					scrolled = this.document.scrollTop(this.document.scrollTop() - o.scrollSpeed);
				} else if(this.window.height() - (event.pageY - this.document.scrollTop()) < o.scrollSensitivity) {
					scrolled = this.document.scrollTop(this.document.scrollTop() + o.scrollSpeed);
				}

				if(event.pageX - this.document.scrollLeft() < o.scrollSensitivity) {
					scrolled = this.document.scrollLeft(this.document.scrollLeft() - o.scrollSpeed);
				} else if(this.window.width() - (event.pageX - this.document.scrollLeft()) < o.scrollSensitivity) {
					scrolled = this.document.scrollLeft(this.document.scrollLeft() + o.scrollSpeed);
				}

			}

			if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
				$.ui.ddmanager.prepareOffsets(this, event);
			}
		}

		//Regenerate the absolute position used for position checks
		this.positionAbs = this._convertPositionTo("absolute");

		//Set the helper position
		if(!this.options.axis || this.options.axis !== "y") {
			this.helper[0].style.left = this.position.left+"px";
		}
		if(!this.options.axis || this.options.axis !== "x") {
			this.helper[0].style.top = this.position.top+"px";
		}

		//Rearrange
		for (i = this.items.length - 1; i >= 0; i--) {

			//Cache variables and intersection, continue if no intersection
			item = this.items[i];
			itemElement = item.item[0];
			intersection = this._intersectsWithPointer(item);
			if (!intersection) {
				continue;
			}

			// Only put the placeholder inside the current Container, skip all
			// items from other containers. This works because when moving
			// an item from one container to another the
			// currentContainer is switched before the placeholder is moved.
			//
			// Without this, moving items in "sub-sortables" can cause
			// the placeholder to jitter between the outer and inner container.
			if (item.instance !== this.currentContainer) {
				continue;
			}

			// cannot intersect with itself
			// no useless actions that have been done before
			// no action if the item moved is the parent of the item checked
			if (itemElement !== this.currentItem[0] &&
				this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
				!$.contains(this.placeholder[0], itemElement) &&
				(this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
			) {

				this.direction = intersection === 1 ? "down" : "up";

				if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
					this._rearrange(event, item);
				} else {
					break;
				}

				this._trigger("change", event, this._uiHash());
				break;
			}
		}

		//Post events to containers
		this._contactContainers(event);

		//Interconnect with droppables
		if($.ui.ddmanager) {
			$.ui.ddmanager.drag(this, event);
		}

		//Call callbacks
		this._trigger("sort", event, this._uiHash());

		this.lastPositionAbs = this.positionAbs;
		return false;

	},

	_mouseStop: function(event, noPropagation) {

		if(!event) {
			return;
		}

		//If we are using droppables, inform the manager about the drop
		if ($.ui.ddmanager && !this.options.dropBehaviour) {
			$.ui.ddmanager.drop(this, event);
		}

		if(this.options.revert) {
			var that = this,
				cur = this.placeholder.offset(),
				axis = this.options.axis,
				animation = {};

			if ( !axis || axis === "x" ) {
				animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollLeft);
			}
			if ( !axis || axis === "y" ) {
				animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollTop);
			}
			this.reverting = true;
			$(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
				that._clear(event);
			});
		} else {
			this._clear(event, noPropagation);
		}

		return false;

	},

	cancel: function() {

		if(this.dragging) {

			this._mouseUp({ target: null });

			if(this.options.helper === "original") {
				this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
			} else {
				this.currentItem.show();
			}

			//Post deactivating events to containers
			for (var i = this.containers.length - 1; i >= 0; i--){
				this.containers[i]._trigger("deactivate", null, this._uiHash(this));
				if(this.containers[i].containerCache.over) {
					this.containers[i]._trigger("out", null, this._uiHash(this));
					this.containers[i].containerCache.over = 0;
				}
			}

		}

		if (this.placeholder) {
			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
			if(this.placeholder[0].parentNode) {
				this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
			}
			if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
				this.helper.remove();
			}

			$.extend(this, {
				helper: null,
				dragging: false,
				reverting: false,
				_noFinalSort: null
			});

			if(this.domPosition.prev) {
				$(this.domPosition.prev).after(this.currentItem);
			} else {
				$(this.domPosition.parent).prepend(this.currentItem);
			}
		}

		return this;

	},

	serialize: function(o) {

		var items = this._getItemsAsjQuery(o && o.connected),
			str = [];
		o = o || {};

		$(items).each(function() {
			var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
			if (res) {
				str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
			}
		});

		if(!str.length && o.key) {
			str.push(o.key + "=");
		}

		return str.join("&");

	},

	toArray: function(o) {

		var items = this._getItemsAsjQuery(o && o.connected),
			ret = [];

		o = o || {};

		items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
		return ret;

	},

	/* Be careful with the following core functions */
	_intersectsWith: function(item) {

		var x1 = this.positionAbs.left,
			x2 = x1 + this.helperProportions.width,
			y1 = this.positionAbs.top,
			y2 = y1 + this.helperProportions.height,
			l = item.left,
			r = l + item.width,
			t = item.top,
			b = t + item.height,
			dyClick = this.offset.click.top,
			dxClick = this.offset.click.left,
			isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
			isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
			isOverElement = isOverElementHeight && isOverElementWidth;

		if ( this.options.tolerance === "pointer" ||
			this.options.forcePointerForContainers ||
			(this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
		) {
			return isOverElement;
		} else {

			return (l < x1 + (this.helperProportions.width / 2) && // Right Half
				x2 - (this.helperProportions.width / 2) < r && // Left Half
				t < y1 + (this.helperProportions.height / 2) && // Bottom Half
				y2 - (this.helperProportions.height / 2) < b ); // Top Half

		}
	},

	_intersectsWithPointer: function(item) {

		var isOverElementHeight = (this.options.axis === "x") || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
			isOverElementWidth = (this.options.axis === "y") || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
			isOverElement = isOverElementHeight && isOverElementWidth,
			verticalDirection = this._getDragVerticalDirection(),
			horizontalDirection = this._getDragHorizontalDirection();

		if (!isOverElement) {
			return false;
		}

		return this.floating ?
			( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
			: ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );

	},

	_intersectsWithSides: function(item) {

		var isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
			isOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
			verticalDirection = this._getDragVerticalDirection(),
			horizontalDirection = this._getDragHorizontalDirection();

		if (this.floating && horizontalDirection) {
			return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
		} else {
			return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
		}

	},

	_getDragVerticalDirection: function() {
		var delta = this.positionAbs.top - this.lastPositionAbs.top;
		return delta !== 0 && (delta > 0 ? "down" : "up");
	},

	_getDragHorizontalDirection: function() {
		var delta = this.positionAbs.left - this.lastPositionAbs.left;
		return delta !== 0 && (delta > 0 ? "right" : "left");
	},

	refresh: function(event) {
		this._refreshItems(event);
		this._setHandleClassName();
		this.refreshPositions();
		return this;
	},

	_connectWith: function() {
		var options = this.options;
		return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
	},

	_getItemsAsjQuery: function(connected) {

		var i, j, cur, inst,
			items = [],
			queries = [],
			connectWith = this._connectWith();

		if(connectWith && connected) {
			for (i = connectWith.length - 1; i >= 0; i--){
				cur = $(connectWith[i], this.document[0]);
				for ( j = cur.length - 1; j >= 0; j--){
					inst = $.data(cur[j], this.widgetFullName);
					if(inst && inst !== this && !inst.options.disabled) {
						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), inst]);
					}
				}
			}
		}

		queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), this]);

		function addItems() {
			items.push( this );
		}
		for (i = queries.length - 1; i >= 0; i--){
			queries[i][0].each( addItems );
		}

		return $(items);

	},

	_removeCurrentsFromItems: function() {

		var list = this.currentItem.find(":data(" + this.widgetName + "-item)");

		this.items = $.grep(this.items, function (item) {
			for (var j=0; j < list.length; j++) {
				if(list[j] === item.item[0]) {
					return false;
				}
			}
			return true;
		});

	},

	_refreshItems: function(event) {

		this.items = [];
		this.containers = [this];

		var i, j, cur, inst, targetData, _queries, item, queriesLength,
			items = this.items,
			queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
			connectWith = this._connectWith();

		if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
			for (i = connectWith.length - 1; i >= 0; i--){
				cur = $(connectWith[i], this.document[0]);
				for (j = cur.length - 1; j >= 0; j--){
					inst = $.data(cur[j], this.widgetFullName);
					if(inst && inst !== this && !inst.options.disabled) {
						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
						this.containers.push(inst);
					}
				}
			}
		}

		for (i = queries.length - 1; i >= 0; i--) {
			targetData = queries[i][1];
			_queries = queries[i][0];

			for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
				item = $(_queries[j]);

				item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)

				items.push({
					item: item,
					instance: targetData,
					width: 0, height: 0,
					left: 0, top: 0
				});
			}
		}

	},

	refreshPositions: function(fast) {

		// Determine whether items are being displayed horizontally
		this.floating = this.items.length ?
			this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
			false;

		//This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
		if(this.offsetParent && this.helper) {
			this.offset.parent = this._getParentOffset();
		}

		var i, item, t, p;

		for (i = this.items.length - 1; i >= 0; i--){
			item = this.items[i];

			//We ignore calculating positions of all connected containers when we're not over them
			if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
				continue;
			}

			t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;

			if (!fast) {
				item.width = t.outerWidth();
				item.height = t.outerHeight();
			}

			p = t.offset();
			item.left = p.left;
			item.top = p.top;
		}

		if(this.options.custom && this.options.custom.refreshContainers) {
			this.options.custom.refreshContainers.call(this);
		} else {
			for (i = this.containers.length - 1; i >= 0; i--){
				p = this.containers[i].element.offset();
				this.containers[i].containerCache.left = p.left;
				this.containers[i].containerCache.top = p.top;
				this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
				this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
			}
		}

		return this;
	},

	_createPlaceholder: function(that) {
		that = that || this;
		var className,
			o = that.options;

		if(!o.placeholder || o.placeholder.constructor === String) {
			className = o.placeholder;
			o.placeholder = {
				element: function() {

					var nodeName = that.currentItem[0].nodeName.toLowerCase(),
						element = $( "<" + nodeName + ">", that.document[0] )
							.addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
							.removeClass("ui-sortable-helper");

					if ( nodeName === "tbody" ) {
						that._createTrPlaceholder(
							that.currentItem.find( "tr" ).eq( 0 ),
							$( "<tr>", that.document[ 0 ] ).appendTo( element )
						);
					} else if ( nodeName === "tr" ) {
						that._createTrPlaceholder( that.currentItem, element );
					} else if ( nodeName === "img" ) {
						element.attr( "src", that.currentItem.attr( "src" ) );
					}

					if ( !className ) {
						element.css( "visibility", "hidden" );
					}

					return element;
				},
				update: function(container, p) {

					// 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
					if(className && !o.forcePlaceholderSize) {
						return;
					}

					//If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
					if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
					if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
				}
			};
		}

		//Create the placeholder
		that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));

		//Append it after the actual current item
		that.currentItem.after(that.placeholder);

		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
		o.placeholder.update(that, that.placeholder);

	},

	_createTrPlaceholder: function( sourceTr, targetTr ) {
		var that = this;

		sourceTr.children().each(function() {
			$( "<td>&#160;</td>", that.document[ 0 ] )
				.attr( "colspan", $( this ).attr( "colspan" ) || 1 )
				.appendTo( targetTr );
		});
	},

	_contactContainers: function(event) {
		var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis,
			innermostContainer = null,
			innermostIndex = null;

		// get innermost container that intersects with item
		for (i = this.containers.length - 1; i >= 0; i--) {

			// never consider a container that's located within the item itself
			if($.contains(this.currentItem[0], this.containers[i].element[0])) {
				continue;
			}

			if(this._intersectsWith(this.containers[i].containerCache)) {

				// if we've already found a container and it's more "inner" than this, then continue
				if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
					continue;
				}

				innermostContainer = this.containers[i];
				innermostIndex = i;

			} else {
				// container doesn't intersect. trigger "out" event if necessary
				if(this.containers[i].containerCache.over) {
					this.containers[i]._trigger("out", event, this._uiHash(this));
					this.containers[i].containerCache.over = 0;
				}
			}

		}

		// if no intersecting containers found, return
		if(!innermostContainer) {
			return;
		}

		// move the item into the container if it's not there already
		if(this.containers.length === 1) {
			if (!this.containers[innermostIndex].containerCache.over) {
				this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
				this.containers[innermostIndex].containerCache.over = 1;
			}
		} else {

			//When entering a new container, we will find the item with the least distance and append our item near it
			dist = 10000;
			itemWithLeastDistance = null;
			floating = innermostContainer.floating || this._isFloating(this.currentItem);
			posProperty = floating ? "left" : "top";
			sizeProperty = floating ? "width" : "height";
			axis = floating ? "clientX" : "clientY";

			for (j = this.items.length - 1; j >= 0; j--) {
				if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
					continue;
				}
				if(this.items[j].item[0] === this.currentItem[0]) {
					continue;
				}

				cur = this.items[j].item.offset()[posProperty];
				nearBottom = false;
				if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
					nearBottom = true;
				}

				if ( Math.abs( event[ axis ] - cur ) < dist ) {
					dist = Math.abs( event[ axis ] - cur );
					itemWithLeastDistance = this.items[ j ];
					this.direction = nearBottom ? "up": "down";
				}
			}

			//Check if dropOnEmpty is enabled
			if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
				return;
			}

			if(this.currentContainer === this.containers[innermostIndex]) {
				if ( !this.currentContainer.containerCache.over ) {
					this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
					this.currentContainer.containerCache.over = 1;
				}
				return;
			}

			itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
			this._trigger("change", event, this._uiHash());
			this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
			this.currentContainer = this.containers[innermostIndex];

			//Update the placeholder
			this.options.placeholder.update(this.currentContainer, this.placeholder);

			this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
			this.containers[innermostIndex].containerCache.over = 1;
		}


	},

	_createHelper: function(event) {

		var o = this.options,
			helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);

		//Add the helper to the DOM if that didn't happen already
		if(!helper.parents("body").length) {
			$(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
		}

		if(helper[0] === this.currentItem[0]) {
			this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
		}

		if(!helper[0].style.width || o.forceHelperSize) {
			helper.width(this.currentItem.width());
		}
		if(!helper[0].style.height || o.forceHelperSize) {
			helper.height(this.currentItem.height());
		}

		return helper;

	},

	_adjustOffsetFromHelper: function(obj) {
		if (typeof obj === "string") {
			obj = obj.split(" ");
		}
		if ($.isArray(obj)) {
			obj = {left: +obj[0], top: +obj[1] || 0};
		}
		if ("left" in obj) {
			this.offset.click.left = obj.left + this.margins.left;
		}
		if ("right" in obj) {
			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
		}
		if ("top" in obj) {
			this.offset.click.top = obj.top + this.margins.top;
		}
		if ("bottom" in obj) {
			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
		}
	},

	_getParentOffset: function() {


		//Get the offsetParent and cache its position
		this.offsetParent = this.helper.offsetParent();
		var po = this.offsetParent.offset();

		// This is a special case where we need to modify a offset calculated on start, since the following happened:
		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
		if(this.cssPosition === "absolute" && this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) {
			po.left += this.scrollParent.scrollLeft();
			po.top += this.scrollParent.scrollTop();
		}

		// This needs to be actually done for all browsers, since pageX/pageY includes this information
		// with an ugly IE fix
		if( this.offsetParent[0] === this.document[0].body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
			po = { top: 0, left: 0 };
		}

		return {
			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
		};

	},

	_getRelativeOffset: function() {

		if(this.cssPosition === "relative") {
			var p = this.currentItem.position();
			return {
				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
			};
		} else {
			return { top: 0, left: 0 };
		}

	},

	_cacheMargins: function() {
		this.margins = {
			left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
			top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
		};
	},

	_cacheHelperProportions: function() {
		this.helperProportions = {
			width: this.helper.outerWidth(),
			height: this.helper.outerHeight()
		};
	},

	_setContainment: function() {

		var ce, co, over,
			o = this.options;
		if(o.containment === "parent") {
			o.containment = this.helper[0].parentNode;
		}
		if(o.containment === "document" || o.containment === "window") {
			this.containment = [
				0 - this.offset.relative.left - this.offset.parent.left,
				0 - this.offset.relative.top - this.offset.parent.top,
				o.containment === "document" ? this.document.width() : this.window.width() - this.helperProportions.width - this.margins.left,
				(o.containment === "document" ? this.document.width() : this.window.height() || this.document[0].body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
			];
		}

		if(!(/^(document|window|parent)$/).test(o.containment)) {
			ce = $(o.containment)[0];
			co = $(o.containment).offset();
			over = ($(ce).css("overflow") !== "hidden");

			this.containment = [
				co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
				co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
				co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
				co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
			];
		}

	},

	_convertPositionTo: function(d, pos) {

		if(!pos) {
			pos = this.position;
		}
		var mod = d === "absolute" ? 1 : -1,
			scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
			scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);

		return {
			top: (
				pos.top	+																// The absolute mouse position
				this.offset.relative.top * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
				this.offset.parent.top * mod -											// The offsetParent's offset without borders (offset + border)
				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
			),
			left: (
				pos.left +																// The absolute mouse position
				this.offset.relative.left * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
				this.offset.parent.left * mod	-										// The offsetParent's offset without borders (offset + border)
				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
			)
		};

	},

	_generatePosition: function(event) {

		var top, left,
			o = this.options,
			pageX = event.pageX,
			pageY = event.pageY,
			scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);

		// This is another very weird special case that only happens for relative elements:
		// 1. If the css position is relative
		// 2. and the scroll parent is the document or similar to the offset parent
		// we have to refresh the relative offset during the scroll so there are no jumps
		if(this.cssPosition === "relative" && !(this.scrollParent[0] !== this.document[0] && this.scrollParent[0] !== this.offsetParent[0])) {
			this.offset.relative = this._getRelativeOffset();
		}

		/*
		 * - Position constraining -
		 * Constrain the position to a mix of grid, containment.
		 */

		if(this.originalPosition) { //If we are not dragging yet, we won't check for options

			if(this.containment) {
				if(event.pageX - this.offset.click.left < this.containment[0]) {
					pageX = this.containment[0] + this.offset.click.left;
				}
				if(event.pageY - this.offset.click.top < this.containment[1]) {
					pageY = this.containment[1] + this.offset.click.top;
				}
				if(event.pageX - this.offset.click.left > this.containment[2]) {
					pageX = this.containment[2] + this.offset.click.left;
				}
				if(event.pageY - this.offset.click.top > this.containment[3]) {
					pageY = this.containment[3] + this.offset.click.top;
				}
			}

			if(o.grid) {
				top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
				pageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;

				left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
				pageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
			}

		}

		return {
			top: (
				pageY -																// The absolute mouse position
				this.offset.click.top -													// Click offset (relative to the element)
				this.offset.relative.top	-											// Only for relative positioned nodes: Relative offset from element to offset parent
				this.offset.parent.top +												// The offsetParent's offset without borders (offset + border)
				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
			),
			left: (
				pageX -																// The absolute mouse position
				this.offset.click.left -												// Click offset (relative to the element)
				this.offset.relative.left	-											// Only for relative positioned nodes: Relative offset from element to offset parent
				this.offset.parent.left +												// The offsetParent's offset without borders (offset + border)
				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
			)
		};

	},

	_rearrange: function(event, i, a, hardRefresh) {

		a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === "down" ? i.item[0] : i.item[0].nextSibling));

		//Various things done here to improve the performance:
		// 1. we create a setTimeout, that calls refreshPositions
		// 2. on the instance, we have a counter variable, that get's higher after every append
		// 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
		// 4. this lets only the last addition to the timeout stack through
		this.counter = this.counter ? ++this.counter : 1;
		var counter = this.counter;

		this._delay(function() {
			if(counter === this.counter) {
				this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
			}
		});

	},

	_clear: function(event, noPropagation) {

		this.reverting = false;
		// We delay all events that have to be triggered to after the point where the placeholder has been removed and
		// everything else normalized again
		var i,
			delayedTriggers = [];

		// We first have to update the dom position of the actual currentItem
		// Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
		if(!this._noFinalSort && this.currentItem.parent().length) {
			this.placeholder.before(this.currentItem);
		}
		this._noFinalSort = null;

		if(this.helper[0] === this.currentItem[0]) {
			for(i in this._storedCSS) {
				if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
					this._storedCSS[i] = "";
				}
			}
			this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
		} else {
			this.currentItem.show();
		}

		if(this.fromOutside && !noPropagation) {
			delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
		}
		if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
			delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
		}

		// Check if the items Container has Changed and trigger appropriate
		// events.
		if (this !== this.currentContainer) {
			if(!noPropagation) {
				delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
				delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
				delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
			}
		}


		//Post events to containers
		function delayEvent( type, instance, container ) {
			return function( event ) {
				container._trigger( type, event, instance._uiHash( instance ) );
			};
		}
		for (i = this.containers.length - 1; i >= 0; i--){
			if (!noPropagation) {
				delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
			}
			if(this.containers[i].containerCache.over) {
				delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
				this.containers[i].containerCache.over = 0;
			}
		}

		//Do what was originally in plugins
		if ( this.storedCursor ) {
			this.document.find( "body" ).css( "cursor", this.storedCursor );
			this.storedStylesheet.remove();
		}
		if(this._storedOpacity) {
			this.helper.css("opacity", this._storedOpacity);
		}
		if(this._storedZIndex) {
			this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
		}

		this.dragging = false;

		if(!noPropagation) {
			this._trigger("beforeStop", event, this._uiHash());
		}

		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
		this.placeholder[0].parentNode.removeChild(this.placeholder[0]);

		if ( !this.cancelHelperRemoval ) {
			if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
				this.helper.remove();
			}
			this.helper = null;
		}

		if(!noPropagation) {
			for (i=0; i < delayedTriggers.length; i++) {
				delayedTriggers[i].call(this, event);
			} //Trigger all delayed events
			this._trigger("stop", event, this._uiHash());
		}

		this.fromOutside = false;
		return !this.cancelHelperRemoval;

	},

	_trigger: function() {
		if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
			this.cancel();
		}
	},

	_uiHash: function(_inst) {
		var inst = _inst || this;
		return {
			helper: inst.helper,
			placeholder: inst.placeholder || $([]),
			position: inst.position,
			originalPosition: inst.originalPosition,
			offset: inst.positionAbs,
			item: inst.currentItem,
			sender: _inst ? _inst.element : null
		};
	}

});


/*!
 * jQuery UI Spinner 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/spinner/
 */


function spinner_modifier( fn ) {
	return function() {
		var previous = this.element.val();
		fn.apply( this, arguments );
		this._refresh();
		if ( previous !== this.element.val() ) {
			this._trigger( "change" );
		}
	};
}

var spinner = $.widget( "ui.spinner", {
	version: "1.11.4",
	defaultElement: "<input>",
	widgetEventPrefix: "spin",
	options: {
		culture: null,
		icons: {
			down: "ui-icon-triangle-1-s",
			up: "ui-icon-triangle-1-n"
		},
		incremental: true,
		max: null,
		min: null,
		numberFormat: null,
		page: 10,
		step: 1,

		change: null,
		spin: null,
		start: null,
		stop: null
	},

	_create: function() {
		// handle string values that need to be parsed
		this._setOption( "max", this.options.max );
		this._setOption( "min", this.options.min );
		this._setOption( "step", this.options.step );

		// Only format if there is a value, prevents the field from being marked
		// as invalid in Firefox, see #9573.
		if ( this.value() !== "" ) {
			// Format the value, but don't constrain.
			this._value( this.element.val(), true );
		}

		this._draw();
		this._on( this._events );
		this._refresh();

		// turning off autocomplete prevents the browser from remembering the
		// value when navigating through history, so we re-enable autocomplete
		// if the page is unloaded before the widget is destroyed. #7790
		this._on( this.window, {
			beforeunload: function() {
				this.element.removeAttr( "autocomplete" );
			}
		});
	},

	_getCreateOptions: function() {
		var options = {},
			element = this.element;

		$.each( [ "min", "max", "step" ], function( i, option ) {
			var value = element.attr( option );
			if ( value !== undefined && value.length ) {
				options[ option ] = value;
			}
		});

		return options;
	},

	_events: {
		keydown: function( event ) {
			if ( this._start( event ) && this._keydown( event ) ) {
				event.preventDefault();
			}
		},
		keyup: "_stop",
		focus: function() {
			this.previous = this.element.val();
		},
		blur: function( event ) {
			if ( this.cancelBlur ) {
				delete this.cancelBlur;
				return;
			}

			this._stop();
			this._refresh();
			if ( this.previous !== this.element.val() ) {
				this._trigger( "change", event );
			}
		},
		mousewheel: function( event, delta ) {
			if ( !delta ) {
				return;
			}
			if ( !this.spinning && !this._start( event ) ) {
				return false;
			}

			this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
			clearTimeout( this.mousewheelTimer );
			this.mousewheelTimer = this._delay(function() {
				if ( this.spinning ) {
					this._stop( event );
				}
			}, 100 );
			event.preventDefault();
		},
		"mousedown .ui-spinner-button": function( event ) {
			var previous;

			// We never want the buttons to have focus; whenever the user is
			// interacting with the spinner, the focus should be on the input.
			// If the input is focused then this.previous is properly set from
			// when the input first received focus. If the input is not focused
			// then we need to set this.previous based on the value before spinning.
			previous = this.element[0] === this.document[0].activeElement ?
				this.previous : this.element.val();
			function checkFocus() {
				var isActive = this.element[0] === this.document[0].activeElement;
				if ( !isActive ) {
					this.element.focus();
					this.previous = previous;
					// support: IE
					// IE sets focus asynchronously, so we need to check if focus
					// moved off of the input because the user clicked on the button.
					this._delay(function() {
						this.previous = previous;
					});
				}
			}

			// ensure focus is on (or stays on) the text field
			event.preventDefault();
			checkFocus.call( this );

			// support: IE
			// IE doesn't prevent moving focus even with event.preventDefault()
			// so we set a flag to know when we should ignore the blur event
			// and check (again) if focus moved off of the input.
			this.cancelBlur = true;
			this._delay(function() {
				delete this.cancelBlur;
				checkFocus.call( this );
			});

			if ( this._start( event ) === false ) {
				return;
			}

			this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
		},
		"mouseup .ui-spinner-button": "_stop",
		"mouseenter .ui-spinner-button": function( event ) {
			// button will add ui-state-active if mouse was down while mouseleave and kept down
			if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
				return;
			}

			if ( this._start( event ) === false ) {
				return false;
			}
			this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
		},
		// TODO: do we really want to consider this a stop?
		// shouldn't we just stop the repeater and wait until mouseup before
		// we trigger the stop event?
		"mouseleave .ui-spinner-button": "_stop"
	},

	_draw: function() {
		var uiSpinner = this.uiSpinner = this.element
			.addClass( "ui-spinner-input" )
			.attr( "autocomplete", "off" )
			.wrap( this._uiSpinnerHtml() )
			.parent()
				// add buttons
				.append( this._buttonHtml() );

		this.element.attr( "role", "spinbutton" );

		// button bindings
		this.buttons = uiSpinner.find( ".ui-spinner-button" )
			.attr( "tabIndex", -1 )
			.button()
			.removeClass( "ui-corner-all" );

		// IE 6 doesn't understand height: 50% for the buttons
		// unless the wrapper has an explicit height
		if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
				uiSpinner.height() > 0 ) {
			uiSpinner.height( uiSpinner.height() );
		}

		// disable spinner if element was already disabled
		if ( this.options.disabled ) {
			this.disable();
		}
	},

	_keydown: function( event ) {
		var options = this.options,
			keyCode = $.ui.keyCode;

		switch ( event.keyCode ) {
		case keyCode.UP:
			this._repeat( null, 1, event );
			return true;
		case keyCode.DOWN:
			this._repeat( null, -1, event );
			return true;
		case keyCode.PAGE_UP:
			this._repeat( null, options.page, event );
			return true;
		case keyCode.PAGE_DOWN:
			this._repeat( null, -options.page, event );
			return true;
		}

		return false;
	},

	_uiSpinnerHtml: function() {
		return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
	},

	_buttonHtml: function() {
		return "" +
			"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
				"<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
			"</a>" +
			"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
				"<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
			"</a>";
	},

	_start: function( event ) {
		if ( !this.spinning && this._trigger( "start", event ) === false ) {
			return false;
		}

		if ( !this.counter ) {
			this.counter = 1;
		}
		this.spinning = true;
		return true;
	},

	_repeat: function( i, steps, event ) {
		i = i || 500;

		clearTimeout( this.timer );
		this.timer = this._delay(function() {
			this._repeat( 40, steps, event );
		}, i );

		this._spin( steps * this.options.step, event );
	},

	_spin: function( step, event ) {
		var value = this.value() || 0;

		if ( !this.counter ) {
			this.counter = 1;
		}

		value = this._adjustValue( value + step * this._increment( this.counter ) );

		if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
			this._value( value );
			this.counter++;
		}
	},

	_increment: function( i ) {
		var incremental = this.options.incremental;

		if ( incremental ) {
			return $.isFunction( incremental ) ?
				incremental( i ) :
				Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
		}

		return 1;
	},

	_precision: function() {
		var precision = this._precisionOf( this.options.step );
		if ( this.options.min !== null ) {
			precision = Math.max( precision, this._precisionOf( this.options.min ) );
		}
		return precision;
	},

	_precisionOf: function( num ) {
		var str = num.toString(),
			decimal = str.indexOf( "." );
		return decimal === -1 ? 0 : str.length - decimal - 1;
	},

	_adjustValue: function( value ) {
		var base, aboveMin,
			options = this.options;

		// make sure we're at a valid step
		// - find out where we are relative to the base (min or 0)
		base = options.min !== null ? options.min : 0;
		aboveMin = value - base;
		// - round to the nearest step
		aboveMin = Math.round(aboveMin / options.step) * options.step;
		// - rounding is based on 0, so adjust back to our base
		value = base + aboveMin;

		// fix precision from bad JS floating point math
		value = parseFloat( value.toFixed( this._precision() ) );

		// clamp the value
		if ( options.max !== null && value > options.max) {
			return options.max;
		}
		if ( options.min !== null && value < options.min ) {
			return options.min;
		}

		return value;
	},

	_stop: function( event ) {
		if ( !this.spinning ) {
			return;
		}

		clearTimeout( this.timer );
		clearTimeout( this.mousewheelTimer );
		this.counter = 0;
		this.spinning = false;
		this._trigger( "stop", event );
	},

	_setOption: function( key, value ) {
		if ( key === "culture" || key === "numberFormat" ) {
			var prevValue = this._parse( this.element.val() );
			this.options[ key ] = value;
			this.element.val( this._format( prevValue ) );
			return;
		}

		if ( key === "max" || key === "min" || key === "step" ) {
			if ( typeof value === "string" ) {
				value = this._parse( value );
			}
		}
		if ( key === "icons" ) {
			this.buttons.first().find( ".ui-icon" )
				.removeClass( this.options.icons.up )
				.addClass( value.up );
			this.buttons.last().find( ".ui-icon" )
				.removeClass( this.options.icons.down )
				.addClass( value.down );
		}

		this._super( key, value );

		if ( key === "disabled" ) {
			this.widget().toggleClass( "ui-state-disabled", !!value );
			this.element.prop( "disabled", !!value );
			this.buttons.button( value ? "disable" : "enable" );
		}
	},

	_setOptions: spinner_modifier(function( options ) {
		this._super( options );
	}),

	_parse: function( val ) {
		if ( typeof val === "string" && val !== "" ) {
			val = window.Globalize && this.options.numberFormat ?
				Globalize.parseFloat( val, 10, this.options.culture ) : +val;
		}
		return val === "" || isNaN( val ) ? null : val;
	},

	_format: function( value ) {
		if ( value === "" ) {
			return "";
		}
		return window.Globalize && this.options.numberFormat ?
			Globalize.format( value, this.options.numberFormat, this.options.culture ) :
			value;
	},

	_refresh: function() {
		this.element.attr({
			"aria-valuemin": this.options.min,
			"aria-valuemax": this.options.max,
			// TODO: what should we do with values that can't be parsed?
			"aria-valuenow": this._parse( this.element.val() )
		});
	},

	isValid: function() {
		var value = this.value();

		// null is invalid
		if ( value === null ) {
			return false;
		}

		// if value gets adjusted, it's invalid
		return value === this._adjustValue( value );
	},

	// update the value without triggering change
	_value: function( value, allowAny ) {
		var parsed;
		if ( value !== "" ) {
			parsed = this._parse( value );
			if ( parsed !== null ) {
				if ( !allowAny ) {
					parsed = this._adjustValue( parsed );
				}
				value = this._format( parsed );
			}
		}
		this.element.val( value );
		this._refresh();
	},

	_destroy: function() {
		this.element
			.removeClass( "ui-spinner-input" )
			.prop( "disabled", false )
			.removeAttr( "autocomplete" )
			.removeAttr( "role" )
			.removeAttr( "aria-valuemin" )
			.removeAttr( "aria-valuemax" )
			.removeAttr( "aria-valuenow" );
		this.uiSpinner.replaceWith( this.element );
	},

	stepUp: spinner_modifier(function( steps ) {
		this._stepUp( steps );
	}),
	_stepUp: function( steps ) {
		if ( this._start() ) {
			this._spin( (steps || 1) * this.options.step );
			this._stop();
		}
	},

	stepDown: spinner_modifier(function( steps ) {
		this._stepDown( steps );
	}),
	_stepDown: function( steps ) {
		if ( this._start() ) {
			this._spin( (steps || 1) * -this.options.step );
			this._stop();
		}
	},

	pageUp: spinner_modifier(function( pages ) {
		this._stepUp( (pages || 1) * this.options.page );
	}),

	pageDown: spinner_modifier(function( pages ) {
		this._stepDown( (pages || 1) * this.options.page );
	}),

	value: function( newVal ) {
		if ( !arguments.length ) {
			return this._parse( this.element.val() );
		}
		spinner_modifier( this._value ).call( this, newVal );
	},

	widget: function() {
		return this.uiSpinner;
	}
});


/*!
 * jQuery UI Tabs 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/tabs/
 */


var tabs = $.widget( "ui.tabs", {
	version: "1.11.4",
	delay: 300,
	options: {
		active: null,
		collapsible: false,
		event: "click",
		heightStyle: "content",
		hide: null,
		show: null,

		// callbacks
		activate: null,
		beforeActivate: null,
		beforeLoad: null,
		load: null
	},

	_isLocal: (function() {
		var rhash = /#.*$/;

		return function( anchor ) {
			var anchorUrl, locationUrl;

			// support: IE7
			// IE7 doesn't normalize the href property when set via script (#9317)
			anchor = anchor.cloneNode( false );

			anchorUrl = anchor.href.replace( rhash, "" );
			locationUrl = location.href.replace( rhash, "" );

			// decoding may throw an error if the URL isn't UTF-8 (#9518)
			try {
				anchorUrl = decodeURIComponent( anchorUrl );
			} catch ( error ) {}
			try {
				locationUrl = decodeURIComponent( locationUrl );
			} catch ( error ) {}

			return anchor.hash.length > 1 && anchorUrl === locationUrl;
		};
	})(),

	_create: function() {
		var that = this,
			options = this.options;

		this.running = false;

		this.element
			.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
			.toggleClass( "ui-tabs-collapsible", options.collapsible );

		this._processTabs();
		options.active = this._initialActive();

		// Take disabling tabs via class attribute from HTML
		// into account and update option properly.
		if ( $.isArray( options.disabled ) ) {
			options.disabled = $.unique( options.disabled.concat(
				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
					return that.tabs.index( li );
				})
			) ).sort();
		}

		// check for length avoids error when initializing empty list
		if ( this.options.active !== false && this.anchors.length ) {
			this.active = this._findActive( options.active );
		} else {
			this.active = $();
		}

		this._refresh();

		if ( this.active.length ) {
			this.load( options.active );
		}
	},

	_initialActive: function() {
		var active = this.options.active,
			collapsible = this.options.collapsible,
			locationHash = location.hash.substring( 1 );

		if ( active === null ) {
			// check the fragment identifier in the URL
			if ( locationHash ) {
				this.tabs.each(function( i, tab ) {
					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
						active = i;
						return false;
					}
				});
			}

			// check for a tab marked active via a class
			if ( active === null ) {
				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
			}

			// no active tab, set to false
			if ( active === null || active === -1 ) {
				active = this.tabs.length ? 0 : false;
			}
		}

		// handle numbers: negative, out of range
		if ( active !== false ) {
			active = this.tabs.index( this.tabs.eq( active ) );
			if ( active === -1 ) {
				active = collapsible ? false : 0;
			}
		}

		// don't allow collapsible: false and active: false
		if ( !collapsible && active === false && this.anchors.length ) {
			active = 0;
		}

		return active;
	},

	_getCreateEventData: function() {
		return {
			tab: this.active,
			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
		};
	},

	_tabKeydown: function( event ) {
		var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
			selectedIndex = this.tabs.index( focusedTab ),
			goingForward = true;

		if ( this._handlePageNav( event ) ) {
			return;
		}

		switch ( event.keyCode ) {
			case $.ui.keyCode.RIGHT:
			case $.ui.keyCode.DOWN:
				selectedIndex++;
				break;
			case $.ui.keyCode.UP:
			case $.ui.keyCode.LEFT:
				goingForward = false;
				selectedIndex--;
				break;
			case $.ui.keyCode.END:
				selectedIndex = this.anchors.length - 1;
				break;
			case $.ui.keyCode.HOME:
				selectedIndex = 0;
				break;
			case $.ui.keyCode.SPACE:
				// Activate only, no collapsing
				event.preventDefault();
				clearTimeout( this.activating );
				this._activate( selectedIndex );
				return;
			case $.ui.keyCode.ENTER:
				// Toggle (cancel delayed activation, allow collapsing)
				event.preventDefault();
				clearTimeout( this.activating );
				// Determine if we should collapse or activate
				this._activate( selectedIndex === this.options.active ? false : selectedIndex );
				return;
			default:
				return;
		}

		// Focus the appropriate tab, based on which key was pressed
		event.preventDefault();
		clearTimeout( this.activating );
		selectedIndex = this._focusNextTab( selectedIndex, goingForward );

		// Navigating with control/command key will prevent automatic activation
		if ( !event.ctrlKey && !event.metaKey ) {

			// Update aria-selected immediately so that AT think the tab is already selected.
			// Otherwise AT may confuse the user by stating that they need to activate the tab,
			// but the tab will already be activated by the time the announcement finishes.
			focusedTab.attr( "aria-selected", "false" );
			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );

			this.activating = this._delay(function() {
				this.option( "active", selectedIndex );
			}, this.delay );
		}
	},

	_panelKeydown: function( event ) {
		if ( this._handlePageNav( event ) ) {
			return;
		}

		// Ctrl+up moves focus to the current tab
		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
			event.preventDefault();
			this.active.focus();
		}
	},

	// Alt+page up/down moves focus to the previous/next tab (and activates)
	_handlePageNav: function( event ) {
		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
			this._activate( this._focusNextTab( this.options.active - 1, false ) );
			return true;
		}
		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
			this._activate( this._focusNextTab( this.options.active + 1, true ) );
			return true;
		}
	},

	_findNextTab: function( index, goingForward ) {
		var lastTabIndex = this.tabs.length - 1;

		function constrain() {
			if ( index > lastTabIndex ) {
				index = 0;
			}
			if ( index < 0 ) {
				index = lastTabIndex;
			}
			return index;
		}

		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
			index = goingForward ? index + 1 : index - 1;
		}

		return index;
	},

	_focusNextTab: function( index, goingForward ) {
		index = this._findNextTab( index, goingForward );
		this.tabs.eq( index ).focus();
		return index;
	},

	_setOption: function( key, value ) {
		if ( key === "active" ) {
			// _activate() will handle invalid values and update this.options
			this._activate( value );
			return;
		}

		if ( key === "disabled" ) {
			// don't use the widget factory's disabled handling
			this._setupDisabled( value );
			return;
		}

		this._super( key, value);

		if ( key === "collapsible" ) {
			this.element.toggleClass( "ui-tabs-collapsible", value );
			// Setting collapsible: false while collapsed; open first panel
			if ( !value && this.options.active === false ) {
				this._activate( 0 );
			}
		}

		if ( key === "event" ) {
			this._setupEvents( value );
		}

		if ( key === "heightStyle" ) {
			this._setupHeightStyle( value );
		}
	},

	_sanitizeSelector: function( hash ) {
		return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
	},

	refresh: function() {
		var options = this.options,
			lis = this.tablist.children( ":has(a[href])" );

		// get disabled tabs from class attribute from HTML
		// this will get converted to a boolean if needed in _refresh()
		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
			return lis.index( tab );
		});

		this._processTabs();

		// was collapsed or no tabs
		if ( options.active === false || !this.anchors.length ) {
			options.active = false;
			this.active = $();
		// was active, but active tab is gone
		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
			// all remaining tabs are disabled
			if ( this.tabs.length === options.disabled.length ) {
				options.active = false;
				this.active = $();
			// activate previous tab
			} else {
				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
			}
		// was active, active tab still exists
		} else {
			// make sure active index is correct
			options.active = this.tabs.index( this.active );
		}

		this._refresh();
	},

	_refresh: function() {
		this._setupDisabled( this.options.disabled );
		this._setupEvents( this.options.event );
		this._setupHeightStyle( this.options.heightStyle );

		this.tabs.not( this.active ).attr({
			"aria-selected": "false",
			"aria-expanded": "false",
			tabIndex: -1
		});
		this.panels.not( this._getPanelForTab( this.active ) )
			.hide()
			.attr({
				"aria-hidden": "true"
			});

		// Make sure one tab is in the tab order
		if ( !this.active.length ) {
			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
		} else {
			this.active
				.addClass( "ui-tabs-active ui-state-active" )
				.attr({
					"aria-selected": "true",
					"aria-expanded": "true",
					tabIndex: 0
				});
			this._getPanelForTab( this.active )
				.show()
				.attr({
					"aria-hidden": "false"
				});
		}
	},

	_processTabs: function() {
		var that = this,
			prevTabs = this.tabs,
			prevAnchors = this.anchors,
			prevPanels = this.panels;

		this.tablist = this._getList()
			.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
			.attr( "role", "tablist" )

			// Prevent users from focusing disabled tabs via click
			.delegate( "> li", "mousedown" + this.eventNamespace, function( event ) {
				if ( $( this ).is( ".ui-state-disabled" ) ) {
					event.preventDefault();
				}
			})

			// support: IE <9
			// Preventing the default action in mousedown doesn't prevent IE
			// from focusing the element, so if the anchor gets focused, blur.
			// We don't have to worry about focusing the previously focused
			// element since clicking on a non-focusable element should focus
			// the body anyway.
			.delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
				if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
					this.blur();
				}
			});

		this.tabs = this.tablist.find( "> li:has(a[href])" )
			.addClass( "ui-state-default ui-corner-top" )
			.attr({
				role: "tab",
				tabIndex: -1
			});

		this.anchors = this.tabs.map(function() {
				return $( "a", this )[ 0 ];
			})
			.addClass( "ui-tabs-anchor" )
			.attr({
				role: "presentation",
				tabIndex: -1
			});

		this.panels = $();

		this.anchors.each(function( i, anchor ) {
			var selector, panel, panelId,
				anchorId = $( anchor ).uniqueId().attr( "id" ),
				tab = $( anchor ).closest( "li" ),
				originalAriaControls = tab.attr( "aria-controls" );

			// inline tab
			if ( that._isLocal( anchor ) ) {
				selector = anchor.hash;
				panelId = selector.substring( 1 );
				panel = that.element.find( that._sanitizeSelector( selector ) );
			// remote tab
			} else {
				// If the tab doesn't already have aria-controls,
				// generate an id by using a throw-away element
				panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
				selector = "#" + panelId;
				panel = that.element.find( selector );
				if ( !panel.length ) {
					panel = that._createPanel( panelId );
					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
				}
				panel.attr( "aria-live", "polite" );
			}

			if ( panel.length) {
				that.panels = that.panels.add( panel );
			}
			if ( originalAriaControls ) {
				tab.data( "ui-tabs-aria-controls", originalAriaControls );
			}
			tab.attr({
				"aria-controls": panelId,
				"aria-labelledby": anchorId
			});
			panel.attr( "aria-labelledby", anchorId );
		});

		this.panels
			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
			.attr( "role", "tabpanel" );

		// Avoid memory leaks (#10056)
		if ( prevTabs ) {
			this._off( prevTabs.not( this.tabs ) );
			this._off( prevAnchors.not( this.anchors ) );
			this._off( prevPanels.not( this.panels ) );
		}
	},

	// allow overriding how to find the list for rare usage scenarios (#7715)
	_getList: function() {
		return this.tablist || this.element.find( "ol,ul" ).eq( 0 );
	},

	_createPanel: function( id ) {
		return $( "<div>" )
			.attr( "id", id )
			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
			.data( "ui-tabs-destroy", true );
	},

	_setupDisabled: function( disabled ) {
		if ( $.isArray( disabled ) ) {
			if ( !disabled.length ) {
				disabled = false;
			} else if ( disabled.length === this.anchors.length ) {
				disabled = true;
			}
		}

		// disable tabs
		for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
				$( li )
					.addClass( "ui-state-disabled" )
					.attr( "aria-disabled", "true" );
			} else {
				$( li )
					.removeClass( "ui-state-disabled" )
					.removeAttr( "aria-disabled" );
			}
		}

		this.options.disabled = disabled;
	},

	_setupEvents: function( event ) {
		var events = {};
		if ( event ) {
			$.each( event.split(" "), function( index, eventName ) {
				events[ eventName ] = "_eventHandler";
			});
		}

		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
		// Always prevent the default action, even when disabled
		this._on( true, this.anchors, {
			click: function( event ) {
				event.preventDefault();
			}
		});
		this._on( this.anchors, events );
		this._on( this.tabs, { keydown: "_tabKeydown" } );
		this._on( this.panels, { keydown: "_panelKeydown" } );

		this._focusable( this.tabs );
		this._hoverable( this.tabs );
	},

	_setupHeightStyle: function( heightStyle ) {
		var maxHeight,
			parent = this.element.parent();

		if ( heightStyle === "fill" ) {
			maxHeight = parent.height();
			maxHeight -= this.element.outerHeight() - this.element.height();

			this.element.siblings( ":visible" ).each(function() {
				var elem = $( this ),
					position = elem.css( "position" );

				if ( position === "absolute" || position === "fixed" ) {
					return;
				}
				maxHeight -= elem.outerHeight( true );
			});

			this.element.children().not( this.panels ).each(function() {
				maxHeight -= $( this ).outerHeight( true );
			});

			this.panels.each(function() {
				$( this ).height( Math.max( 0, maxHeight -
					$( this ).innerHeight() + $( this ).height() ) );
			})
			.css( "overflow", "auto" );
		} else if ( heightStyle === "auto" ) {
			maxHeight = 0;
			this.panels.each(function() {
				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
			}).height( maxHeight );
		}
	},

	_eventHandler: function( event ) {
		var options = this.options,
			active = this.active,
			anchor = $( event.currentTarget ),
			tab = anchor.closest( "li" ),
			clickedIsActive = tab[ 0 ] === active[ 0 ],
			collapsing = clickedIsActive && options.collapsible,
			toShow = collapsing ? $() : this._getPanelForTab( tab ),
			toHide = !active.length ? $() : this._getPanelForTab( active ),
			eventData = {
				oldTab: active,
				oldPanel: toHide,
				newTab: collapsing ? $() : tab,
				newPanel: toShow
			};

		event.preventDefault();

		if ( tab.hasClass( "ui-state-disabled" ) ||
				// tab is already loading
				tab.hasClass( "ui-tabs-loading" ) ||
				// can't switch durning an animation
				this.running ||
				// click on active header, but not collapsible
				( clickedIsActive && !options.collapsible ) ||
				// allow canceling activation
				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
			return;
		}

		options.active = collapsing ? false : this.tabs.index( tab );

		this.active = clickedIsActive ? $() : tab;
		if ( this.xhr ) {
			this.xhr.abort();
		}

		if ( !toHide.length && !toShow.length ) {
			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
		}

		if ( toShow.length ) {
			this.load( this.tabs.index( tab ), event );
		}
		this._toggle( event, eventData );
	},

	// handles show/hide for selecting tabs
	_toggle: function( event, eventData ) {
		var that = this,
			toShow = eventData.newPanel,
			toHide = eventData.oldPanel;

		this.running = true;

		function complete() {
			that.running = false;
			that._trigger( "activate", event, eventData );
		}

		function show() {
			eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );

			if ( toShow.length && that.options.show ) {
				that._show( toShow, that.options.show, complete );
			} else {
				toShow.show();
				complete();
			}
		}

		// start out by hiding, then showing, then completing
		if ( toHide.length && this.options.hide ) {
			this._hide( toHide, this.options.hide, function() {
				eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
				show();
			});
		} else {
			eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
			toHide.hide();
			show();
		}

		toHide.attr( "aria-hidden", "true" );
		eventData.oldTab.attr({
			"aria-selected": "false",
			"aria-expanded": "false"
		});
		// If we're switching tabs, remove the old tab from the tab order.
		// If we're opening from collapsed state, remove the previous tab from the tab order.
		// If we're collapsing, then keep the collapsing tab in the tab order.
		if ( toShow.length && toHide.length ) {
			eventData.oldTab.attr( "tabIndex", -1 );
		} else if ( toShow.length ) {
			this.tabs.filter(function() {
				return $( this ).attr( "tabIndex" ) === 0;
			})
			.attr( "tabIndex", -1 );
		}

		toShow.attr( "aria-hidden", "false" );
		eventData.newTab.attr({
			"aria-selected": "true",
			"aria-expanded": "true",
			tabIndex: 0
		});
	},

	_activate: function( index ) {
		var anchor,
			active = this._findActive( index );

		// trying to activate the already active panel
		if ( active[ 0 ] === this.active[ 0 ] ) {
			return;
		}

		// trying to collapse, simulate a click on the current active header
		if ( !active.length ) {
			active = this.active;
		}

		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
		this._eventHandler({
			target: anchor,
			currentTarget: anchor,
			preventDefault: $.noop
		});
	},

	_findActive: function( index ) {
		return index === false ? $() : this.tabs.eq( index );
	},

	_getIndex: function( index ) {
		// meta-function to give users option to provide a href string instead of a numerical index.
		if ( typeof index === "string" ) {
			index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
		}

		return index;
	},

	_destroy: function() {
		if ( this.xhr ) {
			this.xhr.abort();
		}

		this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );

		this.tablist
			.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
			.removeAttr( "role" );

		this.anchors
			.removeClass( "ui-tabs-anchor" )
			.removeAttr( "role" )
			.removeAttr( "tabIndex" )
			.removeUniqueId();

		this.tablist.unbind( this.eventNamespace );

		this.tabs.add( this.panels ).each(function() {
			if ( $.data( this, "ui-tabs-destroy" ) ) {
				$( this ).remove();
			} else {
				$( this )
					.removeClass( "ui-state-default ui-state-active ui-state-disabled " +
						"ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
					.removeAttr( "tabIndex" )
					.removeAttr( "aria-live" )
					.removeAttr( "aria-busy" )
					.removeAttr( "aria-selected" )
					.removeAttr( "aria-labelledby" )
					.removeAttr( "aria-hidden" )
					.removeAttr( "aria-expanded" )
					.removeAttr( "role" );
			}
		});

		this.tabs.each(function() {
			var li = $( this ),
				prev = li.data( "ui-tabs-aria-controls" );
			if ( prev ) {
				li
					.attr( "aria-controls", prev )
					.removeData( "ui-tabs-aria-controls" );
			} else {
				li.removeAttr( "aria-controls" );
			}
		});

		this.panels.show();

		if ( this.options.heightStyle !== "content" ) {
			this.panels.css( "height", "" );
		}
	},

	enable: function( index ) {
		var disabled = this.options.disabled;
		if ( disabled === false ) {
			return;
		}

		if ( index === undefined ) {
			disabled = false;
		} else {
			index = this._getIndex( index );
			if ( $.isArray( disabled ) ) {
				disabled = $.map( disabled, function( num ) {
					return num !== index ? num : null;
				});
			} else {
				disabled = $.map( this.tabs, function( li, num ) {
					return num !== index ? num : null;
				});
			}
		}
		this._setupDisabled( disabled );
	},

	disable: function( index ) {
		var disabled = this.options.disabled;
		if ( disabled === true ) {
			return;
		}

		if ( index === undefined ) {
			disabled = true;
		} else {
			index = this._getIndex( index );
			if ( $.inArray( index, disabled ) !== -1 ) {
				return;
			}
			if ( $.isArray( disabled ) ) {
				disabled = $.merge( [ index ], disabled ).sort();
			} else {
				disabled = [ index ];
			}
		}
		this._setupDisabled( disabled );
	},

	load: function( index, event ) {
		index = this._getIndex( index );
		var that = this,
			tab = this.tabs.eq( index ),
			anchor = tab.find( ".ui-tabs-anchor" ),
			panel = this._getPanelForTab( tab ),
			eventData = {
				tab: tab,
				panel: panel
			},
			complete = function( jqXHR, status ) {
				if ( status === "abort" ) {
					that.panels.stop( false, true );
				}

				tab.removeClass( "ui-tabs-loading" );
				panel.removeAttr( "aria-busy" );

				if ( jqXHR === that.xhr ) {
					delete that.xhr;
				}
			};

		// not remote
		if ( this._isLocal( anchor[ 0 ] ) ) {
			return;
		}

		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );

		// support: jQuery <1.8
		// jQuery <1.8 returns false if the request is canceled in beforeSend,
		// but as of 1.8, $.ajax() always returns a jqXHR object.
		if ( this.xhr && this.xhr.statusText !== "canceled" ) {
			tab.addClass( "ui-tabs-loading" );
			panel.attr( "aria-busy", "true" );

			this.xhr
				.done(function( response, status, jqXHR ) {
					// support: jQuery <1.8
					// http://bugs.jquery.com/ticket/11778
					setTimeout(function() {
						panel.html( response );
						that._trigger( "load", event, eventData );

						complete( jqXHR, status );
					}, 1 );
				})
				.fail(function( jqXHR, status ) {
					// support: jQuery <1.8
					// http://bugs.jquery.com/ticket/11778
					setTimeout(function() {
						complete( jqXHR, status );
					}, 1 );
				});
		}
	},

	_ajaxSettings: function( anchor, event, eventData ) {
		var that = this;
		return {
			url: anchor.attr( "href" ),
			beforeSend: function( jqXHR, settings ) {
				return that._trigger( "beforeLoad", event,
					$.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
			}
		};
	},

	_getPanelForTab: function( tab ) {
		var id = $( tab ).attr( "aria-controls" );
		return this.element.find( this._sanitizeSelector( "#" + id ) );
	}
});


/*!
 * jQuery UI Tooltip 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/tooltip/
 */


var tooltip = $.widget( "ui.tooltip", {
	version: "1.11.4",
	options: {
		content: function() {
			// support: IE<9, Opera in jQuery <1.7
			// .text() can't accept undefined, so coerce to a string
			var title = $( this ).attr( "title" ) || "";
			// Escape title, since we're going from an attribute to raw HTML
			return $( "<a>" ).text( title ).html();
		},
		hide: true,
		// Disabled elements have inconsistent behavior across browsers (#8661)
		items: "[title]:not([disabled])",
		position: {
			my: "left top+15",
			at: "left bottom",
			collision: "flipfit flip"
		},
		show: true,
		tooltipClass: null,
		track: false,

		// callbacks
		close: null,
		open: null
	},

	_addDescribedBy: function( elem, id ) {
		var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
		describedby.push( id );
		elem
			.data( "ui-tooltip-id", id )
			.attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
	},

	_removeDescribedBy: function( elem ) {
		var id = elem.data( "ui-tooltip-id" ),
			describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
			index = $.inArray( id, describedby );

		if ( index !== -1 ) {
			describedby.splice( index, 1 );
		}

		elem.removeData( "ui-tooltip-id" );
		describedby = $.trim( describedby.join( " " ) );
		if ( describedby ) {
			elem.attr( "aria-describedby", describedby );
		} else {
			elem.removeAttr( "aria-describedby" );
		}
	},

	_create: function() {
		this._on({
			mouseover: "open",
			focusin: "open"
		});

		// IDs of generated tooltips, needed for destroy
		this.tooltips = {};

		// IDs of parent tooltips where we removed the title attribute
		this.parents = {};

		if ( this.options.disabled ) {
			this._disable();
		}

		// Append the aria-live region so tooltips announce correctly
		this.liveRegion = $( "<div>" )
			.attr({
				role: "log",
				"aria-live": "assertive",
				"aria-relevant": "additions"
			})
			.addClass( "ui-helper-hidden-accessible" )
			.appendTo( this.document[ 0 ].body );
	},

	_setOption: function( key, value ) {
		var that = this;

		if ( key === "disabled" ) {
			this[ value ? "_disable" : "_enable" ]();
			this.options[ key ] = value;
			// disable element style changes
			return;
		}

		this._super( key, value );

		if ( key === "content" ) {
			$.each( this.tooltips, function( id, tooltipData ) {
				that._updateContent( tooltipData.element );
			});
		}
	},

	_disable: function() {
		var that = this;

		// close open tooltips
		$.each( this.tooltips, function( id, tooltipData ) {
			var event = $.Event( "blur" );
			event.target = event.currentTarget = tooltipData.element[ 0 ];
			that.close( event, true );
		});

		// remove title attributes to prevent native tooltips
		this.element.find( this.options.items ).addBack().each(function() {
			var element = $( this );
			if ( element.is( "[title]" ) ) {
				element
					.data( "ui-tooltip-title", element.attr( "title" ) )
					.removeAttr( "title" );
			}
		});
	},

	_enable: function() {
		// restore title attributes
		this.element.find( this.options.items ).addBack().each(function() {
			var element = $( this );
			if ( element.data( "ui-tooltip-title" ) ) {
				element.attr( "title", element.data( "ui-tooltip-title" ) );
			}
		});
	},

	open: function( event ) {
		var that = this,
			target = $( event ? event.target : this.element )
				// we need closest here due to mouseover bubbling,
				// but always pointing at the same event target
				.closest( this.options.items );

		// No element to show a tooltip for or the tooltip is already open
		if ( !target.length || target.data( "ui-tooltip-id" ) ) {
			return;
		}

		if ( target.attr( "title" ) ) {
			target.data( "ui-tooltip-title", target.attr( "title" ) );
		}

		target.data( "ui-tooltip-open", true );

		// kill parent tooltips, custom or native, for hover
		if ( event && event.type === "mouseover" ) {
			target.parents().each(function() {
				var parent = $( this ),
					blurEvent;
				if ( parent.data( "ui-tooltip-open" ) ) {
					blurEvent = $.Event( "blur" );
					blurEvent.target = blurEvent.currentTarget = this;
					that.close( blurEvent, true );
				}
				if ( parent.attr( "title" ) ) {
					parent.uniqueId();
					that.parents[ this.id ] = {
						element: this,
						title: parent.attr( "title" )
					};
					parent.attr( "title", "" );
				}
			});
		}

		this._registerCloseHandlers( event, target );
		this._updateContent( target, event );
	},

	_updateContent: function( target, event ) {
		var content,
			contentOption = this.options.content,
			that = this,
			eventType = event ? event.type : null;

		if ( typeof contentOption === "string" ) {
			return this._open( event, target, contentOption );
		}

		content = contentOption.call( target[0], function( response ) {

			// IE may instantly serve a cached response for ajax requests
			// delay this call to _open so the other call to _open runs first
			that._delay(function() {

				// Ignore async response if tooltip was closed already
				if ( !target.data( "ui-tooltip-open" ) ) {
					return;
				}

				// jQuery creates a special event for focusin when it doesn't
				// exist natively. To improve performance, the native event
				// object is reused and the type is changed. Therefore, we can't
				// rely on the type being correct after the event finished
				// bubbling, so we set it back to the previous value. (#8740)
				if ( event ) {
					event.type = eventType;
				}
				this._open( event, target, response );
			});
		});
		if ( content ) {
			this._open( event, target, content );
		}
	},

	_open: function( event, target, content ) {
		var tooltipData, tooltip, delayedShow, a11yContent,
			positionOption = $.extend( {}, this.options.position );

		if ( !content ) {
			return;
		}

		// Content can be updated multiple times. If the tooltip already
		// exists, then just update the content and bail.
		tooltipData = this._find( target );
		if ( tooltipData ) {
			tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
			return;
		}

		// if we have a title, clear it to prevent the native tooltip
		// we have to check first to avoid defining a title if none exists
		// (we don't want to cause an element to start matching [title])
		//
		// We use removeAttr only for key events, to allow IE to export the correct
		// accessible attributes. For mouse events, set to empty string to avoid
		// native tooltip showing up (happens only when removing inside mouseover).
		if ( target.is( "[title]" ) ) {
			if ( event && event.type === "mouseover" ) {
				target.attr( "title", "" );
			} else {
				target.removeAttr( "title" );
			}
		}

		tooltipData = this._tooltip( target );
		tooltip = tooltipData.tooltip;
		this._addDescribedBy( target, tooltip.attr( "id" ) );
		tooltip.find( ".ui-tooltip-content" ).html( content );

		// Support: Voiceover on OS X, JAWS on IE <= 9
		// JAWS announces deletions even when aria-relevant="additions"
		// Voiceover will sometimes re-read the entire log region's contents from the beginning
		this.liveRegion.children().hide();
		if ( content.clone ) {
			a11yContent = content.clone();
			a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
		} else {
			a11yContent = content;
		}
		$( "<div>" ).html( a11yContent ).appendTo( this.liveRegion );

		function position( event ) {
			positionOption.of = event;
			if ( tooltip.is( ":hidden" ) ) {
				return;
			}
			tooltip.position( positionOption );
		}
		if ( this.options.track && event && /^mouse/.test( event.type ) ) {
			this._on( this.document, {
				mousemove: position
			});
			// trigger once to override element-relative positioning
			position( event );
		} else {
			tooltip.position( $.extend({
				of: target
			}, this.options.position ) );
		}

		tooltip.hide();

		this._show( tooltip, this.options.show );
		// Handle tracking tooltips that are shown with a delay (#8644). As soon
		// as the tooltip is visible, position the tooltip using the most recent
		// event.
		if ( this.options.show && this.options.show.delay ) {
			delayedShow = this.delayedShow = setInterval(function() {
				if ( tooltip.is( ":visible" ) ) {
					position( positionOption.of );
					clearInterval( delayedShow );
				}
			}, $.fx.interval );
		}

		this._trigger( "open", event, { tooltip: tooltip } );
	},

	_registerCloseHandlers: function( event, target ) {
		var events = {
			keyup: function( event ) {
				if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
					var fakeEvent = $.Event(event);
					fakeEvent.currentTarget = target[0];
					this.close( fakeEvent, true );
				}
			}
		};

		// Only bind remove handler for delegated targets. Non-delegated
		// tooltips will handle this in destroy.
		if ( target[ 0 ] !== this.element[ 0 ] ) {
			events.remove = function() {
				this._removeTooltip( this._find( target ).tooltip );
			};
		}

		if ( !event || event.type === "mouseover" ) {
			events.mouseleave = "close";
		}
		if ( !event || event.type === "focusin" ) {
			events.focusout = "close";
		}
		this._on( true, target, events );
	},

	close: function( event ) {
		var tooltip,
			that = this,
			target = $( event ? event.currentTarget : this.element ),
			tooltipData = this._find( target );

		// The tooltip may already be closed
		if ( !tooltipData ) {

			// We set ui-tooltip-open immediately upon open (in open()), but only set the
			// additional data once there's actually content to show (in _open()). So even if the
			// tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
			// the period between open() and _open().
			target.removeData( "ui-tooltip-open" );
			return;
		}

		tooltip = tooltipData.tooltip;

		// disabling closes the tooltip, so we need to track when we're closing
		// to avoid an infinite loop in case the tooltip becomes disabled on close
		if ( tooltipData.closing ) {
			return;
		}

		// Clear the interval for delayed tracking tooltips
		clearInterval( this.delayedShow );

		// only set title if we had one before (see comment in _open())
		// If the title attribute has changed since open(), don't restore
		if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
			target.attr( "title", target.data( "ui-tooltip-title" ) );
		}

		this._removeDescribedBy( target );

		tooltipData.hiding = true;
		tooltip.stop( true );
		this._hide( tooltip, this.options.hide, function() {
			that._removeTooltip( $( this ) );
		});

		target.removeData( "ui-tooltip-open" );
		this._off( target, "mouseleave focusout keyup" );

		// Remove 'remove' binding only on delegated targets
		if ( target[ 0 ] !== this.element[ 0 ] ) {
			this._off( target, "remove" );
		}
		this._off( this.document, "mousemove" );

		if ( event && event.type === "mouseleave" ) {
			$.each( this.parents, function( id, parent ) {
				$( parent.element ).attr( "title", parent.title );
				delete that.parents[ id ];
			});
		}

		tooltipData.closing = true;
		this._trigger( "close", event, { tooltip: tooltip } );
		if ( !tooltipData.hiding ) {
			tooltipData.closing = false;
		}
	},

	_tooltip: function( element ) {
		var tooltip = $( "<div>" )
				.attr( "role", "tooltip" )
				.addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
					( this.options.tooltipClass || "" ) ),
			id = tooltip.uniqueId().attr( "id" );

		$( "<div>" )
			.addClass( "ui-tooltip-content" )
			.appendTo( tooltip );

		tooltip.appendTo( this.document[0].body );

		return this.tooltips[ id ] = {
			element: element,
			tooltip: tooltip
		};
	},

	_find: function( target ) {
		var id = target.data( "ui-tooltip-id" );
		return id ? this.tooltips[ id ] : null;
	},

	_removeTooltip: function( tooltip ) {
		tooltip.remove();
		delete this.tooltips[ tooltip.attr( "id" ) ];
	},

	_destroy: function() {
		var that = this;

		// close open tooltips
		$.each( this.tooltips, function( id, tooltipData ) {
			// Delegate to close method to handle common cleanup
			var event = $.Event( "blur" ),
				element = tooltipData.element;
			event.target = event.currentTarget = element[ 0 ];
			that.close( event, true );

			// Remove immediately; destroying an open tooltip doesn't use the
			// hide animation
			$( "#" + id ).remove();

			// Restore the title
			if ( element.data( "ui-tooltip-title" ) ) {
				// If the title attribute has changed since open(), don't restore
				if ( !element.attr( "title" ) ) {
					element.attr( "title", element.data( "ui-tooltip-title" ) );
				}
				element.removeData( "ui-tooltip-title" );
			}
		});
		this.liveRegion.remove();
	}
});



}));

/***/ }),
/* 11 */
/***/ (function(module, exports, __webpack_require__) {

/* WEBPACK VAR INJECTION */(function(jQuery) {/*!
 * jQuery BBQ: Back Button & Query Library - v1.3pre - 8/26/2010
 * http://benalman.com/projects/jquery-bbq-plugin/
 * 
 * Copyright (c) 2010 "Cowboy" Ben Alman
 * Dual licensed under the MIT and GPL licenses.
 * http://benalman.com/about/license/
 */

// Script: jQuery BBQ: Back Button & Query Library
//
// *Version: 1.3pre, Last updated: 8/26/2010*
// 
// Project Home - http://benalman.com/projects/jquery-bbq-plugin/
// GitHub       - http://github.com/cowboy/jquery-bbq/
// Source       - http://github.com/cowboy/jquery-bbq/raw/master/jquery.ba-bbq.js
// (Minified)   - http://github.com/cowboy/jquery-bbq/raw/master/jquery.ba-bbq.min.js (2.2kb gzipped)
// 
// About: License
// 
// Copyright (c) 2010 "Cowboy" Ben Alman,
// Dual licensed under the MIT and GPL licenses.
// http://benalman.com/about/license/
// 
// About: Examples
// 
// These working examples, complete with fully commented code, illustrate a few
// ways in which this plugin can be used.
// 
// Basic AJAX     - http://benalman.com/code/projects/jquery-bbq/examples/fragment-basic/
// Advanced AJAX  - http://benalman.com/code/projects/jquery-bbq/examples/fragment-advanced/
// jQuery UI Tabs - http://benalman.com/code/projects/jquery-bbq/examples/fragment-jquery-ui-tabs/
// Deparam        - http://benalman.com/code/projects/jquery-bbq/examples/deparam/
// 
// About: Support and Testing
// 
// Information about what version or versions of jQuery this plugin has been
// tested with, what browsers it has been tested in, and where the unit tests
// reside (so you can test it yourself).
// 
// jQuery Versions - 1.2.6, 1.3.2, 1.4.1, 1.4.2
// Browsers Tested - Internet Explorer 6-8, Firefox 2-4, Chrome 5-6, Safari 3.2-5,
//                   Opera 9.6-10.60, iPhone 3.1, Android 1.6-2.2, BlackBerry 4.6-5.
// Unit Tests      - http://benalman.com/code/projects/jquery-bbq/unit/
// 
// About: Release History
// 
// 1.3pre - (8/26/2010) Integrated <jQuery hashchange event> v1.3, which adds
//         document.title and document.domain support in IE6/7, BlackBerry
//         support, better Iframe hiding for accessibility reasons, and the new
//         <jQuery.fn.hashchange> "shortcut" method. Added the
//         <jQuery.param.sorted> method which reduces the possibility of
//         extraneous hashchange event triggering. Added the
//         <jQuery.param.fragment.ajaxCrawlable> method which can be used to
//         enable Google "AJAX Crawlable mode."
// 1.2.1 - (2/17/2010) Actually fixed the stale window.location Safari bug from
//         <jQuery hashchange event> in BBQ, which was the main reason for the
//         previous release!
// 1.2   - (2/16/2010) Integrated <jQuery hashchange event> v1.2, which fixes a
//         Safari bug, the event can now be bound before DOM ready, and IE6/7
//         page should no longer scroll when the event is first bound. Also
//         added the <jQuery.param.fragment.noEscape> method, and reworked the
//         <hashchange event (BBQ)> internal "add" method to be compatible with
//         changes made to the jQuery 1.4.2 special events API.
// 1.1.1 - (1/22/2010) Integrated <jQuery hashchange event> v1.1, which fixes an
//         obscure IE8 EmulateIE7 meta tag compatibility mode bug.
// 1.1   - (1/9/2010) Broke out the jQuery BBQ event.special <hashchange event>
//         functionality into a separate plugin for users who want just the
//         basic event & back button support, without all the extra awesomeness
//         that BBQ provides. This plugin will be included as part of jQuery BBQ,
//         but also be available separately. See <jQuery hashchange event>
//         plugin for more information. Also added the <jQuery.bbq.removeState>
//         method and added additional <jQuery.deparam> examples.
// 1.0.3 - (12/2/2009) Fixed an issue in IE 6 where location.search and
//         location.hash would report incorrectly if the hash contained the ?
//         character. Also <jQuery.param.querystring> and <jQuery.param.fragment>
//         will no longer parse params out of a URL that doesn't contain ? or #,
//         respectively.
// 1.0.2 - (10/10/2009) Fixed an issue in IE 6/7 where the hidden IFRAME caused
//         a "This page contains both secure and nonsecure items." warning when
//         used on an https:// page.
// 1.0.1 - (10/7/2009) Fixed an issue in IE 8. Since both "IE7" and "IE8
//         Compatibility View" modes erroneously report that the browser
//         supports the native window.onhashchange event, a slightly more
//         robust test needed to be added.
// 1.0   - (10/2/2009) Initial release

(function($,window){
  '$:nomunge'; // Used by YUI compressor.
  
  // Some convenient shortcuts.
  var undefined,
    aps = Array.prototype.slice,
    decode = decodeURIComponent,
    
    // Method / object references.
    jq_param = $.param,
    jq_param_sorted,
    jq_param_fragment,
    jq_deparam,
    jq_deparam_fragment,
    jq_bbq = $.bbq = $.bbq || {},
    jq_bbq_pushState,
    jq_bbq_getState,
    jq_elemUrlAttr,
    special = $.event.special,
    
    // Reused strings.
    str_hashchange = 'hashchange',
    str_querystring = 'querystring',
    str_fragment = 'fragment',
    str_elemUrlAttr = 'elemUrlAttr',
    str_href = 'href',
    str_src = 'src',
    
    // Reused RegExp.
    re_params_querystring = /^.*\?|#.*$/g,
    re_params_fragment,
    re_fragment,
    re_no_escape,
    
    ajax_crawlable,
    fragment_prefix,
    
    // Used by jQuery.elemUrlAttr.
    elemUrlAttr_cache = {};
  
  // A few commonly used bits, broken out to help reduce minified file size.
  
  function is_string( arg ) {
    return typeof arg === 'string';
  };
  
  // Why write the same function twice? Let's curry! Mmmm, curry..
  
  function curry( func ) {
    var args = aps.call( arguments, 1 );
    
    return function() {
      return func.apply( this, args.concat( aps.call( arguments ) ) );
    };
  };
  
  // Get location.hash (or what you'd expect location.hash to be) sans any
  // leading #. Thanks for making this necessary, Firefox!
  function get_fragment( url ) {
    return url.replace( re_fragment, '$2' );
  };
  
  // Get location.search (or what you'd expect location.search to be) sans any
  // leading #. Thanks for making this necessary, IE6!
  function get_querystring( url ) {
    return url.replace( /(?:^[^?#]*\?([^#]*).*$)?.*/, '$1' );
  };
  
  // Section: Param (to string)
  // 
  // Method: jQuery.param.querystring
  // 
  // Retrieve the query string from a URL or if no arguments are passed, the
  // current window.location.href.
  // 
  // Usage:
  // 
  // > jQuery.param.querystring( [ url ] );
  // 
  // Arguments:
  // 
  //  url - (String) A URL containing query string params to be parsed. If url
  //    is not passed, the current window.location.href is used.
  // 
  // Returns:
  // 
  //  (String) The parsed query string, with any leading "?" removed.
  //
  
  // Method: jQuery.param.querystring (build url)
  // 
  // Merge a URL, with or without pre-existing query string params, plus any
  // object, params string or URL containing query string params into a new URL.
  // 
  // Usage:
  // 
  // > jQuery.param.querystring( url, params [, merge_mode ] );
  // 
  // Arguments:
  // 
  //  url - (String) A valid URL for params to be merged into. This URL may
  //    contain a query string and/or fragment (hash).
  //  params - (String) A params string or URL containing query string params to
  //    be merged into url.
  //  params - (Object) A params object to be merged into url.
  //  merge_mode - (Number) Merge behavior defaults to 0 if merge_mode is not
  //    specified, and is as-follows:
  // 
  //    * 0: params in the params argument will override any query string
  //         params in url.
  //    * 1: any query string params in url will override params in the params
  //         argument.
  //    * 2: params argument will completely replace any query string in url.
  // 
  // Returns:
  // 
  //  (String) A URL with a urlencoded query string in the format '?a=b&c=d&e=f'.
  
  // Method: jQuery.param.fragment
  // 
  // Retrieve the fragment (hash) from a URL or if no arguments are passed, the
  // current window.location.href.
  // 
  // Usage:
  // 
  // > jQuery.param.fragment( [ url ] );
  // 
  // Arguments:
  // 
  //  url - (String) A URL containing fragment (hash) params to be parsed. If
  //    url is not passed, the current window.location.href is used.
  // 
  // Returns:
  // 
  //  (String) The parsed fragment (hash) string, with any leading "#" removed.
  
  // Method: jQuery.param.fragment (build url)
  // 
  // Merge a URL, with or without pre-existing fragment (hash) params, plus any
  // object, params string or URL containing fragment (hash) params into a new
  // URL.
  // 
  // Usage:
  // 
  // > jQuery.param.fragment( url, params [, merge_mode ] );
  // 
  // Arguments:
  // 
  //  url - (String) A valid URL for params to be merged into. This URL may
  //    contain a query string and/or fragment (hash).
  //  params - (String) A params string or URL containing fragment (hash) params
  //    to be merged into url.
  //  params - (Object) A params object to be merged into url.
  //  merge_mode - (Number) Merge behavior defaults to 0 if merge_mode is not
  //    specified, and is as-follows:
  // 
  //    * 0: params in the params argument will override any fragment (hash)
  //         params in url.
  //    * 1: any fragment (hash) params in url will override params in the
  //         params argument.
  //    * 2: params argument will completely replace any query string in url.
  // 
  // Returns:
  // 
  //  (String) A URL with a urlencoded fragment (hash) in the format '#a=b&c=d&e=f'.
  
  function jq_param_sub( is_fragment, get_func, url, params, merge_mode ) {
    var result,
      qs,
      matches,
      url_params,
      hash;
    
    if ( params !== undefined ) {
      // Build URL by merging params into url string.
      
      // matches[1] = url part that precedes params, not including trailing ?/#
      // matches[2] = params, not including leading ?/#
      // matches[3] = if in 'querystring' mode, hash including leading #, otherwise ''
      matches = url.match( is_fragment ? re_fragment : /^([^#?]*)\??([^#]*)(#?.*)/ );
      
      // Get the hash if in 'querystring' mode, and it exists.
      hash = matches[3] || '';
      
      if ( merge_mode === 2 && is_string( params ) ) {
        // If merge_mode is 2 and params is a string, merge the fragment / query
        // string into the URL wholesale, without converting it into an object.
        qs = params.replace( is_fragment ? re_params_fragment : re_params_querystring, '' );
        
      } else {
        // Convert relevant params in url to object.
        url_params = jq_deparam( matches[2] );
        
        params = is_string( params )
          
          // Convert passed params string into object.
          ? jq_deparam[ is_fragment ? str_fragment : str_querystring ]( params )
          
          // Passed params object.
          : params;
        
        qs = merge_mode === 2 ? params                              // passed params replace url params
          : merge_mode === 1  ? $.extend( {}, params, url_params )  // url params override passed params
          : $.extend( {}, url_params, params );                     // passed params override url params
        
        // Convert params object into a sorted params string.
        qs = jq_param_sorted( qs );
        
        // Unescape characters specified via $.param.noEscape. Since only hash-
        // history users have requested this feature, it's only enabled for
        // fragment-related params strings.
        if ( is_fragment ) {
          qs = qs.replace( re_no_escape, decode );
        }
      }
      
      // Build URL from the base url, querystring and hash. In 'querystring'
      // mode, ? is only added if a query string exists. In 'fragment' mode, #
      // is always added.
      result = matches[1] + ( is_fragment ? fragment_prefix : qs || !matches[1] ? '?' : '' ) + qs + hash;
      
    } else {
      // If URL was passed in, parse params from URL string, otherwise parse
      // params from window.location.href.
      result = get_func( url !== undefined ? url : location.href );
    }
    
    return result;
  };
  
  jq_param[ str_querystring ]                  = curry( jq_param_sub, 0, get_querystring );
  jq_param[ str_fragment ] = jq_param_fragment = curry( jq_param_sub, 1, get_fragment );
  
  // Method: jQuery.param.sorted
  // 
  // Returns a params string equivalent to that returned by the internal
  // jQuery.param method, but sorted, which makes it suitable for use as a
  // cache key.
  // 
  // For example, in most browsers jQuery.param({z:1,a:2}) returns "z=1&a=2"
  // and jQuery.param({a:2,z:1}) returns "a=2&z=1". Even though both the
  // objects being serialized and the resulting params strings are equivalent,
  // if these params strings were set into the location.hash fragment
  // sequentially, the hashchange event would be triggered unnecessarily, since
  // the strings are different (even though the data described by them is the
  // same). By sorting the params string, unecessary hashchange event triggering
  // can be avoided.
  // 
  // Usage:
  // 
  // > jQuery.param.sorted( obj [, traditional ] );
  // 
  // Arguments:
  // 
  //  obj - (Object) An object to be serialized.
  //  traditional - (Boolean) Params deep/shallow serialization mode. See the
  //    documentation at http://api.jquery.com/jQuery.param/ for more detail.
  // 
  // Returns:
  // 
  //  (String) A sorted params string.
  
  jq_param.sorted = jq_param_sorted = function( a, traditional ) {
    var arr = [],
      obj = {};
    
    $.each( jq_param( a, traditional ).split( '&' ), function(i,v){
      var key = v.replace( /(?:%5B|=).*$/, '' ),
        key_obj = obj[ key ];
      
      if ( !key_obj ) {
        key_obj = obj[ key ] = [];
        arr.push( key );
      }
      
      key_obj.push( v );
    });
    
    return $.map( arr.sort(), function(v){
      return obj[ v ];
    }).join( '&' );
  };
  
  // Method: jQuery.param.fragment.noEscape
  // 
  // Specify characters that will be left unescaped when fragments are created
  // or merged using <jQuery.param.fragment>, or when the fragment is modified
  // using <jQuery.bbq.pushState>. This option only applies to serialized data
  // object fragments, and not set-as-string fragments. Does not affect the
  // query string. Defaults to ",/" (comma, forward slash).
  // 
  // Note that this is considered a purely aesthetic option, and will help to
  // create URLs that "look pretty" in the address bar or bookmarks, without
  // affecting functionality in any way. That being said, be careful to not
  // unescape characters that are used as delimiters or serve a special
  // purpose, such as the "#?&=+" (octothorpe, question mark, ampersand,
  // equals, plus) characters.
  // 
  // Usage:
  // 
  // > jQuery.param.fragment.noEscape( [ chars ] );
  // 
  // Arguments:
  // 
  //  chars - (String) The characters to not escape in the fragment. If
  //    unspecified, defaults to empty string (escape all characters).
  // 
  // Returns:
  // 
  //  Nothing.
  
  jq_param_fragment.noEscape = function( chars ) {
    chars = chars || '';
    var arr = $.map( chars.split(''), encodeURIComponent );
    re_no_escape = new RegExp( arr.join('|'), 'g' );
  };
  
  // A sensible default. These are the characters people seem to complain about
  // "uglifying up the URL" the most.
  jq_param_fragment.noEscape( ',/' );
  
  // Method: jQuery.param.fragment.ajaxCrawlable
  // 
  // TODO: DESCRIBE
  // 
  // Usage:
  // 
  // > jQuery.param.fragment.ajaxCrawlable( [ state ] );
  // 
  // Arguments:
  // 
  //  state - (Boolean) TODO: DESCRIBE
  // 
  // Returns:
  // 
  //  (Boolean) The current ajaxCrawlable state.
  
  jq_param_fragment.ajaxCrawlable = function( state ) {
    if ( state !== undefined ) {
      if ( state ) {
        re_params_fragment = /^.*(?:#!|#)/;
        re_fragment = /^([^#]*)(?:#!|#)?(.*)$/;
        fragment_prefix = '#!';
      } else {
        re_params_fragment = /^.*#/;
        re_fragment = /^([^#]*)#?(.*)$/;
        fragment_prefix = '#';
      }
      ajax_crawlable = !!state;
    }
    
    return ajax_crawlable;
  };
  
  jq_param_fragment.ajaxCrawlable( 0 );
  
  // Section: Deparam (from string)
  // 
  // Method: jQuery.deparam
  // 
  // Deserialize a params string into an object, optionally coercing numbers,
  // booleans, null and undefined values; this method is the counterpart to the
  // internal jQuery.param method.
  // 
  // Usage:
  // 
  // > jQuery.deparam( params [, coerce ] );
  // 
  // Arguments:
  // 
  //  params - (String) A params string to be parsed.
  //  coerce - (Boolean) If true, coerces any numbers or true, false, null, and
  //    undefined to their actual value. Defaults to false if omitted.
  // 
  // Returns:
  // 
  //  (Object) An object representing the deserialized params string.
  
  $.deparam = jq_deparam = function( params, coerce ) {
    var obj = {},
      coerce_types = { 'true': !0, 'false': !1, 'null': null };
    
    // Iterate over all name=value pairs.
    $.each( params.replace( /\+/g, ' ' ).split( '&' ), function(j,v){
      var param = v.split( '=' ),
        key = decode( param[0] ),
        val,
        cur = obj,
        i = 0,
        
        // If key is more complex than 'foo', like 'a[]' or 'a[b][c]', split it
        // into its component parts.
        keys = key.split( '][' ),
        keys_last = keys.length - 1;
      
      // If the first keys part contains [ and the last ends with ], then []
      // are correctly balanced.
      if ( /\[/.test( keys[0] ) && /\]$/.test( keys[ keys_last ] ) ) {
        // Remove the trailing ] from the last keys part.
        keys[ keys_last ] = keys[ keys_last ].replace( /\]$/, '' );
        
        // Split first keys part into two parts on the [ and add them back onto
        // the beginning of the keys array.
        keys = keys.shift().split('[').concat( keys );
        
        keys_last = keys.length - 1;
      } else {
        // Basic 'foo' style key.
        keys_last = 0;
      }
      
      // Are we dealing with a name=value pair, or just a name?
      if ( param.length === 2 ) {
        val = decode( param[1] );
        
        // Coerce values.
        if ( coerce ) {
          val = val && !isNaN(val)            ? +val              // number
            : val === 'undefined'             ? undefined         // undefined
            : coerce_types[val] !== undefined ? coerce_types[val] // true, false, null
            : val;                                                // string
        }
        
        if ( keys_last ) {
          // Complex key, build deep object structure based on a few rules:
          // * The 'cur' pointer starts at the object top-level.
          // * [] = array push (n is set to array length), [n] = array if n is 
          //   numeric, otherwise object.
          // * If at the last keys part, set the value.
          // * For each keys part, if the current level is undefined create an
          //   object or array based on the type of the next keys part.
          // * Move the 'cur' pointer to the next level.
          // * Rinse & repeat.
          for ( ; i <= keys_last; i++ ) {
            key = keys[i] === '' ? cur.length : keys[i];
            cur = cur[key] = i < keys_last
              ? cur[key] || ( keys[i+1] && isNaN( keys[i+1] ) ? {} : [] )
              : val;
          }
          
        } else {
          // Simple key, even simpler rules, since only scalars and shallow
          // arrays are allowed.
          
          if ( $.isArray( obj[key] ) ) {
            // val is already an array, so push on the next value.
            obj[key].push( val );
            
          } else if ( obj[key] !== undefined ) {
            // val isn't an array, but since a second value has been specified,
            // convert val into an array.
            obj[key] = [ obj[key], val ];
            
          } else {
            // val is a scalar.
            obj[key] = val;
          }
        }
        
      } else if ( key ) {
        // No value was defined, so set something meaningful.
        obj[key] = coerce
          ? undefined
          : '';
      }
    });
    
    return obj;
  };
  
  // Method: jQuery.deparam.querystring
  // 
  // Parse the query string from a URL or the current window.location.href,
  // deserializing it into an object, optionally coercing numbers, booleans,
  // null and undefined values.
  // 
  // Usage:
  // 
  // > jQuery.deparam.querystring( [ url ] [, coerce ] );
  // 
  // Arguments:
  // 
  //  url - (String) An optional params string or URL containing query string
  //    params to be parsed. If url is omitted, the current
  //    window.location.href is used.
  //  coerce - (Boolean) If true, coerces any numbers or true, false, null, and
  //    undefined to their actual value. Defaults to false if omitted.
  // 
  // Returns:
  // 
  //  (Object) An object representing the deserialized params string.
  
  // Method: jQuery.deparam.fragment
  // 
  // Parse the fragment (hash) from a URL or the current window.location.href,
  // deserializing it into an object, optionally coercing numbers, booleans,
  // null and undefined values.
  // 
  // Usage:
  // 
  // > jQuery.deparam.fragment( [ url ] [, coerce ] );
  // 
  // Arguments:
  // 
  //  url - (String) An optional params string or URL containing fragment (hash)
  //    params to be parsed. If url is omitted, the current window.location.href
  //    is used.
  //  coerce - (Boolean) If true, coerces any numbers or true, false, null, and
  //    undefined to their actual value. Defaults to false if omitted.
  // 
  // Returns:
  // 
  //  (Object) An object representing the deserialized params string.
  
  function jq_deparam_sub( is_fragment, url_or_params, coerce ) {
    if ( url_or_params === undefined || typeof url_or_params === 'boolean' ) {
      // url_or_params not specified.
      coerce = url_or_params;
      url_or_params = jq_param[ is_fragment ? str_fragment : str_querystring ]();
    } else {
      url_or_params = is_string( url_or_params )
        ? url_or_params.replace( is_fragment ? re_params_fragment : re_params_querystring, '' )
        : url_or_params;
    }
    
    return jq_deparam( url_or_params, coerce );
  };
  
  jq_deparam[ str_querystring ]                    = curry( jq_deparam_sub, 0 );
  jq_deparam[ str_fragment ] = jq_deparam_fragment = curry( jq_deparam_sub, 1 );
  
  // Section: Element manipulation
  // 
  // Method: jQuery.elemUrlAttr
  // 
  // Get the internal "Default URL attribute per tag" list, or augment the list
  // with additional tag-attribute pairs, in case the defaults are insufficient.
  // 
  // In the <jQuery.fn.querystring> and <jQuery.fn.fragment> methods, this list
  // is used to determine which attribute contains the URL to be modified, if
  // an "attr" param is not specified.
  // 
  // Default Tag-Attribute List:
  // 
  //  a      - href
  //  base   - href
  //  iframe - src
  //  img    - src
  //  input  - src
  //  form   - action
  //  link   - href
  //  script - src
  // 
  // Usage:
  // 
  // > jQuery.elemUrlAttr( [ tag_attr ] );
  // 
  // Arguments:
  // 
  //  tag_attr - (Object) An object containing a list of tag names and their
  //    associated default attribute names in the format { tag: 'attr', ... } to
  //    be merged into the internal tag-attribute list.
  // 
  // Returns:
  // 
  //  (Object) An object containing all stored tag-attribute values.
  
  // Only define function and set defaults if function doesn't already exist, as
  // the urlInternal plugin will provide this method as well.
  $[ str_elemUrlAttr ] || ($[ str_elemUrlAttr ] = function( obj ) {
    return $.extend( elemUrlAttr_cache, obj );
  })({
    a: str_href,
    base: str_href,
    iframe: str_src,
    img: str_src,
    input: str_src,
    form: 'action',
    link: str_href,
    script: str_src
  });
  
  jq_elemUrlAttr = $[ str_elemUrlAttr ];
  
  // Method: jQuery.fn.querystring
  // 
  // Update URL attribute in one or more elements, merging the current URL (with
  // or without pre-existing query string params) plus any params object or
  // string into a new URL, which is then set into that attribute. Like
  // <jQuery.param.querystring (build url)>, but for all elements in a jQuery
  // collection.
  // 
  // Usage:
  // 
  // > jQuery('selector').querystring( [ attr, ] params [, merge_mode ] );
  // 
  // Arguments:
  // 
  //  attr - (String) Optional name of an attribute that will contain a URL to
  //    merge params or url into. See <jQuery.elemUrlAttr> for a list of default
  //    attributes.
  //  params - (Object) A params object to be merged into the URL attribute.
  //  params - (String) A URL containing query string params, or params string
  //    to be merged into the URL attribute.
  //  merge_mode - (Number) Merge behavior defaults to 0 if merge_mode is not
  //    specified, and is as-follows:
  //    
  //    * 0: params in the params argument will override any params in attr URL.
  //    * 1: any params in attr URL will override params in the params argument.
  //    * 2: params argument will completely replace any query string in attr
  //         URL.
  // 
  // Returns:
  // 
  //  (jQuery) The initial jQuery collection of elements, but with modified URL
  //  attribute values.
  
  // Method: jQuery.fn.fragment
  // 
  // Update URL attribute in one or more elements, merging the current URL (with
  // or without pre-existing fragment/hash params) plus any params object or
  // string into a new URL, which is then set into that attribute. Like
  // <jQuery.param.fragment (build url)>, but for all elements in a jQuery
  // collection.
  // 
  // Usage:
  // 
  // > jQuery('selector').fragment( [ attr, ] params [, merge_mode ] );
  // 
  // Arguments:
  // 
  //  attr - (String) Optional name of an attribute that will contain a URL to
  //    merge params into. See <jQuery.elemUrlAttr> for a list of default
  //    attributes.
  //  params - (Object) A params object to be merged into the URL attribute.
  //  params - (String) A URL containing fragment (hash) params, or params
  //    string to be merged into the URL attribute.
  //  merge_mode - (Number) Merge behavior defaults to 0 if merge_mode is not
  //    specified, and is as-follows:
  //    
  //    * 0: params in the params argument will override any params in attr URL.
  //    * 1: any params in attr URL will override params in the params argument.
  //    * 2: params argument will completely replace any fragment (hash) in attr
  //         URL.
  // 
  // Returns:
  // 
  //  (jQuery) The initial jQuery collection of elements, but with modified URL
  //  attribute values.
  
  function jq_fn_sub( mode, force_attr, params, merge_mode ) {
    if ( !is_string( params ) && typeof params !== 'object' ) {
      // force_attr not specified.
      merge_mode = params;
      params = force_attr;
      force_attr = undefined;
    }
    
    return this.each(function(){
      var that = $(this),
        
        // Get attribute specified, or default specified via $.elemUrlAttr.
        attr = force_attr || jq_elemUrlAttr()[ ( this.nodeName || '' ).toLowerCase() ] || '',
        
        // Get URL value.
        url = attr && that.attr( attr ) || '';
      
      // Update attribute with new URL.
      that.attr( attr, jq_param[ mode ]( url, params, merge_mode ) );
    });
    
  };
  
  $.fn[ str_querystring ] = curry( jq_fn_sub, str_querystring );
  $.fn[ str_fragment ]    = curry( jq_fn_sub, str_fragment );
  
  // Section: History, hashchange event
  // 
  // Method: jQuery.bbq.pushState
  // 
  // Adds a 'state' into the browser history at the current position, setting
  // location.hash and triggering any bound <hashchange event> callbacks
  // (provided the new state is different than the previous state).
  // 
  // If no arguments are passed, an empty state is created, which is just a
  // shortcut for jQuery.bbq.pushState( {}, 2 ).
  // 
  // Usage:
  // 
  // > jQuery.bbq.pushState( [ params [, merge_mode ] ] );
  // 
  // Arguments:
  // 
  //  params - (String) A serialized params string or a hash string beginning
  //    with # to merge into location.hash.
  //  params - (Object) A params object to merge into location.hash.
  //  merge_mode - (Number) Merge behavior defaults to 0 if merge_mode is not
  //    specified (unless a hash string beginning with # is specified, in which
  //    case merge behavior defaults to 2), and is as-follows:
  // 
  //    * 0: params in the params argument will override any params in the
  //         current state.
  //    * 1: any params in the current state will override params in the params
  //         argument.
  //    * 2: params argument will completely replace current state.
  // 
  // Returns:
  // 
  //  Nothing.
  // 
  // Additional Notes:
  // 
  //  * Setting an empty state may cause the browser to scroll.
  //  * Unlike the fragment and querystring methods, if a hash string beginning
  //    with # is specified as the params agrument, merge_mode defaults to 2.
  
  jq_bbq.pushState = jq_bbq_pushState = function( params, merge_mode ) {
    if ( is_string( params ) && /^#/.test( params ) && merge_mode === undefined ) {
      // Params string begins with # and merge_mode not specified, so completely
      // overwrite window.location.hash.
      merge_mode = 2;
    }
    
    var has_args = params !== undefined,
      // Merge params into window.location using $.param.fragment.
      url = jq_param_fragment( location.href,
        has_args ? params : {}, has_args ? merge_mode : 2 );
    
    // Set new window.location.href. Note that Safari 3 & Chrome barf on
    // location.hash = '#' so the entire URL is set.
    location.href = url;
  };
  
  // Method: jQuery.bbq.getState
  // 
  // Retrieves the current 'state' from the browser history, parsing
  // location.hash for a specific key or returning an object containing the
  // entire state, optionally coercing numbers, booleans, null and undefined
  // values.
  // 
  // Usage:
  // 
  // > jQuery.bbq.getState( [ key ] [, coerce ] );
  // 
  // Arguments:
  // 
  //  key - (String) An optional state key for which to return a value.
  //  coerce - (Boolean) If true, coerces any numbers or true, false, null, and
  //    undefined to their actual value. Defaults to false.
  // 
  // Returns:
  // 
  //  (Anything) If key is passed, returns the value corresponding with that key
  //    in the location.hash 'state', or undefined. If not, an object
  //    representing the entire 'state' is returned.
  
  jq_bbq.getState = jq_bbq_getState = function( key, coerce ) {
    return key === undefined || typeof key === 'boolean'
      ? jq_deparam_fragment( key ) // 'key' really means 'coerce' here
      : jq_deparam_fragment( coerce )[ key ];
  };
  
  // Method: jQuery.bbq.removeState
  // 
  // Remove one or more keys from the current browser history 'state', creating
  // a new state, setting location.hash and triggering any bound
  // <hashchange event> callbacks (provided the new state is different than
  // the previous state).
  // 
  // If no arguments are passed, an empty state is created, which is just a
  // shortcut for jQuery.bbq.pushState( {}, 2 ).
  // 
  // Usage:
  // 
  // > jQuery.bbq.removeState( [ key [, key ... ] ] );
  // 
  // Arguments:
  // 
  //  key - (String) One or more key values to remove from the current state,
  //    passed as individual arguments.
  //  key - (Array) A single array argument that contains a list of key values
  //    to remove from the current state.
  // 
  // Returns:
  // 
  //  Nothing.
  // 
  // Additional Notes:
  // 
  //  * Setting an empty state may cause the browser to scroll.
  
  jq_bbq.removeState = function( arr ) {
    var state = {};
    
    // If one or more arguments is passed..
    if ( arr !== undefined ) {
      
      // Get the current state.
      state = jq_bbq_getState();
      
      // For each passed key, delete the corresponding property from the current
      // state.
      $.each( $.isArray( arr ) ? arr : arguments, function(i,v){
        delete state[ v ];
      });
    }
    
    // Set the state, completely overriding any existing state.
    jq_bbq_pushState( state, 2 );
  };
  
  // Event: hashchange event (BBQ)
  // 
  // Usage in jQuery 1.4 and newer:
  // 
  // In jQuery 1.4 and newer, the event object passed into any hashchange event
  // callback is augmented with a copy of the location.hash fragment at the time
  // the event was triggered as its event.fragment property. In addition, the
  // event.getState method operates on this property (instead of location.hash)
  // which allows this fragment-as-a-state to be referenced later, even after
  // window.location may have changed.
  // 
  // Note that event.fragment and event.getState are not defined according to
  // W3C (or any other) specification, but will still be available whether or
  // not the hashchange event exists natively in the browser, because of the
  // utility they provide.
  // 
  // The event.fragment property contains the output of <jQuery.param.fragment>
  // and the event.getState method is equivalent to the <jQuery.bbq.getState>
  // method.
  // 
  // > $(window).bind( 'hashchange', function( event ) {
  // >   var hash_str = event.fragment,
  // >     param_obj = event.getState(),
  // >     param_val = event.getState( 'param_name' ),
  // >     param_val_coerced = event.getState( 'param_name', true );
  // >   ...
  // > });
  // 
  // Usage in jQuery 1.3.2:
  // 
  // In jQuery 1.3.2, the event object cannot to be augmented as in jQuery 1.4+,
  // so the fragment state isn't bound to the event object and must instead be
  // parsed using the <jQuery.param.fragment> and <jQuery.bbq.getState> methods.
  // 
  // > $(window).bind( 'hashchange', function( event ) {
  // >   var hash_str = $.param.fragment(),
  // >     param_obj = $.bbq.getState(),
  // >     param_val = $.bbq.getState( 'param_name' ),
  // >     param_val_coerced = $.bbq.getState( 'param_name', true );
  // >   ...
  // > });
  // 
  // Additional Notes:
  // 
  // * Due to changes in the special events API, jQuery BBQ v1.2 or newer is
  //   required to enable the augmented event object in jQuery 1.4.2 and newer.
  // * See <jQuery hashchange event> for more detailed information.
  
  special[ str_hashchange ] = $.extend( special[ str_hashchange ], {
    
    // Augmenting the event object with the .fragment property and .getState
    // method requires jQuery 1.4 or newer. Note: with 1.3.2, everything will
    // work, but the event won't be augmented)
    add: function( handleObj ) {
      var old_handler;
      
      function new_handler(e) {
        // e.fragment is set to the value of location.hash (with any leading #
        // removed) at the time the event is triggered.
        var hash = e[ str_fragment ] = jq_param_fragment();
        
        // e.getState() works just like $.bbq.getState(), but uses the
        // e.fragment property stored on the event object.
        e.getState = function( key, coerce ) {
          return key === undefined || typeof key === 'boolean'
            ? jq_deparam( hash, key ) // 'key' really means 'coerce' here
            : jq_deparam( hash, coerce )[ key ];
        };
        
        old_handler.apply( this, arguments );
      };
      
      // This may seem a little complicated, but it normalizes the special event
      // .add method between jQuery 1.4/1.4.1 and 1.4.2+
      if ( $.isFunction( handleObj ) ) {
        // 1.4, 1.4.1
        old_handler = handleObj;
        return new_handler;
      } else {
        // 1.4.2+
        old_handler = handleObj.handler;
        handleObj.handler = new_handler;
      }
    }
    
  });
  
})(jQuery,this);

/*!
 * jQuery hashchange event - v1.3 - 7/21/2010
 * http://benalman.com/projects/jquery-hashchange-plugin/
 * 
 * Copyright (c) 2010 "Cowboy" Ben Alman
 * Dual licensed under the MIT and GPL licenses.
 * http://benalman.com/about/license/
 */

// Script: jQuery hashchange event
//
// *Version: 1.3, Last updated: 7/21/2010*
// 
// Project Home - http://benalman.com/projects/jquery-hashchange-plugin/
// GitHub       - http://github.com/cowboy/jquery-hashchange/
// Source       - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.js
// (Minified)   - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.min.js (0.8kb gzipped)
// 
// About: License
// 
// Copyright (c) 2010 "Cowboy" Ben Alman,
// Dual licensed under the MIT and GPL licenses.
// http://benalman.com/about/license/
// 
// About: Examples
// 
// These working examples, complete with fully commented code, illustrate a few
// ways in which this plugin can be used.
// 
// hashchange event - http://benalman.com/code/projects/jquery-hashchange/examples/hashchange/
// document.domain - http://benalman.com/code/projects/jquery-hashchange/examples/document_domain/
// 
// About: Support and Testing
// 
// Information about what version or versions of jQuery this plugin has been
// tested with, what browsers it has been tested in, and where the unit tests
// reside (so you can test it yourself).
// 
// jQuery Versions - 1.2.6, 1.3.2, 1.4.1, 1.4.2
// Browsers Tested - Internet Explorer 6-8, Firefox 2-4, Chrome 5-6, Safari 3.2-5,
//                   Opera 9.6-10.60, iPhone 3.1, Android 1.6-2.2, BlackBerry 4.6-5.
// Unit Tests      - http://benalman.com/code/projects/jquery-hashchange/unit/
// 
// About: Known issues
// 
// While this jQuery hashchange event implementation is quite stable and
// robust, there are a few unfortunate browser bugs surrounding expected
// hashchange event-based behaviors, independent of any JavaScript
// window.onhashchange abstraction. See the following examples for more
// information:
// 
// Chrome: Back Button - http://benalman.com/code/projects/jquery-hashchange/examples/bug-chrome-back-button/
// Firefox: Remote XMLHttpRequest - http://benalman.com/code/projects/jquery-hashchange/examples/bug-firefox-remote-xhr/
// WebKit: Back Button in an Iframe - http://benalman.com/code/projects/jquery-hashchange/examples/bug-webkit-hash-iframe/
// Safari: Back Button from a different domain - http://benalman.com/code/projects/jquery-hashchange/examples/bug-safari-back-from-diff-domain/
// 
// Also note that should a browser natively support the window.onhashchange 
// event, but not report that it does, the fallback polling loop will be used.
// 
// About: Release History
// 
// 1.3   - (7/21/2010) Reorganized IE6/7 Iframe code to make it more
//         "removable" for mobile-only development. Added IE6/7 document.title
//         support. Attempted to make Iframe as hidden as possible by using
//         techniques from http://www.paciellogroup.com/blog/?p=604. Added 
//         support for the "shortcut" format $(window).hashchange( fn ) and
//         $(window).hashchange() like jQuery provides for built-in events.
//         Renamed jQuery.hashchangeDelay to <jQuery.fn.hashchange.delay> and
//         lowered its default value to 50. Added <jQuery.fn.hashchange.domain>
//         and <jQuery.fn.hashchange.src> properties plus document-domain.html
//         file to address access denied issues when setting document.domain in
//         IE6/7.
// 1.2   - (2/11/2010) Fixed a bug where coming back to a page using this plugin
//         from a page on another domain would cause an error in Safari 4. Also,
//         IE6/7 Iframe is now inserted after the body (this actually works),
//         which prevents the page from scrolling when the event is first bound.
//         Event can also now be bound before DOM ready, but it won't be usable
//         before then in IE6/7.
// 1.1   - (1/21/2010) Incorporated document.documentMode test to fix IE8 bug
//         where browser version is incorrectly reported as 8.0, despite
//         inclusion of the X-UA-Compatible IE=EmulateIE7 meta tag.
// 1.0   - (1/9/2010) Initial Release. Broke out the jQuery BBQ event.special
//         window.onhashchange functionality into a separate plugin for users
//         who want just the basic event & back button support, without all the
//         extra awesomeness that BBQ provides. This plugin will be included as
//         part of jQuery BBQ, but also be available separately.

(function($,window,undefined){
  '$:nomunge'; // Used by YUI compressor.
  
  // Reused string.
  var str_hashchange = 'hashchange',
    
    // Method / object references.
    doc = document,
    fake_onhashchange,
    special = $.event.special,
    
    // Does the browser support window.onhashchange? Note that IE8 running in
    // IE7 compatibility mode reports true for 'onhashchange' in window, even
    // though the event isn't supported, so also test document.documentMode.
    doc_mode = doc.documentMode,
    supports_onhashchange = 'on' + str_hashchange in window && ( doc_mode === undefined || doc_mode > 7 );
  
  // Get location.hash (or what you'd expect location.hash to be) sans any
  // leading #. Thanks for making this necessary, Firefox!
  function get_fragment( url ) {
    url = url || location.href;
    return '#' + url.replace( /^[^#]*#?(.*)$/, '$1' );
  };
  
  // Method: jQuery.fn.hashchange
  // 
  // Bind a handler to the window.onhashchange event or trigger all bound
  // window.onhashchange event handlers. This behavior is consistent with
  // jQuery's built-in event handlers.
  // 
  // Usage:
  // 
  // > jQuery(window).hashchange( [ handler ] );
  // 
  // Arguments:
  // 
  //  handler - (Function) Optional handler to be bound to the hashchange
  //    event. This is a "shortcut" for the more verbose form:
  //    jQuery(window).bind( 'hashchange', handler ). If handler is omitted,
  //    all bound window.onhashchange event handlers will be triggered. This
  //    is a shortcut for the more verbose
  //    jQuery(window).trigger( 'hashchange' ). These forms are described in
  //    the <hashchange event> section.
  // 
  // Returns:
  // 
  //  (jQuery) The initial jQuery collection of elements.
  
  // Allow the "shortcut" format $(elem).hashchange( fn ) for binding and
  // $(elem).hashchange() for triggering, like jQuery does for built-in events.
  $.fn[ str_hashchange ] = function( fn ) {
    return fn ? this.bind( str_hashchange, fn ) : this.trigger( str_hashchange );
  };
  
  // Property: jQuery.fn.hashchange.delay
  // 
  // The numeric interval (in milliseconds) at which the <hashchange event>
  // polling loop executes. Defaults to 50.
  
  // Property: jQuery.fn.hashchange.domain
  // 
  // If you're setting document.domain in your JavaScript, and you want hash
  // history to work in IE6/7, not only must this property be set, but you must
  // also set document.domain BEFORE jQuery is loaded into the page. This
  // property is only applicable if you are supporting IE6/7 (or IE8 operating
  // in "IE7 compatibility" mode).
  // 
  // In addition, the <jQuery.fn.hashchange.src> property must be set to the
  // path of the included "document-domain.html" file, which can be renamed or
  // modified if necessary (note that the document.domain specified must be the
  // same in both your main JavaScript as well as in this file).
  // 
  // Usage:
  // 
  // jQuery.fn.hashchange.domain = document.domain;
  
  // Property: jQuery.fn.hashchange.src
  // 
  // If, for some reason, you need to specify an Iframe src file (for example,
  // when setting document.domain as in <jQuery.fn.hashchange.domain>), you can
  // do so using this property. Note that when using this property, history
  // won't be recorded in IE6/7 until the Iframe src file loads. This property
  // is only applicable if you are supporting IE6/7 (or IE8 operating in "IE7
  // compatibility" mode).
  // 
  // Usage:
  // 
  // jQuery.fn.hashchange.src = 'path/to/file.html';
  
  $.fn[ str_hashchange ].delay = 50;
  /*
  $.fn[ str_hashchange ].domain = null;
  $.fn[ str_hashchange ].src = null;
  */
  
  // Event: hashchange event
  // 
  // Fired when location.hash changes. In browsers that support it, the native
  // HTML5 window.onhashchange event is used, otherwise a polling loop is
  // initialized, running every <jQuery.fn.hashchange.delay> milliseconds to
  // see if the hash has changed. In IE6/7 (and IE8 operating in "IE7
  // compatibility" mode), a hidden Iframe is created to allow the back button
  // and hash-based history to work.
  // 
  // Usage as described in <jQuery.fn.hashchange>:
  // 
  // > // Bind an event handler.
  // > jQuery(window).hashchange( function(e) {
  // >   var hash = location.hash;
  // >   ...
  // > });
  // > 
  // > // Manually trigger the event handler.
  // > jQuery(window).hashchange();
  // 
  // A more verbose usage that allows for event namespacing:
  // 
  // > // Bind an event handler.
  // > jQuery(window).bind( 'hashchange', function(e) {
  // >   var hash = location.hash;
  // >   ...
  // > });
  // > 
  // > // Manually trigger the event handler.
  // > jQuery(window).trigger( 'hashchange' );
  // 
  // Additional Notes:
  // 
  // * The polling loop and Iframe are not created until at least one handler
  //   is actually bound to the 'hashchange' event.
  // * If you need the bound handler(s) to execute immediately, in cases where
  //   a location.hash exists on page load, via bookmark or page refresh for
  //   example, use jQuery(window).hashchange() or the more verbose 
  //   jQuery(window).trigger( 'hashchange' ).
  // * The event can be bound before DOM ready, but since it won't be usable
  //   before then in IE6/7 (due to the necessary Iframe), recommended usage is
  //   to bind it inside a DOM ready handler.
  
  // Override existing $.event.special.hashchange methods (allowing this plugin
  // to be defined after jQuery BBQ in BBQ's source code).
  special[ str_hashchange ] = $.extend( special[ str_hashchange ], {
    
    // Called only when the first 'hashchange' event is bound to window.
    setup: function() {
      // If window.onhashchange is supported natively, there's nothing to do..
      if ( supports_onhashchange ) { return false; }
      
      // Otherwise, we need to create our own. And we don't want to call this
      // until the user binds to the event, just in case they never do, since it
      // will create a polling loop and possibly even a hidden Iframe.
      $( fake_onhashchange.start );
    },
    
    // Called only when the last 'hashchange' event is unbound from window.
    teardown: function() {
      // If window.onhashchange is supported natively, there's nothing to do..
      if ( supports_onhashchange ) { return false; }
      
      // Otherwise, we need to stop ours (if possible).
      $( fake_onhashchange.stop );
    }
    
  });
  
  // fake_onhashchange does all the work of triggering the window.onhashchange
  // event for browsers that don't natively support it, including creating a
  // polling loop to watch for hash changes and in IE 6/7 creating a hidden
  // Iframe to enable back and forward.
  fake_onhashchange = (function(){
    var self = {},
      timeout_id,
      
      // Remember the initial hash so it doesn't get triggered immediately.
      last_hash = get_fragment(),
      
      fn_retval = function(val){ return val; },
      history_set = fn_retval,
      history_get = fn_retval;
    
    // Start the polling loop.
    self.start = function() {
      timeout_id || poll();
    };
    
    // Stop the polling loop.
    self.stop = function() {
      timeout_id && clearTimeout( timeout_id );
      timeout_id = undefined;
    };
    
    // This polling loop checks every $.fn.hashchange.delay milliseconds to see
    // if location.hash has changed, and triggers the 'hashchange' event on
    // window when necessary.
    function poll() {
      var hash = get_fragment(),
        history_hash = history_get( last_hash );
      
      if ( hash !== last_hash ) {
        history_set( last_hash = hash, history_hash );
        
        $(window).trigger( str_hashchange );
        
      } else if ( history_hash !== last_hash ) {
        location.href = location.href.replace( /#.*/, '' ) + history_hash;
      }
      
      timeout_id = setTimeout( poll, $.fn[ str_hashchange ].delay );
    };
    
    // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
    // vvvvvvvvvvvvvvvvvvv REMOVE IF NOT SUPPORTING IE6/7/8 vvvvvvvvvvvvvvvvvvv
    // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv

    // snippet removed by pgbovine

    // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    // ^^^^^^^^^^^^^^^^^^^ REMOVE IF NOT SUPPORTING IE6/7/8 ^^^^^^^^^^^^^^^^^^^
    // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    
    return self;
  })();
  
})(jQuery,this);

/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0)))

/***/ }),
/* 12 */
/***/ (function(module, exports, __webpack_require__) {

/* WEBPACK VAR INJECTION */(function(jQuery) {jsPlumbUtil={isArray:function(b){return Object.prototype.toString.call(b)==="[object Array]"},isString:function(a){return typeof a==="string"},isObject:function(a){return Object.prototype.toString.call(a)==="[object Object]"},convertStyle:function(b,a){if("transparent"===b){return b}var g=b,f=function(h){return h.length==1?"0"+h:h},c=function(h){return f(Number(h).toString(16))},d=/(rgb[a]?\()(.*)(\))/;if(b.match(d)){var e=b.match(d)[2].split(",");g="#"+c(e[0])+c(e[1])+c(e[2]);if(!a&&e.length==4){g=g+c(e[3])}}return g},gradient:function(b,a){b=jsPlumbUtil.isArray(b)?b:[b.x,b.y];a=jsPlumbUtil.isArray(a)?a:[a.x,a.y];return(a[1]-b[1])/(a[0]-b[0])},normal:function(b,a){return -1/jsPlumbUtil.gradient(b,a)},lineLength:function(b,a){b=jsPlumbUtil.isArray(b)?b:[b.x,b.y];a=jsPlumbUtil.isArray(a)?a:[a.x,a.y];return Math.sqrt(Math.pow(a[1]-b[1],2)+Math.pow(a[0]-b[0],2))},segment:function(b,a){b=jsPlumbUtil.isArray(b)?b:[b.x,b.y];a=jsPlumbUtil.isArray(a)?a:[a.x,a.y];if(a[0]>b[0]){return(a[1]>b[1])?2:1}else{return(a[1]>b[1])?3:4}},intersects:function(f,e){var c=f.x,a=f.x+f.w,k=f.y,h=f.y+f.h,d=e.x,b=e.x+e.w,i=e.y,g=e.y+e.h;return((c<=d&&d<=a)&&(k<=i&&i<=h))||((c<=b&&b<=a)&&(k<=i&&i<=h))||((c<=d&&d<=a)&&(k<=g&&g<=h))||((c<=b&&d<=a)&&(k<=g&&g<=h))||((d<=c&&c<=b)&&(i<=k&&k<=g))||((d<=a&&a<=b)&&(i<=k&&k<=g))||((d<=c&&c<=b)&&(i<=h&&h<=g))||((d<=a&&c<=b)&&(i<=h&&h<=g))},segmentMultipliers:[null,[1,-1],[1,1],[-1,1],[-1,-1]],inverseSegmentMultipliers:[null,[-1,-1],[-1,1],[1,1],[1,-1]],pointOnLine:function(a,e,b){var d=jsPlumbUtil.gradient(a,e),i=jsPlumbUtil.segment(a,e),h=b>0?jsPlumbUtil.segmentMultipliers[i]:jsPlumbUtil.inverseSegmentMultipliers[i],c=Math.atan(d),f=Math.abs(b*Math.sin(c))*h[1],g=Math.abs(b*Math.cos(c))*h[0];return{x:a.x+g,y:a.y+f}},perpendicularLineTo:function(c,d,e){var b=jsPlumbUtil.gradient(c,d),f=Math.atan(-1/b),g=e/2*Math.sin(f),a=e/2*Math.cos(f);return[{x:d.x+a,y:d.y+g},{x:d.x-a,y:d.y-g}]},findWithFunction:function(b,d){if(b){for(var c=0;c<b.length;c++){if(d(b[c])){return c}}}return -1},indexOf:function(a,b){return jsPlumbUtil.findWithFunction(a,function(c){return c==b})},removeWithFunction:function(c,d){var b=jsPlumbUtil.findWithFunction(c,d);if(b>-1){c.splice(b,1)}return b!=-1},remove:function(b,c){var a=jsPlumbUtil.indexOf(b,c);if(a>-1){b.splice(a,1)}return a!=-1},addWithFunction:function(c,b,a){if(jsPlumbUtil.findWithFunction(c,a)==-1){c.push(b)}},addToList:function(d,b,c){var a=d[b];if(a==null){a=[],d[b]=a}a.push(c);return a},EventGenerator:function(){var c={},b=this;var a=["ready"];this.bind=function(d,e){jsPlumbUtil.addToList(c,d,e);return b};this.fire=function(g,h,d){if(c[g]){for(var f=0;f<c[g].length;f++){if(jsPlumbUtil.findWithFunction(a,function(i){return i===g})!=-1){c[g][f](h,d)}else{try{c[g][f](h,d)}catch(k){jsPlumbUtil.log("jsPlumb: fire failed for event "+g+" : "+k)}}}}return b};this.unbind=function(d){if(d){delete c[d]}else{delete c;c={}}return b};this.getListener=function(d){return c[d]}},logEnabled:true,log:function(){if(jsPlumbUtil.logEnabled&&typeof console!="undefined"){try{var b=arguments[arguments.length-1];console.log(b)}catch(a){}}},group:function(a){if(jsPlumbUtil.logEnabled&&typeof console!="undefined"){console.group(a)}},groupEnd:function(a){if(jsPlumbUtil.logEnabled&&typeof console!="undefined"){console.groupEnd(a)}},time:function(a){if(jsPlumbUtil.logEnabled&&typeof console!="undefined"){console.time(a)}},timeEnd:function(a){if(jsPlumbUtil.logEnabled&&typeof console!="undefined"){console.timeEnd(a)}}};(function(){var A=!!document.createElement("canvas").getContext,e=!!window.SVGAngle||document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1"),b=function(){if(b.vml==undefined){var L=document.body.appendChild(document.createElement("div"));L.innerHTML='<v:shape id="vml_flag1" adj="1" />';var K=L.firstChild;K.style.behavior="url(#default#VML)";b.vml=K?typeof K.adj=="object":true;L.parentNode.removeChild(L)}return b.vml};var i=jsPlumbUtil.findWithFunction,J=jsPlumbUtil.indexOf,D=jsPlumbUtil.removeWithFunction,m=jsPlumbUtil.remove,u=jsPlumbUtil.addWithFunction,l=jsPlumbUtil.addToList,n=jsPlumbUtil.isArray,C=jsPlumbUtil.isString,w=jsPlumbUtil.isObject;if(!window.console){window.console={time:function(){},timeEnd:function(){},group:function(){},groupEnd:function(){},log:function(){}}}var x=null,d=function(K,L){return p.CurrentLibrary.getAttribute(F(K),L)},f=function(L,M,K){p.CurrentLibrary.setAttribute(F(L),M,K)},B=function(L,K){p.CurrentLibrary.addClass(F(L),K)},k=function(L,K){return p.CurrentLibrary.hasClass(F(L),K)},o=function(L,K){p.CurrentLibrary.removeClass(F(L),K)},F=function(K){return p.CurrentLibrary.getElementObject(K)},t=function(K){return p.CurrentLibrary.getOffset(F(K))},a=function(K){return p.CurrentLibrary.getSize(F(K))},q=jsPlumbUtil.log,I=jsPlumbUtil.group,h=jsPlumbUtil.groupEnd,H=jsPlumbUtil.time,v=jsPlumbUtil.timeEnd,r=function(){return""+(new Date()).getTime()},E=function(Z){var U=this,aa=arguments,R=false,O=Z.parameters||{},M=U.idPrefix,W=M+(new Date()).getTime(),V=null,ab=null;U._jsPlumb=Z._jsPlumb;U.getId=function(){return W};U.tooltip=Z.tooltip;U.hoverClass=Z.hoverClass||U._jsPlumb.Defaults.HoverClass||p.Defaults.HoverClass;jsPlumbUtil.EventGenerator.apply(this);this.clone=function(){var ac=new Object();U.constructor.apply(ac,aa);return ac};this.getParameter=function(ac){return O[ac]},this.getParameters=function(){return O},this.setParameter=function(ac,ad){O[ac]=ad},this.setParameters=function(ac){O=ac},this.overlayPlacements=[];var N=Z.beforeDetach;this.isDetachAllowed=function(ac){var ad=U._jsPlumb.checkCondition("beforeDetach",ac);if(N){try{ad=N(ac)}catch(ae){q("jsPlumb: beforeDetach callback failed",ae)}}return ad};var Q=Z.beforeDrop;this.isDropAllowed=function(ah,ae,af,ac,ad){var ag=U._jsPlumb.checkCondition("beforeDrop",{sourceId:ah,targetId:ae,scope:af,connection:ac,dropEndpoint:ad});if(Q){try{ag=Q({sourceId:ah,targetId:ae,scope:af,connection:ac,dropEndpoint:ad})}catch(ai){q("jsPlumb: beforeDrop callback failed",ai)}}return ag};var X=function(){if(V&&ab){var ac={};p.extend(ac,V);p.extend(ac,ab);delete U.hoverPaintStyle;if(ac.gradient&&V.fillStyle){delete ac.gradient}ab=ac}};this.setPaintStyle=function(ac,ad){V=ac;U.paintStyleInUse=V;X();if(!ad){U.repaint()}};this.getPaintStyle=function(){return V};this.setHoverPaintStyle=function(ac,ad){ab=ac;X();if(!ad){U.repaint()}};this.getHoverPaintStyle=function(){return ab};this.setHover=function(ac,ae,ad){if(!U._jsPlumb.currentlyDragging&&!U._jsPlumb.isHoverSuspended()){R=ac;if(U.hoverClass!=null&&U.canvas!=null){if(ac){L.addClass(U.canvas,U.hoverClass)}else{L.removeClass(U.canvas,U.hoverClass)}}if(ab!=null){U.paintStyleInUse=ac?ab:V;ad=ad||r();U.repaint({timestamp:ad,recalc:false})}if(U.getAttachedElements&&!ae){Y(ac,r(),U)}}};this.isHover=function(){return R};var L=p.CurrentLibrary,K=["click","dblclick","mouseenter","mouseout","mousemove","mousedown","mouseup","contextmenu"],T={mouseout:"mouseexit"},P=function(ae,af,ad){var ac=T[ad]||ad;L.bind(ae,ad,function(ag){af.fire(ac,af,ag)})},S=function(ae,ad){var ac=T[ad]||ad;L.unbind(ae,ad)};this.attachListeners=function(ad,ae){for(var ac=0;ac<K.length;ac++){P(ad,ae,K[ac])}};var Y=function(ag,af,ac){var ae=U.getAttachedElements();if(ae){for(var ad=0;ad<ae.length;ad++){if(!ac||ac!=ae[ad]){ae[ad].setHover(ag,true,af)}}}};this.reattachListenersForElement=function(ad){if(arguments.length>1){for(var ac=0;ac<K.length;ac++){S(ad,K[ac])}for(var ac=1;ac<arguments.length;ac++){U.attachListeners(ad,arguments[ac])}}}},z=function(P){E.apply(this,arguments);var U=this;this.overlays=[];var N=function(Z){var X=null;if(n(Z)){var W=Z[0],Y=p.extend({component:U,_jsPlumb:U._jsPlumb},Z[1]);if(Z.length==3){p.extend(Y,Z[2])}X=new p.Overlays[U._jsPlumb.getRenderMode()][W](Y);if(Y.events){for(var V in Y.events){X.bind(V,Y.events[V])}}}else{if(Z.constructor==String){X=new p.Overlays[U._jsPlumb.getRenderMode()][Z]({component:U,_jsPlumb:U._jsPlumb})}else{X=Z}}U.overlays.push(X)},O=function(Z){var V=U.defaultOverlayKeys||[],Y=Z.overlays,W=function(aa){return U._jsPlumb.Defaults[aa]||p.Defaults[aa]||[]};if(!Y){Y=[]}for(var X=0;X<V.length;X++){Y.unshift.apply(Y,W(V[X]))}return Y};var L=O(P);if(L){for(var Q=0;Q<L.length;Q++){N(L[Q])}}var K=function(X){var V=-1;for(var W=0;W<U.overlays.length;W++){if(X===U.overlays[W].id){V=W;break}}return V};this.addOverlay=function(V){N(V);U.repaint()};this.getOverlay=function(W){var V=K(W);return V>=0?U.overlays[V]:null};this.getOverlays=function(){return U.overlays};this.hideOverlay=function(W){var V=U.getOverlay(W);if(V){V.hide()}};this.hideOverlays=function(){for(var V=0;V<U.overlays.length;V++){U.overlays[V].hide()}};this.showOverlay=function(W){var V=U.getOverlay(W);if(V){V.show()}};this.showOverlays=function(){for(var V=0;V<U.overlays.length;V++){U.overlays[V].show()}};this.removeAllOverlays=function(){for(var V in U.overlays){U.overlays[V].cleanup()}U.overlays.splice(0,U.overlays.length);U.repaint()};this.removeOverlay=function(W){var V=K(W);if(V!=-1){var X=U.overlays[V];X.cleanup();U.overlays.splice(V,1)}};this.removeOverlays=function(){for(var V=0;V<arguments.length;V++){U.removeOverlay(arguments[V])}};var M="__label",T=function(X){var V={cssClass:X.cssClass,labelStyle:this.labelStyle,id:M,component:U,_jsPlumb:U._jsPlumb},W=p.extend(V,X);return new p.Overlays[U._jsPlumb.getRenderMode()].Label(W)};if(P.label){var R=P.labelLocation||U.defaultLabelLocation||0.5,S=P.labelStyle||U._jsPlumb.Defaults.LabelStyle||p.Defaults.LabelStyle;this.overlays.push(T({label:P.label,location:R,labelStyle:S}))}this.setLabel=function(V){var W=U.getOverlay(M);if(!W){var X=V.constructor==String||V.constructor==Function?{label:V}:V;W=T(X);this.overlays.push(W)}else{if(V.constructor==String||V.constructor==Function){W.setLabel(V)}else{if(V.label){W.setLabel(V.label)}if(V.location){W.setLocation(V.location)}}}U.repaint()};this.getLabel=function(){var V=U.getOverlay(M);return V!=null?V.getLabel():null};this.getLabelOverlay=function(){return U.getOverlay(M)}},G=function(M,K,L){M.bind("click",function(N,O){K.fire("click",K,O)});M.bind("dblclick",function(N,O){K.fire("dblclick",K,O)});M.bind("contextmenu",function(N,O){K.fire("contextmenu",K,O)});M.bind("mouseenter",function(N,O){if(!K.isHover()){L(true);K.fire("mouseenter",K,O)}});M.bind("mouseexit",function(N,O){if(K.isHover()){L(false);K.fire("mouseexit",K,O)}})};var g=0,c=function(){var K=g+1;g++;return K};var y=function(L){this.Defaults={Anchor:"BottomCenter",Anchors:[null,null],ConnectionsDetachable:true,ConnectionOverlays:[],Connector:"Bezier",Container:null,DragOptions:{},DropOptions:{},Endpoint:"Dot",EndpointOverlays:[],Endpoints:[null,null],EndpointStyle:{fillStyle:"#456"},EndpointStyles:[null,null],EndpointHoverStyle:null,EndpointHoverStyles:[null,null],HoverPaintStyle:null,LabelStyle:{color:"black"},LogEnabled:false,Overlays:[],MaxConnections:1,PaintStyle:{lineWidth:8,strokeStyle:"#456"},RenderMode:"svg",Scope:"jsPlumb_DefaultScope"};if(L){p.extend(this.Defaults,L)}this.logEnabled=this.Defaults.LogEnabled;jsPlumbUtil.EventGenerator.apply(this);var bn=this,aL=c(),aO=bn.bind,aC={};for(var aB in this.Defaults){aC[aB]=this.Defaults[aB]}this.bind=function(bw,bv){if("ready"===bw&&M){bv()}else{aO.apply(bn,[bw,bv])}};bn.importDefaults=function(bw){for(var bv in bw){bn.Defaults[bv]=bw[bv]}};bn.restoreDefaults=function(){bn.Defaults=p.extend({},aC)};var P=null,ar=function(){p.repaintEverything()},bp=true,aP=function(){if(bp){ar()}},be=null,M=false,aY={},aT={},aU={},ah={},br={},bf={},bm={},bu=[],ae=[],Q=this.Defaults.Scope,X=null,V=function(by,bw,bx){var bv=by[bw];if(bv==null){bv=[];by[bw]=bv}bv.push(bx);return bv},aW=function(bw,bv){if(bn.Defaults.Container){p.CurrentLibrary.appendElement(bw,bn.Defaults.Container)}else{if(!bv){document.body.appendChild(bw)}else{p.CurrentLibrary.appendElement(bw,bv)}}},aD=1,ak=function(){return""+aD++},aI=function(bv){return bv._nodes?bv._nodes:bv},a6=false,bg=function(bw,bv){a6=bw;if(bv){bn.repaintEverything()}},ba=function(bx,bz,by){if(!a6){var bA=d(bx,"id"),bv=bn.dragManager.getElementsForDraggable(bA);if(by==null){by=r()}bn.anchorManager.redraw(bA,bz,by);if(bv){for(var bw in bv){bn.anchorManager.redraw(bv[bw].id,bz,by,bv[bw].offset)}}}},aG=function(bw,by){var bz=null;if(n(bw)){bz=[];for(var bv=0;bv<bw.length;bv++){var bx=F(bw[bv]),bA=d(bx,"id");bz.push(by(bx,bA))}}else{var bx=F(bw),bA=d(bx,"id");bz=by(bx,bA)}return bz},av=function(bv){return aU[bv]},bb=function(bz,bv,bC){var bE=bv==null?false:bv,bA=p.CurrentLibrary;if(bE){if(bA.isDragSupported(bz)&&!bA.isAlreadyDraggable(bz)){var bD=bC||bn.Defaults.DragOptions||p.Defaults.DragOptions;bD=p.extend({},bD);var bB=bA.dragEvents.drag,bw=bA.dragEvents.stop,by=bA.dragEvents.start;bD[by]=am(bD[by],function(){bn.setHoverSuspended(true)});bD[bB]=am(bD[bB],function(){var bF=bA.getUIPosition(arguments);ba(bz,bF);B(bz,"jsPlumb_dragged")});bD[bw]=am(bD[bw],function(){var bF=bA.getUIPosition(arguments);ba(bz,bF);o(bz,"jsPlumb_dragged");bn.setHoverSuspended(false)});var bx=K(bz);bm[bx]=true;var bE=bm[bx];bD.disabled=bE==null?false:!bE;bA.initDraggable(bz,bD,false);bn.dragManager.register(bz)}}},aA=function(bB,bw){var bv=p.extend({},bB);if(bw){p.extend(bv,bw)}if(bv.source&&bv.source.endpoint){bv.sourceEndpoint=bv.source}if(bv.source&&bv.target.endpoint){bv.targetEndpoint=bv.target}if(bB.uuids){bv.sourceEndpoint=av(bB.uuids[0]);bv.targetEndpoint=av(bB.uuids[1])}if(bv.sourceEndpoint&&bv.sourceEndpoint.isFull()){q(bn,"could not add connection; source endpoint is full");return}if(bv.targetEndpoint&&bv.targetEndpoint.isFull()){q(bn,"could not add connection; target endpoint is full");return}if(bv.sourceEndpoint&&bv.sourceEndpoint.connectorOverlays){bv.overlays=bv.overlays||[];for(var bz=0;bz<bv.sourceEndpoint.connectorOverlays.length;bz++){bv.overlays.push(bv.sourceEndpoint.connectorOverlays[bz])}}bv.tooltip=bB.tooltip;if(!bv.tooltip&&bv.sourceEndpoint&&bv.sourceEndpoint.connectorTooltip){bv.tooltip=bv.sourceEndpoint.connectorTooltip}if(bv.target&&!bv.target.endpoint&&!bv.targetEndpoint&&!bv.newConnection){var bA=K(bv.target),bC=aZ[bA],bx=aH[bA];if(bC){if(!aj[bA]){return}var by=bx!=null?bx:bn.addEndpoint(bv.target,bC);if(bh[bA]){aH[bA]=by}bv.targetEndpoint=by;by._makeTargetCreator=true}}if(bv.source&&!bv.source.endpoint&&!bv.sourceEndpoint&&!bv.newConnection){var bA=K(bv.source),bC=az[bA],bx=a5[bA];if(bC){if(!ac[bA]){return}var by=bx!=null?bx:bn.addEndpoint(bv.source,bC);if(a9[bA]){a5[bA]=by}bv.sourceEndpoint=by}}return bv},ad=function(bz){var by=bn.Defaults.ConnectionType||bn.getDefaultConnectionType(),bx=bn.Defaults.EndpointType||af,bw=p.CurrentLibrary.getParent;if(bz.container){bz.parent=bz.container}else{if(bz.sourceEndpoint){bz.parent=bz.sourceEndpoint.parent}else{if(bz.source.constructor==bx){bz.parent=bz.source.parent}else{bz.parent=bw(bz.source)}}}bz._jsPlumb=bn;var bv=new by(bz);bv.id="con_"+ak();bs("click","click",bv);bs("dblclick","dblclick",bv);bs("contextmenu","contextmenu",bv);return bv},bt=function(bw,bx,bv){bx=bx||{};if(!bw.suspendedEndpoint){V(aY,bw.scope,bw)}if(!bx.doNotFireConnectionEvent&&bx.fireEvent!==false){bn.fire("jsPlumbConnection",{connection:bw,source:bw.source,target:bw.target,sourceId:bw.sourceId,targetId:bw.targetId,sourceEndpoint:bw.endpoints[0],targetEndpoint:bw.endpoints[1]},bv)}bn.anchorManager.newConnection(bw);ba(bw.source)},bs=function(bv,bw,bx){bx.bind(bv,function(bz,by){bn.fire(bw,bx,by)})},aw=function(bx){if(bx.container){return bx.container}else{var bv=p.CurrentLibrary.getTagName(bx.source),bw=p.CurrentLibrary.getParent(bx.source);if(bv&&bv.toLowerCase()==="td"){return p.CurrentLibrary.getParent(bw)}else{return bw}}},aF=function(bx){var bw=bn.Defaults.EndpointType||af;bx.parent=aw(bx);bx._jsPlumb=bn;var bv=new bw(bx);bv.id="ep_"+ak();bs("click","endpointClick",bv);bs("dblclick","endpointDblClick",bv);bs("contextmenu","contextmenu",bv);return bv},U=function(bx,bA,bz){var bv=aT[bx];if(bv&&bv.length){for(var by=0;by<bv.length;by++){for(var bw=0;bw<bv[by].connections.length;bw++){var bB=bA(bv[by].connections[bw]);if(bB){return}}if(bz){bz(bv[by])}}}},Y=function(bw){for(var bv in aT){U(bv,bw)}},au=function(bv,bw){if(bv!=null&&bv.parentNode!=null){bv.parentNode.removeChild(bv)}},aX=function(bx,bw){for(var bv=0;bv<bx.length;bv++){au(bx[bv],bw)}},bk=function(bw,bv){return aG(bw,function(bx,by){bm[by]=bv;if(p.CurrentLibrary.isDragSupported(bx)){p.CurrentLibrary.setDraggable(bx,bv)}})},a3=function(bx,by,bv){by=by==="block";var bw=null;if(bv){if(by){bw=function(bA){bA.setVisible(true,true,true)}}else{bw=function(bA){bA.setVisible(false,true,true)}}}var bz=d(bx,"id");U(bz,function(bB){if(by&&bv){var bA=bB.sourceId===bz?1:0;if(bB.endpoints[bA].isVisible()){bB.setVisible(true)}}else{bB.setVisible(by)}},bw)},bi=function(bv){return aG(bv,function(bx,bw){var by=bm[bw]==null?false:bm[bw];by=!by;bm[bw]=by;p.CurrentLibrary.setDraggable(bx,by);return by})},aQ=function(bv,bx){var bw=null;if(bx){bw=function(by){var bz=by.isVisible();by.setVisible(!bz)}}U(bv,function(bz){var by=bz.isVisible();bz.setVisible(!by)},bw)},W=function(bA){var by=bA.timestamp,bv=bA.recalc,bz=bA.offset,bw=bA.elId;if(!bv){if(by&&by===br[bw]){return ah[bw]}}if(bv||!bz){var bx=F(bw);if(bx!=null){ae[bw]=a(bx);ah[bw]=t(bx);br[bw]=by}}else{ah[bw]=bz;if(ae[bw]==null){var bx=F(bw);if(bx!=null){ae[bw]=a(bx)}}}if(ah[bw]&&!ah[bw].right){ah[bw].right=ah[bw].left+ae[bw][0];ah[bw].bottom=ah[bw].top+ae[bw][1];ah[bw].width=ae[bw][0];ah[bw].height=ae[bw][1];ah[bw].centerx=ah[bw].left+(ah[bw].width/2);ah[bw].centery=ah[bw].top+(ah[bw].height/2)}return ah[bw]},aN=function(bv){var bw=ah[bv];if(!bw){bw=W({elId:bv})}return{o:bw,s:ae[bv]}},K=function(bv,bw,by){var bx=F(bv);var bz=d(bx,"id");if(!bz||bz=="undefined"){if(arguments.length==2&&arguments[1]!=undefined){bz=bw}else{if(arguments.length==1||(arguments.length==3&&!arguments[2])){bz="jsPlumb_"+aL+"_"+ak()}}f(bx,"id",bz)}return bz},am=function(bx,bv,bw){bx=bx||function(){};bv=bv||function(){};return function(){var by=null;try{by=bv.apply(this,arguments)}catch(bz){q(bn,"jsPlumb function failed : "+bz)}if(bw==null||(by!==bw)){try{bx.apply(this,arguments)}catch(bz){q(bn,"wrapped function failed : "+bz)}}return by}};this.connectorClass="_jsPlumb_connector";this.endpointClass="_jsPlumb_endpoint";this.overlayClass="_jsPlumb_overlay";this.Anchors={};this.Connectors={canvas:{},svg:{},vml:{}};this.Endpoints={canvas:{},svg:{},vml:{}};this.Overlays={canvas:{},svg:{},vml:{}};this.addClass=function(bw,bv){return p.CurrentLibrary.addClass(bw,bv)};this.removeClass=function(bw,bv){return p.CurrentLibrary.removeClass(bw,bv)};this.hasClass=function(bw,bv){return p.CurrentLibrary.hasClass(bw,bv)};this.addEndpoint=function(bx,by,bH){bH=bH||{};var bw=p.extend({},bH);p.extend(bw,by);bw.endpoint=bw.endpoint||bn.Defaults.Endpoint||p.Defaults.Endpoint;bw.paintStyle=bw.paintStyle||bn.Defaults.EndpointStyle||p.Defaults.EndpointStyle;bx=aI(bx);var bz=[],bC=bx.length&&bx.constructor!=String?bx:[bx];for(var bA=0;bA<bC.length;bA++){var bF=F(bC[bA]),bv=K(bF);bw.source=bF;W({elId:bv});var bE=aF(bw);if(bw.parentAnchor){bE.parentAnchor=bw.parentAnchor}V(aT,bv,bE);var bD=ah[bv],bB=ae[bv];var bG=bE.anchor.compute({xy:[bD.left,bD.top],wh:bB,element:bE});bE.paint({anchorLoc:bG});bz.push(bE);bn.dragManager.endpointAdded(bF)}return bz.length==1?bz[0]:bz};this.addEndpoints=function(bz,bw,bv){var by=[];for(var bx=0;bx<bw.length;bx++){var bA=bn.addEndpoint(bz,bw[bx],bv);if(n(bA)){Array.prototype.push.apply(by,bA)}else{by.push(bA)}}return by};this.animate=function(bx,bw,bv){var by=F(bx),bB=d(bx,"id");bv=bv||{};var bA=p.CurrentLibrary.dragEvents.step;var bz=p.CurrentLibrary.dragEvents.complete;bv[bA]=am(bv[bA],function(){bn.repaint(bB)});bv[bz]=am(bv[bz],function(){bn.repaint(bB)});p.CurrentLibrary.animate(by,bw,bv)};this.checkCondition=function(bx,bz){var bv=bn.getListener(bx);var by=true;if(bv&&bv.length>0){try{for(var bw=0;bw<bv.length;bw++){by=by&&bv[bw](bz)}}catch(bA){q(bn,"cannot check condition ["+bx+"]"+bA)}}return by};this.connect=function(by,bw){var bv=aA(by,bw);if(bv){if(bv.deleteEndpointsOnDetach==null){bv.deleteEndpointsOnDetach=true}var bx=ad(bv);bt(bx,bv);return bx}};this.deleteEndpoint=function(bw){var bB=(typeof bw=="string")?aU[bw]:bw;if(bB){var by=bB.getUuid();if(by){aU[by]=null}bB.detachAll();aX(bB.endpoint.getDisplayElements());bn.anchorManager.deleteEndpoint(bB);for(var bA in aT){var bv=aT[bA];if(bv){var bz=[];for(var bx=0;bx<bv.length;bx++){if(bv[bx]!=bB){bz.push(bv[bx])}}aT[bA]=bz}}bn.dragManager.endpointDeleted(bB)}};this.deleteEveryEndpoint=function(){for(var bx in aT){var bv=aT[bx];if(bv&&bv.length){for(var bw=0;bw<bv.length;bw++){bn.deleteEndpoint(bv[bw])}}}delete aT;aT={};delete aU;aU={}};var a7=function(by,bA,bv){var bx=bn.Defaults.ConnectionType||bn.getDefaultConnectionType(),bw=by.constructor==bx,bz=bw?{connection:by,source:by.source,target:by.target,sourceId:by.sourceId,targetId:by.targetId,sourceEndpoint:by.endpoints[0],targetEndpoint:by.endpoints[1]}:by;if(bA){bn.fire("jsPlumbConnectionDetached",bz,bv)}bn.anchorManager.connectionDetached(bz)},a4=function(bv){bn.fire("connectionDrag",bv)},aR=function(bv){bn.fire("connectionDragStop",bv)};this.detach=function(){if(arguments.length==0){return}var bz=bn.Defaults.ConnectionType||bn.getDefaultConnectionType(),bA=arguments[0].constructor==bz,by=arguments.length==2?bA?(arguments[1]||{}):arguments[0]:arguments[0],bD=(by.fireEvent!==false),bx=by.forceDetach,bw=bA?arguments[0]:by.connection;if(bw){if(bx||(bw.isDetachAllowed(bw)&&bw.endpoints[0].isDetachAllowed(bw)&&bw.endpoints[1].isDetachAllowed(bw))){if(bx||bn.checkCondition("beforeDetach",bw)){bw.endpoints[0].detach(bw,false,true,bD)}}}else{var bv=p.extend({},by);if(bv.uuids){av(bv.uuids[0]).detachFrom(av(bv.uuids[1]),bD)}else{if(bv.sourceEndpoint&&bv.targetEndpoint){bv.sourceEndpoint.detachFrom(bv.targetEndpoint)}else{var bC=K(bv.source),bB=K(bv.target);U(bC,function(bE){if((bE.sourceId==bC&&bE.targetId==bB)||(bE.targetId==bC&&bE.sourceId==bB)){if(bn.checkCondition("beforeDetach",bE)){bE.endpoints[0].detach(bE,false,true,bD)}}})}}}};this.detachAllConnections=function(bx,by){by=by||{};bx=F(bx);var bz=d(bx,"id"),bv=aT[bz];if(bv&&bv.length){for(var bw=0;bw<bv.length;bw++){bv[bw].detachAll(by.fireEvent)}}};this.detachEveryConnection=function(bx){bx=bx||{};for(var by in aT){var bv=aT[by];if(bv&&bv.length){for(var bw=0;bw<bv.length;bw++){bv[bw].detachAll(bx.fireEvent)}}}delete aY;aY={}};this.draggable=function(bx,bv){if(typeof bx=="object"&&bx.length){for(var bw=0;bw<bx.length;bw++){var by=F(bx[bw]);if(by){bb(by,true,bv)}}}else{if(bx._nodes){for(var bw=0;bw<bx._nodes.length;bw++){var by=F(bx._nodes[bw]);if(by){bb(by,true,bv)}}}else{var by=F(bx);if(by){bb(by,true,bv)}}}};this.extend=function(bw,bv){return p.CurrentLibrary.extend(bw,bv)};this.getDefaultEndpointType=function(){return af};this.getDefaultConnectionType=function(){return ax};var bq=function(bz,by,bw,bv){for(var bx=0;bx<bz.length;bx++){bz[bx][by].apply(bz[bx],bw)}return bv(bz)},S=function(bz,by,bw){var bv=[];for(var bx=0;bx<bz.length;bx++){bv.push([bz[bx][by].apply(bz[bx],bw),bz[bx]])}return bv},an=function(bx,bw,bv){return function(){return bq(bx,bw,arguments,bv)}},ay=function(bw,bv){return function(){return S(bw,bv,arguments)}};this.getConnections=function(bH,bw){if(!bH){bH={}}else{if(bH.constructor==String){bH={scope:bH}}}var bE=function(bI){var bJ=[];if(bI){if(typeof bI=="string"){if(bI==="*"){return bI}bJ.push(bI)}else{bJ=bI}}return bJ},bF=bH.scope||bn.getDefaultScope(),bD=bE(bF),bv=bE(bH.source),bB=bE(bH.target),bx=function(bJ,bI){if(bJ==="*"){return true}return bJ.length>0?J(bJ,bI)!=-1:true},bA=(!bw&&bD.length>1)?{}:[],bG=function(bJ,bK){if(!bw&&bD.length>1){var bI=bA[bJ];if(bI==null){bI=[];bA[bJ]=bI}bI.push(bK)}else{bA.push(bK)}};for(var bz in aY){if(bx(bD,bz)){for(var by=0;by<aY[bz].length;by++){var bC=aY[bz][by];if(bx(bv,bC.sourceId)&&bx(bB,bC.targetId)){bG(bz,bC)}}}}return bA};var aK=function(bv){return{setHover:an(bv,"setHover",aK),removeAllOverlays:an(bv,"removeAllOverlays",aK),setLabel:an(bv,"setLabel",aK),addOverlay:an(bv,"addOverlay",aK),removeOverlay:an(bv,"removeOverlay",aK),removeOverlays:an(bv,"removeOverlays",aK),showOverlay:an(bv,"showOverlay",aK),hideOverlay:an(bv,"hideOverlay",aK),showOverlays:an(bv,"showOverlays",aK),hideOverlays:an(bv,"hideOverlays",aK),setPaintStyle:an(bv,"setPaintStyle",aK),setHoverPaintStyle:an(bv,"setHoverPaintStyle",aK),setDetachable:an(bv,"setDetachable",aK),setConnector:an(bv,"setConnector",aK),setParameter:an(bv,"setParameter",aK),setParameters:an(bv,"setParameters",aK),detach:function(){for(var bw=0;bw<bv.length;bw++){bn.detach(bv[bw])}},getLabel:ay(bv,"getLabel"),getOverlay:ay(bv,"getOverlay"),isHover:ay(bv,"isHover"),isDetachable:ay(bv,"isDetachable"),getParameter:ay(bv,"getParameter"),getParameters:ay(bv,"getParameters"),getPaintStyle:ay(bv,"getPaintStyle"),getHoverPaintStyle:ay(bv,"getHoverPaintStyle"),length:bv.length,each:function(bx){for(var bw=0;bw<bv.length;bw++){bx(bv[bw])}return aK(bv)},get:function(bw){return bv[bw]}}};this.select=function(bv){bv=bv||{};bv.scope=bv.scope||"*";var bw=bn.getConnections(bv,true);return aK(bw)};this.getAllConnections=function(){return aY};this.getDefaultScope=function(){return Q};this.getEndpoint=av;this.getEndpoints=function(bv){return aT[K(bv)]};this.getId=K;this.getOffset=function(bw){var bv=ah[bw];return W({elId:bw})};this.getSelector=function(bv){return p.CurrentLibrary.getSelector(bv)};this.getSize=function(bw){var bv=ae[bw];if(!bv){W({elId:bw})}return ae[bw]};this.appendElement=aW;var aS=false;this.isHoverSuspended=function(){return aS};this.setHoverSuspended=function(bv){aS=bv};this.isCanvasAvailable=function(){return A};this.isSVGAvailable=function(){return e};this.isVMLAvailable=b;this.hide=function(bv,bw){a3(bv,"none",bw)};this.idstamp=ak;this.init=function(){if(!M){bn.setRenderMode(bn.Defaults.RenderMode);var bv=function(bw){p.CurrentLibrary.bind(document,bw,function(bC){if(!bn.currentlyDragging&&X==p.CANVAS){for(var bB in aY){var bD=aY[bB];for(var bz=0;bz<bD.length;bz++){var by=bD[bz].connector[bw](bC);if(by){return}}}for(var bA in aT){var bx=aT[bA];for(var bz=0;bz<bx.length;bz++){if(bx[bz].endpoint[bw](bC)){return}}}}})};bv("click");bv("dblclick");bv("mousemove");bv("mousedown");bv("mouseup");bv("contextmenu");M=true;bn.fire("ready")}};this.log=P;this.jsPlumbUIComponent=E;this.makeAnchor=function(){if(arguments.length==0){return null}var bA=arguments[0],bx=arguments[1],bw=arguments[2],by=null;if(bA.compute&&bA.getOrientation){return bA}else{if(typeof bA=="string"){by=p.Anchors[arguments[0]]({elementId:bx,jsPlumbInstance:bn})}else{if(n(bA)){if(n(bA[0])||C(bA[0])){if(bA.length==2&&C(bA[0])&&w(bA[1])){var bv=p.extend({elementId:bx,jsPlumbInstance:bn},bA[1]);by=p.Anchors[bA[0]](bv)}else{by=new aq(bA,null,bx)}}else{var bz={x:bA[0],y:bA[1],orientation:(bA.length>=4)?[bA[2],bA[3]]:[0,0],offsets:(bA.length==6)?[bA[4],bA[5]]:[0,0],elementId:bx};by=new aa(bz);by.clone=function(){return new aa(bz)}}}}}if(!by.id){by.id="anchor_"+ak()}return by};this.makeAnchors=function(by,bw,bv){var bz=[];for(var bx=0;bx<by.length;bx++){if(typeof by[bx]=="string"){bz.push(p.Anchors[by[bx]]({elementId:bw,jsPlumbInstance:bv}))}else{if(n(by[bx])){bz.push(bn.makeAnchor(by[bx],bw,bv))}}}return bz};this.makeDynamicAnchor=function(bv,bw){return new aq(bv,bw)};var aZ={},aH={},bh={},ap={},ab=function(bv,bw){bv.paintStyle=bv.paintStyle||bn.Defaults.EndpointStyles[bw]||bn.Defaults.EndpointStyle||p.Defaults.EndpointStyles[bw]||p.Defaults.EndpointStyle;bv.hoverPaintStyle=bv.hoverPaintStyle||bn.Defaults.EndpointHoverStyles[bw]||bn.Defaults.EndpointHoverStyle||p.Defaults.EndpointHoverStyles[bw]||p.Defaults.EndpointHoverStyle;bv.anchor=bv.anchor||bn.Defaults.Anchors[bw]||bn.Defaults.Anchor||p.Defaults.Anchors[bw]||p.Defaults.Anchor;bv.endpoint=bv.endpoint||bn.Defaults.Endpoints[bw]||bn.Defaults.Endpoint||p.Defaults.Endpoints[bw]||p.Defaults.Endpoint};this.makeTarget=function(by,bz,bF){var bw=p.extend({_jsPlumb:bn},bF);p.extend(bw,bz);ab(bw,1);var bD=p.CurrentLibrary,bE=bw.scope||bn.Defaults.Scope,bA=!(bw.deleteEndpointsOnDetach===false),bx=bw.maxConnections||-1,bv=function(bK){var bI=K(bK);aZ[bI]=bw;bh[bI]=bw.uniqueEndpoint,ap[bI]=bx,aj[bI]=true,proxyComponent=new E(bw);var bH=p.extend({},bw.dropOptions||{}),bG=function(){var bN=p.CurrentLibrary.getDropEvent(arguments),bP=bn.select({target:bI}).length;if(!aj[bI]||ap[bI]>0&&bP>=ap[bI]){console.log("target element "+bI+" is full.");return false}bn.currentlyDragging=false;var bZ=F(bD.getDragObject(arguments)),bO=d(bZ,"dragId"),bX=d(bZ,"originalScope"),bU=bf[bO],bM=bU.endpoints[0],bL=bw.endpoint?p.extend({},bw.endpoint):{};bM.anchor.locked=false;if(bX){bD.setDragScope(bZ,bX)}var bS=proxyComponent.isDropAllowed(bU.sourceId,K(bK),bU.scope,bU,null);if(bU.endpointsToDeleteOnDetach){if(bM===bU.endpointsToDeleteOnDetach[0]){bU.endpointsToDeleteOnDetach[0]=null}else{if(bM===bU.endpointsToDeleteOnDetach[1]){bU.endpointsToDeleteOnDetach[1]=null}}}if(bU.suspendedEndpoint){bU.targetId=bU.suspendedEndpoint.elementId;bU.target=bD.getElementObject(bU.suspendedEndpoint.elementId);bU.endpoints[1]=bU.suspendedEndpoint}if(bS){bM.detach(bU,false,true,false);var bY=aH[bI]||bn.addEndpoint(bK,bw);if(bw.uniqueEndpoint){aH[bI]=bY}bY._makeTargetCreator=true;if(bY.anchor.positionFinder!=null){var bV=bD.getUIPosition(arguments),bR=bD.getOffset(bK),bW=bD.getSize(bK),bQ=bY.anchor.positionFinder(bV,bR,bW,bY.anchor.constructorParams);bY.anchor.x=bQ[0];bY.anchor.y=bQ[1]}var bT=bn.connect({source:bM,target:bY,scope:bX,previousConnection:bU,container:bU.parent,deleteEndpointsOnDetach:bA,doNotFireConnectionEvent:bM.endpointWillMoveAfterConnection});if(bU.endpoints[1]._makeTargetCreator&&bU.endpoints[1].connections.length<2){bn.deleteEndpoint(bU.endpoints[1])}if(bA){bT.endpointsToDeleteOnDetach=[bM,bY]}bT.repaint()}else{if(bU.suspendedEndpoint){if(bM.isReattach){bU.setHover(false);bU.floatingAnchorIndex=null;bU.suspendedEndpoint.addConnection(bU);bn.repaint(bM.elementId)}else{bM.detach(bU,false,true,true,bN)}}}};var bJ=bD.dragEvents.drop;bH.scope=bH.scope||bE;bH[bJ]=am(bH[bJ],bG);bD.initDroppable(bK,bH,true)};by=aI(by);var bC=by.length&&by.constructor!=String?by:[by];for(var bB=0;bB<bC.length;bB++){bv(F(bC[bB]))}return bn};this.unmakeTarget=function(bw,bx){bw=p.CurrentLibrary.getElementObject(bw);var bv=K(bw);if(!bx){delete aZ[bv];delete bh[bv];delete ap[bv];delete aj[bv]}return bn};this.makeTargets=function(bx,by,bv){for(var bw=0;bw<bx.length;bw++){bn.makeTarget(bx[bw],by,bv)}};var az={},a5={},a9={},ac={},N={},aj={};this.makeSource=function(bz,bC,bv){var bA=p.extend({},bv);p.extend(bA,bC);ab(bA,0);var by=p.CurrentLibrary,bB=function(bK){var bE=K(bK),bL=bA.parent,bD=bL!=null?bn.getId(by.getElementObject(bL)):bE;az[bD]=bA;a9[bD]=bA.uniqueEndpoint;ac[bD]=true;var bF=by.dragEvents.stop,bJ=by.dragEvents.drag,bM=p.extend({},bA.dragOptions||{}),bH=bM.drag,bN=bM.stop,bO=null,bI=false;bM.scope=bM.scope||bA.scope;bM[bJ]=am(bM[bJ],function(){if(bH){bH.apply(this,arguments)}bI=false});bM[bF]=am(bM[bF],function(){if(bN){bN.apply(this,arguments)}bn.currentlyDragging=false;if(bO.connections.length==0){bn.deleteEndpoint(bO)}else{by.unbind(bO.canvas,"mousedown");var bQ=bA.anchor||bn.Defaults.Anchor,bR=bO.anchor,bT=bO.connections[0];bO.anchor=bn.makeAnchor(bQ,bE,bn);if(bA.parent){var bS=by.getElementObject(bA.parent);if(bS){var bP=bO.elementId;var bU=bA.container||bn.Defaults.Container||p.Defaults.Container;bO.setElement(bS,bU);bO.endpointWillMoveAfterConnection=false;bn.anchorManager.rehomeEndpoint(bP,bS);bT.previousConnection=null;D(aY[bT.scope],function(bV){return bV.id===bT.id});bn.anchorManager.connectionDetached({sourceId:bT.sourceId,targetId:bT.targetId,connection:bT});bt(bT)}}bO.repaint();bn.repaint(bO.elementId);bn.repaint(bT.targetId)}});var bG=function(bS){if(!ac[bD]){return}if(bC.filter){var bP=bC.filter(by.getOriginalEvent(bS),bK);if(bP===false){return}}var bW=W({elId:bE});var bV=((bS.pageX||bS.page.x)-bW.left)/bW.width,bU=((bS.pageY||bS.page.y)-bW.top)/bW.height,b0=bV,bZ=bU;if(bA.parent){var bT=by.getElementObject(bA.parent),bR=K(bT);bW=W({elId:bR});b0=((bS.pageX||bS.page.x)-bW.left)/bW.width,bZ=((bS.pageY||bS.page.y)-bW.top)/bW.height}var bY={};p.extend(bY,bA);bY.isSource=true;bY.anchor=[bV,bU,0,0];bY.parentAnchor=[b0,bZ,0,0];bY.dragOptions=bM;if(bA.parent){var bQ=bY.container||bn.Defaults.Container||p.Defaults.Container;if(bQ){bY.container=bQ}else{bY.container=p.CurrentLibrary.getParent(bA.parent)}}bO=bn.addEndpoint(bE,bY);bI=true;bO.endpointWillMoveAfterConnection=bA.parent!=null;bO.endpointWillMoveTo=bA.parent?by.getElementObject(bA.parent):null;var bX=function(){if(bI){bn.deleteEndpoint(bO)}};bn.registerListener(bO.canvas,"mouseup",bX);bn.registerListener(bK,"mouseup",bX);by.trigger(bO.canvas,"mousedown",bS)};bn.registerListener(bK,"mousedown",bG);N[bE]=bG};bz=aI(bz);var bw=bz.length&&bz.constructor!=String?bz:[bz];for(var bx=0;bx<bw.length;bx++){bB(F(bw[bx]))}return bn};this.unmakeSource=function(bw,bx){bw=p.CurrentLibrary.getElementObject(bw);var by=K(bw),bv=N[by];if(bv){bn.unregisterListener(_el,"mousedown",bv)}if(!bx){delete az[by];delete a9[by];delete ac[by];delete N[by]}return bn};this.unmakeEverySource=function(){for(var bv in ac){bn.unmakeSource(bv,true)}az={};a9={};ac={};N={}};this.unmakeEveryTarget=function(){for(var bv in aj){bn.unmakeTarget(bv,true)}aZ={};bh={};ap={};aj={};return bn};this.makeSources=function(bx,by,bv){for(var bw=0;bw<bx.length;bw++){bn.makeSource(bx[bw],by,bv)}return bn};var aM=function(bz,by,bA,bv){var bw=bz=="source"?ac:aj;if(C(by)){bw[by]=bv?!bw[by]:bA}else{if(by.length){by=aI(by);for(var bx=0;bx<by.length;bx++){var bB=_el=p.CurrentLibrary.getElementObject(by[bx]),bB=K(_el);bw[bB]=bv?!bw[bB]:bA}}}return bn};this.setSourceEnabled=function(bv,bw){return aM("source",bv,bw)};this.toggleSourceEnabled=function(bv){aM("source",bv,null,true);return bn.isSourceEnabled(bv)};this.isSource=function(bv){bv=p.CurrentLibrary.getElementObject(bv);return ac[K(bv)]!=null};this.isSourceEnabled=function(bv){bv=p.CurrentLibrary.getElementObject(bv);return ac[K(bv)]===true};this.setTargetEnabled=function(bv,bw){return aM("target",bv,bw)};this.toggleTargetEnabled=function(bv){return aM("target",bv,null,true);return bn.isTargetEnabled(bv)};this.isTarget=function(bv){bv=p.CurrentLibrary.getElementObject(bv);return aj[K(bv)]!=null};this.isTargetEnabled=function(bv){bv=p.CurrentLibrary.getElementObject(bv);return aj[K(bv)]===true};this.ready=function(bv){bn.bind("ready",bv)},this.repaint=function(bw){var bx=function(by){ba(F(by))};if(typeof bw=="object"){for(var bv=0;bv<bw.length;bv++){bx(bw[bv])}}else{bx(bw)}};this.repaintEverything=function(){for(var bv in aT){ba(F(bv),null,null)}};this.removeAllEndpoints=function(bx){var bv=d(bx,"id"),by=aT[bv];if(by){for(var bw=0;bw<by.length;bw++){bn.deleteEndpoint(by[bw])}}aT[bv]=[]};this.removeEveryEndpoint=this.deleteEveryEndpoint;this.removeEndpoint=function(bv,bw){bn.deleteEndpoint(bw)};var ag={},bd=function(){for(var bw in ag){for(var bv=0;bv<ag[bw].length;bv++){var bx=ag[bw][bv];p.CurrentLibrary.unbind(bx.el,bx.event,bx.listener)}}ag={}};this.registerListener=function(bw,bv,bx){p.CurrentLibrary.bind(bw,bv,bx);V(ag,bv,{el:bw,event:bv,listener:bx})};this.unregisterListener=function(bw,bv,bx){p.CurrentLibrary.unbind(bw,bv,bx);D(ag,function(by){return by.type==bv&&by.listener==bx})};this.reset=function(){bn.deleteEveryEndpoint();bn.unbind();aZ={};aH={};bh={};ap={};az={};a5={};a9={};bd();bn.anchorManager.reset();bn.dragManager.reset()};this.setDefaultScope=function(bv){Q=bv};this.setDraggable=bk;this.setId=function(bz,bv,bB){var bC=bz.constructor==String?bz:bn.getId(bz),by=bn.getConnections({source:bC,scope:"*"},true),bx=bn.getConnections({target:bC,scope:"*"},true);bv=""+bv;if(!bB){bz=p.CurrentLibrary.getElementObject(bC);p.CurrentLibrary.setAttribute(bz,"id",bv)}bz=p.CurrentLibrary.getElementObject(bv);aT[bv]=aT[bC]||[];for(var bw=0;bw<aT[bv].length;bw++){aT[bv][bw].elementId=bv;aT[bv][bw].element=bz;aT[bv][bw].anchor.elementId=bv}delete aT[bC];bn.anchorManager.changeId(bC,bv);var bA=function(bG,bD,bF){for(var bE=0;bE<bG.length;bE++){bG[bE].endpoints[bD].elementId=bv;bG[bE].endpoints[bD].element=bz;bG[bE][bF+"Id"]=bv;bG[bE][bF]=bz}};bA(by,0,"source");bA(bx,1,"target")};this.setIdChanged=function(bw,bv){bn.setId(bw,bv,true)};this.setDebugLog=function(bv){P=bv};this.setRepaintFunction=function(bv){ar=bv};this.setSuspendDrawing=bg;this.CANVAS="canvas";this.SVG="svg";this.VML="vml";this.setRenderMode=function(bv){if(bv){bv=bv.toLowerCase()}else{return}if(bv!==p.CANVAS&&bv!==p.SVG&&bv!==p.VML){throw new Error("render mode must be one of jsPlumb.CANVAS, jsPlumb.SVG or jsPlumb.VML")}if(bv===p.SVG){if(e){X=p.SVG}else{if(A){X=p.CANVAS}else{if(b()){X=p.VML}}}}else{if(bv===p.CANVAS&&A){X=p.CANVAS}else{if(b()){X=p.VML}}}return X};this.getRenderMode=function(){return X};this.show=function(bv,bw){a3(bv,"block",bw)};this.sizeCanvas=function(bx,bv,bz,bw,by){if(bx){bx.style.height=by+"px";bx.height=by;bx.style.width=bw+"px";bx.width=bw;bx.style.left=bv+"px";bx.style.top=bz+"px"}};this.getTestHarness=function(){return{endpointsByElement:aT,endpointCount:function(bv){var bw=aT[bv];return bw?bw.length:0},connectionCount:function(bv){bv=bv||Q;var bw=aY[bv];return bw?bw.length:0},getId:K,makeAnchor:self.makeAnchor,makeDynamicAnchor:self.makeDynamicAnchor}};this.toggle=aQ;this.toggleVisible=aQ;this.toggleDraggable=bi;this.unload=function(){};this.wrap=am;this.addListener=this.bind;var bo=function(bA,bx){var by=null,bv=bA;if(bx.tagName.toLowerCase()==="svg"&&bx.parentNode){by=bx.parentNode}else{if(bx.offsetParent){by=bx.offsetParent}}if(by!=null){var bw=by.tagName.toLowerCase()==="body"?{left:0,top:0}:t(by),bz=by.tagName.toLowerCase()==="body"?{left:0,top:0}:{left:by.scrollLeft,top:by.scrollTop};bv[0]=bA[0]-bw.left+bz.left;bv[1]=bA[1]-bw.top+bz.top}return bv};var aa=function(bz){var bx=this;this.x=bz.x||0;this.y=bz.y||0;this.elementId=bz.elementId;var bw=bz.orientation||[0,0];var by=null,bv=null;this.offsets=bz.offsets||[0,0];bx.timestamp=null;this.compute=function(bE){var bD=bE.xy,bA=bE.wh,bB=bE.element,bC=bE.timestamp;if(bC&&bC===bx.timestamp){return bv}bv=[bD[0]+(bx.x*bA[0])+bx.offsets[0],bD[1]+(bx.y*bA[1])+bx.offsets[1]];bv=bo(bv,bB.canvas);bx.timestamp=bC;return bv};this.getOrientation=function(bA){return bw};this.equals=function(bA){if(!bA){return false}var bB=bA.getOrientation();var bC=this.getOrientation();return this.x==bA.x&&this.y==bA.y&&this.offsets[0]==bA.offsets[0]&&this.offsets[1]==bA.offsets[1]&&bC[0]==bB[0]&&bC[1]==bB[1]};this.getCurrentLocation=function(){return bv}};var a1=function(bB){var bz=bB.reference,bA=bB.referenceCanvas,bx=a(F(bA)),bw=0,bC=0,bv=null,by=null;this.x=0;this.y=0;this.isFloating=true;this.compute=function(bG){var bF=bG.xy,bE=bG.element,bD=[bF[0]+(bx[0]/2),bF[1]+(bx[1]/2)];bD=bo(bD,bE.canvas);by=bD;return bD};this.getOrientation=function(bE){if(bv){return bv}else{var bD=bz.getOrientation(bE);return[Math.abs(bD[0])*bw*-1,Math.abs(bD[1])*bC*-1]}};this.over=function(bD){bv=bD.getOrientation()};this.out=function(){bv=null};this.getCurrentLocation=function(){return by}};var aq=function(bx,bw,bC){this.isSelective=true;this.isDynamic=true;var bF=[],bE=this,bD=function(bG){return bG.constructor==aa?bG:bn.makeAnchor(bG,bC,bn)};for(var bB=0;bB<bx.length;bB++){bF[bB]=bD(bx[bB])}this.addAnchor=function(bG){bF.push(bD(bG))};this.getAnchors=function(){return bF};this.locked=false;var by=bF.length>0?bF[0]:null,bA=bF.length>0?0:-1,bE=this,bz=function(bI,bG,bM,bL,bH){var bK=bL[0]+(bI.x*bH[0]),bJ=bL[1]+(bI.y*bH[1]);return Math.sqrt(Math.pow(bG-bK,2)+Math.pow(bM-bJ,2))},bv=bw||function(bQ,bH,bI,bJ,bG){var bL=bI[0]+(bJ[0]/2),bK=bI[1]+(bJ[1]/2);var bN=-1,bP=Infinity;for(var bM=0;bM<bG.length;bM++){var bO=bz(bG[bM],bL,bK,bQ,bH);if(bO<bP){bN=bM+0;bP=bO}}return bG[bN]};this.compute=function(bK){var bJ=bK.xy,bG=bK.wh,bI=bK.timestamp,bH=bK.txy,bL=bK.twh;if(bE.locked||bH==null||bL==null){return by.compute(bK)}else{bK.timestamp=null}by=bv(bJ,bG,bH,bL,bF);bE.x=by.x;bE.y=by.y;return by.compute(bK)};this.getCurrentLocation=function(){return by!=null?by.getCurrentLocation():null};this.getOrientation=function(bG){return by!=null?by.getOrientation(bG):[0,0]};this.over=function(bG){if(by!=null){by.over(bG)}};this.out=function(){if(by!=null){by.out()}}};var bj={},ai={},aJ={},T={HORIZONTAL:"horizontal",VERTICAL:"vertical",DIAGONAL:"diagonal",IDENTITY:"identity"},bl=function(bE,bF,bB,by){if(bE===bF){return{orientation:T.IDENTITY,a:["top","top"]}}var bw=Math.atan2((by.centery-bB.centery),(by.centerx-bB.centerx)),bz=Math.atan2((bB.centery-by.centery),(bB.centerx-by.centerx)),bA=((bB.left<=by.left&&bB.right>=by.left)||(bB.left<=by.right&&bB.right>=by.right)||(bB.left<=by.left&&bB.right>=by.right)||(by.left<=bB.left&&by.right>=bB.right)),bG=((bB.top<=by.top&&bB.bottom>=by.top)||(bB.top<=by.bottom&&bB.bottom>=by.bottom)||(bB.top<=by.top&&bB.bottom>=by.bottom)||(by.top<=bB.top&&by.bottom>=bB.bottom));if(!(bA||bG)){var bD=null,bx=false,bv=false,bC=null;if(by.left>bB.left&&by.top>bB.top){bD=["right","top"]}else{if(by.left>bB.left&&bB.top>by.top){bD=["top","left"]}else{if(by.left<bB.left&&by.top<bB.top){bD=["top","right"]}else{if(by.left<bB.left&&by.top>bB.top){bD=["left","top"]}}}}return{orientation:T.DIAGONAL,a:bD,theta:bw,theta2:bz}}else{if(bA){return{orientation:T.HORIZONTAL,a:bB.top<by.top?["bottom","top"]:["top","bottom"],theta:bw,theta2:bz}}else{return{orientation:T.VERTICAL,a:bB.left<by.left?["right","left"]:["left","right"],theta:bw,theta2:bz}}}},a2=function(bJ,bF,bD,bE,bK,bG,bx){var bL=[],bw=bF[bK?0:1]/(bE.length+1);for(var bH=0;bH<bE.length;bH++){var bM=(bH+1)*bw,bv=bG*bF[bK?1:0];if(bx){bM=bF[bK?0:1]-bM}var bC=(bK?bM:bv),bz=bD[0]+bC,bB=bC/bF[0],bA=(bK?bv:bM),by=bD[1]+bA,bI=bA/bF[1];bL.push([bz,by,bB,bI,bE[bH][1],bE[bH][2]])}return bL},a8=function(bw,bv){return bw[0]>bv[0]?1:-1},Z=function(bv){return function(bx,bw){var by=true;if(bv){if(bx[0][0]<bw[0][0]){by=true}else{by=bx[0][1]>bw[0][1]}}else{if(bx[0][0]>bw[0][0]){by=true}else{by=bx[0][1]>bw[0][1]}}return by===false?-1:1}},O=function(bw,bv){var by=bw[0][0]<0?-Math.PI-bw[0][0]:Math.PI-bw[0][0],bx=bv[0][0]<0?-Math.PI-bv[0][0]:Math.PI-bv[0][0];if(by>bx){return 1}else{return bw[0][1]>bv[0][1]?1:-1}},a0={top:a8,right:Z(true),bottom:Z(true),left:O},ao=function(bv,bw){return bv.sort(bw)},al=function(bw,bv){var by=ae[bw],bz=ah[bw],bx=function(bG,bN,bC,bF,bL,bK,bB){if(bF.length>0){var bJ=ao(bF,a0[bG]),bH=bG==="right"||bG==="top",bA=a2(bG,bN,bC,bJ,bL,bK,bH);var bO=function(bR,bQ){var bP=bo([bQ[0],bQ[1]],bR.canvas);ai[bR.id]=[bP[0],bP[1],bQ[2],bQ[3]];aJ[bR.id]=bB};for(var bD=0;bD<bA.length;bD++){var bI=bA[bD][4],bM=bI.endpoints[0].elementId===bw,bE=bI.endpoints[1].elementId===bw;if(bM){bO(bI.endpoints[0],bA[bD])}else{if(bE){bO(bI.endpoints[1],bA[bD])}}}}};bx("bottom",by,[bz.left,bz.top],bv.bottom,true,1,[0,1]);bx("top",by,[bz.left,bz.top],bv.top,true,0,[0,-1]);bx("left",by,[bz.left,bz.top],bv.left,false,0,[-1,0]);bx("right",by,[bz.left,bz.top],bv.right,false,1,[1,0])},aE=function(){var bv={},bz={},bw=this,by={};this.reset=function(){bv={};bz={};by={}};this.newConnection=function(bD){var bF=bD.sourceId,bC=bD.targetId,bA=bD.endpoints,bE=true,bB=function(bG,bH,bJ,bI,bK){if((bF==bC)&&bJ.isContinuous){p.CurrentLibrary.removeElement(bA[1].canvas);bE=false}V(bz,bI,[bK,bH,bJ.constructor==aq])};bB(0,bA[0],bA[0].anchor,bC,bD);if(bE){bB(1,bA[1],bA[1].anchor,bF,bD)}};this.connectionDetached=function(bA){var bB=bA.connection||bA;var bG=bB.sourceId,bH=bB.targetId,bK=bB.endpoints,bF=function(bL,bM,bO,bN,bP){if(bO.constructor==a1){}else{D(bz[bN],function(bQ){return bQ[0].id==bP.id})}};bF(1,bK[1],bK[1].anchor,bG,bB);bF(0,bK[0],bK[0].anchor,bH,bB);var bC=bB.sourceId,bD=bB.targetId,bJ=bB.endpoints[0].id,bE=bB.endpoints[1].id,bI=function(bN,bL){if(bN){var bM=function(bO){return bO[4]==bL};D(bN.top,bM);D(bN.left,bM);D(bN.bottom,bM);D(bN.right,bM)}};bI(by[bC],bJ);bI(by[bD],bE);bw.redraw(bC);bw.redraw(bD)};this.add=function(bB,bA){V(bv,bA,bB)};this.changeId=function(bB,bA){bz[bA]=bz[bB];bv[bA]=bv[bB];delete bz[bB];delete bv[bB]};this.getConnectionsFor=function(bA){return bz[bA]||[]};this.getEndpointsFor=function(bA){return bv[bA]||[]};this.deleteEndpoint=function(bA){D(bv[bA.elementId],function(bB){return bB.id==bA.id})};this.clearFor=function(bA){delete bv[bA];bv[bA]=[]};var bx=function(bU,bH,bP,bE,bK,bL,bN,bJ,bW,bM,bD,bT){var bR=-1,bC=-1,bF=bE.endpoints[bN],bO=bF.id,bI=[1,0][bN],bA=[[bH,bP],bE,bK,bL,bO],bB=bU[bW],bV=bF._continuousAnchorEdge?bU[bF._continuousAnchorEdge]:null;if(bV){var bS=i(bV,function(bX){return bX[4]==bO});if(bS!=-1){bV.splice(bS,1);for(var bQ=0;bQ<bV.length;bQ++){u(bD,bV[bQ][1],function(bX){return bX.id==bV[bQ][1].id});u(bT,bV[bQ][1].endpoints[bN],function(bX){return bX.id==bV[bQ][1].endpoints[bN].id})}}}for(var bQ=0;bQ<bB.length;bQ++){if(bN==1&&bB[bQ][3]===bL&&bC==-1){bC=bQ}u(bD,bB[bQ][1],function(bX){return bX.id==bB[bQ][1].id});u(bT,bB[bQ][1].endpoints[bN],function(bX){return bX.id==bB[bQ][1].endpoints[bN].id})}if(bR!=-1){bB[bR]=bA}else{var bG=bJ?bC!=-1?bC:0:bB.length;bB.splice(bG,0,bA)}bF._continuousAnchorEdge=bW};this.redraw=function(bP,bR,bC,bF){var b0=bv[bP]||[],bZ=bz[bP]||[],bB=[],bY=[],bD=[];bC=bC||r();bF=bF||{left:0,top:0};if(bR){bR={left:bR.left+bF.left,top:bR.top+bF.top}}W({elId:bP,offset:bR,recalc:false,timestamp:bC});var bK=ah[bP],bG=ae[bP],bM={};for(var bW=0;bW<bZ.length;bW++){var bH=bZ[bW][0],bJ=bH.sourceId,bE=bH.targetId,bI=bH.endpoints[0].anchor.isContinuous,bO=bH.endpoints[1].anchor.isContinuous;if(bI||bO){var bX=bJ+"_"+bE,bU=bE+"_"+bJ,bT=bM[bX],bN=bH.sourceId==bP?1:0;if(bI&&!by[bJ]){by[bJ]={top:[],right:[],bottom:[],left:[]}}if(bO&&!by[bE]){by[bE]={top:[],right:[],bottom:[],left:[]}}if(bP!=bE){W({elId:bE,timestamp:bC})}if(bP!=bJ){W({elId:bJ,timestamp:bC})}var bL=aN(bE),bA=aN(bJ);if(bE==bJ&&(bI||bO)){bx(by[bJ],-Math.PI/2,0,bH,false,bE,0,false,"top",bJ,bB,bY)}else{if(!bT){bT=bl(bJ,bE,bA.o,bL.o);bM[bX]=bT}if(bI){bx(by[bJ],bT.theta,0,bH,false,bE,0,false,bT.a[0],bJ,bB,bY)}if(bO){bx(by[bE],bT.theta2,-1,bH,true,bJ,1,true,bT.a[1],bE,bB,bY)}}if(bI){u(bD,bJ,function(b1){return b1===bJ})}if(bO){u(bD,bE,function(b1){return b1===bE})}u(bB,bH,function(b1){return b1.id==bH.id});if((bI&&bN==0)||(bO&&bN==1)){u(bY,bH.endpoints[bN],function(b1){return b1.id==bH.endpoints[bN].id})}}}for(var bW=0;bW<bD.length;bW++){al(bD[bW],by[bD[bW]])}for(var bW=0;bW<b0.length;bW++){b0[bW].paint({timestamp:bC,offset:bK,dimensions:bG})}for(var bW=0;bW<bY.length;bW++){bY[bW].paint({timestamp:bC,offset:bK,dimensions:bG})}for(var bW=0;bW<bZ.length;bW++){var bQ=bZ[bW][1];if(bQ.anchor.constructor==aq){bQ.paint({elementWithPrecedence:bP});u(bB,bZ[bW][0],function(b1){return b1.id==bZ[bW][0].id});for(var bV=0;bV<bQ.connections.length;bV++){if(bQ.connections[bV]!==bZ[bW][0]){u(bB,bQ.connections[bV],function(b1){return b1.id==bQ.connections[bV].id})}}}else{if(bQ.anchor.constructor==aa){u(bB,bZ[bW][0],function(b1){return b1.id==bZ[bW][0].id})}}}var bS=bf[bP];if(bS){bS.paint({timestamp:bC,recalc:false,elId:bP})}for(var bW=0;bW<bB.length;bW++){bB[bW].paint({elId:bP,timestamp:bC,recalc:false})}};this.rehomeEndpoint=function(bA,bE){var bB=bv[bA]||[],bC=bn.getId(bE);for(var bD=0;bD<bB.length;bD++){bw.add(bB[bD],bC)}bB.splice(0,bB.length)}};bn.anchorManager=new aE();bn.continuousAnchorFactory={get:function(bw){var bv=bj[bw.elementId];if(!bv){bv={type:"Continuous",compute:function(bx){return ai[bx.element.id]||[0,0]},getCurrentLocation:function(bx){return ai[bx.id]||[0,0]},getOrientation:function(bx){return aJ[bx.id]||[0,0]},isDynamic:true,isContinuous:true};bj[bw.elementId]=bv}return bv}};var aV=function(){var by={},bx=[],bw={},bv={};this.register=function(bB){var bA=p.CurrentLibrary;bB=bA.getElementObject(bB);var bD=bn.getId(bB),bz=bA.getDOMElement(bB);if(!by[bD]){by[bD]=bB;bx.push(bB);bw[bD]={}}var bC=function(bH){var bK=bA.getElementObject(bH),bJ=bA.getOffset(bK);for(var bE=0;bE<bH.childNodes.length;bE++){if(bH.childNodes[bE].nodeType!=3){var bG=bA.getElementObject(bH.childNodes[bE]),bI=bn.getId(bG,null,true);if(bI&&bv[bI]&&bv[bI]>0){var bF=bA.getOffset(bG);bw[bD][bI]={id:bI,offset:{left:bF.left-bJ.left,top:bF.top-bJ.top}}}}}};bC(bz)};this.endpointAdded=function(bB){var bF=p.CurrentLibrary,bI=document.body,bz=bn.getId(bB),bH=bF.getDOMElement(bB),bA=bH.parentNode,bD=bA==bI;bv[bz]=bv[bz]?bv[bz]+1:1;while(bA!=bI){var bE=bn.getId(bA);if(by[bE]){var bK=-1,bG=bF.getElementObject(bA),bC=bF.getOffset(bG);if(bw[bE][bz]==null){var bJ=p.CurrentLibrary.getOffset(bB);bw[bE][bz]={id:bz,offset:{left:bJ.left-bC.left,top:bJ.top-bC.top}}}break}bA=bA.parentNode}};this.endpointDeleted=function(bA){if(bv[bA.elementId]){bv[bA.elementId]--;if(bv[bA.elementId]<=0){for(var bz in bw){delete bw[bz][bA.elementId]}}}};this.getElementsForDraggable=function(bz){return bw[bz]};this.reset=function(){by={};bx=[];bw={};bv={}}};bn.dragManager=new aV();var ax=function(bN){var bG=this,bx=true;bG.idPrefix="_jsplumb_c_";bG.defaultLabelLocation=0.5;bG.defaultOverlayKeys=["Overlays","ConnectionOverlays"];this.parent=bN.parent;z.apply(this,arguments);this.isVisible=function(){return bx};this.setVisible=function(bP){bx=bP;bG[bP?"showOverlays":"hideOverlays"]();if(bG.connector&&bG.connector.canvas){bG.connector.canvas.style.display=bP?"block":"none"}};this.source=F(bN.source);this.target=F(bN.target);if(bN.sourceEndpoint){this.source=bN.sourceEndpoint.endpointWillMoveTo||bN.sourceEndpoint.getElement()}if(bN.targetEndpoint){this.target=bN.targetEndpoint.getElement()}bG.previousConnection=bN.previousConnection;var bD=bN.cost;bG.getCost=function(){return bD};bG.setCost=function(bP){bD=bP};var bB=bN.bidirectional===false?false:true;bG.isBidirectional=function(){return bB};this.sourceId=d(this.source,"id");this.targetId=d(this.target,"id");this.getAttachedElements=function(){return bG.endpoints};this.scope=bN.scope;this.endpoints=[];this.endpointStyles=[];var bM=function(bQ,bP){if(bQ){return bn.makeAnchor(bQ,bP,bn)}},bK=function(bP,bV,bQ,bS,bT,bR,bU){if(bP){bG.endpoints[bV]=bP;bP.addConnection(bG)}else{if(!bQ.endpoints){bQ.endpoints=[null,null]}var b1=bQ.endpoints[bV]||bQ.endpoint||bn.Defaults.Endpoints[bV]||p.Defaults.Endpoints[bV]||bn.Defaults.Endpoint||p.Defaults.Endpoint;if(!bQ.endpointStyles){bQ.endpointStyles=[null,null]}if(!bQ.endpointHoverStyles){bQ.endpointHoverStyles=[null,null]}var bZ=bQ.endpointStyles[bV]||bQ.endpointStyle||bn.Defaults.EndpointStyles[bV]||p.Defaults.EndpointStyles[bV]||bn.Defaults.EndpointStyle||p.Defaults.EndpointStyle;if(bZ.fillStyle==null&&bR!=null){bZ.fillStyle=bR.strokeStyle}if(bZ.outlineColor==null&&bR!=null){bZ.outlineColor=bR.outlineColor}if(bZ.outlineWidth==null&&bR!=null){bZ.outlineWidth=bR.outlineWidth}var bY=bQ.endpointHoverStyles[bV]||bQ.endpointHoverStyle||bn.Defaults.EndpointHoverStyles[bV]||p.Defaults.EndpointHoverStyles[bV]||bn.Defaults.EndpointHoverStyle||p.Defaults.EndpointHoverStyle;if(bU!=null){if(bY==null){bY={}}if(bY.fillStyle==null){bY.fillStyle=bU.strokeStyle}}var bX=bQ.anchors?bQ.anchors[bV]:bQ.anchor?bQ.anchor:bM(bn.Defaults.Anchors[bV],bT)||bM(p.Defaults.Anchors[bV],bT)||bM(bn.Defaults.Anchor,bT)||bM(p.Defaults.Anchor,bT),b0=bQ.uuids?bQ.uuids[bV]:null,bW=aF({paintStyle:bZ,hoverPaintStyle:bY,endpoint:b1,connections:[bG],uuid:b0,anchor:bX,source:bS,scope:bQ.scope,container:bQ.container,reattach:bQ.reattach,detachable:bQ.detachable});bG.endpoints[bV]=bW;if(bQ.drawEndpoints===false){bW.setVisible(false,true,true)}return bW}};var bI=bK(bN.sourceEndpoint,0,bN,bG.source,bG.sourceId,bN.paintStyle,bN.hoverPaintStyle);if(bI){V(aT,this.sourceId,bI)}var by=((bG.sourceId==bG.targetId)&&bN.targetEndpoint==null)?bI:bN.targetEndpoint,bH=bK(by,1,bN,bG.target,bG.targetId,bN.paintStyle,bN.hoverPaintStyle);if(bH){V(aT,this.targetId,bH)}if(!this.scope){this.scope=this.endpoints[0].scope}if(bN.deleteEndpointsOnDetach){bG.endpointsToDeleteOnDetach=[bI,bH]}var bw=bn.Defaults.ConnectionsDetachable;if(bN.detachable===false){bw=false}if(bG.endpoints[0].connectionsDetachable===false){bw=false}if(bG.endpoints[1].connectionsDetachable===false){bw=false}if(bD==null){bD=bG.endpoints[0].getConnectionCost()}if(bN.bidirectional==null){bB=bG.endpoints[0].areConnectionsBidirectional()}this.isDetachable=function(){return bw===true};this.setDetachable=function(bP){bw=bP===true};var bO=p.extend({},this.endpoints[0].getParameters());p.extend(bO,this.endpoints[1].getParameters());p.extend(bO,bG.getParameters());bG.setParameters(bO);var bE=bG.setHover;bG.setHover=function(bP){bG.connector.setHover.apply(bG.connector,arguments);bE.apply(bG,arguments)};var bL=function(bP){if(x==null){bG.setHover(bP,false)}};this.setConnector=function(bP,bQ){if(bG.connector!=null){aX(bG.connector.getDisplayElements(),bG.parent)}var bR={_jsPlumb:bG._jsPlumb,parent:bN.parent,cssClass:bN.cssClass,container:bN.container,tooltip:bG.tooltip};if(C(bP)){this.connector=new p.Connectors[X][bP](bR)}else{if(n(bP)){this.connector=new p.Connectors[X][bP[0]](p.extend(bP[1],bR))}}bG.canvas=bG.connector.canvas;G(bG.connector,bG,bL);if(!bQ){bG.repaint()}};bG.setConnector(this.endpoints[0].connector||this.endpoints[1].connector||bN.connector||bn.Defaults.Connector||p.Defaults.Connector,true);this.setPaintStyle(this.endpoints[0].connectorStyle||this.endpoints[1].connectorStyle||bN.paintStyle||bn.Defaults.PaintStyle||p.Defaults.PaintStyle,true);this.setHoverPaintStyle(this.endpoints[0].connectorHoverStyle||this.endpoints[1].connectorHoverStyle||bN.hoverPaintStyle||bn.Defaults.HoverPaintStyle||p.Defaults.HoverPaintStyle,true);this.paintStyleInUse=this.getPaintStyle();this.moveParent=function(bS){var bR=p.CurrentLibrary,bQ=bR.getParent(bG.connector.canvas);if(bG.connector.bgCanvas){bR.removeElement(bG.connector.bgCanvas,bQ);bR.appendElement(bG.connector.bgCanvas,bS)}bR.removeElement(bG.connector.canvas,bQ);bR.appendElement(bG.connector.canvas,bS);for(var bP=0;bP<bG.overlays.length;bP++){if(bG.overlays[bP].isAppendedAtTopLevel){bR.removeElement(bG.overlays[bP].canvas,bQ);bR.appendElement(bG.overlays[bP].canvas,bS);if(bG.overlays[bP].reattachListeners){bG.overlays[bP].reattachListeners(bG.connector)}}}if(bG.connector.reattachListeners){bG.connector.reattachListeners()}};W({elId:this.sourceId});W({elId:this.targetId});var bA=ah[this.sourceId],bz=ae[this.sourceId],bv=ah[this.targetId],bC=ae[this.targetId],bF=r(),bJ=this.endpoints[0].anchor.compute({xy:[bA.left,bA.top],wh:bz,element:this.endpoints[0],elementId:this.endpoints[0].elementId,txy:[bv.left,bv.top],twh:bC,tElement:this.endpoints[1],timestamp:bF});this.endpoints[0].paint({anchorLoc:bJ,timestamp:bF});bJ=this.endpoints[1].anchor.compute({xy:[bv.left,bv.top],wh:bC,element:this.endpoints[1],elementId:this.endpoints[1].elementId,txy:[bA.left,bA.top],twh:bz,tElement:this.endpoints[0],timestamp:bF});this.endpoints[1].paint({anchorLoc:bJ,timestamp:bF});this.paint=function(b6){b6=b6||{};var bX=b6.elId,bY=b6.ui,bV=b6.recalc,bQ=b6.timestamp,bZ=false,b5=bZ?this.sourceId:this.targetId,bU=bZ?this.targetId:this.sourceId,bR=bZ?0:1,b7=bZ?1:0;var b8=W({elId:bX,offset:bY,recalc:bV,timestamp:bQ}),bW=W({elId:b5,timestamp:bQ});var b1=this.endpoints[b7],bP=this.endpoints[bR],bT=b1.anchor.getCurrentLocation(b1),b4=bP.anchor.getCurrentLocation(bP);var bS=0;for(var b3=0;b3<bG.overlays.length;b3++){var b0=bG.overlays[b3];if(b0.isVisible()){bS=Math.max(bS,b0.computeMaxSize(bG.connector))}}var b2=this.connector.compute(bT,b4,this.endpoints[b7],this.endpoints[bR],this.endpoints[b7].anchor,this.endpoints[bR].anchor,bG.paintStyleInUse.lineWidth,bS,b8,bW);bG.connector.paint(b2,bG.paintStyleInUse);for(var b3=0;b3<bG.overlays.length;b3++){var b0=bG.overlays[b3];if(b0.isVisible){bG.overlayPlacements[b3]=b0.draw(bG.connector,bG.paintStyleInUse,b2)}}};this.repaint=function(bQ){bQ=bQ||{};var bP=!(bQ.recalc===false);this.paint({elId:this.sourceId,recalc:bP,timestamp:bQ.timestamp})}};var bc=function(bw){var bv=false;return{drag:function(){if(bv){bv=false;return true}var bx=p.CurrentLibrary.getUIPosition(arguments),by=bw.element;if(by){p.CurrentLibrary.setOffset(by,bx);ba(F(by),bx)}},stopDrag:function(){bv=true}}};var at=function(bz,by,bA,bx,bv){var bw=new a1({reference:by,referenceCanvas:bx});return aF({paintStyle:bz,endpoint:bA,anchor:bw,source:bv,scope:"__floating"})};var R=function(bx,bv){var bz=document.createElement("div");bz.style.position="absolute";var bw=F(bz);aW(bz,bv);var by=K(bw);W({elId:by});bx.id=by;bx.element=bw};var af=function(b0){var bO=this;bO.idPrefix="_jsplumb_e_";bO.defaultLabelLocation=[0.5,0.5];bO.defaultOverlayKeys=["Overlays","EndpointOverlays"];this.parent=b0.parent;z.apply(this,arguments);b0=b0||{};var bA=true,by=!(b0.enabled===false);this.isVisible=function(){return bA};this.setVisible=function(b3,b6,b2){bA=b3;if(bO.canvas){bO.canvas.style.display=b3?"block":"none"}bO[b3?"showOverlays":"hideOverlays"]();if(!b6){for(var b5=0;b5<bO.connections.length;b5++){bO.connections[b5].setVisible(b3);if(!b2){var b4=bO===bO.connections[b5].endpoints[0]?1:0;if(bO.connections[b5].endpoints[b4].connections.length==1){bO.connections[b5].endpoints[b4].setVisible(b3,true,true)}}}}};this.isEnabled=function(){return by};this.setEnabled=function(b2){by=b2};var bN=b0.source,bH=b0.uuid,bY=null,bC=null;if(bH){aU[bH]=bO}var bF=d(bN,"id");this.elementId=bF;this.element=bN;var bx=b0.connectionCost;this.getConnectionCost=function(){return bx};this.setConnectionCost=function(b2){bx=b2};var bX=b0.connectionsBidirectional===false?false:true;this.areConnectionsBidirectional=function(){return bX};this.setConnectionsBidirectional=function(b2){bX=b2};bO.anchor=b0.anchor?bn.makeAnchor(b0.anchor,bF,bn):b0.anchors?bn.makeAnchor(b0.anchors,bF,bn):bn.makeAnchor("TopCenter",bF,bn);if(!b0._transient){bn.anchorManager.add(bO,bF)}var bL=null,bQ=null;this.setEndpoint=function(b2){var b3={_jsPlumb:bO._jsPlumb,parent:b0.parent,container:b0.container,tooltip:b0.tooltip,connectorTooltip:b0.connectorTooltip,endpoint:bO};if(C(b2)){bL=new p.Endpoints[X][b2](b3)}else{if(n(b2)){b3=p.extend(b2[1],b3);bL=new p.Endpoints[X][b2[0]](b3)}else{bL=b2.clone()}}var b4=p.extend({},b3);bL.clone=function(){var b5=new Object();bL.constructor.apply(b5,[b4]);return b5};bO.endpoint=bL;bO.type=bO.endpoint.type};this.setEndpoint(b0.endpoint||bn.Defaults.Endpoint||p.Defaults.Endpoint||"Dot");bQ=bL;var bM=bO.setHover;bO.setHover=function(){bO.endpoint.setHover.apply(bO.endpoint,arguments);bM.apply(bO,arguments)};var b1=function(b2){if(bO.connections.length>0){bO.connections[0].setHover(b2,false)}else{bO.setHover(b2)}};G(bO.endpoint,bO,b1);this.setPaintStyle(b0.paintStyle||b0.style||bn.Defaults.EndpointStyle||p.Defaults.EndpointStyle,true);this.setHoverPaintStyle(b0.hoverPaintStyle||bn.Defaults.EndpointHoverStyle||p.Defaults.EndpointHoverStyle,true);this.paintStyleInUse=this.getPaintStyle();var bJ=this.getPaintStyle();this.connectorStyle=b0.connectorStyle;this.connectorHoverStyle=b0.connectorHoverStyle;this.connectorOverlays=b0.connectorOverlays;this.connector=b0.connector;this.connectorTooltip=b0.connectorTooltip;this.isSource=b0.isSource||false;this.isTarget=b0.isTarget||false;var bU=b0.maxConnections||bn.Defaults.MaxConnections;this.getAttachedElements=function(){return bO.connections};this.canvas=this.endpoint.canvas;this.connections=b0.connections||[];this.scope=b0.scope||Q;this.timestamp=null;bO.isReattach=b0.reattach||false;bO.connectionsDetachable=bn.Defaults.ConnectionsDetachable;if(b0.connectionsDetachable===false||b0.detachable===false){bO.connectionsDetachable=false}var bI=b0.dragAllowedWhenFull||true;this.computeAnchor=function(b2){return bO.anchor.compute(b2)};this.addConnection=function(b2){bO.connections.push(b2)};this.detach=function(b3,b8,b4,cb,b2){var ca=i(bO.connections,function(cd){return cd.id==b3.id}),b9=false;cb=(cb!==false);if(ca>=0){if(b4||b3._forceDetach||b3.isDetachable()||b3.isDetachAllowed(b3)){var cc=b3.endpoints[0]==bO?b3.endpoints[1]:b3.endpoints[0];if(b4||b3._forceDetach||(bO.isDetachAllowed(b3))){bO.connections.splice(ca,1);if(!b8){cc.detach(b3,true,b4);if(b3.endpointsToDeleteOnDetach){for(var b7=0;b7<b3.endpointsToDeleteOnDetach.length;b7++){var b5=b3.endpointsToDeleteOnDetach[b7];if(b5&&b5.connections.length==0){bn.deleteEndpoint(b5)}}}}aX(b3.connector.getDisplayElements(),b3.parent);D(aY[b3.scope],function(cd){return cd.id==b3.id});b9=true;var b6=(!b8&&cb);a7(b3,b6,b2)}}}return b9};this.detachAll=function(b3,b2){while(bO.connections.length>0){bO.detach(bO.connections[0],false,true,b3,b2)}};this.detachFrom=function(b5,b4,b2){var b6=[];for(var b3=0;b3<bO.connections.length;b3++){if(bO.connections[b3].endpoints[1]==b5||bO.connections[b3].endpoints[0]==b5){b6.push(bO.connections[b3])}}for(var b3=0;b3<b6.length;b3++){if(bO.detach(b6[b3],false,true,b4,b2)){b6[b3].setHover(false,false)}}};this.detachFromConnection=function(b3){var b2=i(bO.connections,function(b4){return b4.id==b3.id});if(b2>=0){bO.connections.splice(b2,1)}};this.getElement=function(){return bN};this.setElement=function(b5,b2){var b7=K(b5);D(aT[bO.elementId],function(b8){return b8.id==bO.id});bN=F(b5);bF=K(bN);bO.elementId=bF;var b6=aw({source:b7,container:b2}),b4=bz.getParent(bO.canvas);bz.removeElement(bO.canvas,b4);bz.appendElement(bO.canvas,b6);for(var b3=0;b3<bO.connections.length;b3++){bO.connections[b3].moveParent(b6);bO.connections[b3].sourceId=bF;bO.connections[b3].source=bN}V(aT,b7,bO)};this.getUuid=function(){return bH};this.makeInPlaceCopy=function(){var b4=bO.anchor.getCurrentLocation(bO),b3=bO.anchor.getOrientation(bO),b2={compute:function(){return[b4[0],b4[1]]},getCurrentLocation:function(){return[b4[0],b4[1]]},getOrientation:function(){return b3}};return aF({anchor:b2,source:bN,paintStyle:this.getPaintStyle(),endpoint:bL,_transient:true,scope:bO.scope})};this.isConnectedTo=function(b4){var b3=false;if(b4){for(var b2=0;b2<bO.connections.length;b2++){if(bO.connections[b2].endpoints[1]==b4){b3=true;break}}}return b3};this.isFloating=function(){return bY!=null};this.connectorSelector=function(){var b2=bO.connections[0];if(bO.isTarget&&b2){return b2}else{return(bO.connections.length<bU)||bU==-1?null:b2}};this.isFull=function(){return !(bO.isFloating()||bU<1||bO.connections.length<bU)};this.setDragAllowedWhenFull=function(b2){bI=b2};this.setStyle=bO.setPaintStyle;this.equals=function(b2){return this.anchor.equals(b2.anchor)};var bK=function(b3){var b2=0;if(b3!=null){for(var b4=0;b4<bO.connections.length;b4++){if(bO.connections[b4].sourceId==b3||bO.connections[b4].targetId==b3){b2=b4;break}}}return bO.connections[b2]};this.paint=function(b5){b5=b5||{};var cb=b5.timestamp,ca=!(b5.recalc===false);if(!cb||bO.timestamp!==cb){W({elId:bF,timestamp:cb,recalc:ca});var ch=b5.offset||ah[bF];if(ch){var b8=b5.anchorPoint,b6=b5.connectorPaintStyle;if(b8==null){var b2=b5.dimensions||ae[bF];if(ch==null||b2==null){W({elId:bF,timestamp:cb});ch=ah[bF];b2=ae[bF]}var b4={xy:[ch.left,ch.top],wh:b2,element:bO,timestamp:cb};if(ca&&bO.anchor.isDynamic&&bO.connections.length>0){var ce=bK(b5.elementWithPrecedence),cg=ce.endpoints[0]==bO?1:0,b7=cg==0?ce.sourceId:ce.targetId,cd=ah[b7],cf=ae[b7];b4.txy=[cd.left,cd.top];b4.twh=cf;b4.tElement=ce.endpoints[cg]}b8=bO.anchor.compute(b4)}var cc=bL.compute(b8,bO.anchor.getOrientation(bO),bO.paintStyleInUse,b6||bO.paintStyleInUse);bL.paint(cc,bO.paintStyleInUse,bO.anchor);bO.timestamp=cb;for(var b9=0;b9<bO.overlays.length;b9++){var b3=bO.overlays[b9];if(b3.isVisible){bO.overlayPlacements[b9]=b3.draw(bO.endpoint,bO.paintStyleInUse,cc)}}}}};this.repaint=this.paint;this.removeConnection=this.detach;if(p.CurrentLibrary.isDragSupported(bN)){var bT={id:null,element:null},bS=null,bw=false,bB=null,bv=bc(bT);var bD=function(){bS=bO.connectorSelector();var b2=true;if(!bO.isEnabled()){b2=false}if(bS==null&&!b0.isSource){b2=false}if(b0.isSource&&bO.isFull()&&!bI){b2=false}if(bS!=null&&!bS.isDetachable()){b2=false}if(b2===false){if(p.CurrentLibrary.stopDrag){p.CurrentLibrary.stopDrag()}bv.stopDrag();return false}if(bS&&!bO.isFull()&&b0.isSource){bS=null}W({elId:bF});bC=bO.makeInPlaceCopy();bC.paint();R(bT,bO.parent);var b8=F(bC.canvas),b6=p.CurrentLibrary.getOffset(b8),b3=bo([b6.left,b6.top],bC.canvas);p.CurrentLibrary.setOffset(bT.element,{left:b3[0],top:b3[1]});if(bO.parentAnchor){bO.anchor=bn.makeAnchor(bO.parentAnchor,bO.elementId,bn)}f(F(bO.canvas),"dragId",bT.id);f(F(bO.canvas),"elId",bF);if(b0.proxy){bO.setPaintStyle(b0.proxy.paintStyle)}bY=at(bO.getPaintStyle(),bO.anchor,bL,bO.canvas,bT.element);if(bS==null){bO.anchor.locked=true;bO.setHover(false,false);bS=ad({sourceEndpoint:bO,targetEndpoint:bY,source:bO.endpointWillMoveTo||F(bN),target:bT.element,anchors:[bO.anchor,bY.anchor],paintStyle:b0.connectorStyle,hoverPaintStyle:b0.connectorHoverStyle,connector:b0.connector,overlays:b0.connectorOverlays})}else{bw=true;bS.connector.setHover(false,false);bE(F(bC.canvas),false,true);var b5=bS.endpoints[0].id==bO.id?0:1;bS.floatingAnchorIndex=b5;bO.detachFromConnection(bS);var b9=F(bO.canvas),b7=p.CurrentLibrary.getDragScope(b9);f(b9,"originalScope",b7);var b4=p.CurrentLibrary.getDropScope(b9);p.CurrentLibrary.setDragScope(b9,b4);if(b5==0){bB=[bS.source,bS.sourceId,bW,b7];bS.source=bT.element;bS.sourceId=bT.id}else{bB=[bS.target,bS.targetId,bW,b7];bS.target=bT.element;bS.targetId=bT.id}bS.endpoints[b5==0?1:0].anchor.locked=true;bS.suspendedEndpoint=bS.endpoints[b5];bS.suspendedEndpoint.setHover(false);bS.endpoints[b5]=bY;a4(bS)}bf[bT.id]=bS;bY.addConnection(bS);V(aT,bT.id,bY);bn.currentlyDragging=true};var bz=p.CurrentLibrary,bV=b0.dragOptions||{},bP=p.extend({},bz.defaultDragOptions),bR=bz.dragEvents.start,bZ=bz.dragEvents.stop,bG=bz.dragEvents.drag;bV=p.extend(bP,bV);bV.scope=bV.scope||bO.scope;bV[bR]=am(bV[bR],bD);bV[bG]=am(bV[bG],bv.drag);bV[bZ]=am(bV[bZ],function(){var b3=bz.getDropEvent(arguments);bn.currentlyDragging=false;D(aT[bT.id],function(b4){return b4.id==bY.id});aX([bT.element[0],bY.canvas],bN);au(bC.canvas,bN);bn.anchorManager.clearFor(bT.id);var b2=bS.floatingAnchorIndex==null?1:bS.floatingAnchorIndex;bS.endpoints[b2==0?1:0].anchor.locked=false;bO.setPaintStyle(bJ);if(bS.endpoints[b2]==bY){if(bw&&bS.suspendedEndpoint){if(b2==0){bS.source=bB[0];bS.sourceId=bB[1]}else{bS.target=bB[0];bS.targetId=bB[1]}p.CurrentLibrary.setDragScope(bB[2],bB[3]);bS.endpoints[b2]=bS.suspendedEndpoint;if(bO.isReattach||bS._forceDetach||!bS.endpoints[b2==0?1:0].detach(bS,false,false,true,b3)){bS.setHover(false);bS.floatingAnchorIndex=null;bS.suspendedEndpoint.addConnection(bS);bn.repaint(bB[1])}bS._forceDetach=null}else{aX(bS.connector.getDisplayElements(),bO.parent);bO.detachFromConnection(bS)}}bO.anchor.locked=false;bO.paint({recalc:false});bS.setHover(false,false);aR(bS);bS=null;bC=null;delete aT[bY.elementId];bY.anchor=null;bY=null;bn.currentlyDragging=false});var bW=F(bO.canvas);p.CurrentLibrary.initDraggable(bW,bV,true)}var bE=function(b4,b9,b7,ca){if((b0.isTarget||b9)&&p.CurrentLibrary.isDropSupported(bN)){var b5=b0.dropOptions||bn.Defaults.DropOptions||p.Defaults.DropOptions;b5=p.extend({},b5);b5.scope=b5.scope||bO.scope;var b3=p.CurrentLibrary.dragEvents.drop,b8=p.CurrentLibrary.dragEvents.over,b2=p.CurrentLibrary.dragEvents.out,b6=function(){var cb=p.CurrentLibrary.getDropEvent(arguments),co=F(p.CurrentLibrary.getDragObject(arguments)),cc=d(co,"dragId"),cf=d(co,"elId"),cn=d(co,"originalScope"),ci=bf[cc];if(ci!=null){var ck=ci.floatingAnchorIndex==null?1:ci.floatingAnchorIndex,cl=ck==0?1:0;if(cn){p.CurrentLibrary.setDragScope(co,cn)}var cm=ca!=null?ca.isEnabled():true;if(!bO.isFull()&&!(ck==0&&!bO.isSource)&&!(ck==1&&!bO.isTarget)&&cm){var cg=true;if(ci.suspendedEndpoint&&ci.suspendedEndpoint.id!=bO.id){if(ck==0){ci.source=ci.suspendedEndpoint.element;ci.sourceId=ci.suspendedEndpoint.elementId}else{ci.target=ci.suspendedEndpoint.element;ci.targetId=ci.suspendedEndpoint.elementId}if(!ci.isDetachAllowed(ci)||!ci.endpoints[ck].isDetachAllowed(ci)||!ci.suspendedEndpoint.isDetachAllowed(ci)||!bn.checkCondition("beforeDetach",ci)){cg=false}}if(ck==0){ci.source=bO.element;ci.sourceId=bO.elementId}else{ci.target=bO.element;ci.targetId=bO.elementId}cg=cg&&bO.isDropAllowed(ci.sourceId,ci.targetId,ci.scope,ci,bO);if(cg){ci.endpoints[ck].detachFromConnection(ci);if(ci.suspendedEndpoint){ci.suspendedEndpoint.detachFromConnection(ci)}ci.endpoints[ck]=bO;bO.addConnection(ci);var ce=bO.getParameters();for(var cj in ce){ci.setParameter(cj,ce[cj])}if(!ci.suspendedEndpoint){if(ce.draggable){p.CurrentLibrary.initDraggable(bO.element,bV,true)}}else{var ch=ci.suspendedEndpoint.getElement(),cd=ci.suspendedEndpoint.elementId;a7({source:ck==0?ch:ci.source,target:ck==1?ch:ci.target,sourceId:ck==0?cd:ci.sourceId,targetId:ck==1?cd:ci.targetId,sourceEndpoint:ck==0?ci.suspendedEndpoint:ci.endpoints[0],targetEndpoint:ck==1?ci.suspendedEndpoint:ci.endpoints[1],connection:ci},true,cb)}bt(ci,null,cb)}else{if(ci.suspendedEndpoint){ci.endpoints[ck]=ci.suspendedEndpoint;ci.setHover(false);ci._forceDetach=true;if(ck==0){ci.source=ci.suspendedEndpoint.element;ci.sourceId=ci.suspendedEndpoint.elementId}else{ci.target=ci.suspendedEndpoint.element;ci.targetId=ci.suspendedEndpoint.elementId}ci.suspendedEndpoint.addConnection(ci);ci.endpoints[0].repaint();ci.repaint();bn.repaint(ci.source.elementId);ci._forceDetach=false}}ci.floatingAnchorIndex=null}bn.currentlyDragging=false;delete bf[cc]}};b5[b3]=am(b5[b3],b6);b5[b8]=am(b5[b8],function(){if(bO.isTarget){var cc=p.CurrentLibrary.getDragObject(arguments),ce=d(F(cc),"dragId"),cd=bf[ce];if(cd!=null){var cb=cd.floatingAnchorIndex==null?1:cd.floatingAnchorIndex;cd.endpoints[cb].anchor.over(bO.anchor)}}});b5[b2]=am(b5[b2],function(){if(bO.isTarget){var cc=p.CurrentLibrary.getDragObject(arguments),ce=d(F(cc),"dragId"),cd=bf[ce];if(cd!=null){var cb=cd.floatingAnchorIndex==null?1:cd.floatingAnchorIndex;cd.endpoints[cb].anchor.out()}}});p.CurrentLibrary.initDroppable(b4,b5,true,b7)}};bE(F(bO.canvas),true,!(b0._transient||bO.anchor.isFloating),bO);return bO}};var p=window.jsPlumb=new y();p.getInstance=function(L){var K=new y(L);K.init();return K};var s=function(K,P,M,L,O,N){return function(R){R=R||{};var Q=R.jsPlumbInstance.makeAnchor([K,P,M,L,0,0],R.elementId,R.jsPlumbInstance);Q.type=O;if(N){N(Q,R)}return Q}};p.Anchors.TopCenter=s(0.5,0,0,-1,"TopCenter");p.Anchors.BottomCenter=s(0.5,1,0,1,"BottomCenter");p.Anchors.LeftMiddle=s(0,0.5,-1,0,"LeftMiddle");p.Anchors.RightMiddle=s(1,0.5,1,0,"RightMiddle");p.Anchors.Center=s(0.5,0.5,0,0,"Center");p.Anchors.TopRight=s(1,0,0,-1,"TopRight");p.Anchors.BottomRight=s(1,1,0,1,"BottomRight");p.Anchors.TopLeft=s(0,0,0,-1,"TopLeft");p.Anchors.BottomLeft=s(0,1,0,1,"BottomLeft");p.Defaults.DynamicAnchors=function(K){return K.jsPlumbInstance.makeAnchors(["TopCenter","RightMiddle","BottomCenter","LeftMiddle"],K.elementId,K.jsPlumbInstance)};p.Anchors.AutoDefault=function(L){var K=L.jsPlumbInstance.makeDynamicAnchor(p.Defaults.DynamicAnchors(L));K.type="AutoDefault";return K};p.Anchors.Assign=s(0,0,0,0,"Assign",function(L,M){var K=M.position||"Fixed";L.positionFinder=K.constructor==String?M.jsPlumbInstance.AnchorPositionFinders[K]:K;L.constructorParams=M});p.Anchors.Continuous=function(K){return K.jsPlumbInstance.continuousAnchorFactory.get(K)};p.AnchorPositionFinders={Fixed:function(N,K,M,L){return[(N.left-K.left)/M[0],(N.top-K.top)/M[1]]},Grid:function(K,T,O,L){var S=K.left-T.left,R=K.top-T.top,Q=O[0]/(L.grid[0]),P=O[1]/(L.grid[1]),N=Math.floor(S/Q),M=Math.floor(R/P);return[((N*Q)+(Q/2))/O[0],((M*P)+(P/2))/O[1]]}}})();(function(){jsPlumb.DOMElementComponent=function(c){jsPlumb.jsPlumbUIComponent.apply(this,arguments);this.mousemove=this.dblclick=this.click=this.mousedown=this.mouseup=function(d){}};jsPlumb.Connectors.Straight=function(){this.type="Straight";var r=this,i=null,e,k,p,n,l,f,q,h,g,d,c,o,m;this.compute=function(A,J,s,z,F,t,D,v){var I=Math.abs(A[0]-J[0]),C=Math.abs(A[1]-J[1]),B=0.45*I,u=0.45*C;I*=1.9;C*=1.9;var G=Math.min(A[0],J[0])-B;var E=Math.min(A[1],J[1])-u;var H=Math.max(2*D,v);if(I<H){I=H;G=A[0]+((J[0]-A[0])/2)-(H/2);B=(I-Math.abs(A[0]-J[0]))/2}if(C<H){C=H;E=A[1]+((J[1]-A[1])/2)-(H/2);u=(C-Math.abs(A[1]-J[1]))/2}h=A[0]<J[0]?B:I-B;g=A[1]<J[1]?u:C-u;d=A[0]<J[0]?I-B:B;c=A[1]<J[1]?C-u:u;i=[G,E,I,C,h,g,d,c];n=d-h,l=c-g;e=jsPlumbUtil.gradient({x:h,y:g},{x:d,y:c}),k=-1/e;p=-1*((e*h)-g);f=Math.atan(e);q=Math.atan(k);m=Math.sqrt((n*n)+(l*l));return i};this.pointOnPath=function(t,u){if(t==0&&!u){return{x:h,y:g}}else{if(t==1&&!u){return{x:d,y:c}}else{var s=u?t>0?t:m+t:t*m;return jsPlumbUtil.pointOnLine({x:h,y:g},{x:d,y:c},s)}}};this.gradientAtPoint=function(s){return e};this.pointAlongPathFrom=function(s,w,v){var u=r.pointOnPath(s,v),t=s==1?{x:h+((d-h)*10),y:g+((g-c)*10)}:{x:d,y:c};return jsPlumbUtil.pointOnLine(u,t,w)}};jsPlumb.Connectors.Bezier=function(v){var p=this;v=v||{};this.majorAnchor=v.curviness||150;this.minorAnchor=10;var t=null;this.type="Bezier";this._findControlPoint=function(H,w,C,x,A,F,y){var E=F.getOrientation(x),G=y.getOrientation(A),B=E[0]!=G[0]||E[1]==G[1],z=[],I=p.majorAnchor,D=p.minorAnchor;if(!B){if(E[0]==0){z.push(w[0]<C[0]?H[0]+D:H[0]-D)}else{z.push(H[0]-(I*E[0]))}if(E[1]==0){z.push(w[1]<C[1]?H[1]+D:H[1]-D)}else{z.push(H[1]+(I*G[1]))}}else{if(G[0]==0){z.push(C[0]<w[0]?H[0]+D:H[0]-D)}else{z.push(H[0]+(I*G[0]))}if(G[1]==0){z.push(C[1]<w[1]?H[1]+D:H[1]-D)}else{z.push(H[1]+(I*E[1]))}}return z};var q,l,f,o,n,f,e,s,r,u,d,h,g,k,i;this.compute=function(S,z,M,A,Q,x,w,L){w=w||0;u=Math.abs(S[0]-z[0])+w;d=Math.abs(S[1]-z[1])+w;s=Math.min(S[0],z[0])-(w/2);r=Math.min(S[1],z[1])-(w/2);f=S[0]<z[0]?u-(w/2):(w/2);e=S[1]<z[1]?d-(w/2):(w/2);o=S[0]<z[0]?(w/2):u-(w/2);n=S[1]<z[1]?(w/2):d-(w/2);q=p._findControlPoint([f,e],S,z,M,A,Q,x);l=p._findControlPoint([o,n],z,S,A,M,x,Q);var K=Math.min(f,o),J=Math.min(q[0],l[0]),F=Math.min(K,J),R=Math.max(f,o),O=Math.max(q[0],l[0]),C=Math.max(R,O);if(C>u){u=C}if(F<0){s+=F;var H=Math.abs(F);u+=H;q[0]+=H;f+=H;o+=H;l[0]+=H}var P=Math.min(e,n),N=Math.min(q[1],l[1]),B=Math.min(P,N),G=Math.max(e,n),E=Math.max(q[1],l[1]),y=Math.max(G,E);if(y>d){d=y}if(B<0){r+=B;var D=Math.abs(B);d+=D;q[1]+=D;e+=D;n+=D;l[1]+=D}if(L&&u<L){var I=(L-u)/2;u=L;s-=I;f=f+I;o=o+I;q[0]=q[0]+I;l[0]=l[0]+I}if(L&&d<L){var I=(L-d)/2;d=L;r-=I;e=e+I;n=n+I;q[1]=q[1]+I;l[1]=l[1]+I}t=[s,r,u,d,f,e,o,n,q[0],q[1],l[0],l[1]];return t};var c=function(){return[{x:f,y:e},{x:q[0],y:q[1]},{x:l[0],y:l[1]},{x:o,y:n}]};var m=function(x,w,y){if(y){w=jsBezier.locationAlongCurveFrom(x,w>0?0:1,w)}return w};this.pointOnPath=function(w,y){var x=c();w=m(x,w,y);return jsBezier.pointOnCurve(x,w)};this.gradientAtPoint=function(w,y){var x=c();w=m(x,w,y);return jsBezier.gradientAtPoint(x,w)};this.pointAlongPathFrom=function(w,z,y){var x=c();w=m(x,w,y);return jsBezier.pointAlongCurveFrom(x,w,z)}};jsPlumb.Connectors.Flowchart=function(v){this.type="Flowchart";v=v||{};var n=this,c=v.stub||v.minStubLength||30,f=jsPlumbUtil.isArray(c)?c[0]:c,k=jsPlumbUtil.isArray(c)?c[1]:c,p=v.gap||0,q=[],i=0,d=[],m=[],r=[],o,l,u=-Infinity,s=-Infinity,w=Infinity,t=Infinity,x=function(z,y,D,C){var B=0;for(var A=0;A<q.length;A++){m[A]=q[A][5]/i;d[A]=[B,(B+=(q[A][5]/i))]}},h=function(){r.push(q.length);for(var y=0;y<q.length;y++){r.push(q[y][0]);r.push(q[y][1])}},g=function(I,F,H,G,E,D){var A=q.length==0?H:q[q.length-1][0],z=q.length==0?G:q[q.length-1][1],B=I==A?Infinity:0,C=Math.abs(I==A?F-z:I-A);q.push([I,F,A,z,B,C]);i+=C;u=Math.max(u,I);s=Math.max(s,F);w=Math.min(w,I);t=Math.min(t,F)},e=function(A,C){if(C){A=A>0?A/i:(i+A)/i}var y=d.length-1,z=1;for(var B=0;B<d.length;B++){if(d[B][1]>=A){y=B;z=(A-d[B][0])/m[B];break}}return{segment:q[y],proportion:z,index:y}};this.compute=function(W,ak,z,Q,av,K,U,P,ap,am){q=[];d=[];i=0;m=[];u=s=-Infinity;w=t=Infinity;o=ak[0]<W[0];l=ak[1]<W[1];var aa=U||1,E=(aa/2)+(f+k),B=(aa/2)+(k+f),D=(aa/2)+(f+k),A=(aa/2)+(k+f),N=av.orientation||av.getOrientation(z),aw=K.orientation||K.getOrientation(Q),aj=o?ak[0]:W[0],ai=l?ak[1]:W[1],al=Math.abs(ak[0]-W[0])+E+B,au=Math.abs(ak[1]-W[1])+D+A;if(N[0]==0&&N[1]==0||aw[0]==0&&aw[1]==0){var ac=al>au?0:1,ae=[1,0][ac];N=[];aw=[];N[ac]=W[ac]>ak[ac]?-1:1;aw[ac]=W[ac]>ak[ac]?1:-1;N[ae]=0;aw[ae]=0}if(al<P){E+=(P-al)/2;al=P}if(au<P){D+=(P-au)/2;au=P}var I=o?(al-B)+(p*N[0]):E+(p*N[0]),H=l?(au-A)+(p*N[1]):D+(p*N[1]),ar=o?E+(p*aw[0]):(al-B)+(p*aw[0]),aq=l?D+(p*aw[1]):(au-A)+(p*aw[1]),Z=I+(N[0]*f),Y=H+(N[1]*f),L=ar+(aw[0]*k),J=aq+(aw[1]*k),V=Math.abs(I-ar)>(f+k),X=Math.abs(H-aq)>(f+k),ah=Z+((L-Z)/2),af=Y+((J-Y)/2),O=((N[0]*aw[0])+(N[1]*aw[1])),ab=O==-1,ad=O==0,C=O==1;aj-=E;ai-=D;r=[aj,ai,al,au,I,H,ar,aq];var ao=[];var S=N[0]==0?"y":"x",M=ab?"opposite":C?"orthogonal":"perpendicular",F=jsPlumbUtil.segment([I,H],[ar,aq]),ag=N[S=="x"?0:1]==-1,R={x:[null,4,3,2,1],y:[null,2,1,4,3]};if(ag){F=R[S][F]}g(Z,Y,I,H,ar,aq);var T=function(az,ay,y,ax){return az+(ay*((1-y)*ax)+Math.max(f,k))},G={oppositex:function(){if(z.elementId==Q.elementId){var y=Y+((1-av.y)*ap.height)+Math.max(f,k);return[[Z,y],[L,y]]}else{if(V&&(F==1||F==2)){return[[ah,H],[ah,aq]]}else{return[[Z,af],[L,af]]}}},orthogonalx:function(){if(F==1||F==2){return[[L,Y]]}else{return[[Z,J]]}},perpendicularx:function(){var y=(aq+H)/2;if((F==1&&aw[1]==1)||(F==2&&aw[1]==-1)){if(Math.abs(ar-I)>Math.max(f,k)){return[[L,Y]]}else{return[[Z,Y],[Z,y],[L,y]]}}else{if((F==3&&aw[1]==-1)||(F==4&&aw[1]==1)){return[[Z,y],[L,y]]}else{if((F==3&&aw[1]==1)||(F==4&&aw[1]==-1)){return[[Z,J]]}else{if((F==1&&aw[1]==-1)||(F==2&&aw[1]==1)){if(Math.abs(ar-I)>Math.max(f,k)){return[[ah,Y],[ah,J]]}else{return[[Z,J]]}}}}}},oppositey:function(){if(z.elementId==Q.elementId){var y=Z+((1-av.x)*ap.width)+Math.max(f,k);return[[y,Y],[y,J]]}else{if(X&&(F==2||F==3)){return[[I,af],[ar,af]]}else{return[[ah,Y],[ah,J]]}}},orthogonaly:function(){if(F==2||F==3){return[[Z,J]]}else{return[[L,Y]]}},perpendiculary:function(){var y=(ar+I)/2;if((F==2&&aw[0]==-1)||(F==3&&aw[0]==1)){if(Math.abs(ar-I)>Math.max(f,k)){return[[Z,J]]}else{return[[Z,af],[L,af]]}}else{if((F==1&&aw[0]==-1)||(F==4&&aw[0]==1)){var y=(ar+I)/2;return[[y,Y],[y,J]]}else{if((F==1&&aw[0]==1)||(F==4&&aw[0]==-1)){return[[L,Y]]}else{if((F==2&&aw[0]==1)||(F==3&&aw[0]==-1)){if(Math.abs(aq-H)>Math.max(f,k)){return[[Z,af],[L,af]]}else{return[[L,Y]]}}}}}}};var an=G[M+S]();if(an){for(var at=0;at<an.length;at++){g(an[at][0],an[at][1],I,H,ar,aq)}}g(L,J,I,H,ar,aq);g(ar,aq,I,H,ar,aq);h();x(I,H,ar,aq);if(s>r[3]){r[3]=s+(U*2)}if(u>r[2]){r[2]=u+(U*2)}return r};this.pointOnPath=function(y,z){return n.pointAlongPathFrom(y,0,z)};this.gradientAtPoint=function(y,z){return q[e(y,z)["index"]][4]};this.pointAlongPathFrom=function(F,y,E){var G=e(F,E),C=G.segment,z=G.proportion,B=q[G.index][5],A=q[G.index][4];var D={x:A==Infinity?C[2]:C[2]>C[0]?C[0]+((1-z)*B)-y:C[2]+(z*B)+y,y:A==0?C[3]:C[3]>C[1]?C[1]+((1-z)*B)-y:C[3]+(z*B)+y,segmentInfo:G};return D}};jsPlumb.Endpoints.Dot=function(d){this.type="Dot";var c=this;d=d||{};this.radius=d.radius||10;this.defaultOffset=0.5*this.radius;this.defaultInnerRadius=this.radius/3;this.compute=function(i,f,l,h){var g=l.radius||c.radius,e=i[0]-g,k=i[1]-g;return[e,k,g*2,g*2,g]}};jsPlumb.Endpoints.Rectangle=function(d){this.type="Rectangle";var c=this;d=d||{};this.width=d.width||20;this.height=d.height||20;this.compute=function(k,g,m,i){var h=m.width||c.width,f=m.height||c.height,e=k[0]-(h/2),l=k[1]-(f/2);return[e,l,h,f]}};var a=function(e){jsPlumb.DOMElementComponent.apply(this,arguments);var c=this;var d=[];this.getDisplayElements=function(){return d};this.appendDisplayElement=function(f){d.push(f)}};jsPlumb.Endpoints.Image=function(g){this.type="Image";a.apply(this,arguments);var l=this,f=false,e=g.width,d=g.height,i=null,c=g.endpoint;this.img=new Image();l.ready=false;this.img.onload=function(){l.ready=true;e=e||l.img.width;d=d||l.img.height;if(i){i(l)}};c.setImage=function(m,o){var n=m.constructor==String?m:m.src;i=o;l.img.src=m;if(l.canvas!=null){l.canvas.setAttribute("src",m)}};c.setImage(g.src||g.url,g.onload);this.compute=function(o,m,p,n){l.anchorPoint=o;if(l.ready){return[o[0]-e/2,o[1]-d/2,e,d]}else{return[0,0,0,0]}};l.canvas=document.createElement("img"),f=false;l.canvas.style.margin=0;l.canvas.style.padding=0;l.canvas.style.outline=0;l.canvas.style.position="absolute";var h=g.cssClass?" "+g.cssClass:"";l.canvas.className=jsPlumb.endpointClass+h;if(e){l.canvas.setAttribute("width",e)}if(d){l.canvas.setAttribute("height",d)}jsPlumb.appendElement(l.canvas,g.parent);l.attachListeners(l.canvas,l);var k=function(p,o,n){if(!f){l.canvas.setAttribute("src",l.img.src);l.appendDisplayElement(l.canvas);f=true}var m=l.anchorPoint[0]-(e/2),q=l.anchorPoint[1]-(d/2);jsPlumb.sizeCanvas(l.canvas,m,q,e,d)};this.paint=function(o,n,m){if(l.ready){k(o,n,m)}else{window.setTimeout(function(){l.paint(o,n,m)},200)}}};jsPlumb.Endpoints.Blank=function(d){var c=this;this.type="Blank";a.apply(this,arguments);this.compute=function(g,e,h,f){return[g[0],g[1],10,0]};c.canvas=document.createElement("div");c.canvas.style.display="block";c.canvas.style.width="1px";c.canvas.style.height="1px";c.canvas.style.background="transparent";c.canvas.style.position="absolute";c.canvas.className=c._jsPlumb.endpointClass;jsPlumb.appendElement(c.canvas,d.parent);this.paint=function(g,f,e){jsPlumb.sizeCanvas(c.canvas,g[0],g[1],g[2],g[3])}};jsPlumb.Endpoints.Triangle=function(c){this.type="Triangle";c=c||{};c.width=c.width||55;c.height=c.height||55;this.width=c.width;this.height=c.height;this.compute=function(i,f,l,h){var g=l.width||self.width,e=l.height||self.height,d=i[0]-(g/2),k=i[1]-(e/2);return[d,k,g,e]}};var b=function(e){var d=true,c=this;this.isAppendedAtTopLevel=true;this.component=e.component;this.loc=e.location==null?0.5:e.location;this.endpointLoc=e.endpointLocation==null?[0.5,0.5]:e.endpointLocation;this.setVisible=function(f){d=f;c.component.repaint()};this.isVisible=function(){return d};this.hide=function(){c.setVisible(false)};this.show=function(){c.setVisible(true)};this.incrementLocation=function(f){c.loc+=f;c.component.repaint()};this.setLocation=function(f){c.loc=f;c.component.repaint()};this.getLocation=function(){return c.loc}};jsPlumb.Overlays.Arrow=function(g){this.type="Arrow";b.apply(this,arguments);this.isAppendedAtTopLevel=false;g=g||{};var d=this;this.length=g.length||20;this.width=g.width||20;this.id=g.id;var f=(g.direction||1)<0?-1:1,e=g.paintStyle||{lineWidth:1},c=g.foldback||0.623;this.computeMaxSize=function(){return d.width*1.5};this.cleanup=function(){};this.draw=function(k,z,u){var o,v,h,p,n;if(k.pointAlongPathFrom){if(jsPlumbUtil.isString(d.loc)||d.loc>1||d.loc<0){var i=parseInt(d.loc);o=k.pointAlongPathFrom(i,f*d.length/2,true),v=k.pointOnPath(i,true),h=jsPlumbUtil.pointOnLine(o,v,d.length)}else{if(d.loc==1){o=k.pointOnPath(d.loc);v=k.pointAlongPathFrom(d.loc,-1);h=jsPlumbUtil.pointOnLine(o,v,d.length)}else{if(d.loc==0){h=k.pointOnPath(d.loc);v=k.pointAlongPathFrom(d.loc,1);o=jsPlumbUtil.pointOnLine(h,v,d.length)}else{o=k.pointAlongPathFrom(d.loc,f*d.length/2),v=k.pointOnPath(d.loc),h=jsPlumbUtil.pointOnLine(o,v,d.length)}}}p=jsPlumbUtil.perpendicularLineTo(o,h,d.width);n=jsPlumbUtil.pointOnLine(o,h,c*d.length);var y=Math.min(o.x,p[0].x,p[1].x),s=Math.max(o.x,p[0].x,p[1].x),x=Math.min(o.y,p[0].y,p[1].y),r=Math.max(o.y,p[0].y,p[1].y);var q={hxy:o,tail:p,cxy:n},t=e.strokeStyle||z.strokeStyle,w=e.fillStyle||z.strokeStyle,m=e.lineWidth||z.lineWidth;d.paint(k,q,m,t,w,u);return[y,s,x,r]}else{return[0,0,0,0]}}};jsPlumb.Overlays.PlainArrow=function(d){d=d||{};var c=jsPlumb.extend(d,{foldback:1});jsPlumb.Overlays.Arrow.call(this,c);this.type="PlainArrow"};jsPlumb.Overlays.Diamond=function(e){e=e||{};var c=e.length||40,d=jsPlumb.extend(e,{length:c/2,foldback:2});jsPlumb.Overlays.Arrow.call(this,d);this.type="Diamond"};jsPlumb.Overlays.Label=function(i){this.type="Label";jsPlumb.DOMElementComponent.apply(this,arguments);b.apply(this,arguments);this.labelStyle=i.labelStyle||jsPlumb.Defaults.LabelStyle;this.id=i.id;this.cachedDimensions=null;var e=i.label||"",c=this,f=false,k=document.createElement("div"),g=null;k.style.position="absolute";var d=i._jsPlumb.overlayClass+" "+(c.labelStyle.cssClass?c.labelStyle.cssClass:i.cssClass?i.cssClass:"");k.className=d;jsPlumb.appendElement(k,i.component.parent);jsPlumb.getId(k);c.attachListeners(k,c);c.canvas=k;var h=c.setVisible;c.setVisible=function(l){h(l);k.style.display=l?"block":"none"};this.getElement=function(){return k};this.cleanup=function(){if(k!=null){jsPlumb.CurrentLibrary.removeElement(k)}};this.setLabel=function(m){e=m;g=null;c.component.repaint()};this.getLabel=function(){return e};this.paint=function(l,n,m){if(!f){l.appendDisplayElement(k);c.attachListeners(k,l);f=true}k.style.left=(m[0]+n.minx)+"px";k.style.top=(m[1]+n.miny)+"px"};this.getTextDimensions=function(){if(typeof e=="function"){var l=e(c);k.innerHTML=l.replace(/\r\n/g,"<br/>")}else{if(g==null){g=e;k.innerHTML=g.replace(/\r\n/g,"<br/>")}}var n=jsPlumb.CurrentLibrary.getElementObject(k),m=jsPlumb.CurrentLibrary.getSize(n);return{width:m[0],height:m[1]}};this.computeMaxSize=function(l){var m=c.getTextDimensions(l);return m.width?Math.max(m.width,m.height)*1.5:0};this.draw=function(m,n,o){var s=c.getTextDimensions(m);if(s.width!=null){var p={x:0,y:0};if(m.pointOnPath){var q=c.loc,r=false;if(jsPlumbUtil.isString(c.loc)||c.loc<0||c.loc>1){q=parseInt(c.loc);r=true}p=m.pointOnPath(q,r)}else{var l=c.loc.constructor==Array?c.loc:c.endpointLoc;p={x:l[0]*o[2],y:l[1]*o[3]}}minx=p.x-(s.width/2),miny=p.y-(s.height/2);c.paint(m,{minx:minx,miny:miny,td:s,cxy:p},o);return[minx,minx+s.width,miny,miny+s.height]}else{return[0,0,0,0]}};this.reattachListeners=function(l){if(k){c.reattachListenersForElement(k,c,l)}}};jsPlumb.Overlays.GuideLines=function(){var c=this;c.length=50;c.lineWidth=5;this.type="GuideLines";b.apply(this,arguments);jsPlumb.jsPlumbUIComponent.apply(this,arguments);this.draw=function(e,l,k){var i=e.pointAlongPathFrom(c.loc,c.length/2),h=e.pointOnPath(c.loc),g=jsPlumbUtil.pointOnLine(i,h,c.length),f=jsPlumbUtil.perpendicularLineTo(i,g,40),d=jsPlumbUtil.perpendicularLineTo(g,i,20);c.paint(e,[i,g,f,d],c.lineWidth,"red",null,k);return[Math.min(i.x,g.x),Math.min(i.y,g.y),Math.max(i.x,g.x),Math.max(i.y,g.y)]};this.computeMaxSize=function(){return 50};this.cleanup=function(){}}})();(function(){var c=function(e,g,d,f){this.m=(f-g)/(d-e);this.b=-1*((this.m*e)-g);this.rectIntersect=function(q,p,s,o){var n=[];var k=(p-this.b)/this.m;if(k>=q&&k<=(q+s)){n.push([k,(this.m*k)+this.b])}var t=(this.m*(q+s))+this.b;if(t>=p&&t<=(p+o)){n.push([(t-this.b)/this.m,t])}var k=((p+o)-this.b)/this.m;if(k>=q&&k<=(q+s)){n.push([k,(this.m*k)+this.b])}var t=(this.m*q)+this.b;if(t>=p&&t<=(p+o)){n.push([(t-this.b)/this.m,t])}if(n.length==2){var m=(n[0][0]+n[1][0])/2,l=(n[0][1]+n[1][1])/2;n.push([m,l]);var i=m<=q+(s/2)?-1:1,r=l<=p+(o/2)?-1:1;n.push([i,r]);return n}return null}},a=function(e,g,d,f){if(e<=d&&f<=g){return 1}else{if(e<=d&&g<=f){return 2}else{if(d<=e&&f>=g){return 3}}}return 4},b=function(g,f,i,e,h,m,l,d,k){if(d<=k){return[g,f]}if(i==1){if(e[3]<=0&&h[3]>=1){return[g+(e[2]<0.5?-1*m:m),f]}else{if(e[2]>=1&&h[2]<=0){return[g,f+(e[3]<0.5?-1*l:l)]}else{return[g+(-1*m),f+(-1*l)]}}}else{if(i==2){if(e[3]>=1&&h[3]<=0){return[g+(e[2]<0.5?-1*m:m),f]}else{if(e[2]>=1&&h[2]<=0){return[g,f+(e[3]<0.5?-1*l:l)]}else{return[g+(1*m),f+(-1*l)]}}}else{if(i==3){if(e[3]>=1&&h[3]<=0){return[g+(e[2]<0.5?-1*m:m),f]}else{if(e[2]<=0&&h[2]>=1){return[g,f+(e[3]<0.5?-1*l:l)]}else{return[g+(-1*m),f+(-1*l)]}}}else{if(i==4){if(e[3]<=0&&h[3]>=1){return[g+(e[2]<0.5?-1*m:m),f]}else{if(e[2]<=0&&h[2]>=1){return[g,f+(e[3]<0.5?-1*l:l)]}else{return[g+(1*m),f+(-1*l)]}}}}}}};jsPlumb.Connectors.StateMachine=function(l){var u=this,n=null,o,m,g,e,p=[],d=l.curviness||10,k=l.margin||5,q=l.proximityLimit||80,f=l.orientation&&l.orientation=="clockwise",i=l.loopbackRadius||25,h=false,t=l.showLoopback!==false;this.type="StateMachine";l=l||{};this.compute=function(ad,H,W,I,ac,z,v,U){var Q=Math.abs(ad[0]-H[0]),Y=Math.abs(ad[1]-H[1]),S=0.45*Q,ab=0.45*Y;Q*=1.9;Y*=1.9;v=v||1;var O=Math.min(ad[0],H[0])-S,M=Math.min(ad[1],H[1])-ab;if(!t||(W.elementId!=I.elementId)){h=false;o=ad[0]<H[0]?S:Q-S;m=ad[1]<H[1]?ab:Y-ab;g=ad[0]<H[0]?Q-S:S;e=ad[1]<H[1]?Y-ab:ab;if(ad[2]==0){o-=k}if(ad[2]==1){o+=k}if(ad[3]==0){m-=k}if(ad[3]==1){m+=k}if(H[2]==0){g-=k}if(H[2]==1){g+=k}if(H[3]==0){e-=k}if(H[3]==1){e+=k}var N=(o+g)/2,L=(m+e)/2,A=(-1*N)/L,V=Math.atan(A),P=(A==Infinity||A==-Infinity)?0:Math.abs(d/2*Math.sin(V)),R=(A==Infinity||A==-Infinity)?0:Math.abs(d/2*Math.cos(V)),B=a(o,m,g,e),J=Math.sqrt(Math.pow(g-o,2)+Math.pow(e-m,2));p=b(N,L,B,ad,H,d,d,J,q);var G=Math.max(Math.abs(p[0]-o)*3,Math.abs(p[0]-g)*3,Math.abs(g-o),2*v,U),K=Math.max(Math.abs(p[1]-m)*3,Math.abs(p[1]-e)*3,Math.abs(e-m),2*v,U);if(Q<G){var T=G-Q;O-=(T/2);o+=(T/2);g+=(T/2);Q=G;p[0]+=(T/2)}if(Y<K){var aa=K-Y;M-=(aa/2);m+=(aa/2);e+=(aa/2);Y=K;p[1]+=(aa/2)}n=[O,M,Q,Y,o,m,g,e,p[0],p[1]]}else{h=true;var Z=ad[0],X=ad[0],F=ad[1]-k,D=ad[1]-k,E=Z,C=F-i;Q=((2*v)+(4*i)),Y=((2*v)+(4*i));O=E-i-v-i,M=C-i-v-i;n=[O,M,Q,Y,E-O,C-M,i,f,Z-O,F-M,X-O,D-M]}return n};var r=function(){return[{x:g,y:e},{x:p[0],y:p[1]},{x:p[0]+1,y:p[1]+1},{x:o,y:m}]};var s=function(w,v,x){if(x){v=jsBezier.locationAlongCurveFrom(w,v>0?0:1,v)}return v};this.pointOnPath=function(x,B){if(h){if(B){var y=Math.PI*2*i;x=x/y}if(x>0&&x<1){x=1-x}var z=(x*2*Math.PI)+(Math.PI/2),w=n[4]+(n[6]*Math.cos(z)),v=n[5]+(n[6]*Math.sin(z));return{x:w,y:v}}else{var A=r();x=s(A,x,B);return jsBezier.pointOnCurve(A,x)}};this.gradientAtPoint=function(v,y){if(h){if(y){var w=Math.PI*2*i;v=v/w}return Math.atan(v*2*Math.PI)}else{var x=r();v=s(x,v,y);return jsBezier.gradientAtPoint(x,v)}};this.pointAlongPathFrom=function(D,v,C){if(h){if(C){var B=Math.PI*2*i;D=D/B}if(D>0&&D<1){D=1-D}var B=2*Math.PI*n[6],w=v/B*2*Math.PI,z=(D*2*Math.PI)-w+(Math.PI/2),y=n[4]+(n[6]*Math.cos(z)),x=n[5]+(n[6]*Math.sin(z));return{x:y,y:x}}else{var A=r();D=s(A,D,C);return jsBezier.pointAlongCurveFrom(A,D,v)}}};jsPlumb.Connectors.canvas.StateMachine=function(f){f=f||{};var d=this,g=f.drawGuideline||true,e=f.avoidSelector;jsPlumb.Connectors.StateMachine.apply(this,arguments);jsPlumb.CanvasConnector.apply(this,arguments);this._paint=function(l){if(l.length==10){d.ctx.beginPath();d.ctx.moveTo(l[4],l[5]);d.ctx.bezierCurveTo(l[8],l[9],l[8],l[9],l[6],l[7]);d.ctx.stroke()}else{d.ctx.save();d.ctx.beginPath();var k=0,i=2*Math.PI,h=l[7];d.ctx.arc(l[4],l[5],l[6],0,i,h);d.ctx.stroke();d.ctx.closePath();d.ctx.restore()}};this.createGradient=function(i,h){return h.createLinearGradient(i[4],i[5],i[6],i[7])}};jsPlumb.Connectors.svg.StateMachine=function(){var d=this;jsPlumb.Connectors.StateMachine.apply(this,arguments);jsPlumb.SvgConnector.apply(this,arguments);this.getPath=function(e){if(e.length==10){return"M "+e[4]+" "+e[5]+" C "+e[8]+" "+e[9]+" "+e[8]+" "+e[9]+" "+e[6]+" "+e[7]}else{return"M"+(e[8]+4)+" "+e[9]+" A "+e[6]+" "+e[6]+" 0 1,0 "+(e[8]-4)+" "+e[9]}}};jsPlumb.Connectors.vml.StateMachine=function(){jsPlumb.Connectors.StateMachine.apply(this,arguments);jsPlumb.VmlConnector.apply(this,arguments);var d=jsPlumb.vml.convertValue;this.getPath=function(k){if(k.length==10){return"m"+d(k[4])+","+d(k[5])+" c"+d(k[8])+","+d(k[9])+","+d(k[8])+","+d(k[9])+","+d(k[6])+","+d(k[7])+" e"}else{var h=d(k[8]-k[6]),g=d(k[9]-(2*k[6])),f=h+d(2*k[6]),e=g+d(2*k[6]),l=h+","+g+","+f+","+e;var i="ar "+l+","+d(k[8])+","+d(k[9])+","+d(k[8])+","+d(k[9])+" e";return i}}}})();(function(){var h={"stroke-linejoin":"joinstyle",joinstyle:"joinstyle",endcap:"endcap",miterlimit:"miterlimit"},c=null;if(document.createStyleSheet&&document.namespaces){var m=[".jsplumb_vml","jsplumb\\:textbox","jsplumb\\:oval","jsplumb\\:rect","jsplumb\\:stroke","jsplumb\\:shape","jsplumb\\:group"],g="behavior:url(#default#VML);position:absolute;";c=document.createStyleSheet();for(var r=0;r<m.length;r++){c.addRule(m[r],g)}document.namespaces.add("jsplumb","urn:schemas-microsoft-com:vml")}jsPlumb.vml={};var t=1000,s={},a=function(u,i){var w=jsPlumb.getId(u),v=s[w];if(!v){v=f("group",[0,0,t,t],{"class":i});v.style.backgroundColor="red";s[w]=v;jsPlumb.appendElement(v,u)}return v},e=function(v,w){for(var u in w){v[u]=w[u]}},f=function(u,x,y,v,i){y=y||{};var w=document.createElement("jsplumb:"+u);i.appendElement(w,v);w.className=(y["class"]?y["class"]+" ":"")+"jsplumb_vml";k(w,x);e(w,y);return w},k=function(u,i){u.style.left=i[0]+"px";u.style.top=i[1]+"px";u.style.width=i[2]+"px";u.style.height=i[3]+"px";u.style.position="absolute"},p=jsPlumb.vml.convertValue=function(i){return Math.floor(i*t)},b=function(w,u,v,i){if("transparent"===u){i.setOpacity(v,"0.0")}else{i.setOpacity(v,"1.0")}},q=function(y,u,B,C){var x={};if(u.strokeStyle){x.stroked="true";var D=jsPlumbUtil.convertStyle(u.strokeStyle,true);x.strokecolor=D;b(x,D,"stroke",B);x.strokeweight=u.lineWidth+"px"}else{x.stroked="false"}if(u.fillStyle){x.filled="true";var v=jsPlumbUtil.convertStyle(u.fillStyle,true);x.fillcolor=v;b(x,v,"fill",B)}else{x.filled="false"}if(u.dashstyle){if(B.strokeNode==null){B.strokeNode=f("stroke",[0,0,0,0],{dashstyle:u.dashstyle},y,C)}else{B.strokeNode.dashstyle=u.dashstyle}}else{if(u["stroke-dasharray"]&&u.lineWidth){var E=u["stroke-dasharray"].indexOf(",")==-1?" ":",",z=u["stroke-dasharray"].split(E),w="";for(var A=0;A<z.length;A++){w+=(Math.floor(z[A]/u.lineWidth)+E)}if(B.strokeNode==null){B.strokeNode=f("stroke",[0,0,0,0],{dashstyle:w},y,C)}else{B.strokeNode.dashstyle=w}}}e(y,x)},n=function(){var i=this;jsPlumb.jsPlumbUIComponent.apply(this,arguments);this.opacityNodes={stroke:null,fill:null};this.initOpacityNodes=function(v){i.opacityNodes.stroke=f("stroke",[0,0,1,1],{opacity:"0.0"},v,i._jsPlumb);i.opacityNodes.fill=f("fill",[0,0,1,1],{opacity:"0.0"},v,i._jsPlumb)};this.setOpacity=function(v,x){var w=i.opacityNodes[v];if(w){w.opacity=""+x}};var u=[];this.getDisplayElements=function(){return u};this.appendDisplayElement=function(w,v){if(!v){i.canvas.parentNode.appendChild(w)}u.push(w)}},d=jsPlumb.VmlConnector=function(v){var i=this;i.strokeNode=null;i.canvas=null;n.apply(this,arguments);var u=i._jsPlumb.connectorClass+(v.cssClass?(" "+v.cssClass):"");this.paint=function(A,x,z){if(x!=null){var E=i.getPath(A),y={path:E};if(x.outlineColor){var C=x.outlineWidth||1,D=x.lineWidth+(2*C),B={strokeStyle:jsPlumbUtil.convertStyle(x.outlineColor),lineWidth:D};for(var w in h){B[w]=x[w]}if(i.bgCanvas==null){y["class"]=u;y.coordsize=(A[2]*t)+","+(A[3]*t);i.bgCanvas=f("shape",A,y,v.parent,i._jsPlumb);k(i.bgCanvas,A);i.appendDisplayElement(i.bgCanvas,true);i.attachListeners(i.bgCanvas,i);i.initOpacityNodes(i.bgCanvas,["stroke"])}else{y.coordsize=(A[2]*t)+","+(A[3]*t);k(i.bgCanvas,A);e(i.bgCanvas,y)}q(i.bgCanvas,B,i)}if(i.canvas==null){y["class"]=u;y.coordsize=(A[2]*t)+","+(A[3]*t);if(i.tooltip){y.label=i.tooltip}i.canvas=f("shape",A,y,v.parent,i._jsPlumb);i.appendDisplayElement(i.canvas,true);i.attachListeners(i.canvas,i);i.initOpacityNodes(i.canvas,["stroke"])}else{y.coordsize=(A[2]*t)+","+(A[3]*t);k(i.canvas,A);e(i.canvas,y)}q(i.canvas,x,i,i._jsPlumb)}};this.reattachListeners=function(){if(i.canvas){i.reattachListenersForElement(i.canvas,i)}}},l=window.VmlEndpoint=function(y){n.apply(this,arguments);var i=null,v=this,u=null,x=null;v.canvas=document.createElement("div");v.canvas.style.position="absolute";var w=v._jsPlumb.endpointClass+(y.cssClass?(" "+y.cssClass):"");y._jsPlumb.appendElement(v.canvas,y.parent);if(v.tooltip){v.canvas.setAttribute("label",v.tooltip)}this.paint=function(C,A,z){var B={};jsPlumb.sizeCanvas(v.canvas,C[0],C[1],C[2],C[3]);if(i==null){B["class"]=w;i=v.getVml([0,0,C[2],C[3]],B,z,v.canvas,v._jsPlumb);v.attachListeners(i,v);v.appendDisplayElement(i,true);v.appendDisplayElement(v.canvas,true);v.initOpacityNodes(i,["fill"])}else{k(i,[0,0,C[2],C[3]]);e(i,B)}q(i,A,v)};this.reattachListeners=function(){if(i){v.reattachListenersForElement(i,v)}}};jsPlumb.Connectors.vml.Bezier=function(){jsPlumb.Connectors.Bezier.apply(this,arguments);d.apply(this,arguments);this.getPath=function(i){return"m"+p(i[4])+","+p(i[5])+" c"+p(i[8])+","+p(i[9])+","+p(i[10])+","+p(i[11])+","+p(i[6])+","+p(i[7])+" e"}};jsPlumb.Connectors.vml.Straight=function(){jsPlumb.Connectors.Straight.apply(this,arguments);d.apply(this,arguments);this.getPath=function(i){return"m"+p(i[4])+","+p(i[5])+" l"+p(i[6])+","+p(i[7])+" e"}};jsPlumb.Connectors.vml.Flowchart=function(){jsPlumb.Connectors.Flowchart.apply(this,arguments);d.apply(this,arguments);this.getPath=function(v){var w="m "+p(v[4])+","+p(v[5])+" l";for(var u=0;u<v[8];u++){w=w+" "+p(v[9+(u*2)])+","+p(v[10+(u*2)])}w=w+" "+p(v[6])+","+p(v[7])+" e";return w}};jsPlumb.Endpoints.vml.Dot=function(){jsPlumb.Endpoints.Dot.apply(this,arguments);l.apply(this,arguments);this.getVml=function(w,x,u,v,i){return f("oval",w,x,v,i)}};jsPlumb.Endpoints.vml.Rectangle=function(){jsPlumb.Endpoints.Rectangle.apply(this,arguments);l.apply(this,arguments);this.getVml=function(w,x,u,v,i){return f("rect",w,x,v,i)}};jsPlumb.Endpoints.vml.Image=jsPlumb.Endpoints.Image;jsPlumb.Endpoints.vml.Blank=jsPlumb.Endpoints.Blank;jsPlumb.Overlays.vml.Label=jsPlumb.Overlays.Label;var o=function(x,v){x.apply(this,v);n.apply(this,v);var u=this,w=null;u.canvas=null;u.isAppendedAtTopLevel=true;var i=function(z,y){return"m "+p(z.hxy.x)+","+p(z.hxy.y)+" l "+p(z.tail[0].x)+","+p(z.tail[0].y)+" "+p(z.cxy.x)+","+p(z.cxy.y)+" "+p(z.tail[1].x)+","+p(z.tail[1].y)+" x e"};this.paint=function(B,G,F,H,L,K){var z={};if(H){z.stroked="true";z.strokecolor=jsPlumbUtil.convertStyle(H,true)}if(F){z.strokeweight=F+"px"}if(L){z.filled="true";z.fillcolor=L}var y=Math.min(G.hxy.x,G.tail[0].x,G.tail[1].x,G.cxy.x),J=Math.min(G.hxy.y,G.tail[0].y,G.tail[1].y,G.cxy.y),C=Math.max(G.hxy.x,G.tail[0].x,G.tail[1].x,G.cxy.x),A=Math.max(G.hxy.y,G.tail[0].y,G.tail[1].y,G.cxy.y),I=Math.abs(C-y),E=Math.abs(A-J),D=[y,J,I,E];z.path=i(G,K);z.coordsize=(K[2]*t)+","+(K[3]*t);D[0]=K[0];D[1]=K[1];D[2]=K[2];D[3]=K[3];if(u.canvas==null){u.canvas=f("shape",D,z,B.canvas.parentNode,B._jsPlumb);B.appendDisplayElement(u.canvas,true);u.attachListeners(u.canvas,B);u.attachListeners(u.canvas,u)}else{k(u.canvas,D);e(u.canvas,z)}};this.reattachListeners=function(){if(u.canvas){u.reattachListenersForElement(u.canvas,u)}};this.cleanup=function(){if(u.canvas!=null){jsPlumb.CurrentLibrary.removeElement(u.canvas)}}};jsPlumb.Overlays.vml.Arrow=function(){o.apply(this,[jsPlumb.Overlays.Arrow,arguments])};jsPlumb.Overlays.vml.PlainArrow=function(){o.apply(this,[jsPlumb.Overlays.PlainArrow,arguments])};jsPlumb.Overlays.vml.Diamond=function(){o.apply(this,[jsPlumb.Overlays.Diamond,arguments])}})();(function(){var l={joinstyle:"stroke-linejoin","stroke-linejoin":"stroke-linejoin","stroke-dashoffset":"stroke-dashoffset","stroke-linecap":"stroke-linecap"},w="stroke-dasharray",A="dashstyle",e="linearGradient",b="radialGradient",c="fill",a="stop",z="stroke",q="stroke-width",h="style",m="none",t="jsplumb_gradient_",o="lineWidth",C={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml"},g=function(F,D){for(var E in D){F.setAttribute(E,""+D[E])}},f=function(E,D){var F=document.createElementNS(C.svg,E);D=D||{};D.version="1.1";D.xmlns=C.xhtml;g(F,D);return F},n=function(D){return"position:absolute;left:"+D[0]+"px;top:"+D[1]+"px"},i=function(E){for(var D=0;D<E.childNodes.length;D++){if(E.childNodes[D].tagName==e||E.childNodes[D].tagName==b){E.removeChild(E.childNodes[D])}}},v=function(N,I,F,D,J){var G=t+J._jsPlumb.idstamp();i(N);if(!F.gradient.offset){var L=f(e,{id:G,gradientUnits:"userSpaceOnUse"});N.appendChild(L)}else{var L=f(b,{id:G});N.appendChild(L)}for(var K=0;K<F.gradient.stops.length;K++){var H=K;if(D.length==8){H=D[4]<D[6]?K:F.gradient.stops.length-1-K}else{H=D[4]<D[6]?F.gradient.stops.length-1-K:K}var M=jsPlumbUtil.convertStyle(F.gradient.stops[H][1],true);var O=f(a,{offset:Math.floor(F.gradient.stops[K][0]*100)+"%","stop-color":M});L.appendChild(O)}var E=F.strokeStyle?z:c;I.setAttribute(h,E+":url(#"+G+")")},x=function(K,G,E,D,H){if(E.gradient){v(K,G,E,D,H)}else{i(K);G.setAttribute(h,"")}G.setAttribute(c,E.fillStyle?jsPlumbUtil.convertStyle(E.fillStyle,true):m);G.setAttribute(z,E.strokeStyle?jsPlumbUtil.convertStyle(E.strokeStyle,true):m);if(E.lineWidth){G.setAttribute(q,E.lineWidth)}if(E[A]&&E[o]&&!E[w]){var L=E[A].indexOf(",")==-1?" ":",",I=E[A].split(L),F="";I.forEach(function(M){F+=(Math.floor(M*E.lineWidth)+L)});G.setAttribute(w,F)}else{if(E[w]){G.setAttribute(w,E[w])}}for(var J in l){if(E[J]){G.setAttribute(l[J],E[J])}}},B=function(F){var D=/([0-9].)(p[xt])\s(.*)/;var E=F.match(D);return{size:E[1]+E[2],font:E[3]}},r=function(I,J,E){var K=E.split(" "),H=I.className,G=H.baseVal.split(" ");for(var F=0;F<K.length;F++){if(J){if(G.indexOf(K[F])==-1){G.push(K[F])}}else{var D=G.indexOf(K[F]);if(D!=-1){G.splice(D,1)}}}I.className.baseVal=G.join(" ")},u=function(E,D){r(E,true,D)},k=function(E,D){r(E,false,D)};jsPlumbUtil.svg={addClass:u,removeClass:k,node:f,attr:g,pos:n};var s=function(H){var D=this,G=H.pointerEventsSpec||"all";jsPlumb.jsPlumbUIComponent.apply(this,H.originalArgs);D.canvas=null,D.path=null,D.svg=null;var F=H.cssClass+" "+(H.originalArgs[0].cssClass||""),I={style:"",width:0,height:0,"pointer-events":G,position:"absolute"};if(D.tooltip){I.title=D.tooltip}D.svg=f("svg",I);if(H.useDivWrapper){D.canvas=document.createElement("div");D.canvas.style.position="absolute";jsPlumb.sizeCanvas(D.canvas,0,0,1,1);D.canvas.className=F;if(D.tooltip){D.canvas.setAttribute("title",D.tooltip)}}else{g(D.svg,{"class":F});D.canvas=D.svg}H._jsPlumb.appendElement(D.canvas,H.originalArgs[0]["parent"]);if(H.useDivWrapper){D.canvas.appendChild(D.svg)}var E=[D.canvas];this.getDisplayElements=function(){return E};this.appendDisplayElement=function(J){E.push(J)};this.paint=function(M,L,K){if(L!=null){var J=M[0],N=M[1];if(H.useDivWrapper){jsPlumb.sizeCanvas(D.canvas,M[0],M[1],M[2],M[3]);J=0,N=0}g(D.svg,{style:n([J,N,M[2],M[3]]),width:M[2],height:M[3]});D._paint.apply(this,arguments)}}};var d=jsPlumb.SvgConnector=function(E){var D=this;s.apply(this,[{cssClass:E._jsPlumb.connectorClass,originalArgs:arguments,pointerEventsSpec:"none",tooltip:E.tooltip,_jsPlumb:E._jsPlumb}]);this._paint=function(L,H){var K=D.getPath(L),F={d:K},J=null;F["pointer-events"]="all";if(H.outlineColor){var I=H.outlineWidth||1,G=H.lineWidth+(2*I),J=jsPlumb.CurrentLibrary.extend({},H);J.strokeStyle=jsPlumbUtil.convertStyle(H.outlineColor);J.lineWidth=G;if(D.bgPath==null){D.bgPath=f("path",F);D.svg.appendChild(D.bgPath);D.attachListeners(D.bgPath,D)}else{g(D.bgPath,F)}x(D.svg,D.bgPath,J,L,D)}if(D.path==null){D.path=f("path",F);D.svg.appendChild(D.path);D.attachListeners(D.path,D)}else{g(D.path,F)}x(D.svg,D.path,H,L,D)};this.reattachListeners=function(){if(D.bgPath){D.reattachListenersForElement(D.bgPath,D)}if(D.path){D.reattachListenersForElement(D.path,D)}}};jsPlumb.Connectors.svg.Bezier=function(D){jsPlumb.Connectors.Bezier.apply(this,arguments);d.apply(this,arguments);this.getPath=function(F){var E="M "+F[4]+" "+F[5];E+=(" C "+F[8]+" "+F[9]+" "+F[10]+" "+F[11]+" "+F[6]+" "+F[7]);return E}};jsPlumb.Connectors.svg.Straight=function(D){jsPlumb.Connectors.Straight.apply(this,arguments);d.apply(this,arguments);this.getPath=function(E){return"M "+E[4]+" "+E[5]+" L "+E[6]+" "+E[7]}};jsPlumb.Connectors.svg.Flowchart=function(){var D=this;jsPlumb.Connectors.Flowchart.apply(this,arguments);d.apply(this,arguments);this.getPath=function(F){var G="M "+F[4]+","+F[5];for(var E=0;E<F[8];E++){G=G+" L "+F[9+(E*2)]+" "+F[10+(E*2)]}G=G+" "+F[6]+","+F[7];return G}};var y=window.SvgEndpoint=function(E){var D=this;s.apply(this,[{cssClass:E._jsPlumb.endpointClass,originalArgs:arguments,pointerEventsSpec:"all",useDivWrapper:true,_jsPlumb:E._jsPlumb}]);this._paint=function(H,G){var F=jsPlumb.extend({},G);if(F.outlineColor){F.strokeWidth=F.outlineWidth;F.strokeStyle=jsPlumbUtil.convertStyle(F.outlineColor,true)}if(D.node==null){D.node=D.makeNode(H,F);D.svg.appendChild(D.node);D.attachListeners(D.node,D)}x(D.svg,D.node,F,H,D);n(D.node,H)};this.reattachListeners=function(){if(D.node){D.reattachListenersForElement(D.node,D)}}};jsPlumb.Endpoints.svg.Dot=function(){jsPlumb.Endpoints.Dot.apply(this,arguments);y.apply(this,arguments);this.makeNode=function(E,D){return f("circle",{cx:E[2]/2,cy:E[3]/2,r:E[2]/2})}};jsPlumb.Endpoints.svg.Rectangle=function(){jsPlumb.Endpoints.Rectangle.apply(this,arguments);y.apply(this,arguments);this.makeNode=function(E,D){return f("rect",{width:E[2],height:E[3]})}};jsPlumb.Endpoints.svg.Image=jsPlumb.Endpoints.Image;jsPlumb.Endpoints.svg.Blank=jsPlumb.Endpoints.Blank;jsPlumb.Overlays.svg.Label=jsPlumb.Overlays.Label;var p=function(H,F){H.apply(this,F);jsPlumb.jsPlumbUIComponent.apply(this,F);this.isAppendedAtTopLevel=false;var D=this,G=null;this.paint=function(J,M,I,N,K){if(G==null){G=f("path",{"pointer-events":"all"});J.svg.appendChild(G);D.attachListeners(G,J);D.attachListeners(G,D)}var L=F&&(F.length==1)?(F[0].cssClass||""):"";g(G,{d:E(M),"class":L,stroke:N?N:null,fill:K?K:null})};var E=function(I){return"M"+I.hxy.x+","+I.hxy.y+" L"+I.tail[0].x+","+I.tail[0].y+" L"+I.cxy.x+","+I.cxy.y+" L"+I.tail[1].x+","+I.tail[1].y+" L"+I.hxy.x+","+I.hxy.y};this.reattachListeners=function(){if(G){D.reattachListenersForElement(G,D)}};this.cleanup=function(){if(G!=null){jsPlumb.CurrentLibrary.removeElement(G)}}};jsPlumb.Overlays.svg.Arrow=function(){p.apply(this,[jsPlumb.Overlays.Arrow,arguments])};jsPlumb.Overlays.svg.PlainArrow=function(){p.apply(this,[jsPlumb.Overlays.PlainArrow,arguments])};jsPlumb.Overlays.svg.Diamond=function(){p.apply(this,[jsPlumb.Overlays.Diamond,arguments])};jsPlumb.Overlays.svg.GuideLines=function(){var I=null,D=this,H=null,G,F;jsPlumb.Overlays.GuideLines.apply(this,arguments);this.paint=function(K,M,J,N,L){if(I==null){I=f("path");K.svg.appendChild(I);D.attachListeners(I,K);D.attachListeners(I,D);G=f("path");K.svg.appendChild(G);D.attachListeners(G,K);D.attachListeners(G,D);F=f("path");K.svg.appendChild(F);D.attachListeners(F,K);D.attachListeners(F,D)}g(I,{d:E(M[0],M[1]),stroke:"red",fill:null});g(G,{d:E(M[2][0],M[2][1]),stroke:"blue",fill:null});g(F,{d:E(M[3][0],M[3][1]),stroke:"green",fill:null})};var E=function(K,J){return"M "+K.x+","+K.y+" L"+J.x+","+J.y}}})();(function(){var d=null,i=function(p,o){return jsPlumb.CurrentLibrary.hasClass(a(p),o)},a=function(o){return jsPlumb.CurrentLibrary.getElementObject(o)},m=function(o){return jsPlumb.CurrentLibrary.getOffset(a(o))},n=function(o){return jsPlumb.CurrentLibrary.getPageXY(o)},f=function(o){return jsPlumb.CurrentLibrary.getClientXY(o)};var k=function(){var q=this;q.overlayPlacements=[];jsPlumb.jsPlumbUIComponent.apply(this,arguments);jsPlumbUtil.EventGenerator.apply(this,arguments);this._over=function(z){var B=m(a(q.canvas)),D=n(z),u=D[0]-B.left,C=D[1]-B.top;if(u>0&&C>0&&u<q.canvas.width&&C<q.canvas.height){for(var v=0;v<q.overlayPlacements.length;v++){var w=q.overlayPlacements[v];if(w&&(w[0]<=u&&w[1]>=u&&w[2]<=C&&w[3]>=C)){return true}}var A=q.canvas.getContext("2d").getImageData(parseInt(u),parseInt(C),1,1);return A.data[0]!=0||A.data[1]!=0||A.data[2]!=0||A.data[3]!=0}return false};var p=false,o=false,t=null,s=false,r=function(v,u){return v!=null&&i(v,u)};this.mousemove=function(x){var z=n(x),w=f(x),v=document.elementFromPoint(w[0],w[1]),y=r(v,"_jsPlumb_overlay");var u=d==null&&(r(v,"_jsPlumb_endpoint")||r(v,"_jsPlumb_connector"));if(!p&&u&&q._over(x)){p=true;q.fire("mouseenter",q,x);return true}else{if(p&&(!q._over(x)||!u)&&!y){p=false;q.fire("mouseexit",q,x)}}q.fire("mousemove",q,x)};this.click=function(u){if(p&&q._over(u)&&!s){q.fire("click",q,u)}s=false};this.dblclick=function(u){if(p&&q._over(u)&&!s){q.fire("dblclick",q,u)}s=false};this.mousedown=function(u){if(q._over(u)&&!o){o=true;t=m(a(q.canvas));q.fire("mousedown",q,u)}};this.mouseup=function(u){o=false;q.fire("mouseup",q,u)};this.contextmenu=function(u){if(p&&q._over(u)&&!s){q.fire("contextmenu",q,u)}s=false}};var c=function(p){var o=document.createElement("canvas");p._jsPlumb.appendElement(o,p.parent);o.style.position="absolute";if(p["class"]){o.className=p["class"]}p._jsPlumb.getId(o,p.uuid);if(p.tooltip){o.setAttribute("title",p.tooltip)}return o};var l=function(p){k.apply(this,arguments);var o=[];this.getDisplayElements=function(){return o};this.appendDisplayElement=function(q){o.push(q)}};var h=jsPlumb.CanvasConnector=function(r){l.apply(this,arguments);var o=function(v,t){p.ctx.save();jsPlumb.extend(p.ctx,t);if(t.gradient){var u=p.createGradient(v,p.ctx);for(var s=0;s<t.gradient.stops.length;s++){u.addColorStop(t.gradient.stops[s][0],t.gradient.stops[s][1])}p.ctx.strokeStyle=u}p._paint(v,t);p.ctx.restore()};var p=this,q=p._jsPlumb.connectorClass+" "+(r.cssClass||"");p.canvas=c({"class":q,_jsPlumb:p._jsPlumb,parent:r.parent,tooltip:r.tooltip});p.ctx=p.canvas.getContext("2d");p.appendDisplayElement(p.canvas);p.paint=function(w,t){if(t!=null){jsPlumb.sizeCanvas(p.canvas,w[0],w[1],w[2],w[3]);if(t.outlineColor!=null){var v=t.outlineWidth||1,s=t.lineWidth+(2*v),u={strokeStyle:t.outlineColor,lineWidth:s};o(w,u)}o(w,t)}}};var b=function(r){var p=this;l.apply(this,arguments);var q=p._jsPlumb.endpointClass+" "+(r.cssClass||""),o={"class":q,_jsPlumb:p._jsPlumb,parent:r.parent,tooltip:p.tooltip};p.canvas=c(o);p.ctx=p.canvas.getContext("2d");p.appendDisplayElement(p.canvas);this.paint=function(x,u,s){jsPlumb.sizeCanvas(p.canvas,x[0],x[1],x[2],x[3]);if(u.outlineColor!=null){var w=u.outlineWidth||1,t=u.lineWidth+(2*w);var v={strokeStyle:u.outlineColor,lineWidth:t}}p._paint.apply(this,arguments)}};jsPlumb.Endpoints.canvas.Dot=function(r){jsPlumb.Endpoints.Dot.apply(this,arguments);b.apply(this,arguments);var q=this,p=function(s){try{return parseInt(s)}catch(t){if(s.substring(s.length-1)=="%"){return parseInt(s.substring(0,s-1))}}},o=function(u){var s=q.defaultOffset,t=q.defaultInnerRadius;u.offset&&(s=p(u.offset));u.innerRadius&&(t=p(u.innerRadius));return[s,t]};this._paint=function(A,t,x){if(t!=null){var B=q.canvas.getContext("2d"),u=x.getOrientation(q);jsPlumb.extend(B,t);if(t.gradient){var v=o(t.gradient),y=u[1]==1?v[0]*-1:v[0],s=u[0]==1?v[0]*-1:v[0],z=B.createRadialGradient(A[4],A[4],A[4],A[4]+s,A[4]+y,v[1]);for(var w=0;w<t.gradient.stops.length;w++){z.addColorStop(t.gradient.stops[w][0],t.gradient.stops[w][1])}B.fillStyle=z}B.beginPath();B.arc(A[4],A[4],A[4],0,Math.PI*2,true);B.closePath();if(t.fillStyle||t.gradient){B.fill()}if(t.strokeStyle){B.stroke()}}}};jsPlumb.Endpoints.canvas.Rectangle=function(p){var o=this;jsPlumb.Endpoints.Rectangle.apply(this,arguments);b.apply(this,arguments);this._paint=function(x,r,v){var A=o.canvas.getContext("2d"),t=v.getOrientation(o);jsPlumb.extend(A,r);if(r.gradient){var z=t[1]==1?x[3]:t[1]==0?x[3]/2:0;var y=t[1]==-1?x[3]:t[1]==0?x[3]/2:0;var s=t[0]==1?x[2]:t[0]==0?x[2]/2:0;var q=t[0]==-1?x[2]:t[0]==0?x[2]/2:0;var w=A.createLinearGradient(s,z,q,y);for(var u=0;u<r.gradient.stops.length;u++){w.addColorStop(r.gradient.stops[u][0],r.gradient.stops[u][1])}A.fillStyle=w}A.beginPath();A.rect(0,0,x[2],x[3]);A.closePath();if(r.fillStyle||r.gradient){A.fill()}if(r.strokeStyle){A.stroke()}}};jsPlumb.Endpoints.canvas.Triangle=function(p){var o=this;jsPlumb.Endpoints.Triangle.apply(this,arguments);b.apply(this,arguments);this._paint=function(z,q,v){var s=z[2],C=z[3],B=z[0],A=z[1],D=o.canvas.getContext("2d"),w=0,u=0,t=0,r=v.getOrientation(o);if(r[0]==1){w=s;u=C;t=180}if(r[1]==-1){w=s;t=90}if(r[1]==1){u=C;t=-90}D.fillStyle=q.fillStyle;D.translate(w,u);D.rotate(t*Math.PI/180);D.beginPath();D.moveTo(0,0);D.lineTo(s/2,C/2);D.lineTo(0,C);D.closePath();if(q.fillStyle||q.gradient){D.fill()}if(q.strokeStyle){D.stroke()}}};jsPlumb.Endpoints.canvas.Image=jsPlumb.Endpoints.Image;jsPlumb.Endpoints.canvas.Blank=jsPlumb.Endpoints.Blank;jsPlumb.Connectors.canvas.Bezier=function(){var o=this;jsPlumb.Connectors.Bezier.apply(this,arguments);h.apply(this,arguments);this._paint=function(q,p){o.ctx.beginPath();o.ctx.moveTo(q[4],q[5]);o.ctx.bezierCurveTo(q[8],q[9],q[10],q[11],q[6],q[7]);o.ctx.stroke()};this.createGradient=function(r,p,q){return o.ctx.createLinearGradient(r[6],r[7],r[4],r[5])}};jsPlumb.Connectors.canvas.Straight=function(){var p=this,o=[null,[1,-1],[1,1],[-1,1],[-1,-1]];jsPlumb.Connectors.Straight.apply(this,arguments);h.apply(this,arguments);this._paint=function(r,t){p.ctx.beginPath();if(t.dashstyle&&t.dashstyle.split(" ").length==2){var v=t.dashstyle.split(" ");if(v.length!=2){v=[2,2]}var C=[v[0]*t.lineWidth,v[1]*t.lineWidth],y=(r[6]-r[4])/(r[7]-r[5]),G=jsPlumbUtil.segment([r[4],r[5]],[r[6],r[7]]),x=o[G],u=Math.atan(y),z=Math.sqrt(Math.pow(r[6]-r[4],2)+Math.pow(r[7]-r[5],2)),B=Math.floor(z/(C[0]+C[1])),w=[r[4],r[5]];for(var A=0;A<B;A++){p.ctx.moveTo(w[0],w[1]);var q=w[0]+(Math.abs(Math.sin(u)*C[0])*x[0]),F=w[1]+(Math.abs(Math.cos(u)*C[0])*x[1]),E=w[0]+(Math.abs(Math.sin(u)*(C[0]+C[1]))*x[0]),D=w[1]+(Math.abs(Math.cos(u)*(C[0]+C[1]))*x[1]);p.ctx.lineTo(q,F);w=[E,D]}p.ctx.moveTo(w[0],w[1]);p.ctx.lineTo(r[6],r[7])}else{p.ctx.moveTo(r[4],r[5]);p.ctx.lineTo(r[6],r[7])}p.ctx.stroke()};this.createGradient=function(r,q){return q.createLinearGradient(r[4],r[5],r[6],r[7])}};jsPlumb.Connectors.canvas.Flowchart=function(){var o=this;jsPlumb.Connectors.Flowchart.apply(this,arguments);h.apply(this,arguments);this._paint=function(r,q){o.ctx.beginPath();o.ctx.moveTo(r[4],r[5]);for(var p=0;p<r[8];p++){o.ctx.lineTo(r[9+(p*2)],r[10+(p*2)])}o.ctx.lineTo(r[6],r[7]);o.ctx.stroke()};this.createGradient=function(q,p){return p.createLinearGradient(q[4],q[5],q[6],q[7])}};jsPlumb.Overlays.canvas.Label=jsPlumb.Overlays.Label;var g=function(){jsPlumb.jsPlumbUIComponent.apply(this,arguments)};var e=function(p,o){p.apply(this,o);g.apply(this,o);this.paint=function(s,u,q,v,t){var r=s.ctx;r.lineWidth=q;r.beginPath();r.moveTo(u.hxy.x,u.hxy.y);r.lineTo(u.tail[0].x,u.tail[0].y);r.lineTo(u.cxy.x,u.cxy.y);r.lineTo(u.tail[1].x,u.tail[1].y);r.lineTo(u.hxy.x,u.hxy.y);r.closePath();if(v){r.strokeStyle=v;r.stroke()}if(t){r.fillStyle=t;r.fill()}}};jsPlumb.Overlays.canvas.Arrow=function(){e.apply(this,[jsPlumb.Overlays.Arrow,arguments])};jsPlumb.Overlays.canvas.PlainArrow=function(){e.apply(this,[jsPlumb.Overlays.PlainArrow,arguments])};jsPlumb.Overlays.canvas.Diamond=function(){e.apply(this,[jsPlumb.Overlays.Diamond,arguments])}})();(function(a){jsPlumb.CurrentLibrary={addClass:function(c,b){c=jsPlumb.CurrentLibrary.getElementObject(c);try{if(c[0].className.constructor==SVGAnimatedString){jsPlumb.util.svg.addClass(c[0],b)}}catch(d){}c.addClass(b)},animate:function(d,c,b){d.animate(c,b)},appendElement:function(c,b){jsPlumb.CurrentLibrary.getElementObject(b).append(c)},ajax:function(b){b=b||{};b.type=b.type||"get";a.ajax(b)},bind:function(b,c,d){b=jsPlumb.CurrentLibrary.getElementObject(b);b.bind(c,d)},dragEvents:{start:"start",stop:"stop",drag:"drag",step:"step",over:"over",out:"out",drop:"drop",complete:"complete"},extend:function(c,b){return a.extend(c,b)},getAttribute:function(b,c){return b.attr(c)},getClientXY:function(b){return[b.clientX,b.clientY]},getDocumentElement:function(){return document},getDragObject:function(b){return b[1].draggable},getDragScope:function(b){return b.draggable("option","scope")},getDropEvent:function(b){return b[0]},getDropScope:function(b){return b.droppable("option","scope")},getDOMElement:function(b){if(typeof(b)=="string"){return document.getElementById(b)}else{if(b.context){return b[0]}else{return b}}},getElementObject:function(b){return typeof(b)=="string"?a("#"+b):a(b)},getOffset:function(b){return b.offset()},getOriginalEvent:function(b){return b.originalEvent},getPageXY:function(b){return[b.pageX,b.pageY]},getParent:function(b){return jsPlumb.CurrentLibrary.getElementObject(b).parent()},getScrollLeft:function(b){return b.scrollLeft()},getScrollTop:function(b){return b.scrollTop()},getSelector:function(b){return a(b)},getSize:function(b){return[b.outerWidth(),b.outerHeight()]},getTagName:function(b){var c=jsPlumb.CurrentLibrary.getElementObject(b);return c.length>0?c[0].tagName:null},getUIPosition:function(c){if(c.length==1){ret={left:c[0].pageX,top:c[0].pageY}}else{var d=c[1],b=d.offset;ret=b||d.absolutePosition}return ret},hasClass:function(c,b){return c.hasClass(b)},initDraggable:function(c,b,d){b=b||{};b.helper=null;if(d){b.scope=b.scope||jsPlumb.Defaults.Scope}c.draggable(b)},initDroppable:function(c,b){b.scope=b.scope||jsPlumb.Defaults.Scope;c.droppable(b)},isAlreadyDraggable:function(b){b=jsPlumb.CurrentLibrary.getElementObject(b);return b.hasClass("ui-draggable")},isDragSupported:function(c,b){return c.draggable},isDropSupported:function(c,b){return c.droppable},removeClass:function(c,b){c=jsPlumb.CurrentLibrary.getElementObject(c);try{if(c[0].className.constructor==SVGAnimatedString){jsPlumb.util.svg.removeClass(c[0],b)}}catch(d){}c.removeClass(b)},removeElement:function(b,c){jsPlumb.CurrentLibrary.getElementObject(b).remove()},setAttribute:function(c,d,b){c.attr(d,b)},setDraggable:function(c,b){c.draggable("option","disabled",!b)},setDragScope:function(c,b){c.draggable("option","scope",b)},setOffset:function(b,c){jsPlumb.CurrentLibrary.getElementObject(b).offset(c)},trigger:function(d,e,b){var c=jQuery._data(jsPlumb.CurrentLibrary.getElementObject(d)[0],"handle");c(b)},unbind:function(b,c,d){b=jsPlumb.CurrentLibrary.getElementObject(b);b.unbind(c,d)}};a(document).ready(jsPlumb.init)})(jQuery);(function(){"undefined"==typeof Math.sgn&&(Math.sgn=function(l){return 0==l?0:0<l?1:-1});var d={subtract:function(m,l){return{x:m.x-l.x,y:m.y-l.y}},dotProduct:function(m,l){return m.x*l.x+m.y*l.y},square:function(l){return Math.sqrt(l.x*l.x+l.y*l.y)},scale:function(m,l){return{x:m.x*l,y:m.y*l}}},f=Math.pow(2,-65),h=function(y,x){for(var t=[],v=x.length-1,r=2*v-1,s=[],w=[],p=[],q=[],o=[[1,0.6,0.3,0.1],[0.4,0.6,0.6,0.4],[0.1,0.3,0.6,1]],u=0;u<=v;u++){s[u]=d.subtract(x[u],y)}for(u=0;u<=v-1;u++){w[u]=d.subtract(x[u+1],x[u]);w[u]=d.scale(w[u],3)}for(u=0;u<=v-1;u++){for(var m=0;m<=v;m++){p[u]||(p[u]=[]);p[u][m]=d.dotProduct(w[u],s[m])}}for(u=0;u<=r;u++){q[u]||(q[u]=[]);q[u].y=0;q[u].x=parseFloat(u)/r}r=v-1;for(s=0;s<=v+r;s++){u=Math.max(0,s-r);for(w=Math.min(s,v);u<=w;u++){j=s-u;q[u+j].y=q[u+j].y+p[j][u]*o[j][u]}}v=x.length-1;q=a(q,2*v-1,t,0);r=d.subtract(y,x[0]);p=d.square(r);for(u=o=0;u<q;u++){r=d.subtract(y,k(x,v,t[u],null,null));r=d.square(r);if(r<p){p=r;o=t[u]}}r=d.subtract(y,x[v]);r=d.square(r);if(r<p){p=r;o=1}return{location:o,distance:p}},a=function(C,B,x,z){var v=[],w=[],A=[],t=[],u=0,s,y;y=Math.sgn(C[0].y);for(var q=1;q<=B;q++){s=Math.sgn(C[q].y);s!=y&&u++;y=s}switch(u){case 0:return 0;case 1:if(z>=64){x[0]=(C[0].x+C[B].x)/2;return 1}var p,u=C[0].y-C[B].y;y=C[B].x-C[0].x;q=C[0].x*C[B].y-C[B].x*C[0].y;s=max_distance_below=0;for(p=1;p<B;p++){var r=u*C[p].x+y*C[p].y+q;r>s?s=r:r<max_distance_below&&(max_distance_below=r)}p=y;s=(1*(q-s)-p*0)*(1/(0*p-u*1));p=y;y=q-max_distance_below;u=(1*y-p*0)*(1/(0*p-u*1));y=Math.min(s,u);if(Math.max(s,u)-y<f){A=C[B].x-C[0].x;t=C[B].y-C[0].y;x[0]=0+1*(A*(C[0].y-0)-t*(C[0].x-0))*(1/(A*0-t*1));return 1}}k(C,B,0.5,v,w);C=a(v,B,A,z+1);B=a(w,B,t,z+1);for(z=0;z<C;z++){x[z]=A[z]}for(z=0;z<B;z++){x[z+C]=t[z]}return C+B},k=function(m,l,p,q,n){for(var o=[[]],r=0;r<=l;r++){o[0][r]=m[r]}for(m=1;m<=l;m++){for(r=0;r<=l-m;r++){o[m]||(o[m]=[]);o[m][r]||(o[m][r]={});o[m][r].x=(1-p)*o[m-1][r].x+p*o[m-1][r+1].x;o[m][r].y=(1-p)*o[m-1][r].y+p*o[m-1][r+1].y}}if(q!=null){for(r=0;r<=l;r++){q[r]=o[r][0]}}if(n!=null){for(r=0;r<=l;r++){n[r]=o[l-r][r]}}return o[l][0]},g={},e=function(t){var s=g[t];if(!s){var s=[],p=function(u){return function(){return u}},q=function(){return function(u){return u}},n=function(){return function(u){return 1-u}},o=function(u){return function(v){for(var x=1,w=0;w<u.length;w++){x=x*u[w](v)}return x}};s.push(new function(){return function(u){return Math.pow(u,t)}});for(var r=1;r<t;r++){for(var l=[new p(t)],m=0;m<t-r;m++){l.push(new q)}for(m=0;m<r;m++){l.push(new n)}s.push(new o(l))}s.push(new function(){return function(u){return Math.pow(1-u,t)}});g[t]=s}return s},c=function(m,l){for(var p=e(m.length-1),q=0,n=0,o=0;o<m.length;o++){q=q+m[o].x*p[o](l);n=n+m[o].y*p[o](l)}return{x:q,y:n}},b=function(m,l,p){for(var q=c(m,l),n=0,o=p>0?1:-1,r=null;n<Math.abs(p);){l=l+0.005*o;r=c(m,l);n=n+Math.sqrt(Math.pow(r.x-q.x,2)+Math.pow(r.y-q.y,2));q=r}return{point:r,location:l}},i=function(m,l){var o=c(m,l),p=c(m.slice(0,m.length-1),l),n=p.y-o.y,o=p.x-o.x;return n==0?Infinity:Math.atan(n/o)};window.jsBezier={distanceFromCurve:h,gradientAtPoint:i,gradientAtPointAlongCurveFrom:function(m,l,n){l=b(m,l,n);if(l.location>1){l.location=1}if(l.location<0){l.location=0}return i(m,l.location)},nearestPointOnCurve:function(m,l){var n=h(m,l);return{point:k(l,l.length-1,n.location,null,null),location:n.location}},pointOnCurve:c,pointAlongCurveFrom:function(m,l,n){return b(m,l,n).point},perpendicularToCurveAt:function(m,l,n,o){l=b(m,l,o==null?0:o);m=i(m,l.location);o=Math.atan(-1/m);m=n/2*Math.sin(o);n=n/2*Math.cos(o);return[{x:l.point.x+n,y:l.point.y+m},{x:l.point.x-n,y:l.point.y-m}]},locationAlongCurveFrom:function(m,l,n){return b(m,l,n).location}}})();
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0)))

/***/ }),
/* 13 */
/***/ (function(module, exports, __webpack_require__) {

exports = module.exports = __webpack_require__(2)(false);
// imports


// module
exports.push([module.i, "/*\n\nOnline Python Tutor\nhttps://github.com/pgbovine/OnlinePythonTutor/\n\nCopyright (C) Philip J. Guo (philip@pgbovine.net)\n\nPermission is hereby granted, free of charge, to any person obtaining a\ncopy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be included\nin all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\nOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n*/\n\n/* Most recent color scheme redesign on 2012-08-19 */\n\n/* To prevent CSS namespace clashes, prefix all rules with:\n     div.ExecutionVisualizer\n*/\n\n\n/* reset some styles to nullify effects of existing stylesheets\n   e.g., http://meyerweb.com/eric/tools/css/reset/\n*/\ndiv.ExecutionVisualizer {\n  /* none for now */\n}\n\ndiv.ExecutionVisualizer table.visualizer {\n  font-family: verdana, arial, helvetica, sans-serif;\n  font-size: 10pt;\n  margin-bottom: 10px;\n}\n\ndiv.ExecutionVisualizer table.visualizer td.vizLayoutTd {\n  vertical-align: top;\n}\n\ndiv.ExecutionVisualizer td#stack_td,\ndiv.ExecutionVisualizer td#heap_td {\n  vertical-align:top;\n  font-size: 10pt; /* don't make fonts in the heap so big! */\n}\n\ndiv.ExecutionVisualizer #dataViz {\n  /*margin-left: 25px;*/\n}\n\ndiv.ExecutionVisualizer #selectiveHideStatus {\n  /*margin-left: 25px;*/\n  font-size: 9pt;\n  margin-bottom: 15px;\n  margin-left: 13px;\n}\n\n/*\ndiv.ExecutionVisualizer div#codeDisplayDiv {\n  width: 550px;\n}\n*/\n\ndiv.ExecutionVisualizer div#pyCodeOutputDiv {\n  /*max-width: 550px;*/\n  max-height: 460px;\n  /*max-height: 620px;*/\n  overflow: auto;\n  /*margin-bottom: 4px;*/\n\n  margin-left: auto;\n  margin-right: auto;\n}\n\ndiv.ExecutionVisualizer table#pyCodeOutput {\n  font-family: Andale mono, monospace;\n  /*font-size:12pt;*/\n  font-size:11pt;\n  line-height:1.1em;\n\n  border-collapse: separate; /* some crazy CSS voodoo that needs to be\n                                there so that SVG arrows to the left\n                                of the code line up vertically in Chrome */\n  border-spacing: 0px;\n  border-top: 1px solid #bbb;\n  padding-top: 3px;\n  border-bottom: 1px solid #bbb;\n  /*margin-top: 6px;*/\n  margin: 6px auto; /* Center code in its pane */\n}\n\n/* don't wrap lines within code output ... FORCE scrollbars to appear */\ndiv.ExecutionVisualizer table#pyCodeOutput td {\n  white-space: nowrap;\n  vertical-align: middle; /* explicitly force, to override external CSS conflicts */\n}\n\ndiv.ExecutionVisualizer #leftCodeGutterSVG {\n  width: 18px;\n  min-width: 18px; /* make sure it doesn't squash too thin */\n  height: 0px; /* programmatically set this later ... IE needs this to\n                  be 0 or it defaults to something arbitrary and gross */\n}\n\ndiv.ExecutionVisualizer #prevLegendArrowSVG,\ndiv.ExecutionVisualizer #curLegendArrowSVG {\n  width: 18px;\n  height: 10px;\n}\n\ndiv.ExecutionVisualizer .arrow {\n  font-size: 16pt;\n}\n\ndiv.ExecutionVisualizer table#pyCodeOutput .lineNo {\n  color: #aaa;\n  padding: 0.2em;\n  padding-left: 0.3em;\n  padding-right: 0.5em;\n  text-align: right;\n}\n\ndiv.ExecutionVisualizer table#pyCodeOutput .cod {\n  /*font-weight: bold;*/\n  margin-left: 3px;\n  padding-left: 7px;\n  text-align: left; /* necessary or else doesn't work properly in IE */\n}\n\ndiv.ExecutionVisualizer div#progOutputs {\n  margin-left: 13px; /* line up with heap visualizations */\n  margin-bottom: 3px;\n}\n\ndiv.ExecutionVisualizer div#legendDiv {\n  padding: 0px;\n  text-align: left;\n  color: #666;\n  font-size: 9pt;\n}\n\ndiv.ExecutionVisualizer div#editCodeLinkDiv {\n  text-align: center;\n  /*\n  margin-top: 12px;\n  margin-bottom: 4px;\n  */\n  margin: 8px auto;\n  font-size: 11pt;\n}\n\ndiv.ExecutionVisualizer div#annotateLinkDiv {\n  /*text-align: left;*/\n  margin-top: 0px;\n  margin-bottom: 12px;\n  /*\n  margin-left: auto;\n  margin-right: auto;\n  */\n}\n\ndiv.ExecutionVisualizer div#stepAnnotationDiv {\n  margin-bottom: 12px;\n}\n\ndiv.ExecutionVisualizer textarea#stepAnnotationEditor,\ndiv.ExecutionVisualizer textarea#vizTitleEditor,\ndiv.ExecutionVisualizer textarea#vizDescriptionEditor {\n  border: 1px solid #999999;\n  padding: 4px;\n\n  overflow: auto; /* to look pretty on IE */\n  /* make sure textarea doesn't grow and stretch */\n  resize: none;\n}\n\n\ndiv.ExecutionVisualizer #errorOutput {\n  color: #e93f34; /* should match brightRed JavaScript variable */\n  font-size: 11pt;\n  padding-top: 2px;\n  line-height: 1.5em;\n  margin-bottom: 4px;\n}\n\n/* VCR control buttons for stepping through execution */\n\ndiv.ExecutionVisualizer #vcrControls {\n  margin-top: 15px;\n  margin-bottom: 6px;\n  /*width: 100%;*/\n  text-align: center;\n}\n\ndiv.ExecutionVisualizer #vcrControls button {\n  margin-left: 2px;\n  margin-right: 2px;\n}\n\ndiv.ExecutionVisualizer #curInstr {\n  text-align: center;\n}\n\ndiv.ExecutionVisualizer #pyStdout {\n  border: 1px solid #999999;\n  font-size: 10pt;\n  padding: 3px;\n  font-family: Andale mono, monospace;\n\n  overflow: auto; /* to look pretty on IE */\n  /* make sure textarea doesn't grow and stretch */\n  resize: none;\n}\n\n\ndiv.ExecutionVisualizer .vizFrame {\n  margin-bottom: 20px;\n  padding-left: 8px;\n  border-left: 2px solid #cccccc;\n}\n\n\n/* Rendering of primitive types */\n\ndiv.ExecutionVisualizer .importedObj {\n  font-size: 8pt;\n}\n\ndiv.ExecutionVisualizer .nullObj {\n/*  font-size: 8pt; */\n}\n\ndiv.ExecutionVisualizer .stringObj,\ndiv.ExecutionVisualizer .customObj,\ndiv.ExecutionVisualizer .funcObj {\n  font-family: Andale mono, monospace;\n  white-space: nowrap;\n}\n\ndiv.ExecutionVisualizer .funcCode {\n  font-size: 8pt;\n}\n\ndiv.ExecutionVisualizer .retval {\n  font-size: 9pt;\n}\n\ndiv.ExecutionVisualizer .stackFrame .retval {\n  color: #e93f34; /* highlight non-zombie stack frame return values -\n                     should match brightRed JavaScript variable */\n}\n\n/* Rendering of basic compound types */\n\ndiv.ExecutionVisualizer table.listTbl,\ndiv.ExecutionVisualizer table.tupleTbl,\ndiv.ExecutionVisualizer table.setTbl {\n  background-color: #ffffc6;\n}\n\n\ndiv.ExecutionVisualizer table.listTbl {\n  border: 0px solid black;\n  border-spacing: 0px;\n}\n\ndiv.ExecutionVisualizer table.listTbl td.listHeader,\ndiv.ExecutionVisualizer table.tupleTbl td.tupleHeader {\n  padding-left: 4px;\n  padding-top: 2px;\n  padding-bottom: 3px;\n  font-size: 8pt;\n  color: #777;\n  text-align: left;\n  border-left: 1px solid #555555;\n}\n\ndiv.ExecutionVisualizer table.tupleTbl {\n  border-spacing: 0px;\n  color: black;\n\n  border-bottom: 1px solid #555555; /* must match td.tupleHeader border */\n  border-top: 1px solid #555555; /* must match td.tupleHeader border */\n  border-right: 1px solid #555555; /* must match td.tupleHeader border */\n}\n\n\ndiv.ExecutionVisualizer table.listTbl td.listElt {\n  border-bottom: 1px solid #555555; /* must match td.listHeader border */\n  border-left: 1px solid #555555; /* must match td.listHeader border */\n}\n\n\n/* for C and C++ visualizations */\n\n/* make this slightly more compact than listTbl since arrays can be\n   rendered on the stack so we want to kinda conserve space */\ndiv.ExecutionVisualizer table.cArrayTbl {\n  background-color: #ffffc6;\n  padding-left: 0px;\n  padding-top: 0px;\n  padding-bottom: 0px;\n  font-size: 8pt;\n  color: #777;\n  text-align: left;\n  border: 0px solid black;\n  border-spacing: 0px;\n}\n\ndiv.ExecutionVisualizer table.cArrayTbl td.cArrayHeader {\n  padding-left: 5px;\n  padding-top: 0px;\n  padding-bottom: 2px;\n  font-size: 6pt;\n  color: #777;\n  text-align: left;\n  border-bottom: 0px solid black; /* override whatever we're nested in */\n}\n\ndiv.ExecutionVisualizer table.cArrayTbl td.cArrayElt {\n  border-bottom: 1px solid #888;\n  border-left: 1px solid #888;\n  border-top: 0px solid black;\n  color: black;\n\n  padding-top: 2px;\n  padding-bottom: 4px;\n  padding-left: 5px;\n  padding-right: 4px;\n  vertical-align: bottom;\n}\n\ndiv.ExecutionVisualizer table.cArrayTbl td.cMultidimArrayHeader {\n  padding-left: 5px;\n  padding-right: 5px;\n  padding-top: 1px;\n  padding-bottom: 3px;\n  font-size: 6pt;\n  color: #777;\n  text-align: left;\n  border-top: 1px solid #888;\n  border-left: 1px solid #888;\n  border-bottom: 0px solid black; /* override whatever we're nested in */\n}\n\ndiv.ExecutionVisualizer table.cArrayTbl td.cMultidimArrayElt {\n  border-left: 1px solid #888;\n  color: black;\n  padding-top: 1px;\n  padding-bottom: 4px;\n  padding-left: 5px;\n  padding-right: 5px;\n  vertical-align: bottom;\n}\n\n\ndiv.ExecutionVisualizer .cdataHeader {\n  font-size: 6pt;\n  color: #555;\n  padding-bottom: 2px;\n}\n\ndiv.ExecutionVisualizer .cdataElt {\n  font-size: 10pt;\n}\n\ndiv.ExecutionVisualizer .cdataUninit {\n  color: #888;\n}\n\n\ndiv.ExecutionVisualizer table.tupleTbl td.tupleElt {\n  border-left: 1px solid #555555; /* must match td.tupleHeader border */\n}\n\ndiv.ExecutionVisualizer table.customObjTbl {\n  background-color: white;\n  color: black;\n  border: 1px solid black;\n}\n\ndiv.ExecutionVisualizer table.customObjTbl td.customObjElt {\n  padding: 5px;\n  font-size: 9pt; /* make this smaller */\n}\n\ndiv.ExecutionVisualizer table.listTbl td.listElt,\ndiv.ExecutionVisualizer table.tupleTbl td.tupleElt {\n  padding-top: 0px;\n  padding-bottom: 8px;\n  padding-left: 10px;\n  padding-right: 10px;\n  vertical-align: bottom;\n}\n\ndiv.ExecutionVisualizer table.setTbl {\n  border: 1px solid #555555;\n  border-spacing: 0px;\n  text-align: center;\n}\n\ndiv.ExecutionVisualizer table.setTbl td.setElt {\n  padding: 8px;\n}\n\n\ndiv.ExecutionVisualizer table.dictTbl,\ndiv.ExecutionVisualizer table.instTbl,\ndiv.ExecutionVisualizer table.classTbl {\n  border-spacing: 1px;\n}\n\ndiv.ExecutionVisualizer table.dictTbl td.dictKey,\ndiv.ExecutionVisualizer table.instTbl td.instKey,\ndiv.ExecutionVisualizer table.classTbl td.classKey {\n  background-color: #faebbf;\n}\n\ndiv.ExecutionVisualizer table.dictTbl td.dictVal,\ndiv.ExecutionVisualizer table.instTbl td.instVal,\ndiv.ExecutionVisualizer table.classTbl td.classVal,\ndiv.ExecutionVisualizer td.funcCod {\n  background-color: #ffffc6;\n}\n\n\ndiv.ExecutionVisualizer table.dictTbl td.dictKey,\ndiv.ExecutionVisualizer table.instTbl td.instKey,\ndiv.ExecutionVisualizer table.classTbl td.classKey {\n  padding-top: 6px /*15px*/;\n  padding-bottom: 6px;\n  padding-left: 10px;\n  padding-right: 4px;\n\n  text-align: right;\n}\n\ndiv.ExecutionVisualizer table.dictTbl td.dictVal,\ndiv.ExecutionVisualizer table.instTbl td.instVal,\ndiv.ExecutionVisualizer table.classTbl td.classVal {\n  padding-top: 6px; /*15px*/;\n  padding-bottom: 6px;\n  padding-right: 10px;\n  padding-left: 4px;\n}\n\ndiv.ExecutionVisualizer td.funcCod {\n  padding-left: 4px;\n}\n\ndiv.ExecutionVisualizer table.classTbl td,\ndiv.ExecutionVisualizer table.instTbl td {\n  border-bottom: 1px #888 solid;\n}\n\ndiv.ExecutionVisualizer table.classTbl td.classVal,\ndiv.ExecutionVisualizer table.instTbl td.instVal {\n  border-left: 1px #888 solid;\n}\n\ndiv.ExecutionVisualizer table.classTbl,\ndiv.ExecutionVisualizer table.funcTbl {\n  border-collapse: collapse;\n  border: 1px #888 solid;\n}\n\n/* only add a border to dicts if they're embedded within another object */\ndiv.ExecutionVisualizer td.listElt table.dictTbl,\ndiv.ExecutionVisualizer td.tupleElt table.dictTbl,\ndiv.ExecutionVisualizer td.dictVal table.dictTbl,\ndiv.ExecutionVisualizer td.instVal table.dictTbl,\ndiv.ExecutionVisualizer td.classVal table.dictTbl {\n  border: 1px #888 solid;\n}\n\ndiv.ExecutionVisualizer .objectIdLabel {\n  font-size: 8pt;\n  color: #444;\n  margin-bottom: 2px;\n}\n\ndiv.ExecutionVisualizer .typeLabel {\n  font-size: 8pt;\n  color: #555;\n  margin-bottom: 2px;\n}\n\ndiv.ExecutionVisualizer div#stack,\ndiv.ExecutionVisualizer div#globals_area {\n  padding-left: 10px;\n  padding-right: 30px;\n\n  /* no longer necessary ... */\n  /*float: left;*/\n  /* border-right: 1px dashed #bbbbbb; */\n}\n\ndiv.ExecutionVisualizer div.stackFrame,\ndiv.ExecutionVisualizer div.zombieStackFrame {\n  background-color: #ffffff;\n  margin-bottom: 15px;\n  padding: 2px;\n  padding-left: 6px;\n  padding-right: 6px;\n  padding-bottom: 4px;\n  font-size: 10pt;\n}\n\ndiv.ExecutionVisualizer div.zombieStackFrame {\n  border-left: 1px dotted #aaa;\n  /*color: #c0c0c0;*/\n  color: #a0a0a0;\n}\n\ndiv.ExecutionVisualizer div.highlightedStackFrame {\n  background-color: #e2ebf6;\n  /*background-color: #d7e7fb;*/\n\n  /*background-color: #c0daf8;*/\n  /*background-color: #9eeaff #c5dfea;*/\n}\n\ndiv.ExecutionVisualizer div.stackFrame,\ndiv.ExecutionVisualizer div.highlightedStackFrame {\n  border-left: 1px solid #a6b3b6;\n}\n\n\ndiv.ExecutionVisualizer div.stackFrameHeader {\n  font-family: Andale mono, monospace;\n  font-size: 10pt;\n  margin-top: 4px;\n  margin-bottom: 3px;\n  white-space: nowrap;\n}\n\ndiv.ExecutionVisualizer td.stackFrameVar {\n  text-align: right;\n  padding-right: 8px;\n  padding-top: 3px;\n  padding-bottom: 3px;\n}\n\ndiv.ExecutionVisualizer td.stackFrameValue {\n  text-align: left;\n  border-bottom: 1px solid #aaaaaa;\n  border-left: 1px solid #aaaaaa;\n\n  vertical-align: middle;\n\n  padding-top: 3px;\n  padding-left: 3px;\n  padding-bottom: 3px;\n}\n\ndiv.ExecutionVisualizer .stackFrameVarTable tr {\n\n}\n\ndiv.ExecutionVisualizer .stackFrameVarTable {\n  text-align: right;\n  padding-top: 3px;\n\n  /* right-align the table */\n  margin-left: auto;\n  margin-right: 0px;\n\n  /* hack to counteract possible nasty CSS reset styles from parent divs */\n  border-collapse: separate;\n  border-spacing: 2px;\n}\n\ndiv.ExecutionVisualizer div#heap {\n  float: left;\n  padding-left: 30px;\n}\n\ndiv.ExecutionVisualizer td.toplevelHeapObject {\n  /* needed for d3 to do transitions */\n  padding-left: 8px;\n  padding-right: 8px;\n  padding-top: 4px;\n  padding-bottom: 4px;\n  /*\n  border: 2px dotted white;\n  border-color: white;\n  */\n}\n\ndiv.ExecutionVisualizer table.heapRow {\n  margin-bottom: 10px;\n}\n\ndiv.ExecutionVisualizer div.heapObject {\n  padding-left: 2px; /* leave a TINY amount of room for connector endpoints */\n}\n\ndiv.ExecutionVisualizer div.heapPrimitive {\n  padding-left: 4px; /* leave some more room for connector endpoints */\n}\n\ndiv.ExecutionVisualizer div#stackHeader {\n  margin-bottom: 15px;\n  text-align: right;\n}\n\ndiv.ExecutionVisualizer div#heapHeader {\n  /*margin-top: 2px;\n  margin-bottom: 13px;*/\n  margin-bottom: 15px;\n}\n\ndiv.ExecutionVisualizer div#langDisplayDiv {\n  text-align: center;\n  margin-top: 2pt;\n  margin-bottom: 3pt;\n}\n\ndiv.ExecutionVisualizer div#langDisplayDiv,\ndiv.ExecutionVisualizer div#stackHeader,\ndiv.ExecutionVisualizer div#heapHeader {\n  color: #333333;\n  font-size: 10pt;\n}\n\ndiv.ExecutionVisualizer #executionSlider {\n  /* if you set 'width', then it looks ugly when you dynamically resize */\n  margin-top: 15px;\n  margin-bottom: 5px;\n\n  /* DON'T center this, since we need breakpoints in executionSliderFooter to be well aligned */\n  width: 98%;\n}\n\ndiv.ExecutionVisualizer #executionSliderCaption {\n  font-size: 8pt;\n  color: #666666;\n  margin-top: 15px;\n}\n\ndiv.ExecutionVisualizer #executionSliderFooter {\n  margin-top: -7px; /* make it butt up against #executionSlider */\n}\n\ndiv.ExecutionVisualizer #codeFooterDocs,\ndiv.ExecutionVisualizer #printOutputDocs {\n  margin-bottom: 3px;\n  font-size: 8pt;\n  color: #666;\n}\n\ndiv.ExecutionVisualizer #codeFooterDocs {\n  margin-top: 5px;\n  margin-bottom: 12px;\n  width: 95%;\n}\n\n/* darken slider handle a bit */\ndiv.ExecutionVisualizer .ui-slider .ui-slider-handle {\n  border: 1px solid #999;\n}\n\n\n/* for annotation bubbles */\n\n/* For styling tricks, see: http://css-tricks.com/textarea-tricks/ */\ntextarea.bubbleInputText {\n  border: 1px solid #ccc;\n  outline: none;\n  overflow: auto; /* to look pretty on IE */\n\n  /* make sure textarea doesn't grow and stretch the enclosing bubble */\n  resize: none;\n  width: 225px;\n  max-width: 225px;\n  height: 35px;\n  max-height: 35px;\n}\n\ndiv.ExecutionVisualizer .annotationText,\ndiv.ExecutionVisualizer .vizDescriptionText {\n  font-family: verdana, arial, helvetica, sans-serif;\n  font-size: 11pt;\n  line-height: 1.5em;\n}\n\ndiv.ExecutionVisualizer .vizTitleText {\n  font-family: verdana, arial, helvetica, sans-serif;\n  font-size: 16pt;\n  margin-bottom: 12pt;\n}\n\ndiv.ExecutionVisualizer div#vizHeader {\n  margin-bottom: 10px;\n  width: 700px;\n  max-width: 700px;\n}\n\n/* prev then curr, so curr gets precedence when both apply */\ndiv.ExecutionVisualizer .highlight-prev {\n  background-color: #F0F0EA;\n}\n\ndiv.ExecutionVisualizer .highlight-cur {\n  background-color: #FFFF66;\n}\n\ndiv.ExecutionVisualizer .highlight-legend {\n  padding: 2px;\n}\n\n/* resizing sliders from David Pritchard */\n.ui-resizable-e {\n  background-color: #dddddd;\n  width: 1px;\n  border: 3px solid white;\n}\n\n.ui-resizable-e:hover {\n  border-color: #dddddd;\n}\n\ndiv.ExecutionVisualizer a,\ndiv.ExecutionVisualizer a:visited,\ndiv.ExecutionVisualizer a:hover {\n  color: #3D58A2;\n}\n\ndiv.ExecutionVisualizer div#rawUserInputDiv {\n  padding: 5px;\n  width: 95%;\n  margin: 5px auto;\n  text-align: center;\n  border: 1px #e93f34 solid;\n}\n\n/* for pyCrazyMode */\n\n/* prev then curr, so curr gets precedence when both apply */\ndiv.ExecutionVisualizer .pycrazy-highlight-prev {\n  background-color: #eeeeee; /*#F0F0EA;*/\n  /*\n  text-decoration: none;\n  border-bottom: 1px solid #dddddd;\n  */\n}\n\ndiv.ExecutionVisualizer .pycrazy-highlight-cur {\n  background-color: #FFFF66;\n  /* aligned slightly higher than border-bottom */\n  /*\n  text-decoration: none;\n  border-bottom: 1px solid #e93f34;\n  */\n}\n\ndiv.ExecutionVisualizer .pycrazy-highlight-prev-and-cur {\n  background-color: #FFFF66;\n\n  text-decoration: none;\n  border-bottom: 1px solid #999999;\n}\n\n\n#optTabularView thead.stepTableThead {\n  background-color: #bbb;\n}\n\n#optTabularView tbody.stepTableTbody {\n}\n\n#optTabularView td.stepTableTd {\n  padding: 3px 10px;\n}\n\n#uiControlsPane {\n  font-size: 8pt;\n}\n\n\n/* BEGIN Java frontend by David Pritchard and Will Gwozdz */\n\n/* stack and queue css by Will Gwozdz */\ndiv.ExecutionVisualizer table.queueTbl,\ndiv.ExecutionVisualizer table.stackTbl {\n  background-color: #ffffc6;\n}\n\ndiv.ExecutionVisualizer table.queueTbl,\ndiv.ExecutionVisualizer table.stackTbl {\n  border: 0px solid black;\n  border-spacing: 0px;\n}\n\ndiv.ExecutionVisualizer table.stackTbl td.stackElt,\ndiv.ExecutionVisualizer table.queueTbl td.queueElt {\n  padding-left: 8px;\n  padding-right: 8px;\n  padding-top: 2px;\n  padding-bottom: 3px;\n  border-top: 1px solid #555555;\n  border-bottom: 1px solid #555555;\n  border-left: 1px dashed #555555;\n}\n\ndiv.ExecutionVisualizer table.stackTbl td.stackFElt,\ndiv.ExecutionVisualizer table.queueTbl td.queueFElt {\n  background-color: white;\n  border-top: 1px solid #555555;\n  border-bottom: 1px solid #555555;\n}\n\ndiv.ExecutionVisualizer table.stackTbl td.stackLElt {\n  background-color: white;\n  border-left: 1px solid #555555;\n}\n\ndiv.ExecutionVisualizer table.queueTbl td.queueLElt {\n  background-color: white;\n  border-top: 1px solid#555555;\n  border-bottom: 1px solid #555555;\n  border-left: 1px dashed #555555;\n}\n\n/* This ensures a border is drawn around a dict\n   if its nested in another object. */\ndiv.ExecutionVisualizer td.stackElt table.dictTbl,\ndiv.ExecutionVisualizer td.stackLElt table.dictTbl,\ndiv.ExecutionVisualizer td.stackFElt table.dictTbl,\ndiv.ExecutionVisualizer td.queueElt table.dictTbl,\ndiv.ExecutionVisualizer td.queueLElt table.dictTbl,\ndiv.ExecutionVisualizer td.queueFElt table.dictTbl {\n  border: 1px #888 solid;\n}\n\n.symbolic {\n  font-size: 18pt;\n}\n\n/* END Java frontend by David Pritchard and Will Gwozdz */\n", ""]);

// exports


/***/ }),
/* 14 */
/***/ (function(module, exports, __webpack_require__) {

var escape = __webpack_require__(8);
exports = module.exports = __webpack_require__(2)(false);
// imports


// module
exports.push([module.i, "/*! jQuery UI - v1.11.4 - 2015-03-11\n* http://jqueryui.com\n* Includes: core.css, accordion.css, autocomplete.css, button.css, datepicker.css, dialog.css, draggable.css, menu.css, progressbar.css, resizable.css, selectable.css, selectmenu.css, slider.css, sortable.css, spinner.css, tabs.css, tooltip.css, theme.css\n* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS%2CTahoma%2CVerdana%2CArial%2Csans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=gloss_wave&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=highlight_soft&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=glass&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=glass&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=highlight_soft&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=diagonals_thick&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=diagonals_thick&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=flat&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px\n* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */\n\n/* Layout helpers\n----------------------------------*/\n.ui-helper-hidden {\n\tdisplay: none;\n}\n.ui-helper-hidden-accessible {\n\tborder: 0;\n\tclip: rect(0 0 0 0);\n\theight: 1px;\n\tmargin: -1px;\n\toverflow: hidden;\n\tpadding: 0;\n\tposition: absolute;\n\twidth: 1px;\n}\n.ui-helper-reset {\n\tmargin: 0;\n\tpadding: 0;\n\tborder: 0;\n\toutline: 0;\n\tline-height: 1.3;\n\ttext-decoration: none;\n\tfont-size: 100%;\n\tlist-style: none;\n}\n.ui-helper-clearfix:before,\n.ui-helper-clearfix:after {\n\tcontent: \"\";\n\tdisplay: table;\n\tborder-collapse: collapse;\n}\n.ui-helper-clearfix:after {\n\tclear: both;\n}\n.ui-helper-clearfix {\n\tmin-height: 0; /* support: IE7 */\n}\n.ui-helper-zfix {\n\twidth: 100%;\n\theight: 100%;\n\ttop: 0;\n\tleft: 0;\n\tposition: absolute;\n\topacity: 0;\n\tfilter:Alpha(Opacity=0); /* support: IE8 */\n}\n\n.ui-front {\n\tz-index: 100;\n}\n\n\n/* Interaction Cues\n----------------------------------*/\n.ui-state-disabled {\n\tcursor: default !important;\n}\n\n\n/* Icons\n----------------------------------*/\n\n/* states and images */\n.ui-icon {\n\tdisplay: block;\n\ttext-indent: -99999px;\n\toverflow: hidden;\n\tbackground-repeat: no-repeat;\n}\n\n\n/* Misc visuals\n----------------------------------*/\n\n/* Overlays */\n.ui-widget-overlay {\n\tposition: fixed;\n\ttop: 0;\n\tleft: 0;\n\twidth: 100%;\n\theight: 100%;\n}\n.ui-accordion .ui-accordion-header {\n\tdisplay: block;\n\tcursor: pointer;\n\tposition: relative;\n\tmargin: 2px 0 0 0;\n\tpadding: .5em .5em .5em .7em;\n\tmin-height: 0; /* support: IE7 */\n\tfont-size: 100%;\n}\n.ui-accordion .ui-accordion-icons {\n\tpadding-left: 2.2em;\n}\n.ui-accordion .ui-accordion-icons .ui-accordion-icons {\n\tpadding-left: 2.2em;\n}\n.ui-accordion .ui-accordion-header .ui-accordion-header-icon {\n\tposition: absolute;\n\tleft: .5em;\n\ttop: 50%;\n\tmargin-top: -8px;\n}\n.ui-accordion .ui-accordion-content {\n\tpadding: 1em 2.2em;\n\tborder-top: 0;\n\toverflow: auto;\n}\n.ui-autocomplete {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tcursor: default;\n}\n.ui-button {\n\tdisplay: inline-block;\n\tposition: relative;\n\tpadding: 0;\n\tline-height: normal;\n\tmargin-right: .1em;\n\tcursor: pointer;\n\tvertical-align: middle;\n\ttext-align: center;\n\toverflow: visible; /* removes extra width in IE */\n}\n.ui-button,\n.ui-button:link,\n.ui-button:visited,\n.ui-button:hover,\n.ui-button:active {\n\ttext-decoration: none;\n}\n/* to make room for the icon, a width needs to be set here */\n.ui-button-icon-only {\n\twidth: 2.2em;\n}\n/* button elements seem to need a little more width */\nbutton.ui-button-icon-only {\n\twidth: 2.4em;\n}\n.ui-button-icons-only {\n\twidth: 3.4em;\n}\nbutton.ui-button-icons-only {\n\twidth: 3.7em;\n}\n\n/* button text element */\n.ui-button .ui-button-text {\n\tdisplay: block;\n\tline-height: normal;\n}\n.ui-button-text-only .ui-button-text {\n\tpadding: .4em 1em;\n}\n.ui-button-icon-only .ui-button-text,\n.ui-button-icons-only .ui-button-text {\n\tpadding: .4em;\n\ttext-indent: -9999999px;\n}\n.ui-button-text-icon-primary .ui-button-text,\n.ui-button-text-icons .ui-button-text {\n\tpadding: .4em 1em .4em 2.1em;\n}\n.ui-button-text-icon-secondary .ui-button-text,\n.ui-button-text-icons .ui-button-text {\n\tpadding: .4em 2.1em .4em 1em;\n}\n.ui-button-text-icons .ui-button-text {\n\tpadding-left: 2.1em;\n\tpadding-right: 2.1em;\n}\n/* no icon support for input elements, provide padding by default */\ninput.ui-button {\n\tpadding: .4em 1em;\n}\n\n/* button icon element(s) */\n.ui-button-icon-only .ui-icon,\n.ui-button-text-icon-primary .ui-icon,\n.ui-button-text-icon-secondary .ui-icon,\n.ui-button-text-icons .ui-icon,\n.ui-button-icons-only .ui-icon {\n\tposition: absolute;\n\ttop: 50%;\n\tmargin-top: -8px;\n}\n.ui-button-icon-only .ui-icon {\n\tleft: 50%;\n\tmargin-left: -8px;\n}\n.ui-button-text-icon-primary .ui-button-icon-primary,\n.ui-button-text-icons .ui-button-icon-primary,\n.ui-button-icons-only .ui-button-icon-primary {\n\tleft: .5em;\n}\n.ui-button-text-icon-secondary .ui-button-icon-secondary,\n.ui-button-text-icons .ui-button-icon-secondary,\n.ui-button-icons-only .ui-button-icon-secondary {\n\tright: .5em;\n}\n\n/* button sets */\n.ui-buttonset {\n\tmargin-right: 7px;\n}\n.ui-buttonset .ui-button {\n\tmargin-left: 0;\n\tmargin-right: -.3em;\n}\n\n/* workarounds */\n/* reset extra padding in Firefox, see h5bp.com/l */\ninput.ui-button::-moz-focus-inner,\nbutton.ui-button::-moz-focus-inner {\n\tborder: 0;\n\tpadding: 0;\n}\n.ui-datepicker {\n\twidth: 17em;\n\tpadding: .2em .2em 0;\n\tdisplay: none;\n}\n.ui-datepicker .ui-datepicker-header {\n\tposition: relative;\n\tpadding: .2em 0;\n}\n.ui-datepicker .ui-datepicker-prev,\n.ui-datepicker .ui-datepicker-next {\n\tposition: absolute;\n\ttop: 2px;\n\twidth: 1.8em;\n\theight: 1.8em;\n}\n.ui-datepicker .ui-datepicker-prev-hover,\n.ui-datepicker .ui-datepicker-next-hover {\n\ttop: 1px;\n}\n.ui-datepicker .ui-datepicker-prev {\n\tleft: 2px;\n}\n.ui-datepicker .ui-datepicker-next {\n\tright: 2px;\n}\n.ui-datepicker .ui-datepicker-prev-hover {\n\tleft: 1px;\n}\n.ui-datepicker .ui-datepicker-next-hover {\n\tright: 1px;\n}\n.ui-datepicker .ui-datepicker-prev span,\n.ui-datepicker .ui-datepicker-next span {\n\tdisplay: block;\n\tposition: absolute;\n\tleft: 50%;\n\tmargin-left: -8px;\n\ttop: 50%;\n\tmargin-top: -8px;\n}\n.ui-datepicker .ui-datepicker-title {\n\tmargin: 0 2.3em;\n\tline-height: 1.8em;\n\ttext-align: center;\n}\n.ui-datepicker .ui-datepicker-title select {\n\tfont-size: 1em;\n\tmargin: 1px 0;\n}\n.ui-datepicker select.ui-datepicker-month,\n.ui-datepicker select.ui-datepicker-year {\n\twidth: 45%;\n}\n.ui-datepicker table {\n\twidth: 100%;\n\tfont-size: .9em;\n\tborder-collapse: collapse;\n\tmargin: 0 0 .4em;\n}\n.ui-datepicker th {\n\tpadding: .7em .3em;\n\ttext-align: center;\n\tfont-weight: bold;\n\tborder: 0;\n}\n.ui-datepicker td {\n\tborder: 0;\n\tpadding: 1px;\n}\n.ui-datepicker td span,\n.ui-datepicker td a {\n\tdisplay: block;\n\tpadding: .2em;\n\ttext-align: right;\n\ttext-decoration: none;\n}\n.ui-datepicker .ui-datepicker-buttonpane {\n\tbackground-image: none;\n\tmargin: .7em 0 0 0;\n\tpadding: 0 .2em;\n\tborder-left: 0;\n\tborder-right: 0;\n\tborder-bottom: 0;\n}\n.ui-datepicker .ui-datepicker-buttonpane button {\n\tfloat: right;\n\tmargin: .5em .2em .4em;\n\tcursor: pointer;\n\tpadding: .2em .6em .3em .6em;\n\twidth: auto;\n\toverflow: visible;\n}\n.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {\n\tfloat: left;\n}\n\n/* with multiple calendars */\n.ui-datepicker.ui-datepicker-multi {\n\twidth: auto;\n}\n.ui-datepicker-multi .ui-datepicker-group {\n\tfloat: left;\n}\n.ui-datepicker-multi .ui-datepicker-group table {\n\twidth: 95%;\n\tmargin: 0 auto .4em;\n}\n.ui-datepicker-multi-2 .ui-datepicker-group {\n\twidth: 50%;\n}\n.ui-datepicker-multi-3 .ui-datepicker-group {\n\twidth: 33.3%;\n}\n.ui-datepicker-multi-4 .ui-datepicker-group {\n\twidth: 25%;\n}\n.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,\n.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {\n\tborder-left-width: 0;\n}\n.ui-datepicker-multi .ui-datepicker-buttonpane {\n\tclear: left;\n}\n.ui-datepicker-row-break {\n\tclear: both;\n\twidth: 100%;\n\tfont-size: 0;\n}\n\n/* RTL support */\n.ui-datepicker-rtl {\n\tdirection: rtl;\n}\n.ui-datepicker-rtl .ui-datepicker-prev {\n\tright: 2px;\n\tleft: auto;\n}\n.ui-datepicker-rtl .ui-datepicker-next {\n\tleft: 2px;\n\tright: auto;\n}\n.ui-datepicker-rtl .ui-datepicker-prev:hover {\n\tright: 1px;\n\tleft: auto;\n}\n.ui-datepicker-rtl .ui-datepicker-next:hover {\n\tleft: 1px;\n\tright: auto;\n}\n.ui-datepicker-rtl .ui-datepicker-buttonpane {\n\tclear: right;\n}\n.ui-datepicker-rtl .ui-datepicker-buttonpane button {\n\tfloat: left;\n}\n.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,\n.ui-datepicker-rtl .ui-datepicker-group {\n\tfloat: right;\n}\n.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,\n.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {\n\tborder-right-width: 0;\n\tborder-left-width: 1px;\n}\n.ui-dialog {\n\toverflow: hidden;\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tpadding: .2em;\n\toutline: 0;\n}\n.ui-dialog .ui-dialog-titlebar {\n\tpadding: .4em 1em;\n\tposition: relative;\n}\n.ui-dialog .ui-dialog-title {\n\tfloat: left;\n\tmargin: .1em 0;\n\twhite-space: nowrap;\n\twidth: 90%;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n}\n.ui-dialog .ui-dialog-titlebar-close {\n\tposition: absolute;\n\tright: .3em;\n\ttop: 50%;\n\twidth: 20px;\n\tmargin: -10px 0 0 0;\n\tpadding: 1px;\n\theight: 20px;\n}\n.ui-dialog .ui-dialog-content {\n\tposition: relative;\n\tborder: 0;\n\tpadding: .5em 1em;\n\tbackground: none;\n\toverflow: auto;\n}\n.ui-dialog .ui-dialog-buttonpane {\n\ttext-align: left;\n\tborder-width: 1px 0 0 0;\n\tbackground-image: none;\n\tmargin-top: .5em;\n\tpadding: .3em 1em .5em .4em;\n}\n.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {\n\tfloat: right;\n}\n.ui-dialog .ui-dialog-buttonpane button {\n\tmargin: .5em .4em .5em 0;\n\tcursor: pointer;\n}\n.ui-dialog .ui-resizable-se {\n\twidth: 12px;\n\theight: 12px;\n\tright: -5px;\n\tbottom: -5px;\n\tbackground-position: 16px 16px;\n}\n.ui-draggable .ui-dialog-titlebar {\n\tcursor: move;\n}\n.ui-draggable-handle {\n\t-ms-touch-action: none;\n\ttouch-action: none;\n}\n.ui-menu {\n\tlist-style: none;\n\tpadding: 0;\n\tmargin: 0;\n\tdisplay: block;\n\toutline: none;\n}\n.ui-menu .ui-menu {\n\tposition: absolute;\n}\n.ui-menu .ui-menu-item {\n\tposition: relative;\n\tmargin: 0;\n\tpadding: 3px 1em 3px .4em;\n\tcursor: pointer;\n\tmin-height: 0; /* support: IE7 */\n\t/* support: IE10, see #8844 */\n\tlist-style-image: url(\"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\");\n}\n.ui-menu .ui-menu-divider {\n\tmargin: 5px 0;\n\theight: 0;\n\tfont-size: 0;\n\tline-height: 0;\n\tborder-width: 1px 0 0 0;\n}\n.ui-menu .ui-state-focus,\n.ui-menu .ui-state-active {\n\tmargin: -1px;\n}\n\n/* icon support */\n.ui-menu-icons {\n\tposition: relative;\n}\n.ui-menu-icons .ui-menu-item {\n\tpadding-left: 2em;\n}\n\n/* left-aligned */\n.ui-menu .ui-icon {\n\tposition: absolute;\n\ttop: 0;\n\tbottom: 0;\n\tleft: .2em;\n\tmargin: auto 0;\n}\n\n/* right-aligned */\n.ui-menu .ui-menu-icon {\n\tleft: auto;\n\tright: 0;\n}\n.ui-progressbar {\n\theight: 2em;\n\ttext-align: left;\n\toverflow: hidden;\n}\n.ui-progressbar .ui-progressbar-value {\n\tmargin: -1px;\n\theight: 100%;\n}\n.ui-progressbar .ui-progressbar-overlay {\n\tbackground: url(\"data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==\");\n\theight: 100%;\n\tfilter: alpha(opacity=25); /* support: IE8 */\n\topacity: 0.25;\n}\n.ui-progressbar-indeterminate .ui-progressbar-value {\n\tbackground-image: none;\n}\n.ui-resizable {\n\tposition: relative;\n}\n.ui-resizable-handle {\n\tposition: absolute;\n\tfont-size: 0.1px;\n\tdisplay: block;\n\t-ms-touch-action: none;\n\ttouch-action: none;\n}\n.ui-resizable-disabled .ui-resizable-handle,\n.ui-resizable-autohide .ui-resizable-handle {\n\tdisplay: none;\n}\n.ui-resizable-n {\n\tcursor: n-resize;\n\theight: 7px;\n\twidth: 100%;\n\ttop: -5px;\n\tleft: 0;\n}\n.ui-resizable-s {\n\tcursor: s-resize;\n\theight: 7px;\n\twidth: 100%;\n\tbottom: -5px;\n\tleft: 0;\n}\n.ui-resizable-e {\n\tcursor: e-resize;\n\twidth: 7px;\n\tright: -5px;\n\ttop: 0;\n\theight: 100%;\n}\n.ui-resizable-w {\n\tcursor: w-resize;\n\twidth: 7px;\n\tleft: -5px;\n\ttop: 0;\n\theight: 100%;\n}\n.ui-resizable-se {\n\tcursor: se-resize;\n\twidth: 12px;\n\theight: 12px;\n\tright: 1px;\n\tbottom: 1px;\n}\n.ui-resizable-sw {\n\tcursor: sw-resize;\n\twidth: 9px;\n\theight: 9px;\n\tleft: -5px;\n\tbottom: -5px;\n}\n.ui-resizable-nw {\n\tcursor: nw-resize;\n\twidth: 9px;\n\theight: 9px;\n\tleft: -5px;\n\ttop: -5px;\n}\n.ui-resizable-ne {\n\tcursor: ne-resize;\n\twidth: 9px;\n\theight: 9px;\n\tright: -5px;\n\ttop: -5px;\n}\n.ui-selectable {\n\t-ms-touch-action: none;\n\ttouch-action: none;\n}\n.ui-selectable-helper {\n\tposition: absolute;\n\tz-index: 100;\n\tborder: 1px dotted black;\n}\n.ui-selectmenu-menu {\n\tpadding: 0;\n\tmargin: 0;\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tdisplay: none;\n}\n.ui-selectmenu-menu .ui-menu {\n\toverflow: auto;\n\t/* Support: IE7 */\n\toverflow-x: hidden;\n\tpadding-bottom: 1px;\n}\n.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup {\n\tfont-size: 1em;\n\tfont-weight: bold;\n\tline-height: 1.5;\n\tpadding: 2px 0.4em;\n\tmargin: 0.5em 0 0 0;\n\theight: auto;\n\tborder: 0;\n}\n.ui-selectmenu-open {\n\tdisplay: block;\n}\n.ui-selectmenu-button {\n\tdisplay: inline-block;\n\toverflow: hidden;\n\tposition: relative;\n\ttext-decoration: none;\n\tcursor: pointer;\n}\n.ui-selectmenu-button span.ui-icon {\n\tright: 0.5em;\n\tleft: auto;\n\tmargin-top: -8px;\n\tposition: absolute;\n\ttop: 50%;\n}\n.ui-selectmenu-button span.ui-selectmenu-text {\n\ttext-align: left;\n\tpadding: 0.4em 2.1em 0.4em 1em;\n\tdisplay: block;\n\tline-height: 1.4;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n}\n.ui-slider {\n\tposition: relative;\n\ttext-align: left;\n}\n.ui-slider .ui-slider-handle {\n\tposition: absolute;\n\tz-index: 2;\n\twidth: 1.2em;\n\theight: 1.2em;\n\tcursor: default;\n\t-ms-touch-action: none;\n\ttouch-action: none;\n}\n.ui-slider .ui-slider-range {\n\tposition: absolute;\n\tz-index: 1;\n\tfont-size: .7em;\n\tdisplay: block;\n\tborder: 0;\n\tbackground-position: 0 0;\n}\n\n/* support: IE8 - See #6727 */\n.ui-slider.ui-state-disabled .ui-slider-handle,\n.ui-slider.ui-state-disabled .ui-slider-range {\n\tfilter: inherit;\n}\n\n.ui-slider-horizontal {\n\theight: .8em;\n}\n.ui-slider-horizontal .ui-slider-handle {\n\ttop: -.3em;\n\tmargin-left: -.6em;\n}\n.ui-slider-horizontal .ui-slider-range {\n\ttop: 0;\n\theight: 100%;\n}\n.ui-slider-horizontal .ui-slider-range-min {\n\tleft: 0;\n}\n.ui-slider-horizontal .ui-slider-range-max {\n\tright: 0;\n}\n\n.ui-slider-vertical {\n\twidth: .8em;\n\theight: 100px;\n}\n.ui-slider-vertical .ui-slider-handle {\n\tleft: -.3em;\n\tmargin-left: 0;\n\tmargin-bottom: -.6em;\n}\n.ui-slider-vertical .ui-slider-range {\n\tleft: 0;\n\twidth: 100%;\n}\n.ui-slider-vertical .ui-slider-range-min {\n\tbottom: 0;\n}\n.ui-slider-vertical .ui-slider-range-max {\n\ttop: 0;\n}\n.ui-sortable-handle {\n\t-ms-touch-action: none;\n\ttouch-action: none;\n}\n.ui-spinner {\n\tposition: relative;\n\tdisplay: inline-block;\n\toverflow: hidden;\n\tpadding: 0;\n\tvertical-align: middle;\n}\n.ui-spinner-input {\n\tborder: none;\n\tbackground: none;\n\tcolor: inherit;\n\tpadding: 0;\n\tmargin: .2em 0;\n\tvertical-align: middle;\n\tmargin-left: .4em;\n\tmargin-right: 22px;\n}\n.ui-spinner-button {\n\twidth: 16px;\n\theight: 50%;\n\tfont-size: .5em;\n\tpadding: 0;\n\tmargin: 0;\n\ttext-align: center;\n\tposition: absolute;\n\tcursor: default;\n\tdisplay: block;\n\toverflow: hidden;\n\tright: 0;\n}\n/* more specificity required here to override default borders */\n.ui-spinner a.ui-spinner-button {\n\tborder-top: none;\n\tborder-bottom: none;\n\tborder-right: none;\n}\n/* vertically center icon */\n.ui-spinner .ui-icon {\n\tposition: absolute;\n\tmargin-top: -8px;\n\ttop: 50%;\n\tleft: 0;\n}\n.ui-spinner-up {\n\ttop: 0;\n}\n.ui-spinner-down {\n\tbottom: 0;\n}\n\n/* TR overrides */\n.ui-spinner .ui-icon-triangle-1-s {\n\t/* need to fix icons sprite */\n\tbackground-position: -65px -16px;\n}\n.ui-tabs {\n\tposition: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as \"fixed\") */\n\tpadding: .2em;\n}\n.ui-tabs .ui-tabs-nav {\n\tmargin: 0;\n\tpadding: .2em .2em 0;\n}\n.ui-tabs .ui-tabs-nav li {\n\tlist-style: none;\n\tfloat: left;\n\tposition: relative;\n\ttop: 0;\n\tmargin: 1px .2em 0 0;\n\tborder-bottom-width: 0;\n\tpadding: 0;\n\twhite-space: nowrap;\n}\n.ui-tabs .ui-tabs-nav .ui-tabs-anchor {\n\tfloat: left;\n\tpadding: .5em 1em;\n\ttext-decoration: none;\n}\n.ui-tabs .ui-tabs-nav li.ui-tabs-active {\n\tmargin-bottom: -1px;\n\tpadding-bottom: 1px;\n}\n.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,\n.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,\n.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor {\n\tcursor: text;\n}\n.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor {\n\tcursor: pointer;\n}\n.ui-tabs .ui-tabs-panel {\n\tdisplay: block;\n\tborder-width: 0;\n\tpadding: 1em 1.4em;\n\tbackground: none;\n}\n.ui-tooltip {\n\tpadding: 8px;\n\tposition: absolute;\n\tz-index: 9999;\n\tmax-width: 300px;\n\t-webkit-box-shadow: 0 0 5px #aaa;\n\tbox-shadow: 0 0 5px #aaa;\n}\nbody .ui-tooltip {\n\tborder-width: 2px;\n}\n\n/* Component containers\n----------------------------------*/\n.ui-widget {\n\tfont-family: Trebuchet MS,Tahoma,Verdana,Arial,sans-serif;\n\tfont-size: 1.1em;\n}\n.ui-widget .ui-widget {\n\tfont-size: 1em;\n}\n.ui-widget input,\n.ui-widget select,\n.ui-widget textarea,\n.ui-widget button {\n\tfont-family: Trebuchet MS,Tahoma,Verdana,Arial,sans-serif;\n\tfont-size: 1em;\n}\n.ui-widget-content {\n\tborder: 1px solid #dddddd;\n\tbackground: #eeeeee url(" + escape(__webpack_require__(25)) + ") 50% top repeat-x;\n\tcolor: #333333;\n}\n.ui-widget-content a {\n\tcolor: #333333;\n}\n.ui-widget-header {\n\tborder: 1px solid #e78f08;\n\tbackground: #f6a828 url(" + escape(__webpack_require__(24)) + ") 50% 50% repeat-x;\n\tcolor: #ffffff;\n\tfont-weight: bold;\n}\n.ui-widget-header a {\n\tcolor: #ffffff;\n}\n\n/* Interaction states\n----------------------------------*/\n.ui-state-default,\n.ui-widget-content .ui-state-default,\n.ui-widget-header .ui-state-default {\n\tborder: 1px solid #cccccc;\n\tbackground: #f6f6f6 url(" + escape(__webpack_require__(21)) + ") 50% 50% repeat-x;\n\tfont-weight: bold;\n\tcolor: #1c94c4;\n}\n.ui-state-default a,\n.ui-state-default a:link,\n.ui-state-default a:visited {\n\tcolor: #1c94c4;\n\ttext-decoration: none;\n}\n.ui-state-hover,\n.ui-widget-content .ui-state-hover,\n.ui-widget-header .ui-state-hover,\n.ui-state-focus,\n.ui-widget-content .ui-state-focus,\n.ui-widget-header .ui-state-focus {\n\tborder: 1px solid #fbcb09;\n\tbackground: #fdf5ce url(" + escape(__webpack_require__(22)) + ") 50% 50% repeat-x;\n\tfont-weight: bold;\n\tcolor: #c77405;\n}\n.ui-state-hover a,\n.ui-state-hover a:hover,\n.ui-state-hover a:link,\n.ui-state-hover a:visited,\n.ui-state-focus a,\n.ui-state-focus a:hover,\n.ui-state-focus a:link,\n.ui-state-focus a:visited {\n\tcolor: #c77405;\n\ttext-decoration: none;\n}\n.ui-state-active,\n.ui-widget-content .ui-state-active,\n.ui-widget-header .ui-state-active {\n\tborder: 1px solid #fbd850;\n\tbackground: #ffffff url(" + escape(__webpack_require__(23)) + ") 50% 50% repeat-x;\n\tfont-weight: bold;\n\tcolor: #eb8f00;\n}\n.ui-state-active a,\n.ui-state-active a:link,\n.ui-state-active a:visited {\n\tcolor: #eb8f00;\n\ttext-decoration: none;\n}\n\n/* Interaction Cues\n----------------------------------*/\n.ui-state-highlight,\n.ui-widget-content .ui-state-highlight,\n.ui-widget-header .ui-state-highlight {\n\tborder: 1px solid #fed22f;\n\tbackground: #ffe45c url(" + escape(__webpack_require__(26)) + ") 50% top repeat-x;\n\tcolor: #363636;\n}\n.ui-state-highlight a,\n.ui-widget-content .ui-state-highlight a,\n.ui-widget-header .ui-state-highlight a {\n\tcolor: #363636;\n}\n.ui-state-error,\n.ui-widget-content .ui-state-error,\n.ui-widget-header .ui-state-error {\n\tborder: 1px solid #cd0a0a;\n\tbackground: #b81900 url(" + escape(__webpack_require__(18)) + ") 50% 50% repeat;\n\tcolor: #ffffff;\n}\n.ui-state-error a,\n.ui-widget-content .ui-state-error a,\n.ui-widget-header .ui-state-error a {\n\tcolor: #ffffff;\n}\n.ui-state-error-text,\n.ui-widget-content .ui-state-error-text,\n.ui-widget-header .ui-state-error-text {\n\tcolor: #ffffff;\n}\n.ui-priority-primary,\n.ui-widget-content .ui-priority-primary,\n.ui-widget-header .ui-priority-primary {\n\tfont-weight: bold;\n}\n.ui-priority-secondary,\n.ui-widget-content .ui-priority-secondary,\n.ui-widget-header .ui-priority-secondary {\n\topacity: .7;\n\tfilter:Alpha(Opacity=70); /* support: IE8 */\n\tfont-weight: normal;\n}\n.ui-state-disabled,\n.ui-widget-content .ui-state-disabled,\n.ui-widget-header .ui-state-disabled {\n\topacity: .35;\n\tfilter:Alpha(Opacity=35); /* support: IE8 */\n\tbackground-image: none;\n}\n.ui-state-disabled .ui-icon {\n\tfilter:Alpha(Opacity=35); /* support: IE8 - See #6059 */\n}\n\n/* Icons\n----------------------------------*/\n\n/* states and images */\n.ui-icon {\n\twidth: 16px;\n\theight: 16px;\n}\n.ui-icon,\n.ui-widget-content .ui-icon {\n\tbackground-image: url(" + escape(__webpack_require__(27)) + ");\n}\n.ui-widget-header .ui-icon {\n\tbackground-image: url(" + escape(__webpack_require__(30)) + ");\n}\n.ui-state-default .ui-icon {\n\tbackground-image: url(" + escape(__webpack_require__(5)) + ");\n}\n.ui-state-hover .ui-icon,\n.ui-state-focus .ui-icon {\n\tbackground-image: url(" + escape(__webpack_require__(5)) + ");\n}\n.ui-state-active .ui-icon {\n\tbackground-image: url(" + escape(__webpack_require__(5)) + ");\n}\n.ui-state-highlight .ui-icon {\n\tbackground-image: url(" + escape(__webpack_require__(28)) + ");\n}\n.ui-state-error .ui-icon,\n.ui-state-error-text .ui-icon {\n\tbackground-image: url(" + escape(__webpack_require__(29)) + ");\n}\n\n/* positioning */\n.ui-icon-blank { background-position: 16px 16px; }\n.ui-icon-carat-1-n { background-position: 0 0; }\n.ui-icon-carat-1-ne { background-position: -16px 0; }\n.ui-icon-carat-1-e { background-position: -32px 0; }\n.ui-icon-carat-1-se { background-position: -48px 0; }\n.ui-icon-carat-1-s { background-position: -64px 0; }\n.ui-icon-carat-1-sw { background-position: -80px 0; }\n.ui-icon-carat-1-w { background-position: -96px 0; }\n.ui-icon-carat-1-nw { background-position: -112px 0; }\n.ui-icon-carat-2-n-s { background-position: -128px 0; }\n.ui-icon-carat-2-e-w { background-position: -144px 0; }\n.ui-icon-triangle-1-n { background-position: 0 -16px; }\n.ui-icon-triangle-1-ne { background-position: -16px -16px; }\n.ui-icon-triangle-1-e { background-position: -32px -16px; }\n.ui-icon-triangle-1-se { background-position: -48px -16px; }\n.ui-icon-triangle-1-s { background-position: -64px -16px; }\n.ui-icon-triangle-1-sw { background-position: -80px -16px; }\n.ui-icon-triangle-1-w { background-position: -96px -16px; }\n.ui-icon-triangle-1-nw { background-position: -112px -16px; }\n.ui-icon-triangle-2-n-s { background-position: -128px -16px; }\n.ui-icon-triangle-2-e-w { background-position: -144px -16px; }\n.ui-icon-arrow-1-n { background-position: 0 -32px; }\n.ui-icon-arrow-1-ne { background-position: -16px -32px; }\n.ui-icon-arrow-1-e { background-position: -32px -32px; }\n.ui-icon-arrow-1-se { background-position: -48px -32px; }\n.ui-icon-arrow-1-s { background-position: -64px -32px; }\n.ui-icon-arrow-1-sw { background-position: -80px -32px; }\n.ui-icon-arrow-1-w { background-position: -96px -32px; }\n.ui-icon-arrow-1-nw { background-position: -112px -32px; }\n.ui-icon-arrow-2-n-s { background-position: -128px -32px; }\n.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }\n.ui-icon-arrow-2-e-w { background-position: -160px -32px; }\n.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }\n.ui-icon-arrowstop-1-n { background-position: -192px -32px; }\n.ui-icon-arrowstop-1-e { background-position: -208px -32px; }\n.ui-icon-arrowstop-1-s { background-position: -224px -32px; }\n.ui-icon-arrowstop-1-w { background-position: -240px -32px; }\n.ui-icon-arrowthick-1-n { background-position: 0 -48px; }\n.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }\n.ui-icon-arrowthick-1-e { background-position: -32px -48px; }\n.ui-icon-arrowthick-1-se { background-position: -48px -48px; }\n.ui-icon-arrowthick-1-s { background-position: -64px -48px; }\n.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }\n.ui-icon-arrowthick-1-w { background-position: -96px -48px; }\n.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }\n.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }\n.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }\n.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }\n.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }\n.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }\n.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }\n.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }\n.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }\n.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }\n.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }\n.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }\n.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }\n.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }\n.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }\n.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }\n.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }\n.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }\n.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }\n.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }\n.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }\n.ui-icon-arrow-4 { background-position: 0 -80px; }\n.ui-icon-arrow-4-diag { background-position: -16px -80px; }\n.ui-icon-extlink { background-position: -32px -80px; }\n.ui-icon-newwin { background-position: -48px -80px; }\n.ui-icon-refresh { background-position: -64px -80px; }\n.ui-icon-shuffle { background-position: -80px -80px; }\n.ui-icon-transfer-e-w { background-position: -96px -80px; }\n.ui-icon-transferthick-e-w { background-position: -112px -80px; }\n.ui-icon-folder-collapsed { background-position: 0 -96px; }\n.ui-icon-folder-open { background-position: -16px -96px; }\n.ui-icon-document { background-position: -32px -96px; }\n.ui-icon-document-b { background-position: -48px -96px; }\n.ui-icon-note { background-position: -64px -96px; }\n.ui-icon-mail-closed { background-position: -80px -96px; }\n.ui-icon-mail-open { background-position: -96px -96px; }\n.ui-icon-suitcase { background-position: -112px -96px; }\n.ui-icon-comment { background-position: -128px -96px; }\n.ui-icon-person { background-position: -144px -96px; }\n.ui-icon-print { background-position: -160px -96px; }\n.ui-icon-trash { background-position: -176px -96px; }\n.ui-icon-locked { background-position: -192px -96px; }\n.ui-icon-unlocked { background-position: -208px -96px; }\n.ui-icon-bookmark { background-position: -224px -96px; }\n.ui-icon-tag { background-position: -240px -96px; }\n.ui-icon-home { background-position: 0 -112px; }\n.ui-icon-flag { background-position: -16px -112px; }\n.ui-icon-calendar { background-position: -32px -112px; }\n.ui-icon-cart { background-position: -48px -112px; }\n.ui-icon-pencil { background-position: -64px -112px; }\n.ui-icon-clock { background-position: -80px -112px; }\n.ui-icon-disk { background-position: -96px -112px; }\n.ui-icon-calculator { background-position: -112px -112px; }\n.ui-icon-zoomin { background-position: -128px -112px; }\n.ui-icon-zoomout { background-position: -144px -112px; }\n.ui-icon-search { background-position: -160px -112px; }\n.ui-icon-wrench { background-position: -176px -112px; }\n.ui-icon-gear { background-position: -192px -112px; }\n.ui-icon-heart { background-position: -208px -112px; }\n.ui-icon-star { background-position: -224px -112px; }\n.ui-icon-link { background-position: -240px -112px; }\n.ui-icon-cancel { background-position: 0 -128px; }\n.ui-icon-plus { background-position: -16px -128px; }\n.ui-icon-plusthick { background-position: -32px -128px; }\n.ui-icon-minus { background-position: -48px -128px; }\n.ui-icon-minusthick { background-position: -64px -128px; }\n.ui-icon-close { background-position: -80px -128px; }\n.ui-icon-closethick { background-position: -96px -128px; }\n.ui-icon-key { background-position: -112px -128px; }\n.ui-icon-lightbulb { background-position: -128px -128px; }\n.ui-icon-scissors { background-position: -144px -128px; }\n.ui-icon-clipboard { background-position: -160px -128px; }\n.ui-icon-copy { background-position: -176px -128px; }\n.ui-icon-contact { background-position: -192px -128px; }\n.ui-icon-image { background-position: -208px -128px; }\n.ui-icon-video { background-position: -224px -128px; }\n.ui-icon-script { background-position: -240px -128px; }\n.ui-icon-alert { background-position: 0 -144px; }\n.ui-icon-info { background-position: -16px -144px; }\n.ui-icon-notice { background-position: -32px -144px; }\n.ui-icon-help { background-position: -48px -144px; }\n.ui-icon-check { background-position: -64px -144px; }\n.ui-icon-bullet { background-position: -80px -144px; }\n.ui-icon-radio-on { background-position: -96px -144px; }\n.ui-icon-radio-off { background-position: -112px -144px; }\n.ui-icon-pin-w { background-position: -128px -144px; }\n.ui-icon-pin-s { background-position: -144px -144px; }\n.ui-icon-play { background-position: 0 -160px; }\n.ui-icon-pause { background-position: -16px -160px; }\n.ui-icon-seek-next { background-position: -32px -160px; }\n.ui-icon-seek-prev { background-position: -48px -160px; }\n.ui-icon-seek-end { background-position: -64px -160px; }\n.ui-icon-seek-start { background-position: -80px -160px; }\n/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */\n.ui-icon-seek-first { background-position: -80px -160px; }\n.ui-icon-stop { background-position: -96px -160px; }\n.ui-icon-eject { background-position: -112px -160px; }\n.ui-icon-volume-off { background-position: -128px -160px; }\n.ui-icon-volume-on { background-position: -144px -160px; }\n.ui-icon-power { background-position: 0 -176px; }\n.ui-icon-signal-diag { background-position: -16px -176px; }\n.ui-icon-signal { background-position: -32px -176px; }\n.ui-icon-battery-0 { background-position: -48px -176px; }\n.ui-icon-battery-1 { background-position: -64px -176px; }\n.ui-icon-battery-2 { background-position: -80px -176px; }\n.ui-icon-battery-3 { background-position: -96px -176px; }\n.ui-icon-circle-plus { background-position: 0 -192px; }\n.ui-icon-circle-minus { background-position: -16px -192px; }\n.ui-icon-circle-close { background-position: -32px -192px; }\n.ui-icon-circle-triangle-e { background-position: -48px -192px; }\n.ui-icon-circle-triangle-s { background-position: -64px -192px; }\n.ui-icon-circle-triangle-w { background-position: -80px -192px; }\n.ui-icon-circle-triangle-n { background-position: -96px -192px; }\n.ui-icon-circle-arrow-e { background-position: -112px -192px; }\n.ui-icon-circle-arrow-s { background-position: -128px -192px; }\n.ui-icon-circle-arrow-w { background-position: -144px -192px; }\n.ui-icon-circle-arrow-n { background-position: -160px -192px; }\n.ui-icon-circle-zoomin { background-position: -176px -192px; }\n.ui-icon-circle-zoomout { background-position: -192px -192px; }\n.ui-icon-circle-check { background-position: -208px -192px; }\n.ui-icon-circlesmall-plus { background-position: 0 -208px; }\n.ui-icon-circlesmall-minus { background-position: -16px -208px; }\n.ui-icon-circlesmall-close { background-position: -32px -208px; }\n.ui-icon-squaresmall-plus { background-position: -48px -208px; }\n.ui-icon-squaresmall-minus { background-position: -64px -208px; }\n.ui-icon-squaresmall-close { background-position: -80px -208px; }\n.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }\n.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }\n.ui-icon-grip-solid-vertical { background-position: -32px -224px; }\n.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }\n.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }\n.ui-icon-grip-diagonal-se { background-position: -80px -224px; }\n\n\n/* Misc visuals\n----------------------------------*/\n\n/* Corner radius */\n.ui-corner-all,\n.ui-corner-top,\n.ui-corner-left,\n.ui-corner-tl {\n\tborder-top-left-radius: 4px;\n}\n.ui-corner-all,\n.ui-corner-top,\n.ui-corner-right,\n.ui-corner-tr {\n\tborder-top-right-radius: 4px;\n}\n.ui-corner-all,\n.ui-corner-bottom,\n.ui-corner-left,\n.ui-corner-bl {\n\tborder-bottom-left-radius: 4px;\n}\n.ui-corner-all,\n.ui-corner-bottom,\n.ui-corner-right,\n.ui-corner-br {\n\tborder-bottom-right-radius: 4px;\n}\n\n/* Overlays */\n.ui-widget-overlay {\n\tbackground: #666666 url(" + escape(__webpack_require__(19)) + ") 50% 50% repeat;\n\topacity: .5;\n\tfilter: Alpha(Opacity=50); /* support: IE8 */\n}\n.ui-widget-shadow {\n\tmargin: -5px 0 0 -5px;\n\tpadding: 5px;\n\tbackground: #000000 url(" + escape(__webpack_require__(20)) + ") 50% 50% repeat-x;\n\topacity: .2;\n\tfilter: Alpha(Opacity=20); /* support: IE8 */\n\tborder-radius: 5px;\n}\n", ""]);

// exports


/***/ }),
/* 15 */
/***/ (function(module, exports, __webpack_require__) {


var content = __webpack_require__(13);

if(typeof content === 'string') content = [[module.i, content, '']];

var transform;
var insertInto;



var options = {"hmr":true}

options.transform = transform
options.insertInto = undefined;

var update = __webpack_require__(3)(content, options);

if(content.locals) module.exports = content.locals;

if(false) {
	module.hot.accept("!!../node_modules/css-loader/index.js!./pytutor.css", function() {
		var newContent = require("!!../node_modules/css-loader/index.js!./pytutor.css");

		if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];

		var locals = (function(a, b) {
			var key, idx = 0;

			for(key in a) {
				if(!b || a[key] !== b[key]) return false;
				idx++;
			}

			for(key in b) idx--;

			return idx === 0;
		}(content.locals, newContent.locals));

		if(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');

		update(newContent);
	});

	module.hot.dispose(function() { update(); });
}

/***/ }),
/* 16 */
/***/ (function(module, exports, __webpack_require__) {


var content = __webpack_require__(14);

if(typeof content === 'string') content = [[module.i, content, '']];

var transform;
var insertInto;



var options = {"hmr":true}

options.transform = transform
options.insertInto = undefined;

var update = __webpack_require__(3)(content, options);

if(content.locals) module.exports = content.locals;

if(false) {
	module.hot.accept("!!../../../node_modules/css-loader/index.js!./jquery-ui.css", function() {
		var newContent = require("!!../../../node_modules/css-loader/index.js!./jquery-ui.css");

		if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];

		var locals = (function(a, b) {
			var key, idx = 0;

			for(key in a) {
				if(!b || a[key] !== b[key]) return false;
				idx++;
			}

			for(key in b) idx--;

			return idx === 0;
		}(content.locals, newContent.locals));

		if(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');

		update(newContent);
	});

	module.hot.dispose(function() { update(); });
}

/***/ }),
/* 17 */
/***/ (function(module, exports) {


/**
 * When source maps are enabled, `style-loader` uses a link element with a data-uri to
 * embed the css on the page. This breaks all relative urls because now they are relative to a
 * bundle instead of the current page.
 *
 * One solution is to only use full urls, but that may be impossible.
 *
 * Instead, this function "fixes" the relative urls to be absolute according to the current page location.
 *
 * A rudimentary test suite is located at `test/fixUrls.js` and can be run via the `npm test` command.
 *
 */

module.exports = function (css) {
  // get current location
  var location = typeof window !== "undefined" && window.location;

  if (!location) {
    throw new Error("fixUrls requires window.location");
  }

	// blank or null?
	if (!css || typeof css !== "string") {
	  return css;
  }

  var baseUrl = location.protocol + "//" + location.host;
  var currentDir = baseUrl + location.pathname.replace(/\/[^\/]*$/, "/");

	// convert each url(...)
	/*
	This regular expression is just a way to recursively match brackets within
	a string.

	 /url\s*\(  = Match on the word "url" with any whitespace after it and then a parens
	   (  = Start a capturing group
	     (?:  = Start a non-capturing group
	         [^)(]  = Match anything that isn't a parentheses
	         |  = OR
	         \(  = Match a start parentheses
	             (?:  = Start another non-capturing groups
	                 [^)(]+  = Match anything that isn't a parentheses
	                 |  = OR
	                 \(  = Match a start parentheses
	                     [^)(]*  = Match anything that isn't a parentheses
	                 \)  = Match a end parentheses
	             )  = End Group
              *\) = Match anything and then a close parens
          )  = Close non-capturing group
          *  = Match anything
       )  = Close capturing group
	 \)  = Match a close parens

	 /gi  = Get all matches, not the first.  Be case insensitive.
	 */
	var fixedCss = css.replace(/url\s*\(((?:[^)(]|\((?:[^)(]+|\([^)(]*\))*\))*)\)/gi, function(fullMatch, origUrl) {
		// strip quotes (if they exist)
		var unquotedOrigUrl = origUrl
			.trim()
			.replace(/^"(.*)"$/, function(o, $1){ return $1; })
			.replace(/^'(.*)'$/, function(o, $1){ return $1; });

		// already a full url? no change
		if (/^(#|data:|http:\/\/|https:\/\/|file:\/\/\/|\s*$)/i.test(unquotedOrigUrl)) {
		  return fullMatch;
		}

		// convert the url to a full url
		var newUrl;

		if (unquotedOrigUrl.indexOf("//") === 0) {
		  	//TODO: should we add protocol?
			newUrl = unquotedOrigUrl;
		} else if (unquotedOrigUrl.indexOf("/") === 0) {
			// path should be relative to the base url
			newUrl = baseUrl + unquotedOrigUrl; // already starts with '/'
		} else {
			// path should be relative to current directory
			newUrl = currentDir + unquotedOrigUrl.replace(/^\.\//, ""); // Strip leading './'
		}

		// send back the fixed url(...)
		return "url(" + JSON.stringify(newUrl) + ")";
	});

	// send back the fixed css
	return fixedCss;
};


/***/ }),
/* 18 */
/***/ (function(module, exports) {

module.exports = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAIAAABTDPN5AAAABmJLR0T///////8JWPfcAAAACXBIWXMAAABIAAAASABGyWs+AAAA4ElEQVRo3u3YMQoCMRBG4c02XkCQLcXKwsN5Eq+znScRa8FasLP4q0DGZASLecmr0mSHr9tMuh5Pr91+MnpfnofHfXK2OW9v9jdb+t/cuR+qCaZSC2A2NQP3QFVpXZfFfy0iVc3eC3GpmusAR6fq3ARmUJvAJGoFzKOaYCq1AGZTM3APVJW+v5ZIVOX+8YhL1dwfwRGpOrvBcalucHSqA8ygNoFJ1AqYRzXBVGoBzKZm4B6oauy0uNSx06JTm8AkagXMo5pgKrUAZlMzcA9UNXZaXOrYadGpbnB0qgPMoKoPsn/eaLRwj54AAAAldEVYdGRhdGU6Y3JlYXRlADIwMTUtMDMtMTFUMDg6NDk6MzUtMDc6MDA6ngyxAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE1LTAzLTExVDA4OjQ5OjM1LTA3OjAwS8O0DQAAAABJRU5ErkJggg=="

/***/ }),
/* 19 */
/***/ (function(module, exports) {

module.exports = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoEAAAAAD5BTvyAAAAAmJLR0T//xSrMc0AAAAJcEhZcwAAAEgAAABIAEbJaz4AAAB6SURBVEjH7dXLEYAgDEVRqk0HNmpFMgxi+Lnw3Z0hSzJnmZuO8x6b3vPn530vsVwDKa6CHFdAkssgyy1AjTNLLDeAOteBBOdAhmsgxVWQ4wpIchlkuQ34nXPni+EWoMZNoMoNoM51IMFFU3QumqJz0RSdi6bo3C+bcgHap6IryOSd+AAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNS0wMy0xMVQwODo0OTozNS0wNzowMDqeDLEAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTUtMDMtMTFUMDg6NDk6MzUtMDc6MDBLw7QNAAAAAElFTkSuQmCC"

/***/ }),
/* 20 */
/***/ (function(module, exports) {

module.exports = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAABkAQAAAADcH0/XAAAAAmJLR0QAAd2KE6QAAAAJcEhZcwAAAEgAAABIAEbJaz4AAAAPSURBVCjPY2AYBaOA+gAAAlgAAXU2hncAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTUtMDMtMTFUMDg6NDk6MzUtMDc6MDA6ngyxAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE1LTAzLTExVDA4OjQ5OjM1LTA3OjAwS8O0DQAAAABJRU5ErkJggg=="

/***/ }),
/* 21 */
/***/ (function(module, exports) {

module.exports = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAGQEAAAAAAao4lEAAAAAmJLR0T//xSrMc0AAAAJcEhZcwAAAEgAAABIAEbJaz4AAABISURBVDjLY/g1mWEUjSKqo2/fGL5LMXzPYfh+nOGHFsOPBQw/xRh+TmX4JcLwq4vhNwPD71yG3xcZ/igx/Ilk+JM0ikYRMQgA8pJH3iOhTlAAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTUtMDMtMTFUMDg6NDk6MzQtMDc6MDCc6QcFAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE1LTAzLTExVDA4OjQ5OjM0LTA3OjAw7bS/uQAAAABJRU5ErkJggg=="

/***/ }),
/* 22 */
/***/ (function(module, exports) {

module.exports = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAGQEAIAAACwqkHPAAAABmJLR0T///////8JWPfcAAAACXBIWXMAAABIAAAASABGyWs+AAAAmklEQVRIx+3PPwsBARgH4N/7s0gmXZSuKMvNdl/AV2A1X1ltzBaf5UazEp3RpKujFMV0uT/dy6cQwzs98wPdZVk8IwAAhmEYxrdBWSZJGFKq4smGaGDENeFgwgfREp8d6Ph1OEZEWxaVOXSVRieHcGXJALrNnvEQes6nlz20yO9Xl9IUn128e0VwS4k6BvQIoob+X6QNwzB+yAca/jJVRVy4gQAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNS0wMy0xMVQwODo0OTozNS0wNzowMDqeDLEAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTUtMDMtMTFUMDg6NDk6MzUtMDc6MDBLw7QNAAAAAElFTkSuQmCC"

/***/ }),
/* 23 */
/***/ (function(module, exports) {

module.exports = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAGQAQAAAABHIzd2AAAAAmJLR0QAAd2KE6QAAAAJcEhZcwAAAEgAAABIAEbJaz4AAAARSURBVCjPY2hgGIWjcBTigACVaMgB0zSxaQAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNS0wMy0xMVQwODo0OTozNC0wNzowMJzpBwUAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTUtMDMtMTFUMDg6NDk6MzQtMDc6MDDttL+5AAAAAElFTkSuQmCC"

/***/ }),
/* 24 */
/***/ (function(module, exports) {

module.exports = "data:image/png;base64,[encoded data, 7756 characters]"

/***/ }),
/* 25 */
/***/ (function(module, exports) {

module.exports = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAABkEAAAAAAy19n/AAAAAmJLR0T//xSrMc0AAAAJcEhZcwAAAEgAAABIAEbJaz4AAABYSURBVBjTxcK9DUBAAIDRjxk0dBQaE4gR7KFVM4rEDBIjEKVV7s79OZ0teHk8FR/NCAehJ6TcK3eD3/EtbsPV2AVbYmZMgh7RMdfAFaEmVIE8kR0yR4gfv1IulNTJHsTLAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE1LTAzLTExVDA4OjQ5OjM0LTA3OjAwnOkHBQAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNS0wMy0xMVQwODo0OTozNC0wNzowMO20v7kAAAAASUVORK5CYII="

/***/ }),
/* 26 */
/***/ (function(module, exports) {

module.exports = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAABkEAIAAACY3hF0AAAABmJLR0T///////8JWPfcAAAACXBIWXMAAABIAAAASABGyWs+AAAAhklEQVQoz+WQMQrCUBBEH1NaCzaxTc7iHcwhcoiktP6kS8BK8BIWHkYQrM1mLD5Bb6Bg9Xg7syws9mNztADgj3CjFbifk4A+0od1UWDfr2kloJkGgZsYBdRTKfB+qgTOtgzrqHJWCtg9T++9pdnEIHAb22yjwPk6XRQCzvNa4IsP3//ST+MF5uU/iXGyfBoAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTUtMDMtMTFUMDg6NDk6MzUtMDc6MDA6ngyxAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE1LTAzLTExVDA4OjQ5OjM1LTA3OjAwS8O0DQAAAABJRU5ErkJggg=="

/***/ }),
/* 27 */
/***/ (function(module, exports) {

module.exports = "data:image/png;base64,[encoded data, 9232 characters]"

/***/ }),
/* 28 */
/***/ (function(module, exports) {

module.exports = "data:image/png;base64,[encoded data, 6068 characters]"

/***/ }),
/* 29 */
/***/ (function(module, exports) {

module.exports = "data:image/png;base64,[encoded data, 6068 characters]"

/***/ }),
/* 30 */
/***/ (function(module, exports) {

module.exports = "data:image/png;base64,[encoded data, 8400 characters]"

/***/ }),
/* 31 */
/***/ (function(module, exports) {

/* WEBPACK VAR INJECTION */(function(__webpack_amd_options__) {/* globals __webpack_amd_options__ */
module.exports = __webpack_amd_options__;

/* WEBPACK VAR INJECTION */}.call(exports, {}))

/***/ }),
/* 32 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
/* WEBPACK VAR INJECTION */(function($) {
// Python Tutor: https://github.com/pgbovine/OnlinePythonTutor/
// Copyright (C) Philip Guo (philip@pgbovine.net)
// LICENSE: https://github.com/pgbovine/OnlinePythonTutor/blob/master/LICENSE.txt
Object.defineProperty(exports, "__esModule", { value: true });
/// <reference path="_references.ts" />
__webpack_require__(36);
__webpack_require__(7);
// need to directly import the class for type checking to work
var pytutor_1 = __webpack_require__(4);
var footer_html_1 = __webpack_require__(6);
// the main event!
//
// NB: this still relies on global state such as localStorage and the
// browser URL hash string, so you still can't have more than one of these
// objects per page; should still be instantiated as a SINGLETON
var AbstractBaseFrontend = /** @class */ (function () {
    function AbstractBaseFrontend(params) {
        var _this = this;
        if (params === void 0) { params = {}; }
        this.sessionUUID = generateUUID(); // remains constant throughout one page load ("session")
        // a cache where each element is a pair:
        // [appState, cached execution trace]
        // that way, if you execute the same code with the same settings again and
        // get a cache hit, then there's no need to make a server call
        this.traceCache = [];
        // 'edit' or 'display'. also support 'visualize' for backward
        // compatibility (same as 'display')
        this.appMode = 'edit';
        // inputted by user for raw_input / mouse_input events
        this.rawInputLst = [];
        this.isExecutingCode = false;
        // optional: not all frontends keep track of deltas
        this.dmp = new diff_match_patch();
        this.curCode = ''; // for dmp snapshots, kinda kludgy
        this.deltaObj = undefined;
        this.num414Tries = 0;
        // note that we use '2' and '3' instead of 'py2' and 'py3' due to legacy reasons
        this.langSettingToBackendScript = {
            // backend scripts to execute (Python 2 and 3 variants, if available)
            // make two copies of ../web_exec.py and give them the following names,
            // then change the first line (starting with #!) to the proper version
            // of the Python interpreter (i.e., Python 2 or Python 3).
            // Note that your hosting provider might have stringent rules for what
            // kind of scripts are allowed to execute. For instance, my provider
            // (Webfaction) seems to let scripts execute only if permissions are
            // something like:
            // -rwxr-xr-x 1 pgbovine pgbovine 2.5K Jul  5 22:46 web_exec_py2.py*
            // (most notably, only the owner of the file should have write
            //  permissions)
            '2': 'web_exec_py2.py',
            '3': 'web_exec_py3.py',
            // empty dummy scripts just to do logging on Apache server
            'js': 'web_exec_js.py',
            'ts': 'web_exec_ts.py',
            'java': 'web_exec_java.py',
            'ruby': 'web_exec_ruby.py',
            'c': 'web_exec_c.py',
            'cpp': 'web_exec_cpp.py',
            // experimental!
            'py3anaconda': 'web_exec_py3anaconda.py',
        };
        // these settings are all customized for my own server setup,
        // so you will need to customize for your server:
        this.serverRoot = (window.location.protocol === 'https:') ?
            'https://cokapi.com/' : // my certificate for https is registered via cokapi.com, so use it for now
            'http://cokapi.com/'; // try cokapi.com so that hopefully it works through firewalls better than directly using its IP addr (which should be 104.237.139.253)
        // (but that's just an unsubstantiated hunch)
        // randomly pick one backup server to load balance:
        this.backupHttpServerRoot = (Math.random() >= 0.5) ? 'http://45.33.41.179/' : 'http://23.239.12.25/';
        // see ../../v4-cokapi/cokapi.js for details
        this.langSettingToJsonpEndpoint = {
            '2': null,
            '3': null,
            'js': this.serverRoot + 'exec_js_jsonp',
            'ts': this.serverRoot + 'exec_ts_jsonp',
            'java': this.serverRoot + 'exec_java_jsonp',
            'ruby': this.serverRoot + 'exec_ruby_jsonp',
            'c': this.serverRoot + 'exec_c_jsonp',
            'cpp': this.serverRoot + 'exec_cpp_jsonp',
            'py3anaconda': this.serverRoot + 'exec_pyanaconda_jsonp',
        };
        this.langSettingToJsonpEndpointBackup = {
            '2': null,
            '3': null,
            'js': this.backupHttpServerRoot + 'exec_js_jsonp',
            'ts': this.backupHttpServerRoot + 'exec_ts_jsonp',
            'java': this.backupHttpServerRoot + 'exec_java_jsonp',
            'ruby': this.backupHttpServerRoot + 'exec_ruby_jsonp',
            'c': this.backupHttpServerRoot + 'exec_c_jsonp',
            'cpp': this.backupHttpServerRoot + 'exec_cpp_jsonp',
            'py3anaconda': this.backupHttpServerRoot + 'exec_pyanaconda_jsonp',
        };
        if (supports_html5_storage()) {
            // generate a unique UUID per "user" (as indicated by a single browser
            // instance on a user's machine, which can be more precise than IP
            // addresses due to sharing of IP addresses within, say, a school
            // computer lab)
            // added on 2015-01-27 for more precise user identification
            if (!localStorage.getItem('opt_uuid')) {
                localStorage.setItem('opt_uuid', generateUUID());
            }
            this.userUUID = localStorage.getItem('opt_uuid');
            pytutor_1.assert(this.userUUID);
        }
        else {
            this.userUUID = undefined;
        }
        // register a generic AJAX error handler
        $(document).ajaxError(function (evt, jqxhr, settings, exception) {
            if (_this.ignoreAjaxError(settings)) {
                return; // early return!
            }
            // On my server ...
            // This jqxhr.responseText might mean the URL is too long, since the error
            // message returned by the server is something like this in nginx:
            //
            //   <html>
            //   <head><title>414 Request-URI Too Large</title></head>
            //   <body bgcolor="white">
            //   <center><h1>414 Request-URI Too Large</h1></center>
            //   <hr><center>nginx</center>
            //   </body>
            //   </html>
            //
            // Note that you'll probably need to customize this check for your server.
            if (jqxhr && jqxhr.responseText && jqxhr.responseText.indexOf('414') >= 0) {
                // ok this is an UBER UBER hack. If this happens just once, then
                // force click the "Visualize Execution" button again and re-try.
                // why? what's the difference the second time around? the diffs_json
                // parameter (derived from deltaObj) will be *empty* the second time
                // around since it gets reset on every execution. if diffs_json is
                // HUGE, then that might force the URL to be too big without your
                // code necessarily being too big, so give it a second shot with an
                // empty diffs_json. if it STILL fails, then display the error
                // message and give up.
                if (_this.num414Tries === 0) {
                    _this.num414Tries++;
                    $("#executeBtn").click();
                }
                else {
                    _this.setFronendError(["Server error! Your code might be too long for this tool. Shorten your code and re-try. [#CodeTooLong]"]);
                    _this.num414Tries = 0; // reset this to 0 AFTER setFronendError so that in setFronendError we can know that it's a 414 error (super hacky!)
                }
            }
            else {
                _this.setFronendError(["Server error! Your code might have an INFINITE LOOP or be running for too long.",
                    "The server may also be OVERLOADED. Or you're behind a FIREWALL that blocks access.",
                    "Try again later. This site is free with NO technical support. [#UnknownServerError]"]);
            }
            _this.doneExecutingCode();
        });
        this.clearFrontendError();
        $("#embedLinkDiv").hide();
        $("#executeBtn")
            .attr('disabled', false)
            .click(this.executeCodeFromScratch.bind(this));
    }
    AbstractBaseFrontend.prototype.ignoreAjaxError = function (settings) { return false; }; // subclasses should override
    // empty stub so that our code doesn't crash.
    // TODO: override this with a version in codeopticon-learner.js if needed
    AbstractBaseFrontend.prototype.logEventCodeopticon = function (obj) { }; // NOP
    AbstractBaseFrontend.prototype.getAppState = function () { return {}; }; // NOP -- subclasses need to override
    AbstractBaseFrontend.prototype.setFronendError = function (lines, ignoreLog) {
        if (ignoreLog === void 0) { ignoreLog = false; }
        $("#frontendErrorOutput").html(lines.map(pytutor_1.htmlspecialchars).join('<br/>') +
            (ignoreLog ? '' : '<p/>(' + footer_html_1.unsupportedFeaturesStr + ')'));
        // log it to the server as well (unless ignoreLog is on)
        if (!ignoreLog) {
            var errorStr = lines.join();
            var myArgs = this.getAppState();
            myArgs.opt_uuid = this.userUUID;
            myArgs.session_uuid = this.sessionUUID;
            myArgs.error_msg = errorStr;
            // very subtle! if you have a 414 error, that means your original
            // code was too long to fit in the URL, so CLEAR THE FULL CODE from
            // myArgs, or else it will generate a URL that will give a 414 again
            // when you run error_log.py!!! this relies on this.num414Tries not
            // being reset yet at this point:
            if (this.num414Tries > 0) {
                myArgs.code = '#CodeTooLong: ' + String(myArgs.code.length) + ' bytes';
            }
            $.get('error_log.py', myArgs, function (dat) { }); // added this logging feature on 2018-02-18
        }
    };
    AbstractBaseFrontend.prototype.clearFrontendError = function () {
        $("#frontendErrorOutput").html('');
    };
    // parsing the URL query string hash
    AbstractBaseFrontend.prototype.getQueryStringOptions = function () {
        var ril = $.bbq.getState('rawInputLstJSON');
        var testCasesLstJSON = $.bbq.getState('testCasesJSON');
        // note that any of these can be 'undefined'
        return { preseededCode: $.bbq.getState('code'),
            preseededCurInstr: Number($.bbq.getState('curInstr')),
            verticalStack: $.bbq.getState('verticalStack'),
            appMode: $.bbq.getState('mode'),
            py: $.bbq.getState('py'),
            cumulative: $.bbq.getState('cumulative'),
            heapPrimitives: $.bbq.getState('heapPrimitives'),
            textReferences: $.bbq.getState('textReferences'),
            rawInputLst: ril ? $.parseJSON(ril) : undefined,
            demoMode: $.bbq.getState('demo'),
            codcastFile: $.bbq.getState('codcast'),
            codeopticonSession: $.bbq.getState('cosession'),
            codeopticonUsername: $.bbq.getState('couser'),
            testCasesLst: testCasesLstJSON ? $.parseJSON(testCasesLstJSON) : undefined
        };
    };
    AbstractBaseFrontend.prototype.redrawConnectors = function () {
        if (this.myVisualizer &&
            (this.appMode == 'display' ||
                this.appMode == 'visualize' /* deprecated */)) {
            this.myVisualizer.redrawConnectors();
        }
    };
    AbstractBaseFrontend.prototype.getBaseBackendOptionsObj = function () {
        var ret = { cumulative_mode: ($('#cumulativeModeSelector').val() == 'true'),
            heap_primitives: ($('#heapPrimitivesSelector').val() == 'true'),
            show_only_outputs: false,
            origin: this.originFrontendJsFile };
        return ret;
    };
    AbstractBaseFrontend.prototype.getBaseFrontendOptionsObj = function () {
        var ret = {
            disableHeapNesting: (($('#heapPrimitivesSelector').val() == 'true') ||
                ($('#heapPrimitivesSelector').val() == 'nevernest')),
            textualMemoryLabels: ($('#textualMemoryLabelsSelector').val() == 'true'),
            executeCodeWithRawInputFunc: this.executeCodeWithRawInput.bind(this),
            // always use the same visualizer ID for all
            // instantiated ExecutionVisualizer objects,
            // so that they can sync properly across
            // multiple clients using TogetherJS in shared sessions.
            // this shouldn't lead to problems since only ONE
            // ExecutionVisualizer will be shown at a time
            visualizerIdOverride: '1',
            updateOutputCallback: this.updateOutputCallbackFunc.bind(this),
            startingInstruction: 0,
        };
        return ret;
    };
    AbstractBaseFrontend.prototype.updateOutputCallbackFunc = function () {
        $('#urlOutput,#urlOutputShortened,#embedCodeOutput').val('');
    };
    AbstractBaseFrontend.prototype.executeCodeFromScratch = function () {
        this.rawInputLst = []; // reset!
        this.executeCode();
    };
    AbstractBaseFrontend.prototype.executeCodeWithRawInput = function (rawInputStr, curInstr) {
        this.rawInputLst.push(rawInputStr);
        this.executeCode(curInstr);
    };
    AbstractBaseFrontend.prototype.startExecutingCode = function (startingInstruction) {
        if (startingInstruction === void 0) { startingInstruction = 0; }
        $('#executeBtn').html("Please wait ... executing (takes up to 10 seconds)");
        $('#executeBtn').attr('disabled', true);
        this.isExecutingCode = true;
    };
    AbstractBaseFrontend.prototype.doneExecutingCode = function () {
        $('#executeBtn').html("Visualize Execution");
        $('#executeBtn').attr('disabled', false);
        this.isExecutingCode = false;
    };
    // execute codeToExec and create a new ExecutionVisualizer
    // object with outputDiv as its DOM parent
    AbstractBaseFrontend.prototype.executeCodeAndCreateViz = function (codeToExec, pyState, backendOptionsObj, frontendOptionsObj, outputDiv) {
        var _this = this;
        var vizCallback = function (dataFromBackend) {
            var trace = dataFromBackend.trace;
            // don't enter visualize mode if there are killer errors:
            if (!trace ||
                (trace.length == 0) ||
                (trace[trace.length - 1].event == 'uncaught_exception')) {
                _this.handleUncaughtException(trace);
                if (trace.length == 1) {
                    _this.setFronendError([trace[0].exception_msg]);
                }
                else if (trace.length > 0 && trace[trace.length - 1].exception_msg) {
                    _this.setFronendError([trace[trace.length - 1].exception_msg]);
                }
                else {
                    _this.setFronendError(footer_html_1.nullTraceErrorLst);
                }
            }
            else {
                // fail-soft to prevent running off of the end of trace
                if (frontendOptionsObj.startingInstruction >= trace.length) {
                    frontendOptionsObj.startingInstruction = 0;
                }
                if (frontendOptionsObj.runTestCaseCallback) {
                    // hacky! DO NOT actually create a visualization! instead call:
                    frontendOptionsObj.runTestCaseCallback(trace);
                }
                else {
                    // success!
                    _this.myVisualizer = new pytutor_1.ExecutionVisualizer(outputDiv, dataFromBackend, frontendOptionsObj);
                    // SUPER HACK -- slip in backendOptionsObj as an extra field
                    // NB: why do we do this? for more detailed logging?
                    _this.myVisualizer.backendOptionsObj = backendOptionsObj;
                    _this.finishSuccessfulExecution(); // TODO: should we also run this if we're calling runTestCaseCallback?
                }
            }
        };
        this.executeCodeAndRunCallback(codeToExec, pyState, backendOptionsObj, frontendOptionsObj, vizCallback.bind(this));
    };
    // execute code and call the execCallback function when the server
    // returns data via Ajax
    AbstractBaseFrontend.prototype.executeCodeAndRunCallback = function (codeToExec, pyState, backendOptionsObj, frontendOptionsObj, execCallback) {
        var _this = this;
        var callbackWrapper = function (dataFromBackend) {
            _this.clearFrontendError(); // clear old errors first; execCallback may put in a new error:
            execCallback(dataFromBackend); // call the main event first
            // run this at the VERY END after all the dust has settled
            _this.doneExecutingCode(); // rain or shine, we're done executing!
            // tricky hacky reset
            _this.num414Tries = 0;
        };
        var backendScript = this.langSettingToBackendScript[pyState];
        pytutor_1.assert(backendScript);
        var jsonp_endpoint = this.langSettingToJsonpEndpoint[pyState]; // maybe null
        if (!backendScript) {
            this.setFronendError(["Server configuration error: No backend script"]);
            return;
        }
        this.clearFrontendError();
        this.startExecutingCode(frontendOptionsObj.startingInstruction);
        frontendOptionsObj.lang = pyState;
        // kludgy exceptions
        if (pyState === '2') {
            frontendOptionsObj.lang = 'py2';
        }
        else if (pyState === '3') {
            frontendOptionsObj.lang = 'py3';
        }
        else if (pyState === 'java') {
            // TODO: should we still keep this exceptional case?
            frontendOptionsObj.disableHeapNesting = true; // never nest Java objects, seems like a good default
        }
        // if we don't have any deltas, then don't bother sending deltaObj:
        // NB: not all subclasses will initialize this.deltaObj
        var deltaObjStringified = (this.deltaObj && (this.deltaObj.deltas.length > 0)) ? JSON.stringify(this.deltaObj) : null;
        if (deltaObjStringified) {
            // if deltaObjStringified is too long, then that will likely make
            // the URL way too long. in that case, just make it null and don't
            // send a delta (NB: actually set it to a canary value "overflow").
            // we'll lose some info but at least the URL will hopefully not overflow:
            if (deltaObjStringified.length > 4096) {
                deltaObjStringified = "overflow"; // set a canary to overflow
            }
        }
        else {
            // if we got here due to the num414Tries retries hack, set
            // canary to "overflow"
            if (this.num414Tries > 0) {
                deltaObjStringified = "overflow_414";
            }
        }
        // if we can find a matching cache entry, then use it!!!
        if (this.traceCache) {
            var appState = this.getAppState();
            var cachedTrace = this.traceCacheGet(appState);
            if (cachedTrace) {
                //console.log("CACHE HIT!", appState);
                callbackWrapper({ code: appState.code, trace: cachedTrace });
                return; // return early without going to the server at all!
            }
        }
        // everything below here is an ajax (async) call to the server ...
        if (jsonp_endpoint) {
            pytutor_1.assert(pyState !== '2' && pyState !== '3');
            // 2018-08-19: this is an uncommon use case (only used for https iframe embedding)
            if (jsonp_endpoint.indexOf('https:') == 0) {
                this.setFronendError(["Error: https execution of non-Python code is not currently supported. [#nonPythonHttps]"]);
                this.doneExecutingCode();
                return;
            }
            var retryOnBackupServer = function () {
                // first log a #TryBackup error entry:
                _this.setFronendError(["Main server is busy or has errors; re-trying using backup server " + _this.backupHttpServerRoot + " ... [#TryBackup]"]);
                // now re-try the query using the backup server:
                var backup_jsonp_endpoint = _this.langSettingToJsonpEndpointBackup[pyState];
                pytutor_1.assert(backup_jsonp_endpoint);
                $.ajax({
                    url: backup_jsonp_endpoint,
                    // The name of the callback parameter, as specified by the YQL service
                    jsonp: "callback",
                    dataType: "jsonp",
                    data: { user_script: codeToExec,
                        options_json: JSON.stringify(backendOptionsObj),
                        raw_input_json: _this.rawInputLst.length > 0 ? JSON.stringify(_this.rawInputLst) : null,
                    },
                    success: callbackWrapper
                });
            };
            // for non-python, this should be a dummy script for logging
            // only, and to check whether there's a 414 error for #CodeTooLong
            $.get(backendScript, { user_script: codeToExec,
                options_json: JSON.stringify(backendOptionsObj),
                user_uuid: this.userUUID,
                session_uuid: this.sessionUUID,
                diffs_json: deltaObjStringified }, function (dat) {
                // this is super important! only if this first call is a
                // SUCCESS do we actually make the REAL call using JSONP.
                // the reason why is that we might get a 414 error for
                // #CodeTooLong if we try to execute this code, in which
                // case we want to either re-try or bail out. this also
                // keeps the control flow synchronous. we always try
                // the original backendScript, and then we try
                // jsonp_endpoint only if that's successful:
                // the REAL call uses JSONP
                // http://learn.jquery.com/ajax/working-with-jsonp/
                $.ajax({
                    url: jsonp_endpoint,
                    // for testing
                    //url: 'http://cokapi.com/test_failure_jsonp',
                    //url: 'http://cokapi.com/unknown_url',
                    // The name of the callback parameter, as specified by the YQL service
                    jsonp: "callback",
                    dataType: "jsonp",
                    data: { user_script: codeToExec,
                        options_json: JSON.stringify(backendOptionsObj),
                        raw_input_json: _this.rawInputLst.length > 0 ? JSON.stringify(_this.rawInputLst) : null,
                    },
                    success: function (dataFromBackend) {
                        var trace = dataFromBackend.trace;
                        var shouldRetry = false;
                        // the cokapi backend responded successfully, but the
                        // backend may have issued an error. if so, then
                        // RETRY with backupHttpServerRoot. otherwise let it
                        // through to callbackWrapper
                        if (!trace ||
                            (trace.length == 0) ||
                            (trace[trace.length - 1].event == 'uncaught_exception')) {
                            if (trace.length == 1) {
                                // we should only retry if there's a legit
                                // backend error and not just a syntax error:
                                var msg = trace[0].exception_msg;
                                if (msg.indexOf('#BackendError') >= 0) {
                                    shouldRetry = true;
                                }
                            }
                            else {
                                shouldRetry = true;
                            }
                        }
                        // don't bother re-trying for https since we don't
                        // currently have an https backup server
                        if (window.location.protocol === 'https:') {
                            shouldRetry = false;
                        }
                        if (shouldRetry) {
                            retryOnBackupServer();
                        }
                        else {
                            // accept our fate without retrying
                            callbackWrapper(dataFromBackend);
                        }
                    },
                    // if there's a server error, then ALWAYS retry:
                    error: function (jqXHR, textStatus, errorThrown) {
                        retryOnBackupServer();
                        // use 'global: false;' below to NOT run the generic ajaxError() function
                    },
                    global: false,
                });
            }, "text");
        }
        else {
            // for Python 2 or 3, directly execute backendScript
            pytutor_1.assert(pyState === '2' || pyState === '3');
            $.get(backendScript, { user_script: codeToExec,
                raw_input_json: this.rawInputLst.length > 0 ? JSON.stringify(this.rawInputLst) : '',
                options_json: JSON.stringify(backendOptionsObj),
                user_uuid: this.userUUID,
                session_uuid: this.sessionUUID,
                diffs_json: deltaObjStringified }, callbackWrapper, "json");
        }
    };
    // manage traceCache
    // return whether two states match, except don't worry about mode or curInstr
    AbstractBaseFrontend.appStateEqForCache = function (s1, s2) {
        // NB: this isn't always true if we're recording and replaying
        // in different frontend files ...
        //assert(s1.origin == s2.origin); // sanity check!
        return (s1.code == s2.code &&
            s1.cumulative == s2.cumulative &&
            s1.heapPrimitives == s1.heapPrimitives &&
            s1.textReferences == s2.textReferences &&
            s1.py == s2.py &&
            s1.rawInputLstJSON == s2.rawInputLstJSON);
    };
    // SILENTLY fail without doing anything if the current app state is
    // already in the cache
    AbstractBaseFrontend.prototype.traceCacheAdd = function () {
        // should only be called if you currently have a working trace;
        // otherwise it's useless
        pytutor_1.assert(this.myVisualizer && this.myVisualizer.curTrace);
        var appState = this.getAppState();
        // make sure nothing in the cache currently matches appState
        for (var i = 0; i < this.traceCache.length; i++) {
            var e = this.traceCache[i];
            if (AbstractBaseFrontend.appStateEqForCache(e[0], appState)) {
                console.warn("traceCacheAdd silently failed, entry already in cache");
                return;
            }
        }
        this.traceCache.push([appState, this.myVisualizer.curTrace]);
        console.log('traceCacheAdd', this.traceCache);
    };
    AbstractBaseFrontend.prototype.traceCacheGet = function (appState) {
        for (var i = 0; i < this.traceCache.length; i++) {
            var e = this.traceCache[i];
            if (AbstractBaseFrontend.appStateEqForCache(e[0], appState)) {
                return e[1];
            }
        }
        return null;
    };
    AbstractBaseFrontend.prototype.traceCacheClear = function () {
        this.traceCache = [];
    };
    AbstractBaseFrontend.prototype.setSurveyHTML = function () {
        // use ${this.userUUID} within the string ...
        var survey_v14 = "\n    <p style=\"font-size: 9pt; margin-top: 12px; margin-bottom: 15px; line-height: 150%;\">\n\n    Help improve this tool by completing a <a style=\"font-size: 10pt; font-weight: bold;\" href=\"https://docs.google.com/forms/d/e/1FAIpQLSfQJP1ojlv8XzXAvHz0al-J_Hs3GQu4XeblxT8EzS8dIzuaYA/viewform?entry.956368502=" + this.userUUID + "\" target=\"_blank\">short user survey</a>\n    </p>";
        $('#surveyPane').html(survey_v14);
    };
    return AbstractBaseFrontend;
}()); // END class AbstractBaseFrontend
exports.AbstractBaseFrontend = AbstractBaseFrontend;
// removed donation link on 2019-03-26
//    Keep this tool free by making a <a style="font-size: 10pt; font-weight: bold;" href="http://pgbovine.net/support.htm" target="_blank">small donation</a> (PayPal, Patreon, credit/debit card)
/* For survey questions. Versions of survey wording:

[see ../../v3/js/opt-frontend-common.js for older versions of survey wording - v1 to v7]

v8: (deployed on 2016-06-20) - like v7 except emphasize the main usage survey more, and have the over-60 survey as auxiliary
const survey_v8 = '\n\
<p style="font-size: 10pt; margin-top: 10px; margin-bottom: 15px; line-height: 175%;">\n\
<span>Support our research and keep this tool free by <a href="https://docs.google.com/forms/d/1-aKilu0PECHZVRSIXHv8vJpEuKUO9uG3MrH864uX56U/viewform" target="_blank">filling out this user survey</a>.</span>\n\
<br/>\n\
<span style="font-size: 9pt;">If you are <b>at least 60 years old</b>, please also fill out <a href="https://docs.google.com/forms/d/1lrXsE04ghfX9wNzTVwm1Wc6gQ5I-B4uw91ACrbDhJs8/viewform" target="_blank">our survey about learning programming</a>.</span>\n\
</p>'

v9: (deployed on 2016-08-14, taken down 2016-12-05) - only put up the "older adults" survey except generalize it to ALL ages, take down the OPT usage survey for now
const survey_v9 = '\n\
<p style="font-size: 10pt; margin-top: 10px; margin-bottom: 15px; line-height: 175%;">\n\
<span>Support our research and keep this tool free by <a href="https://docs.google.com/forms/d/1lrXsE04ghfX9wNzTVwm1Wc6gQ5I-B4uw91ACrbDhJs8/viewform" target="_blank"><b>filling out this user survey</b></a>.</span>\n\
</p>'

v10: (deployed on 2016-12-05) - survey of how native languages affects learning programming
     (taken down on 2017-07-28)
[see survey_v10 variable above]

    // use ${this.userUUID} within the string ...
    var survey_v10 = '\n\
    <p style="font-size: 11pt; margin-top: 12px; margin-bottom: 15px; line-height: 150%;">\n\
    <span><span style="color: #e93f34;">Support our research and keep this tool free</span> by filling out this <a href="https://docs.google.com/forms/d/e/1FAIpQLSe48NsBZPvu1hrTBwc8-aSic7nPSxpsxFqpUxV5AN4LwnyJWg/viewform?entry.956368502=';
    survey_v10 += this.userUUID;
    survey_v10 += '" target="_blank">survey on how your native spoken language affects how you learn programming</a>.</span></p>';

    $('#surveyPane').html(survey_v10);

v11: labinthewild python debugging experiment (deployed on 2017-07-28, taken down on 2017-09-12)
    var survey_v11 = `<p style="font-size: 10pt; margin-top: 12px; margin-bottom: 15px; line-height: 150%;">
                        <span>
                          <span style="color: #e93f34;">Support our research and practice Python</span>
                          by trying our new
                          <a target="_blank" href="http://www.labinthewild.org/studies/python_tutor/">debugging skill test</a>!`;

v12: simplified demographic survey which is a simplified hybrid of the v8 general usage survey and the v10 native language survey (deployed on 2017-09-12)

    // use ${this.userUUID} within the string ...
    var survey_v12 = '\n\
    <p style="font-size: 10pt; margin-top: 12px; margin-bottom: 15px; line-height: 150%;">\n\
    <span>Support our research and keep this tool free by <a href="https://docs.google.com/forms/d/e/1FAIpQLSfQJP1ojlv8XzXAvHz0al-J_Hs3GQu4XeblxT8EzS8dIzuaYA/viewform?entry.956368502=';
    survey_v12 += this.userUUID;
    survey_v12 += '" target="_blank"><b>filling out this short user survey</b></a>.</span></p>';

v13: same as v12 except with slightly different wording, and adding a
call for donations (deployed on 2017-12-27)

    // use ${this.userUUID} within the string ...
    var survey_v13 = '\n\
    <p style="font-size: 10pt; margin-top: 12px; margin-bottom: 15px; line-height: 150%;">\n\
    <div style="margin-bottom: 12px;">Keep this tool free for everyone by <a href="http://pgbovine.net/support.htm" target="_blank"><b>making a small donation</b></a> <span style="font-size: 8pt;">(PayPal, Patreon, credit/debit card)</span></div>\
    <span>Support our research by completing a <a href="https://docs.google.com/forms/d/e/1FAIpQLSfQJP1ojlv8XzXAvHz0al-J_Hs3GQu4XeblxT8EzS8dIzuaYA/viewform?entry.956368502=';
    survey_v13 += this.userUUID;
    survey_v13 += '" target="_blank"><b>short user survey</b></a></span></p>';


v14: very similar to v13 (deployed on 2018-03-11)
[see the survey_v14 variable]

*/
// misc utilities:
// From http://stackoverflow.com/a/8809472
function generateUUID() {
    var d = new Date().getTime();
    var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
        var r = (d + Math.random() * 16) % 16 | 0;
        d = Math.floor(d / 16);
        return (c == 'x' ? r : (r & 0x7 | 0x8)).toString(16);
    });
    return uuid;
}
exports.generateUUID = generateUUID;
;
// Adapted from http://diveintohtml5.info/storage.html
function supports_html5_storage() {
    try {
        if ('localStorage' in window && window['localStorage'] !== null) {
            // From: http://stackoverflow.com/questions/21159301/
            // Safari before v11, in Private Browsing Mode, looks like it supports localStorage but all calls to
            // setItem throw QuotaExceededError.  Making these calls in the try block will detect that situation
            // with the catch below, returning false.
            localStorage.setItem('_localStorage_test', '1');
            localStorage.removeItem('_localStorage_test');
            return true;
        }
        else {
            return false;
        }
    }
    catch (e) {
        return false;
    }
}
exports.supports_html5_storage = supports_html5_storage;

/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0)))

/***/ }),
/* 33 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
/* WEBPACK VAR INJECTION */(function(jQuery, $) {
// Python Tutor: https://github.com/pgbovine/OnlinePythonTutor/
// Copyright (C) Philip Guo (philip@pgbovine.net)
// LICENSE: https://github.com/pgbovine/OnlinePythonTutor/blob/master/LICENSE.txt
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
// Implements shared sessions (a.k.a. Codechella)
// VERY IMPORTANT to grab the value of togetherjsInUrl before loading
// togetherjs-min.js, since loading that file deletes #togetherjs from URL
// NB: kinda gross global
//
// if this is true, this means that you JOINED SOMEONE ELSE'S SESSION
// rather than starting your own session
var togetherjsInUrl = !!(window.location.hash.match(/togetherjs=/)); // turn into bool
if (togetherjsInUrl) {
    console.log("togetherjsInUrl!");
}
else {
    // if you're *not* loading a URL with togetherjs in it (i.e., joining into
    // an existing session), then do this hack at the VERY BEGINNING before
    // loading togetherjs-min.js to prevent TogetherJS from annoyingly
    // auto-starting when, say, you're in a shared session and reload
    // your browser (which can lead to weird interactions with the help queue)
    console.log("NOT togetherjsInUrl!");
    window.TogetherJSConfig_noAutoStart = true;
}
__webpack_require__(62);
__webpack_require__(61); // https://momentjs.com/
__webpack_require__(60); // http://hgoebl.github.io/mobile-detect.js/ https://github.com/hgoebl/mobile-detect.js
exports.TogetherJS = window.TogetherJS;
var opt_frontend_common_1 = __webpack_require__(32);
var opt_frontend_1 = __webpack_require__(35);
var demovideo_1 = __webpack_require__(56);
var pytutor_1 = __webpack_require__(4);
// copypasta from pytutor.ts
// https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet#RULE_.231_-_HTML_Escape_Before_Inserting_Untrusted_Data_into_HTML_Element_Content
var entityMap = {
    "&": "&amp;",
    "<": "&lt;",
    ">": "&gt;",
    '"': '&quot;',
    "'": '&#x27;',
    "/": '&#x2F;'
};
function escapeHtmlAntiXSS(string) {
    return String(string).replace(/[&<>"'\/]/g, function (s) {
        return entityMap[s];
    });
}
;
// copy-pasta from // https://github.com/kidh0/jquery.idle
/**
 *  File: jquery.idle.js
 *  Title:  JQuery Idle.
 *  A dead simple jQuery plugin that executes a callback function if the user is idle.
 *  About: Author
 *  Henrique Boaventura (hboaventura@gmail.com).
 *  About: Version
 *  1.2.7
 *  About: License
 *  Copyright (C) 2013, Henrique Boaventura (hboaventura@gmail.com).
 *  MIT License:
 *  Permission is hereby granted, free of charge, to any person obtaining a copy
 *  of this software and associated documentation files (the "Software"), to deal
 *  in the Software without restriction, including without limitation the rights
 *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *  copies of the Software, and to permit persons to whom the Software is
 *  furnished to do so, subject to the following conditions:
 *  - The above copyright notice and this permission notice shall be included in all
 *    copies or substantial portions of the Software.
 *  - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 *    SOFTWARE.
 **/
/*jslint browser: true */
/*global jQuery: false */
(function ($) {
    'use strict';
    $.fn.idle = function (options) {
        var defaults = {
            idle: 60000,
            events: 'mousemove keydown mousedown touchstart',
            onIdle: function () { },
            onActive: function () { },
            onHide: function () { },
            onShow: function () { },
            keepTracking: true,
            startAtIdle: false,
            recurIdleCall: false
        }, idle = options.startAtIdle || false, visible = !options.startAtIdle || true, settings = $.extend({}, defaults, options), lastId = null, resetTimeout, timeout;
        //event to clear all idle events
        $(this).on("idle:stop", {}, function (event) {
            $(this).off(settings.events);
            settings.keepTracking = false;
            resetTimeout(lastId, settings);
        });
        resetTimeout = function (id, settings) {
            if (idle) {
                idle = false;
                settings.onActive.call();
            }
            clearTimeout(id);
            if (settings.keepTracking) {
                return timeout(settings);
            }
        };
        timeout = function (settings) {
            var timer = (settings.recurIdleCall ? setInterval : setTimeout), id;
            id = timer(function () {
                idle = true;
                settings.onIdle.call();
            }, settings.idle);
            return id;
        };
        return this.each(function () {
            lastId = timeout(settings);
            $(this).on(settings.events, function (e) {
                lastId = resetTimeout(lastId, settings);
            });
            if (settings.onShow || settings.onHide) {
                $(document).on("visibilitychange webkitvisibilitychange mozvisibilitychange msvisibilitychange", function () {
                    if (document.hidden || document.webkitHidden || document.mozHidden || document.msHidden) {
                        if (visible) {
                            visible = false;
                            settings.onHide.call();
                        }
                    }
                    else {
                        if (!visible) {
                            visible = true;
                            settings.onShow.call();
                        }
                    }
                });
            }
        });
    };
}(jQuery));
// "Get live help!" survey versions
// initial pilot version: deployed on 2017-11-10, taken down on 2017-11-13
// deployed a single version of the survey to EVERYONE who requested or
// volunteered to help in the server logs under the /survey endpoint, i recorded
// *ONLY* those people who made a non-null response (for the most part) ...
// which is unlike subsequent versions, which record ALL impressions, even null
// responses, so that we can know approximately how many times each survey
// question got deployed and can thus get a rough response rate
/*
var liveHelpSurvey = {
  requestHelp:   [{prompt: 'You are now on the help queue. Please support our research by answering below: Why did you decide to ask for help at this time? What motivated you to click the "Get live help" button?',
                  v: 'r1'}],
  volunteerHelp: [{prompt: "Thanks for volunteering! You're about to join a live chat session. Please support our research by answering below: Why did you decide to volunteer at this time? What motivated you to click on this help link?",
                  v: 'h1'}],
};
*/
// second version, deployed on 2017-11-13. randomly select one of these
// questions to ask whenever a user triggers the survey, but save their
// responses in localStorage so that when they return, it will ask them
// a different question. starting from this version, th server logs
// under the /survey endpoint will record *all* responses to the survey,
// even null responses, since we can use that data to calculate survey
// response rates.
// (taken down on 2018-01-22 and replaced with third version below)
/*
var liveHelpSurvey = {
  requestHelp:   [ {prompt: 'You\'re now on the help queue. Support our research by answering below:\n\nWhy did you decide to ask for help at this time? What motivated you to click the "Get live help" button?',
                    v: 'r2a'}, // identical to 'r1'
                   {prompt: 'You\'re now on the help queue. Support our research by answering below:\n\nWhy are you asking for help anonymously on this website? Are there people you know around you who can help as well?',
                    v: 'r2b'},
                   {prompt: 'You\'re now on the help queue. Support our research by answering below:\n\nHow did you first find this website? What are you currently using this website for?',
                    v: 'r2c'},
                 ],
  volunteerHelp: [ {prompt: "Thanks for volunteering! Support our research by answering below:\n\nWhy did you decide to volunteer at this time? What motivated you to click on this help link?",
                    v: 'h2a'}, // identical to 'h1'
                   {prompt: "Thanks for volunteering! Support our research by answering below:\n\nWhat is your current profession (e.g., student, teaching assistant, instructor)? Why are you using this website?",
                    v: 'h2b'},
                   {prompt: "Thanks for volunteering! Support our research by answering below:\n\nWhat kind of code are you working on right now? What made you decide to stop coding and volunteer at this time?",
                    v: 'h2c'},
                 ]
};
*/
// third version, deployed on 2018-01-22 (modeled off of the second version above)
/*
var liveHelpSurvey = {
  requestHelp:   [ {prompt: 'You\'re now on the help queue. Support our research by answering below:\n\nWhy did you decide to ask for help at this time?',
                    v: 'r3a'}, // almost identical to 'r2a'
                   {prompt: 'You\'re now on the help queue. Support our research by answering below:\n\nWhy did you choose to ask for help anonymously here rather than getting help from someone you know?',
                    v: 'r3b'},
                 ],
  volunteerHelp: [ {prompt: "Thanks for volunteering! Support our research by answering below:\n\nWhy did you decide to volunteer at this time?",
                    v: 'h3a'}, // almost identical to 'h2a'
                   {prompt: "Thanks for volunteering! Support our research by answering below:\n\nWhat is your current job or profession?",
                    v: 'h3b'},
                   {prompt: "Thanks for volunteering! Support our research by answering below:\n\nWhat kind of code were you working on right before you volunteered?",
                    v: 'h3c'},
                 ]
};
*/
// fourth version, deployed on 2018-03-12
/*
var liveHelpSurvey = {
  requestHelp:   [ {prompt: 'You\'re now on the help queue. Support our research by answering below:\n\nWhy did you decide to ask for help at this time?',
                    v: 'r4a'},
                   {prompt: 'You\'re now on the help queue. Support our research by answering below:\n\nWhy did you ask for help anonymously on this website rather than getting help from someone you know?',
                    v: 'r4b'},
                 ],
  volunteerHelp: [ {prompt: "Thanks for volunteering! Support our research by answering below:\n\nWhy did you decide to volunteer at this time? What motivated you to click on this particular help link?",
                    v: 'h4a'},
                   {prompt: "Thanks for volunteering! Support our research by answering below:\n\nWhat is your current job or profession?",
                    v: 'h4b'},
                 ]
};
*/
// 2018-03-17: minor tweaks on version 4's wording to make it sound a bit more optional and casual
/*
var liveHelpSurvey = {
  requestHelp:   [ {prompt: 'You are now on the help queue. Please wait for help to arrive.\n\n[OPTIONAL] Support our research by letting us know:\nWhy did you decide to ask for help at this time?',
                    v: 'r4a'},
                   {prompt: 'You are now on the help queue. Please wait for help to arrive.\n\n[OPTIONAL] Support our research by letting us know:\nWhy did you ask for help anonymously on this website rather than getting help from someone you know?',
                    v: 'r4b'},
                 ],
  volunteerHelp: [ {prompt: "Thanks for volunteering! You are about to join a live chat.\n\n[OPTIONAL] Support our research by letting us know:\nWhy did you decide to volunteer at this time? What motivated you to click on this particular help link?",
                    v: 'h4a'},
                   {prompt: "Thanks for volunteering! You are about to join a live chat.\n\n[OPTIONAL] Support our research by letting us know:\nWhat is your current job or profession?",
                    v: 'h4b'},
                 ]
};
*/
// 2018-06-24: version 5 is nearly identical to version 4, except that I turned
// on noRepeats=true so we don't ask users the same question more than once
//
// 2018-08-09: remove this feature entirely for help requests only (r5a, r5b)
//             since Chrome seems to handle prompt() weirdly now
//             (it seems to have done so for quite a while);
//             [it still seems fine when someone is *volunteering* to help]
//
// 2019-03-26: took this down to simplify the UI more
var liveHelpSurvey = {
    requestHelp: [{ prompt: 'You are now on the help queue. Please wait for help to arrive.\n\nSupport our research by letting us know:\nWhy did you decide to ask for help at this time?',
            v: 'r5a' },
        { prompt: 'You are now on the help queue. Please wait for help to arrive.\n\nSupport our research by letting us know:\nWhy did you ask for help anonymously on this website rather than getting help from someone you know?',
            v: 'r5b' },
    ],
    volunteerHelp: [{ prompt: "Thanks for volunteering! You are about to join a live chat.\n\nSupport our research by letting us know:\nWhy did you decide to volunteer at this time? What motivated you to click on this particular help link?",
            v: 'h5a' },
        { prompt: "Thanks for volunteering! You are about to join a live chat.\n\nSupport our research by letting us know:\nWhat is your current job or profession?",
            v: 'h5b' },
    ]
};
// randomly picks a survey item from liveHelpSurvey and mutates
// localStorage to record that this has been randomly picked, so it won't
// be picked again during the next call
//
// 2018-06-24: if noRepeats is true, then don't ask this user repeated
// questions; simply return null if all questions have already been asked
function randomlyPickSurveyItem(key, noRepeats) {
    if (noRepeats === void 0) { noRepeats = false; }
    var lst = liveHelpSurvey[key];
    var filteredLst = [];
    // filter lst down to filteredLst to find all elements whose version
    // numbers 'v' does NOT already exist in localStorage
    if (opt_frontend_common_1.supports_html5_storage()) {
        lst.forEach(function (e) {
            if (!localStorage.getItem(e.v)) {
                filteredLst.push(e);
            }
        });
    }
    else {
        filteredLst = lst;
    }
    // if ALL entries have been filtered out, then reset everything and
    // start from scratch:
    if (filteredLst.length == 0) {
        if (noRepeats) {
            return null; // punt early if noRepeats=true!!!
        }
        if (opt_frontend_common_1.supports_html5_storage()) {
            lst.forEach(function (e) {
                localStorage.removeItem(e.v);
            });
        }
        filteredLst = lst;
    }
    // now randomly pick an entry and show it:
    // random number in [0, filteredLst.length)
    var randInt = Math.floor(Math.random() * filteredLst.length);
    var randomEntry = filteredLst[randInt];
    if (opt_frontend_common_1.supports_html5_storage()) {
        localStorage.setItem(randomEntry.v, '1');
    }
    return randomEntry;
}
var OptFrontendSharedSessions = /** @class */ (function (_super) {
    __extends(OptFrontendSharedSessions, _super);
    function OptFrontendSharedSessions(params) {
        if (params === void 0) { params = {}; }
        var _this = _super.call(this, params) || this;
        _this.executeCodeSignalFromRemote = false;
        _this.togetherjsSyncRequested = false;
        _this.pendingCodeOutputScrollTop = null;
        _this.updateOutputSignalFromRemote = false;
        _this.wantsPublicHelp = false;
        _this.iMadeAPublicHelpRequest = false; // subtly different than wantsPublicHelp (see usage)
        _this.disableSharedSessions = false;
        _this.isIdle = false;
        _this.peopleIveKickedOut = []; // #savage
        _this.sessionActivityStats = {};
        _this.payItForwardMsg = "If you found this service useful, please take the time to help others in the future. We depend on volunteers like you to provide help.";
        _this.payItForwardMsgVersion = 'v1';
        _this.fullCodeSnapshots = []; // a list of full snapshots of code taken at given times, with:
        _this.curPeekSnapshotIndex = -1; // current index you're peeking at inside of fullCodeSnapshots, -1 if not peeking at anything
        // overriden by the OptDemoRecorder subclass but put it here since
        // we use it at parts (yeah, abstraction violation, but oh wells,
        // it's too troublesome to clean up at this point ...)
        _this.isPlayingDemo = false;
        _this.initTogetherJS();
        _this.initABTest();
        _this.Range = ace.require('ace/range').Range; // for Ace Range() objects
        _this.pyInputAceEditor.getSession().on("change", function (e) {
            // unfortunately, Ace doesn't detect whether a change was caused
            // by a setValue call
            if (exports.TogetherJS.running && !_this.isPlayingDemo) {
                exports.TogetherJS.send({ type: "codemirror-edit" });
            }
        });
        // NB: don't sync changeScrollTop for Ace since I can't get it working yet
        //this.pyInputAceEditor.getSession().on('changeScrollTop', () => {
        //  if (typeof TogetherJS !== 'undefined' && TogetherJS.running) {
        //    $.doTimeout('codeInputScroll', 100, function() { // debounce
        //      // note that this will send a signal back and forth both ways
        //      // (there's no easy way to prevent this), but it shouldn't keep
        //      // bouncing back and forth indefinitely since no the second signal
        //      // causes no additional scrolling
        //      TogetherJS.send({type: "codeInputScroll",
        //                       scrollTop: pyInputGetScrollTop()});
        //    });
        //  }
        //});
        var md = new MobileDetect(window.navigator.userAgent);
        if (md.mobile()) { // mobile or tablet device
            _this.disableSharedSessions = true;
        }
        if (_this.disableSharedSessions) {
            return _this;
        }
        var ssDiv = "\n\n<button id=\"requestHelpBtn\" type=\"button\" class=\"togetherjsBtn\" style=\"font-size: 11pt; margin-bottom: 6pt; font-weight: bold;\">\nGet live help!\n</button>\n\n<div id=\"ssDiv\">\n  <button id=\"sharedSessionBtn\" type=\"button\" class=\"togetherjsBtn\" style=\"font-size: 9pt;\">\n  Start private chat\n  </button>\n</div>\n\n<div id=\"sharedSessionDisplayDiv\" style=\"display: none; margin-right: 5px;\">\n  <button id=\"stopTogetherJSBtn\" type=\"button\" class=\"togetherjsBtn\">\n  Stop this chat session\n  </button>\n</div>\n";
        // 2019-04-01: eliminated this link and put up '(chat service may crash at any time)' warning
        //<a href="https://www.youtube.com/watch?v=oDY7ScMPtqI" target="_blank">How do I use this?</a>
        var togetherJsDiv = "\n<div id=\"togetherjsStatus\">\n  <div id=\"publicHelpQueue\"></div>\n</div>\n";
        $("td#headerTdLeft").append(ssDiv);
        $("td#headerTdRight").append(togetherJsDiv);
        // shut down chat features on 2019-03-24 due to technical difficulties, reactivated on 2019-03-26:
        //$("td#headerTdLeft").width('200px');
        //$("td#headerTdLeft").append("<div style=\"font-size: 6pt; font-color: #666;\">Live chat mode is shut down indefinitely due to technical difficulties. Please don't email me to ask about this issue.</div>");
        // do this all after creating the DOM elements above dynamically:
        $("#sharedSessionBtn").click(_this.startSharedSession.bind(_this, false));
        $("#stopTogetherJSBtn").click(exports.TogetherJS); // toggles off
        $("#requestHelpBtn").click(_this.requestPublicHelpButtonClick.bind(_this));
        // jquery.idle:
        $(document).idle({
            onIdle: function () {
                _this.isIdle = true;
                console.log('I\'m idle');
            },
            onActive: function () {
                _this.isIdle = false; // set this first!
                console.log('I\'m back!');
                // update the help queue as soon as you're back:
                _this.getHelpQueue();
                // ... and maybe snappy snapshot it
                _this.periodicMaybeTakeSnapshot();
            },
            idle: 60 * 1000 // 1-minute timeout by default for idleness
        });
        // polling every 5 seconds seems reasonable; note that you won't
        // send an HTTP request to the server when this.isIdle is true, to conserve
        // resources and get a more accurate indicator of who is active at
        // the moment
        setInterval(_this.getHelpQueue.bind(_this), 5 * 1000);
        setInterval(_this.getNumObservers.bind(_this), 5 * 1000);
        // update this pretty frequently; doesn't require any ajax calls:
        setInterval(_this.updateModerationPanel.bind(_this), 2 * 1000);
        // take a snapshot every 30 seconds or so if you're in a TogetherJS
        // session and not idle
        setInterval(_this.periodicMaybeTakeSnapshot.bind(_this), 30 * 1000);
        setInterval(_this.periodicMaybeChatNudge.bind(_this), 60 * 1000);
        // add an additional listener in addition to whatever the superclasses added
        window.addEventListener("hashchange", function (e) {
            if (exports.TogetherJS.running && !_this.isPlayingDemo && !_this.isExecutingCode) {
                exports.TogetherJS.send({ type: "hashchange",
                    appMode: _this.appMode,
                    codeInputScrollTop: _this.pyInputGetScrollTop(),
                    myAppState: _this.getAppState() });
            }
        });
        // shut down TogetherJS if it's still running
        // (use 'on' to add an additional listener in addition to whatever event
        // handlers the superclasses already added)
        $(window).on('beforeunload', function () {
            if (exports.TogetherJS.running) {
                exports.TogetherJS();
            }
        });
        $(window).on('unload', function () {
            if (exports.TogetherJS.running) {
                exports.TogetherJS();
            }
        });
        return _this;
    }
    OptFrontendSharedSessions.prototype.parseQueryString = function () {
        _super.prototype.parseQueryString.call(this);
        // AFTERWARDS, immediately get help queue. this way, if the query
        // string option demo=true is set, then it will properly disable
        // shared sessions before getting the help queue
        this.getHelpQueue(1500); // set a short timeout in ms so we fail faster if we can't reach help queue server for some reason (e.g., firewall)
    };
    OptFrontendSharedSessions.prototype.demoModeChanged = function () {
        console.log('demoModeChanged', this.demoMode);
        if (this.demoMode) {
            // hide the shared sessions header ...
            $("td#headerTdLeft,td#headerTdRight").hide();
            // we need to not only hide this header, but also NOT call
            // getHelpQueue periodically, or else the server will *think* that
            // we're monitoring the help queue when in fact we aren't:
            this.disableSharedSessions = true;
            // disable all surveys too
            this.activateSyntaxErrorSurvey = false;
            this.activateRuntimeErrorSurvey = false;
            this.activateEurekaSurvey = false;
        }
        else {
            $("td#headerTdLeft,td#headerTdRight").show();
            this.disableSharedSessions = false;
        }
    };
    OptFrontendSharedSessions.prototype.loadCodcastFile = function () {
        var _this = this;
        pytutor_1.assert(this.codcastFile);
        console.log('loadCodcastFile', this.codcastFile);
        this.disableSharedSessions = true;
        this.activateSyntaxErrorSurvey = false;
        this.activateRuntimeErrorSurvey = false;
        this.activateEurekaSurvey = false;
        // TODO: also disable undo/redo feature since that can get annoying
        // when replaying demo "videos"
        $("td#headerTdLeft").html(''); // clobber the existing contents
        $.get(this.codcastFile, {}, function (dat) {
            // create an OptDemoVideo object from the serialized JSON data contained
            // in that file
            _this.demoVideo = new demovideo_1.OptDemoVideo(_this, dat);
            _this.startPlayback();
        }, 'text' /* grab data as plain text */);
    };
    // for A/B testing -- store this information PER USER in localStorage,
    // so that it can last throughout all sessions where this user
    // used the same browser. that way, every user will consistently get
    // put into one particular A/B test bucket.
    OptFrontendSharedSessions.prototype.initABTest = function () {
        if (opt_frontend_common_1.supports_html5_storage() && localStorage.getItem('abtest_settings')) {
            this.abTestSettings = JSON.parse(localStorage.getItem('abtest_settings'));
        }
        else {
            this.abTestSettings = {};
        }
        // all values in the range of [0, 1)
        if (this.abTestSettings.nudge === undefined) {
            this.abTestSettings.nudge = Math.random();
        }
        if (this.abTestSettings.payItForward === undefined) {
            this.abTestSettings.payItForward = Math.random();
        }
        if (this.abTestSettings.helperGreeting === undefined) {
            this.abTestSettings.helperGreeting = Math.random();
        }
        // always save it again for robustness (we might have added some new
        // keys to this user's abTestSettings object)
        if (opt_frontend_common_1.supports_html5_storage()) {
            localStorage.setItem('abtest_settings', JSON.stringify(this.abTestSettings));
        }
        console.log('initABTest:', this.abTestSettings);
    };
    OptFrontendSharedSessions.prototype.langToEnglish = function (lang) {
        if (lang === '2') {
            return 'Python2';
        }
        else if (lang === '3' || lang == 'py3anaconda') {
            return 'Python3';
        }
        else if (lang === 'java') {
            return 'Java';
        }
        else if (lang === 'js') {
            return 'JavaScript';
        }
        else if (lang === 'ts') {
            return 'TypeScript';
        }
        else if (lang === 'ruby') {
            return 'Ruby';
        }
        else if (lang === 'c') {
            return 'C';
        }
        else if (lang === 'cpp') {
            return 'C++';
        }
        return '???'; // fail soft, even though this shouldn't ever happen
    };
    // timeout=0 default means no timeout; explicitly set it in ms to make
    // a shorter timeout
    OptFrontendSharedSessions.prototype.getHelpQueue = function (timeout) {
        var _this = this;
        if (timeout === void 0) { timeout = 0; }
        // VERY IMPORTANT: to avoid overloading the server, don't send these
        // requests when you're idle or disableSharedSessions is on.
        // this is important also for accurate logging, since if you're not
        // currently looking at the queue, the server shouldn't count you as
        // an "observer" who is looking at the queue at the moment, or else
        // it might overestimate the number of people who are observing the
        // queue at each moment ...
        if (this.isIdle || this.disableSharedSessions) {
            $("#publicHelpQueue").empty(); // clear when idle so that you don't have stale results
            return; // return early before making a GET request to server!
        }
        // if we can't even see the help queue for some reason, then don't bother
        // calling /getHelpQueue on the server since we can't see the help queue!!
        if (!$("#publicHelpQueue").is(":visible")) {
            console.log('getHelpQueue canned because #publicHelpQueue not visible');
            return; // return early before making a GET request to server!
        }
        var ghqUrl = exports.TogetherJS.config.get("hubBase").replace(/\/*$/, "") + "/getHelpQueue";
        var curState = this.getAppState();
        $.ajax({
            url: ghqUrl,
            dataType: "json",
            timeout: timeout,
            data: { user_uuid: this.userUUID, lang: curState.py, mode: curState.mode, origin: curState.origin },
            error: function () {
                console.log('/getHelpQueue error');
                // hide all shared session related stuff if you can't even
                // getHelpQueue successfully, because that means you likely
                // can't get connected to the chat server at all:
                $("td#headerTdLeft").hide(); // TODO: make a better name for this!
                if (_this.wantsPublicHelp) {
                    //$("#publicHelpQueue").html("ERROR: live chat is down or your firewall is blocking it. If you asked for help, something is wrong; stop this session and try again later. Do NOT email to ask when live chat will be back up.");
                    // 2019-11-04: friendlier error msg
                    $("#publicHelpQueue").html("ERROR: live chat is down or your WiFi/firewall is blocking it. If you asked for help, something is wrong; stop this session and try again later.");
                }
                else {
                    //$("#publicHelpQueue").empty(); // avoid showing stale results
                    //$("#publicHelpQueue").html("ERROR: live chat is down or your firewall is blocking it. Do NOT email to ask when live chat will be back up."); // show error msg
                    // 2019-11-04: friendlier error msg
                    $("#publicHelpQueue").html("(Live chat is down or your WiFi/firewall is blocking it. Try again later. There is NO technical support available.)"); // show error msg
                }
            },
            success: function (resp) {
                if (!$("td#headerTdLeft").is(":visible")) {
                    console.log('td#headerTdLeft show');
                    $("td#headerTdLeft").show(); // TODO: make a better name for this!
                }
                var displayEmptyQueueMsg = false;
                var me = _this;
                if (resp && resp.length > 0) {
                    $("#publicHelpQueue").empty();
                    var myShareId = exports.TogetherJS.shareId();
                    var regularEntries = [];
                    var grayedOutEntries = [];
                    var idleTimeoutMs = 3 * 60 * 1000; // 3 minutes seems reasonable
                    resp.forEach(function (e) {
                        // sometimes there are bogus incomplete entries on the queue. if
                        // there's not even a URL, then nobody can join the chat,
                        // so skip right away at the VERY BEGINNING:
                        if (!e.url) {
                            return;
                        }
                        // if there's no username, then something else is wrong, so punt as well ...
                        if (!e.username) {
                            return;
                        }
                        // when testing on localhost, we sometimes use the
                        // production TogetherJS chat server, but we don't want to
                        // show localhost entries on the global queue for people on
                        // the real site since there's no way they can jump in to join
                        //
                        // i.e., if your browser isn't on localhost but the URL of
                        // the help queue entry is on localhost, then *don't* display it
                        if ((window.location.href.indexOf('localhost') < 0) &&
                            (e.url.indexOf('localhost') >= 0)) {
                            return;
                        }
                        // use moment.js to generate human-readable relative times:
                        var d = new Date();
                        var timeSinceCreationStr = moment(d.valueOf() - e.timeSinceCreation).fromNow();
                        var timeSinceLastMsgStr = moment(d.valueOf() - e.timeSinceLastMsg).fromNow();
                        var langName = _this.langToEnglish(e.lang);
                        var curStr = pytutor_1.htmlspecialchars(e.username);
                        if (e.country && e.city) {
                            // print 'region' (i.e., state) for US addresses:
                            if (e.country === "United States" && e.region) {
                                curStr += ' from ' + e.city + ', ' + e.region + ', US needs help with ' + langName;
                            }
                            else {
                                curStr += ' from ' + e.city + ', ' + e.country + ' needs help with ' + langName;
                            }
                        }
                        else if (e.country) {
                            curStr += ' from ' + e.country + ' needs help with ' + langName;
                        }
                        else if (e.city) {
                            curStr += ' from ' + e.city + ' needs help with ' + langName;
                        }
                        else {
                            curStr += ' needs help with ' + langName;
                        }
                        if (e.id === myShareId) {
                            curStr += ' - <span class="redBold">this is you!</span>';
                        }
                        else {
                            // only display this if there's *currently* more than 1
                            // person in the session AND more than 1 person has chatted.
                            if ((e.numClients > 1) && (e.numChatters > 1)) {
                                if (e.numChatters < e.numClients) {
                                    curStr += ' - ' + String(e.numChatters) + ' people chatting';
                                }
                                else { // subtle: can't have more chatters than current clients
                                    curStr += ' - ' + String(e.numClients) + ' people chatting';
                                }
                            }
                            curStr += " - <a class=\"gotoHelpLink\" data-id=\"" + escapeHtmlAntiXSS(e.id) + "\" href=\"" + e.url + "\" target=\"_blank\">click to help</a>";
                        }
                        if (e.timeSinceLastMsg < idleTimeoutMs) {
                            curStr += ' <span class="helpQueueSmallText">(active ' + timeSinceLastMsgStr + ', requested ' + timeSinceCreationStr + ') </span>';
                            regularEntries.push(curStr);
                        }
                        else {
                            curStr += ' <span class="helpQueueSmallText">(IDLE: last active ' + timeSinceLastMsgStr + ', requested ' + timeSinceCreationStr + ') </span>';
                            grayedOutEntries.push(curStr);
                        }
                    });
                    if ((regularEntries.length + grayedOutEntries.length) > 0) {
                        if (!_this.wantsPublicHelp) {
                            $("#publicHelpQueue").html('<div style="margin-bottom: 5px;">These Python Tutor users are asking for help right now. Please volunteer to help!</div>');
                        }
                        else {
                            // if i'm asking for public help and am currently on the
                            // queue, eliminate this redundant message:
                            $("#publicHelpQueue").html('');
                        }
                        regularEntries.forEach(function (e) {
                            $("#publicHelpQueue").append('<li>' + e + '</li>');
                            $("#publicHelpQueue a.gotoHelpLink").last().css('font-weight', 'bold');
                        });
                        // gray it out to make it not look as prominent
                        grayedOutEntries.forEach(function (e) {
                            $("#publicHelpQueue").append('<li style="color: #888;">' + e + '</li>');
                        });
                        // add these handlers AFTER the respective DOM nodes have been added above:
                        // 2019-03-26: took this down to simplify the UI more
                        /*
                        $(".gotoHelpLink").click(function() {
                          // 2018-06-24: don't show the user repeated questions (noRepeats=true)
                          var surveyItem = randomlyPickSurveyItem('volunteerHelp', true);
                          if (!surveyItem) {
                            // punt early!
                            return true; // ALWAYS cause the link to be clicked
                          }
                          var miniSurveyResponse = prompt(surveyItem.prompt);
            
                          // always log every impression, even if miniSurveyResponse is blank,
                          // since we can know how many times that survey question was ever seen:
                          var idToJoin = $(this).attr('data-id');
                          var surveyUrl = TogetherJS.config.get("hubBase").replace(/\/*$/, "") + "/survey";
                          $.ajax({
                            url: surveyUrl,
                            dataType: "json",
                            data: {id: idToJoin, user_uuid: me.userUUID, kind: 'volunteerHelp', v: surveyItem.v, response: miniSurveyResponse},
                            success: function() {}, // NOP
                            error: function() {},   // NOP
                          });
            
                          return true; // ALWAYS cause the link to be clicked
                        });
                        */
                        // 2019-08-26 added this message:
                        $(".gotoHelpLink").click(function () {
                            var x = confirm('This site is 100% run by volunteers like you, so thanks for helping! Please be polite and patient with students, but feel free to leave at any time if you do not feel comfortable with the session.\n\nClick OK to join (you may need to enable pop-ups in browser).');
                            return x;
                        });
                    }
                    else {
                        displayEmptyQueueMsg = true;
                    }
                }
                else {
                    displayEmptyQueueMsg = true;
                }
                if (displayEmptyQueueMsg) {
                    if (_this.wantsPublicHelp) {
                        $("#publicHelpQueue").html('Nobody is currently on the help queue. <span style="color: red; font-weight: bold;">If you have asked for help, something is not working</span>; stop this session and try again later.');
                    }
                    else {
                        $("#publicHelpQueue").html('Nobody is currently asking for help using the "Get live help!" button. Be the first!');
                    }
                }
            },
        });
    };
    OptFrontendSharedSessions.prototype.getNumObservers = function () {
        // VERY IMPORTANT: to avoid overloading the server, don't send these
        // requests when you're idle or disableSharedSessions is on.
        if (this.isIdle || this.disableSharedSessions) {
            return; // return early before making a GET request to server!
        }
        // if we can't even see the numObserversSpan element, then don't bother
        // calling /getNumObservers on the server since we wouldn't even be
        // able to see it now anyhow
        if (!$("#numObserversSpan").is(":visible")) {
            return; // return early before making a GET request to server!
        }
        var ghqUrl = exports.TogetherJS.config.get("hubBase").replace(/\/*$/, "") + "/getNumObservers";
        $.ajax({
            url: ghqUrl,
            dataType: "json",
            error: function () {
                console.log('/getNumObservers error');
                $("#numObserversSpan").empty(); // avoid showing stale results
            },
            success: function (data) {
                var numPython = 0; // '2' and '3' and 'py3anaconda'
                var numJs = 0; // 'js' and 'ts'
                var numCpp = 0; // 'c' and 'cpp'
                var numJava = 0; // 'java'
                var numRuby = 0; // 'ruby'
                if (data['2'] > 0) {
                    numPython += data['2'];
                }
                if (data['3'] > 0) {
                    numPython += data['3'];
                }
                if (data['py3anaconda'] > 0) {
                    numPython += data['3'];
                }
                if (data['js'] > 0) {
                    numJs += data['js'];
                }
                if (data['ts'] > 0) {
                    numJs += data['ts'];
                }
                if (data['c'] > 0) {
                    numCpp += data['c'];
                }
                if (data['cpp'] > 0) {
                    numCpp += data['cpp'];
                }
                if (data['java'] > 0) {
                    numJava += data['java'];
                }
                if (data['ruby'] > 0) {
                    numRuby += data['ruby'];
                }
                var tot = numPython + numJs + numCpp + numJava + numRuby;
                var outputArr = [[numPython, 'coding in Python'],
                    [numJs, 'in JavaScript'],
                    [numCpp, 'in C/C++'],
                    [numJava, 'in Java'],
                    [numRuby, 'in Ruby']];
                outputArr.sort(function (a, b) { return (b[0] - a[0]); }); // sort descending
                var outputStr = outputArr.filter(function (e) { return e[0] > 0; }).map(function (e) { return e[0] + " " + e[1]; }).join(', ');
                $("#numObserversSpan").html("There are now " + tot + " people on this website: " + outputStr + "<br/>");
            },
        });
    };
    // did I *originally* create this session, or did I join?
    OptFrontendSharedSessions.prototype.meCreatedThisSession = function () {
        if (!exports.TogetherJS.running) {
            return false;
        }
        var session = exports.TogetherJS.require("session");
        var meIsCreator = !session.isClient; // adapted from lib/togetherjs/togetherjs/togetherjsPackage.js
        return meIsCreator;
    };
    // this will be called periodically, so make sure it doesn't block
    // execution by, say, taking too long:
    OptFrontendSharedSessions.prototype.updateModerationPanel = function () {
        // only do this if you initiated the session AND TogetherJS is currently on
        if (!exports.TogetherJS.running || !this.meCreatedThisSession()) {
            return;
        }
        $("#moderationPanel").empty(); // always start from scratch
        var allPeers = exports.TogetherJS.require("peers").getAllPeers();
        var livePeers = [];
        allPeers.forEach(function (e) {
            if (e.status !== "live") { // don't count people who've already left!!!
                return;
            }
            var clientId = e.id;
            var username = e.name;
            livePeers.push({ username: username, clientId: clientId });
        });
        if (livePeers.length > 0) {
            if (this.wantsPublicHelp) {
                $("#moderationPanel").append("\n          <button id=\"stopRequestHelpBtn\" type=\"button\" class=\"togetherjsBtn\"\n                  style=\"margin-bottom: 6pt; font-size: 10pt; font-weight: bold; padding: 4px;\">\n            Make session private so nobody else can join.\n          </button><br/>");
                $("#stopRequestHelpBtn").click(this.initStopRequestingPublicHelp.bind(this));
            }
            else {
                $("#moderationPanel").append('This is a private session. To ask for public help, click the "Get live help!" button at the left.<br/><br/>');
                if (!$("#requestHelpBtn").is(':visible')) {
                    $("#requestHelpBtn").show(); // make sure there's a way to get back on the queue
                }
            }
            $("#moderationPanel").append('Kick out disruptive users: ');
            livePeers.forEach(function (e) {
                $("#moderationPanel").append('<button class="kickLink">' + pytutor_1.htmlspecialchars(e.username) + '</button>');
                $("#moderationPanel .kickLink").last()
                    .data('clientId', e.clientId)
                    .data('username', e.username);
            });
            var me = this; // ugh
            $("#moderationPanel .kickLink").click(function () {
                var idToKick = $(this).data('clientId');
                var confirmation = confirm('Press OK to kick and ban ' + $(this).data('username') + ' from this session.\n\nUndo their code changes using the UNDO/restore buttons.');
                if (confirmation) {
                    exports.TogetherJS.send({ type: "kickOut", idToKick: idToKick });
                    me.peopleIveKickedOut.push(idToKick);
                    me.takeFullCodeSnapshot(); // 2018-03-15: save a snapshot at the time when you kick someone out, so that UNDO button will appear to show you older snapshots
                }
            });
        }
        else {
            if (this.wantsPublicHelp) {
                $("#moderationPanel").html('Nobody is here yet. Please be patient and keep working normally.');
            }
            else {
                $("#moderationPanel").html('This is a private session, so nobody can join unless you send them the URL below. To ask for public help, click the "Get live help!" button at the left.');
                if (!$("#requestHelpBtn").is(':visible')) {
                    $("#requestHelpBtn").show(); // make sure this is shown since we say it in instructions
                }
            }
        }
    };
    // important overrides to inject in pieces of TogetherJS functionality
    // without triggering spurious error messages
    OptFrontendSharedSessions.prototype.ignoreAjaxError = function (settings) {
        if (settings.url.indexOf('togetherjs') > -1) {
            return true;
        }
        else if (settings.url.indexOf('getHelpQueue') > -1) {
            return true;
        }
        else if (settings.url.indexOf('getNumObservers') > -1) {
            return true;
        }
        else if (settings.url.indexOf('requestPublicHelp') > -1) {
            return true;
        }
        else if (settings.url.indexOf('survey') > -1) {
            return true;
        }
        else if (settings.url.indexOf('nudge') > -1) {
            return true;
        }
        else if (settings.url.indexOf('freegeoip') > -1) { // deprecated
            return true;
        }
        else {
            return _super.prototype.ignoreAjaxError.call(this, settings);
        }
    };
    OptFrontendSharedSessions.prototype.logEditDelta = function (delta) {
        _super.prototype.logEditDelta.call(this, delta);
        if (exports.TogetherJS.running && !this.isPlayingDemo) {
            exports.TogetherJS.send({ type: "editCode", delta: delta });
        }
    };
    OptFrontendSharedSessions.prototype.startExecutingCode = function (startingInstruction) {
        if (startingInstruction === void 0) { startingInstruction = 0; }
        if (exports.TogetherJS.running && !this.isPlayingDemo && !this.executeCodeSignalFromRemote) {
            exports.TogetherJS.send({ type: "executeCode",
                myAppState: this.getAppState(),
                forceStartingInstr: startingInstruction,
                rawInputLst: this.rawInputLst });
        }
        _super.prototype.startExecutingCode.call(this, startingInstruction);
    };
    OptFrontendSharedSessions.prototype.updateAppDisplay = function (newAppMode) {
        _super.prototype.updateAppDisplay.call(this, newAppMode); // do this first!
        // now this.appMode should be canonicalized to either 'edit' or 'display'
        if (this.appMode === 'edit') {
            // pass
        }
        else if (this.appMode === 'display') {
            pytutor_1.assert(this.myVisualizer);
            if (!exports.TogetherJS.running) {
                $("#surveyHeader").show();
            }
            if (this.pendingCodeOutputScrollTop) {
                this.myVisualizer.domRoot.find('#pyCodeOutputDiv').scrollTop(this.pendingCodeOutputScrollTop);
                this.pendingCodeOutputScrollTop = null;
            }
            $.doTimeout('pyCodeOutputDivScroll'); // cancel any prior scheduled calls
            // TODO: this might interfere with experimentalPopUpSyntaxErrorSurvey (2015-04-19)
            this.myVisualizer.domRoot.find('#pyCodeOutputDiv').scroll(function (e) {
                var elt = $(this);
                // debounce
                $.doTimeout('pyCodeOutputDivScroll', 100, function () {
                    // note that this will send a signal back and forth both ways
                    if (exports.TogetherJS.running && !this.isPlayingDemo) {
                        // (there's no easy way to prevent this), but it shouldn't keep
                        // bouncing back and forth indefinitely since no the second signal
                        // causes no additional scrolling
                        exports.TogetherJS.send({ type: "pyCodeOutputDivScroll",
                            scrollTop: elt.scrollTop() });
                    }
                });
            });
        }
        else {
            pytutor_1.assert(false);
        }
    };
    OptFrontendSharedSessions.prototype.finishSuccessfulExecution = function () {
        var _this = this;
        pytutor_1.assert(this.myVisualizer);
        this.myVisualizer.add_pytutor_hook("end_updateOutput", function (args) {
            if (_this.updateOutputSignalFromRemote) {
                return [true]; // die early; no more hooks should run after this one!
            }
            if (exports.TogetherJS.running && !_this.isPlayingDemo && !_this.isExecutingCode) {
                exports.TogetherJS.send({ type: "updateOutput", step: args.myViz.curInstr });
            }
            return [false]; // pass through to let other hooks keep handling
        });
        // do this late since we want the hook in this function to be installed
        // FIRST so that it can run before the hook installed by our superclass
        _super.prototype.finishSuccessfulExecution.call(this);
        // VERY SUBTLE -- reinitialize TogetherJS at the END so that it can detect
        // and sync any new elements that are now inside myVisualizer
        if (exports.TogetherJS.running) {
            // TogetherJS.reinitialize() is ASYNCHRONOUS so the signal handler runs
            // way too late when we're playing a demo all at once using playFirstNSteps()
            // because all calls must be synchronous. in that case, use the
            // synchronous "equivalent":
            if (this.isPlayingDemo) {
                var setInit = exports.TogetherJS.config.get('setInit');
                setInit(); // this is synchronous so it happens instantly
                // TODO: does this do everything we need or do we
                // need to pull out more functionality from the handler
                // of TogetherJS.reinitialize()?
            }
            else {
                exports.TogetherJS.reinitialize();
            }
        }
    };
    // subclasses can override
    OptFrontendSharedSessions.prototype.updateOutputTogetherJsHandler = function (msg) {
        if (!msg.sameUrl)
            return; // make sure we're on the same page
        if (this.isExecutingCode) {
            return;
        }
        if (this.myVisualizer) {
            // to prevent this call to updateOutput from firing its own TogetherJS event
            this.updateOutputSignalFromRemote = true;
            try {
                this.myVisualizer.renderStep(msg.step);
            }
            finally {
                this.updateOutputSignalFromRemote = false;
            }
        }
    };
    OptFrontendSharedSessions.prototype.initTogetherJS = function () {
        var _this = this;
        pytutor_1.assert(exports.TogetherJS);
        if (togetherjsInUrl) { // kinda gross global
            $("#ssDiv,#surveyHeader").hide(); // hide ASAP!
            $("#togetherjsStatus").html("Please wait ... loading live help chat session");
        }
        // clear your name from the cache every time to prevent privacy leaks
        if (opt_frontend_common_1.supports_html5_storage()) {
            localStorage.removeItem('togetherjs.settings.name');
        }
        // this event triggers when some new user joins (whether it's you or
        // someone else) and says 'hello' ... the server attempts to
        // geolocate their IP address server-side (since it's more accurate
        // than doing it client-side, apparently) ...
        //
        // 2018-06-22: *disabled* this feature in
        // ../../v3/opt_togetherjs/server.js since ipstack.com limits number of
        // API calls per month, so we don't want to exceed limits!
        exports.TogetherJS.hub.on("togetherjs.pg-hello-geolocate", function (msg) {
            if (!msg.sameUrl)
                return; // make sure we're on the same page
            // make sure clientId isn't YOU so you don't display info about yourself:
            var myClientId = exports.TogetherJS.clientId();
            if (msg.clientId != myClientId) {
                var geo = msg.geo;
                var curStr;
                // follow the same format as how geolocation data is displayed
                // in the public help queue
                if (geo.country_name && geo.city) {
                    // print 'region_name' (i.e., state) for US addresses:
                    if (geo.country_name === "United States" && geo.region_name) {
                        curStr = geo.city + ', ' + geo.region_name + ', US';
                    }
                    else {
                        curStr = geo.city + ', ' + geo.country_name;
                    }
                }
                else if (geo.country_name) {
                    curStr = geo.country_name;
                }
                else if (geo.city) {
                    curStr = geo.city;
                }
                if (curStr) {
                    curStr = 'Someone from ' + curStr + ' just joined this chat.';
                    _this.chatbotPostMsg(curStr);
                }
            }
        });
        // This event triggers when you first join a session and say 'hello',
        // and then one of your peers says hello back to you. If they have the
        // exact same name as you, then change your own name to avoid ambiguity.
        // Remember, they were here first (that's why they're saying 'hello-back'),
        // so they keep their own name, but you need to change yours :)
        exports.TogetherJS.hub.on("togetherjs.hello-back", function (msg) {
            if (!msg.sameUrl)
                return; // make sure we're on the same page
            var p = exports.TogetherJS.require("peers");
            var peerNames = p.getAllPeers().map(function (e) { return e.name; });
            if (msg.name == p.Self.name) {
                var newName = undefined;
                var toks = msg.name.split(' ');
                var count = Number(toks[1]);
                // make sure the name is truly unique, incrementing count as necessary
                do {
                    if (!isNaN(count)) {
                        newName = toks[0] + '_' + String(count + 1); // e.g., "Tutor 3"
                        count++;
                    }
                    else {
                        // the original name was something like "Tutor", so make
                        // newName into, say, "Tutor 2"
                        newName = p.Self.name + '_2';
                        count = 2;
                    }
                } while ($.inArray(newName, peerNames) >= 0); // i.e., is newName in peerNames?
                p.Self.update({ name: newName }); // change our own name
            }
            // TODO: ugh this doesn't quite work since it sends this message
            // to EVERYONE except for the session creator (which gets
            // triggered whenever ANYONE enters the room, not just you)
            //if (!this.meCreatedThisSession()) {
            //  // 2019-03-26: display a more prominent warning here:
            //  this.chatbotPostMsg('Thanks for helping! This service is NOT being actively maintained, so it may crash at any time. Please do not contact the site owner for technical support or feature requests.');
            //}
        });
        // someone ELSE sent a chat
        exports.TogetherJS.hub.on("togetherjs.chat", function (msg) {
            var obj = _this.sessionActivityStats.numChatsByPeers;
            if (!(obj[msg.clientId])) {
                obj[msg.clientId] = 0;
            }
            obj[msg.clientId]++;
        });
        // someone ELSE edited code
        exports.TogetherJS.hub.on("editCode", function (msg) {
            var obj = _this.sessionActivityStats.numCodeEditsByPeers;
            if (!(obj[msg.clientId])) {
                obj[msg.clientId] = 0;
            }
            obj[msg.clientId]++;
        });
        // someone (other than you) left this session; if *you* left, then
        // TogetherJS will be shut off by the time this signal is sent, so
        // this callback function won't run
        exports.TogetherJS.hub.on("togetherjs.bye", function (msg) {
            _this.takeFullCodeSnapshot(); // take a snapshot whenever someone leaves so that we can undo to the point right before they left
            console.log('PEER JUST LEFT: # chats, # code edits:', _this.sessionActivityStats.numChatsByPeers[msg.clientId], _this.sessionActivityStats.numCodeEditsByPeers[msg.clientId]);
            // A/B test the pay-it-forward nudge
            //
            // if YOU were the help requester, and the person who just left had
            // >= 10 chats or code edits, then they did SOMETHING non-trivial, so
            // possibly pop up a pay-it-forward message. they're not
            // guaranteed to have successfully helped you, but at least they
            // did something and weren't just lurking silently.
            //
            // note that we use this.iMadeAPublicHelpRequest, which will pick up
            // on only those requests you made by putting yourself on the public
            // help queue
            if (_this.iMadeAPublicHelpRequest &&
                ((_this.sessionActivityStats.numChatsByPeers[msg.clientId] >= 10) ||
                    (_this.sessionActivityStats.numCodeEditsByPeers[msg.clientId] >= 10))) {
                var isRealPayItForward = (_this.abTestSettings && _this.abTestSettings.payItForward < 0.5);
                if (isRealPayItForward) {
                    _this.chatbotPostMsg(_this.payItForwardMsg);
                }
                // regardless of isRealPayItForward, log an entry on the server to aid in data analysis later:
                // note that we co-opt the 'nudge' endpoint for simplicity
                var nudgeUrl = exports.TogetherJS.config.get("hubBase").replace(/\/*$/, "") + "/nudge";
                $.ajax({
                    url: nudgeUrl,
                    dataType: "json",
                    data: { nudgeType: 'payItForward',
                        v: _this.payItForwardMsgVersion,
                        info: 'peerJustLeft',
                        isRealNudge: isRealPayItForward,
                        id: exports.TogetherJS.shareId(),
                        user_uuid: _this.userUUID },
                    success: function () { },
                    error: function () { },
                });
            }
        });
        exports.TogetherJS.hub.on("updateOutput", this.updateOutputTogetherJsHandler.bind(this));
        exports.TogetherJS.hub.on("executeCode", function (msg) {
            if (!msg.sameUrl)
                return; // make sure we're on the same page
            if (_this.isExecutingCode) {
                return;
            }
            _this.executeCodeSignalFromRemote = true;
            try {
                _this.executeCode(msg.forceStartingInstr, msg.rawInputLst);
            }
            finally {
                _this.executeCodeSignalFromRemote = false;
            }
        });
        exports.TogetherJS.hub.on("hashchange", function (msg) {
            if (!msg.sameUrl)
                return; // make sure we're on the same page
            if (_this.isExecutingCode) {
                return;
            }
            console.log("TogetherJS RECEIVE hashchange", msg.appMode);
            if (msg.appMode != _this.appMode) {
                _this.updateAppDisplay(msg.appMode);
                if (_this.appMode == 'edit' && msg.codeInputScrollTop !== undefined &&
                    _this.pyInputGetScrollTop() != msg.codeInputScrollTop) {
                    // hack: give it a bit of time to settle first ...
                    $.doTimeout('pyInputCodeMirrorInit', 200, function () {
                        _this.pyInputSetScrollTop(msg.codeInputScrollTop);
                    });
                }
            }
        });
        exports.TogetherJS.hub.on("codemirror-edit", function (msg) {
            if (!msg.sameUrl)
                return; // make sure we're on the same page
            $("#codeInputWarnings").hide();
            $("#someoneIsTypingDiv").show();
            $.doTimeout('codeMirrorWarningTimeout', 500, function () {
                $("#codeInputWarnings").show();
                $("#someoneIsTypingDiv").hide();
            });
        });
        exports.TogetherJS.hub.on("requestSync", function (msg) {
            // DON'T USE msg.sameUrl check here since it doesn't work properly, eek!
            exports.TogetherJS.send({ type: "myAppState",
                myAppState: _this.getAppState(),
                codeInputScrollTop: _this.pyInputGetScrollTop(),
                pyCodeOutputDivScrollTop: _this.myVisualizer ?
                    _this.myVisualizer.domRoot.find('#pyCodeOutputDiv').scrollTop() :
                    undefined });
        });
        // if you *received* this signal from someone, that means someone new just
        // joined your session. check if you've previously kicked them out ...
        // if so, FORCEABLY kick them out again to prevent people from somehow
        // sneaking back into your session. thus, we have defense in depth of
        // enforcing the ban from both the client and server sides ...
        exports.TogetherJS.hub.on("initialAppState", function (msg) {
            // take a snapshot whenever someone joins your session so that if
            // they destroy/deface your code, at least you can restore it to
            // what was there right before they joined
            _this.takeFullCodeSnapshot();
            _this.peopleIveKickedOut.forEach(function (e) {
                if (e === msg.clientId) {
                    console.log(e, "trying to sneak back in, kicking out again", _this.peopleIveKickedOut);
                    exports.TogetherJS.send({ type: "kickOutAgainBecauseSnuckBackIn", idToKick: e }); // server doesn't do anything with this; just log it for posterity
                    exports.TogetherJS.send({ type: "kickOut", idToKick: e });
                }
            });
            // 2018-06-22: *disabled* pg-hello-geolocate feature in
            // ../../v3/opt_togetherjs/server.js since ipstack.com limits number of
            // API calls per month, so we don't want to exceed limits!
            // instead display a generic "Someone just joined this session" msg
            //
            // make sure clientId isn't YOU so you don't display info about yourself:
            var myClientId = exports.TogetherJS.clientId();
            if (msg.clientId != myClientId) {
                //this.chatbotPostMsg('Someone just joined this session.');
                // 2019-04-01: display a more dire warning about server load:
                /*
                if (this.meCreatedThisSession()) {
                  this.chatbotPostMsg('Someone just joined. The server may get slow or crash if too many users join. Use button at top to *make your session private* so nobody else can join.');
                } else {
                  this.chatbotPostMsg('Someone just joined. The server may get slow or crash if too many users join.');
                }
                */
                // 2019-08-26: altered the message a bit ...
                if (_this.meCreatedThisSession()) {
                    _this.chatbotPostMsg('Someone just joined; please be polite since they are volunteering here for free. Server may crash if too many join; use button at top to *make session private* so nobody else can join.');
                }
                else {
                    _this.chatbotPostMsg('Someone just joined; server may crash if too many users join.');
                }
            }
        });
        exports.TogetherJS.hub.on("myAppState", function (msg) {
            // DON'T USE msg.sameUrl check here since it doesn't work properly, eek!
            // if we didn't explicitly request a sync, then don't do anything
            if (!_this.togetherjsSyncRequested) {
                return;
            }
            _this.togetherjsSyncRequested = false;
            var learnerAppState = msg.myAppState;
            if (learnerAppState.mode == 'display') {
                if (OptFrontendSharedSessions.appStateEq(_this.getAppState(), learnerAppState)) {
                    // update curInstr only
                    console.log("on:myAppState - app states equal, renderStep", learnerAppState.curInstr);
                    _this.myVisualizer.renderStep(learnerAppState.curInstr);
                    if (msg.pyCodeOutputDivScrollTop !== undefined) {
                        _this.myVisualizer.domRoot.find('#pyCodeOutputDiv').scrollTop(msg.pyCodeOutputDivScrollTop);
                    }
                }
                else if (!_this.isExecutingCode) { // if already executing from a prior signal, ignore
                    console.log("on:myAppState - app states unequal, executing", learnerAppState);
                    _this.syncAppState(learnerAppState);
                    _this.executeCodeSignalFromRemote = true;
                    try {
                        if (msg.pyCodeOutputDivScrollTop !== undefined) {
                            _this.pendingCodeOutputScrollTop = msg.pyCodeOutputDivScrollTop;
                        }
                        var learnerRawInputLst = JSON.parse(learnerAppState.rawInputLstJSON);
                        if (learnerRawInputLst && learnerRawInputLst.length > 0) {
                            _this.executeCode(learnerAppState.curInstr, learnerRawInputLst);
                        }
                        else {
                            _this.executeCode(learnerAppState.curInstr);
                        }
                    }
                    finally {
                        _this.executeCodeSignalFromRemote = false;
                    }
                }
            }
            else {
                pytutor_1.assert(learnerAppState.mode == 'edit');
                if (!OptFrontendSharedSessions.appStateEq(_this.getAppState(), learnerAppState)) {
                    console.log("on:myAppState - edit mode sync");
                    _this.syncAppState(learnerAppState);
                    _this.enterEditMode();
                }
            }
            if (msg.codeInputScrollTop !== undefined) {
                // give pyInputAceEditor a bit of time to settle with
                // its new value. this is hacky; ideally we have a callback for
                // when setValue() completes.
                $.doTimeout('pyInputCodeMirrorInit', 200, function () {
                    _this.pyInputSetScrollTop(msg.codeInputScrollTop);
                });
            }
        });
        exports.TogetherJS.hub.on("syncAppState", function (msg) {
            if (!msg.sameUrl)
                return; // make sure we're on the same page
            _this.syncAppState(msg.myAppState);
        });
        exports.TogetherJS.hub.on("codeInputScroll", function (msg) {
            if (!msg.sameUrl)
                return; // make sure we're on the same page
            // don't sync for Ace editor since I can't get it working properly yet
        });
        exports.TogetherJS.hub.on("pyCodeOutputDivScroll", function (msg) {
            if (!msg.sameUrl)
                return; // make sure we're on the same page
            if (_this.myVisualizer) {
                _this.myVisualizer.domRoot.find('#pyCodeOutputDiv').scrollTop(msg.scrollTop);
            }
        });
        // someone issued a kickOut message to kick somebody out of the
        // session; maybe it's you, maybe it isn't ...
        exports.TogetherJS.hub.on("kickOut", function (msg) {
            var myClientId = exports.TogetherJS.clientId();
            //console.log('RECEIVED kickOut', msg.idToKick, myClientId);
            // disconnect yourself if idToKick matches your client id:
            if (msg.idToKick && msg.idToKick === myClientId) {
                // first send a message of shame to the server ...
                exports.TogetherJS.send({ type: "iGotKickedOut",
                    clientId: myClientId,
                    user_uuid: _this.userUUID });
                // then nuke all of your shared sessions controls so that you
                // have to restart a new browser session before trying to get
                // back into anything; otherwise you might be able to jump back
                // in instantly using your same session #weird:
                $("#requestHelpBtn,#ssDiv").remove(); // totally remove them, eeek!
                exports.TogetherJS(); // ... then shut down TogetherJS
            }
        });
        // fired when TogetherJS is activated. might fire on page load if there's
        // already an open session from a prior page load in the recent past.
        exports.TogetherJS.on("ready", function () {
            console.log("TogetherJS ready");
            $("#sharedSessionDisplayDiv").show();
            $("#ssDiv,#testCasesParent").hide();
            // 2019-04-09: hide live programming mode whenever you're in a shared session
            $("#liveModeBtn").hide();
            // send this to the server for the purposes of logging, but other
            // clients shouldn't do anything with this data
            if (exports.TogetherJS.running && !_this.isPlayingDemo) {
                exports.TogetherJS.send({ type: "initialAppState",
                    myAppState: _this.getAppState(),
                    user_uuid: _this.userUUID,
                    // so that you can tell whether someone else
                    // shared a TogetherJS URL with you to invite you
                    // into this shared session:
                    togetherjsInUrl: togetherjsInUrl }); // kinda gross global
            }
            _this.requestSync(); // immediately try to sync upon startup so that if
            // others are already in the session, we will be
            // synced up. and if nobody is here, then this is a NOP.
            _this.TogetherjsReadyHandler();
            _this.redrawConnectors(); // update all arrows at the end
        });
        // emitted when TogetherJS is closed. This is not emitted when the
        // webpage simply closes or navigates elsewhere, ONLY when TogetherJS
        // is explicitly stopped via a call to TogetherJS()
        exports.TogetherJS.on("close", function () {
            console.log("TogetherJS close");
            $("#togetherjsStatus").html('<div id="publicHelpQueue"></div>'); // clear it (tricky! leave a publicHelpQueue node here!)
            $("#sharedSessionDisplayDiv").hide();
            $("#ssDiv,#requestHelpBtn,#testCasesParent").show();
            _this.TogetherjsCloseHandler();
            _this.redrawConnectors(); // update all arrows at the end
        });
        // for codcasts: note that there's only ONE cursor, so this isn't
        // like Google Docs where each user gets their own cursor. this may
        // cause some confusion during attempted simultaneous editing
        //
        // TODO: should we record these to the codechella logs?
        exports.TogetherJS.hub.on("aceChangeCursor", function (msg) {
            //console.warn('TogetherJS.hub.on("aceChangeCursor"', msg.row, msg.column);
            _this.pyInputAceEditor.selection.moveCursorTo(msg.row, msg.column, false /* keepDesiredColumn */);
        });
        exports.TogetherJS.hub.on("aceChangeSelection", function (msg) {
            //console.warn('TogetherJS.hub.on("aceChangeSelection"', msg.start, msg.end);
            _this.pyInputAceEditor.selection.setSelectionRange(new _this.Range(msg.start.row, msg.start.column, msg.end.row, msg.end.column), false /* reverse */);
        });
    };
    OptFrontendSharedSessions.prototype.requestSync = function () {
        if (exports.TogetherJS.running) {
            this.togetherjsSyncRequested = true;
            exports.TogetherJS.send({ type: "requestSync" });
        }
    };
    OptFrontendSharedSessions.prototype.syncAppState = function (appState) {
        this.setToggleOptions(appState);
        // VERY VERY subtle -- temporarily prevent TogetherJS from sending
        // form update events while we set the input value. otherwise
        // this will send an incorrect delta to the other end and screw things
        // up because the initial states of the two forms aren't equal.
        var orig = exports.TogetherJS.config.get('ignoreForms');
        exports.TogetherJS.config('ignoreForms', true);
        this.pyInputSetValue(appState.code);
        exports.TogetherJS.config('ignoreForms', orig);
        if (appState.rawInputLst) {
            this.rawInputLst = $.parseJSON(appState.rawInputLstJSON);
        }
        else {
            this.rawInputLst = [];
        }
    };
    // TogetherJS is ready to rock and roll, so do real initiatlization all here:
    OptFrontendSharedSessions.prototype.TogetherjsReadyHandler = function () {
        if (this.isPlayingDemo) {
            this.demoVideo.playbackTogetherJsReady();
            exports.TogetherJS.send({ type: "startPlayingDemo" }); // so that we can tell in the TogetherJS logs which sessions are demo plays; we can filter those out later
            return; // GET OUT EARLY!!! don't do the rest if you're playing a demo
        }
        this.takeFullCodeSnapshot();
        $("#surveyHeader").hide();
        // disable syntax and runtime surveys when shared sessions is on:
        this.activateSyntaxErrorSurvey = false;
        this.activateRuntimeErrorSurvey = false;
        this.activateEurekaSurvey = false;
        $("#eureka_survey").remove(); // if a survey is already displayed on-screen, then kill it
        this.sessionActivityStats = {
            // Key: clientId of another person who's joined this session
            // Value: number of times these events occurred
            numChatsByPeers: {},
            numCodeEditsByPeers: {},
        };
        if (this.wantsPublicHelp) {
            this.initRequestPublicHelp();
        }
        else {
            this.initPrivateSharedSession();
        }
    };
    OptFrontendSharedSessions.prototype.TogetherjsCloseHandler = function () {
        // A/B test the pay-it-forward nudge
        //
        // if YOU were the help requester and ANYONE in your session had
        // >= 10 chats or code edits, then they did SOMETHING non-trivial, so
        // possibly pop up a pay-it-forward message. they're not
        // guaranteed to have successfully helped you, but at least they
        // did something and weren't just lurking silently.
        //
        // note that we use this.iMadeAPublicHelpRequest, which will pick up
        // on only those requests you made by putting yourself on the public
        // help queue
        if (this.iMadeAPublicHelpRequest) {
            var nonTrivialSession = false;
            var ncbp = this.sessionActivityStats.numChatsByPeers;
            var ncebp = this.sessionActivityStats.numCodeEditsByPeers;
            for (var key in ncbp) {
                if (ncbp[key] >= 10) {
                    nonTrivialSession = true;
                    break;
                }
            }
            for (var key in ncebp) {
                if (ncebp[key] >= 10) {
                    nonTrivialSession = true;
                    break;
                }
            }
            if (nonTrivialSession) {
                var isRealPayItForward = (this.abTestSettings && this.abTestSettings.payItForward < 0.5);
                if (isRealPayItForward) {
                    // we can't use the chatbot since we just closed the TogetherJS session, so we'll have to go with an alert
                    // TODO: replace with a less annoying modal pop-up in the future, maybe from jQuery UI
                    alert(this.payItForwardMsg);
                }
                // regardless of isRealPayItForward, log an entry on the server to aid in data analysis later:
                // note that we co-opt the 'nudge' endpoint for simplicity
                var nudgeUrl = exports.TogetherJS.config.get("hubBase").replace(/\/*$/, "") + "/nudge";
                $.ajax({
                    url: nudgeUrl,
                    dataType: "json",
                    data: { nudgeType: 'payItForward',
                        v: this.payItForwardMsgVersion,
                        info: 'sessionStopped',
                        isRealNudge: isRealPayItForward,
                        //id: TogetherJS.shareId(), // we don't have a shareId anymore since the session has been stopped
                        user_uuid: this.userUUID },
                    success: function () { },
                    error: function () { },
                });
            }
        }
        if (this.appMode === "display") {
            $("#surveyHeader").show();
        }
        this.wantsPublicHelp = false; // explicitly reset it
        this.iMadeAPublicHelpRequest = false; // explicitly reset it
        if (this.isPlayingDemo) {
            this.demoVideo.stopPlayback();
            pytutor_1.assert(!this.isPlayingDemo);
        }
    };
    OptFrontendSharedSessions.prototype.startSharedSession = function (wantsPublicHelp) {
        $("#ssDiv,#surveyHeader").hide(); // hide ASAP!
        $("#togetherjsStatus").html("Please wait ... loading live help chat session");
        exports.TogetherJS();
        // TODO: unify everything into 1 boolean
        this.wantsPublicHelp = wantsPublicHelp;
    };
    OptFrontendSharedSessions.prototype.requestPublicHelpButtonClick = function () {
        if (exports.TogetherJS.running) {
            // TogetherJS is already running
            this.wantsPublicHelp = true;
            this.initRequestPublicHelp();
        }
        else {
            // TogetherJS isn't running yet, so start up a shared session AND
            // request public help at the same time ...
            this.startSharedSession(true);
        }
    };
    // return whether two states match, except don't worry about curInstr
    OptFrontendSharedSessions.appStateEq = function (s1, s2) {
        pytutor_1.assert(s1.origin == s2.origin); // sanity check!
        return (s1.code == s2.code &&
            s1.mode == s2.mode &&
            s1.cumulative == s2.cumulative &&
            s1.heapPrimitives == s1.heapPrimitives &&
            s1.textReferences == s2.textReferences &&
            s1.py == s2.py &&
            s1.rawInputLstJSON == s2.rawInputLstJSON);
    };
    OptFrontendSharedSessions.prototype.initRequestPublicHelp = function () {
        pytutor_1.assert(this.wantsPublicHelp);
        pytutor_1.assert(exports.TogetherJS.running);
        var shareId = exports.TogetherJS.shareId();
        // pop up the survey BEFORE you make the request, so in case you get
        // hung up on the prompt() and take a long time to answer the question,
        // you're not put on the queue yet until you finish or click Cancel:
        //
        // 2018-06-24: don't show the user repeated questions (noRepeats=true)
        // 2018-08-09: remove this feature entirely for help requests only
        //             since Chrome seems to handle prompt() weirdly now
        //             (it seems to have done so for quite a while);
        //             [it still seems fine when someone is *volunteering* to help]
        //             consider using JS library for pop-up questions in the future
        /*
        var surveyItem = randomlyPickSurveyItem('requestHelp', true);
        if (surveyItem) {
          var miniSurveyResponse = prompt(surveyItem.prompt);
    
          // always log every impression, even if miniSurveyResponse is blank,
          // since we can know how many times that survey question was ever seen:
          var surveyUrl = TogetherJS.config.get("hubBase").replace(/\/*$/, "") + "/survey";
          $.ajax({
            url: surveyUrl,
            dataType: "json",
            data: {id: shareId, user_uuid: this.userUUID, kind: 'requestHelp', v: surveyItem.v, response: miniSurveyResponse},
            success: function() {}, // NOP
            error: function() {},   // NOP
          });
        }
        */
        this.iMadeAPublicHelpRequest = true; // this will always be true even if you shut the door later and don't let people in (i.e., make this into a private session)
        // first make a /requestPublicHelp request to the TogetherJS server:
        var rphUrl = exports.TogetherJS.config.get("hubBase").replace(/\/*$/, "") + "/requestPublicHelp";
        var shareUrl = exports.TogetherJS.shareUrl();
        var lang = this.getAppState().py;
        var getUserName = exports.TogetherJS.config.get("getUserName");
        var username = getUserName();
        $.ajax({
            url: rphUrl,
            dataType: "json",
            data: { id: shareId, url: shareUrl, lang: lang, username: username, user_uuid: this.userUUID },
            success: this.doneRequestingPublicHelp.bind(this),
            error: this.rphError.bind(this),
        });
    };
    OptFrontendSharedSessions.prototype.rphError = function () {
        alert("ERROR in getting live help. This isn't working at the moment. Please try again later.");
        if (exports.TogetherJS.running) {
            exports.TogetherJS(); // shut down TogetherJS
        }
        this.redrawConnectors(); // update all arrows at the end
    };
    OptFrontendSharedSessions.prototype.doneRequestingPublicHelp = function (resp) {
        pytutor_1.assert(exports.TogetherJS.running);
        if (resp.status === "OKIE DOKIE") {
            $("#togetherjsStatus").html("\n        <div id=\"moderationPanel\"></div>\n        <div style=\"margin-bottom: 10px;\">You have requested help as <span class=\"redBold\">" +
                exports.TogetherJS.config.get("getUserName")() +
                "</span>. <span id=\"numObserversSpan\"></span></div>\n        <div id=\"publicHelpQueue\"></div>");
            // 2019-03-26: removed this line from next to numObserversSpan
            // "The longer you wait, the more likely that someone on this website will volunteer to help you. But there is no guarantee that someone will come help."
            this.updateModerationPanel(); // update it right away
            this.getHelpQueue(); // update it right away
            this.getNumObservers(); // update it right away
            this.appendTogetherJsFooter();
            $("#requestHelpBtn").hide();
            // 2019-03-26: display a more prominent warning here:
            //this.chatbotPostMsg('This service is NOT being maintained, so it may crash any time and lose your code. It is available for free with no technical support. Do not contact the site owner to make any feature requests.');
            // 2019-08-26: updated message
            this.chatbotPostMsg('Welcome! This service is free with no technical support and no quality guarantees of any kind. Please do NOT contact the site owner to make any requests about this service.');
        }
        else {
            alert("ERROR in getting live help. This isn't working at the moment. Please try again later.");
            if (exports.TogetherJS.running) {
                exports.TogetherJS(); // shut down TogetherJS
            }
        }
        this.redrawConnectors(); // update all arrows at the end
    };
    OptFrontendSharedSessions.prototype.initStopRequestingPublicHelp = function () {
        var rphUrl = exports.TogetherJS.config.get("hubBase").replace(/\/*$/, "") + "/requestPublicHelp";
        var shareId = exports.TogetherJS.shareId();
        $.ajax({
            url: rphUrl,
            dataType: "json",
            data: { id: shareId, user_uuid: this.userUUID, removeFromQueue: true },
            success: this.doneStopRequestingPublicHelp.bind(this),
            error: function () {
                alert("Server error: request failed. Please try again later.");
            },
        });
    };
    OptFrontendSharedSessions.prototype.doneStopRequestingPublicHelp = function () {
        this.wantsPublicHelp = false;
        this.initPrivateSharedSession();
    };
    OptFrontendSharedSessions.prototype.initPrivateSharedSession = function () {
        pytutor_1.assert(!this.wantsPublicHelp);
        if (!this.meCreatedThisSession()) { // you've joined someone else's session
            // if you're joining someone else's session, disable ALL chat
            // controls so that the only way out of the chat is to close your window;
            // otherwise confusion arises when you quit out of the session and
            // start a new one in the *same* window, which will re-join that
            // session just cuz that's how TogetherJS works; it's hella confusing.
            $("td#headerTdLeft").hide(); // TODO: make a better name for this!
            $("#togetherjsStatus").html("<div>Thanks for helping! Your username is <b>" + exports.TogetherJS.config.get("getUserName")() + "</b>. Close this window when you're done.</div>");
        }
        else { // you started your own session
            var urlToShare = exports.TogetherJS.shareUrl();
            $("#togetherjsStatus").html("\n        <div id=\"moderationPanel\"></div>\n        URL for others to join: <input type=\"text\" style=\"font-size: 10pt;\n        font-weight: bold; padding: 3px;\n        margin-top: 3pt;\n        margin-bottom: 6pt;\"\n        id=\"togetherjsURL\" size=\"70\" readonly=\"readonly\"/>");
            $("#togetherjsURL").val(urlToShare).attr('size', urlToShare.length + 20);
            this.updateModerationPanel(); // update it right away
        }
        this.appendTogetherJsFooter();
        this.redrawConnectors(); // update all arrows at the end
    };
    OptFrontendSharedSessions.prototype.appendTogetherJsFooter = function () {
        // deployed on 2019-03-26
        var extraHtml = '<div style="margin-top: 3px; margin-bottom: 6px; font-size: 9pt;">Don\'t move or type too fast. If you get out of sync, click <button id="syncBtn" type="button">force sync</button> </div>';
        // deployed on 2018-03-24
        //var extraHtml = '<div style="margin-top: 3px; margin-bottom: 6px; font-size: 9pt;"><a href="https://docs.google.com/forms/d/126ZijTGux_peoDusn1F9C1prkR226897DQ0MTTB5Q4M/viewform" target="_blank">Report bugs & feedback</a>. Don\'t move or type too fast. If you get out of sync, click <button id="syncBtn" type="button">force sync</button> </div>';
        // retired on 2018-03-24 to simplify the text on the page:
        //var extraHtml = '<div style="margin-top: 3px; margin-bottom: 10px; font-size: 8pt;">This is a <span style="color: #e93f34;">highly experimental</span> feature. Use at your own risk. Do not move or type too quickly. If you get out of sync, click: <button id="syncBtn" type="button">force sync</button> <a href="https://docs.google.com/forms/d/126ZijTGux_peoDusn1F9C1prkR226897DQ0MTTB5Q4M/viewform" target="_blank">Report bugs/feedback</a></div>';
        $("#togetherjsStatus").append(extraHtml);
        $("#syncBtn").click(this.requestSync.bind(this));
    };
    // mutates this.fullCodeSnapshots. snapshots the ENTIRE contents of
    // the code rather than a diff, for simplicity.
    // don't do this too frequently or else things might blow up.
    OptFrontendSharedSessions.prototype.takeFullCodeSnapshot = function () {
        var _this = this;
        var curCod = this.pyInputGetValue();
        // brute-force search through all of this.fullCodeSnapshots for an
        // exact duplicate ... if it exists, then don't snapshot it again.
        // this is super crude/potentially-inefficient but is the most robust
        // way to check for changes in light of weird TogetherJS happenings
        for (var i = 0; i < this.fullCodeSnapshots.length; i++) {
            var e = this.fullCodeSnapshots[i];
            if (e == curCod) {
                return; // RETURN EARLY if there's a duplicate match!!!
            }
        }
        this.fullCodeSnapshots.push(curCod);
        console.log('takeFullCodeSnapshot', this.fullCodeSnapshots.length, 'idx:', this.curPeekSnapshotIndex);
        // only give the option to restore old versions if YOU started this session,
        // or else it's too confusing if everyone gets to restore as a free-for-all.
        // also wait until this.fullCodeSnapshots has more than 1 element.
        if ((this.fullCodeSnapshots.length > 1) &&
            ($("#codeInputWarnings #snapshotHistory").length == 0) /* if you haven't rendered it yet */ &&
            this.meCreatedThisSession()) {
            $("#codeInputWarnings #liveModeExtraWarning").remove(); // for ../live.html
            $("#codeInputWarnings").append("\n        <span id=\"snapshotHistory\" style=\"font-size: 9pt; margin-left: 5px;\">\n          <span style=\"color: red; font-weight: bold;\">UNDO</span>/restore old code:\n          <button id=\"prevSnapshot\">&lt; Prev</button>\n          <span id=\"curSnapIndex\"/>/<span id=\"numTotalSnaps\"/>\n          <button id=\"nextSnapshot\">Next &gt;</button>\n        </span>");
            $("#snapshotHistory #prevSnapshot").click(function () {
                if (_this.curPeekSnapshotIndex == 0) {
                    return;
                }
                _this.takeFullCodeSnapshot(); // try to snapshot *first* before you change the code
                if (_this.curPeekSnapshotIndex < 0) {
                    _this.curPeekSnapshotIndex = _this.fullCodeSnapshots.length - 1;
                }
                _this.curPeekSnapshotIndex--;
                _this.renderCodeSnapshot();
                exports.TogetherJS.send({ type: "snapshotPeek", btn: 'prev', idx: _this.curPeekSnapshotIndex, tot: _this.fullCodeSnapshots.length });
            });
            $("#snapshotHistory #nextSnapshot").click(function () {
                if (_this.curPeekSnapshotIndex >= _this.fullCodeSnapshots.length - 1) {
                    return;
                }
                if (_this.curPeekSnapshotIndex < 0) {
                    return; // meaningless if you're not peeking
                }
                _this.takeFullCodeSnapshot(); // try to snapshot *first* before you change the code
                _this.curPeekSnapshotIndex++;
                _this.renderCodeSnapshot();
                exports.TogetherJS.send({ type: "snapshotPeek", btn: 'next', idx: _this.curPeekSnapshotIndex, tot: _this.fullCodeSnapshots.length });
            });
        }
        // SUPER SUBTLE SH*T -- if we're taking a new snapshot, bring us to the
        // "latest" version right now, which means that we're no longer peeking
        this.curPeekSnapshotIndex = -1;
        // update the display at the end if necessary
        this.renderCodeSnapshot();
    };
    OptFrontendSharedSessions.prototype.renderCodeSnapshot = function () {
        // always update the display
        $("#codeInputWarnings #numTotalSnaps").html(String(this.fullCodeSnapshots.length));
        if (this.curPeekSnapshotIndex < 0) {
            $("#codeInputWarnings #curSnapIndex").html(String(this.fullCodeSnapshots.length));
        }
        else {
            $("#codeInputWarnings #curSnapIndex").html(String(this.curPeekSnapshotIndex + 1));
        }
        // if we're not peeking, then no need to re-render:
        if (this.curPeekSnapshotIndex < 0) {
            return;
        }
        //console.log('renderCodeSnapshot', this.fullCodeSnapshots.length, this.curPeekSnapshotIndex);
        var curCod = this.pyInputGetValue();
        var cod;
        // this shouldn't happen but fail-soft just in case
        if (this.curPeekSnapshotIndex >= this.fullCodeSnapshots.length) {
            cod = this.fullCodeSnapshots[this.fullCodeSnapshots.length - 1];
        }
        else {
            cod = this.fullCodeSnapshots[this.curPeekSnapshotIndex];
        }
        if (curCod != cod) { // don't re-render unless absolutely necessary
            this.pyInputSetValue(cod);
        }
    };
    // only take a snapshot in a shared session where you're not idle
    OptFrontendSharedSessions.prototype.periodicMaybeTakeSnapshot = function () {
        if (exports.TogetherJS.running && !this.isIdle) {
            this.takeFullCodeSnapshot();
        }
    };
    // send an encouraging nudge message in the chat box if you're not idle ...
    // deployed on 2017-12-10
    //
    // starting on 2018-03-16, set this up as an A/B test where if
    // (this.abTestSettings.nudge < 0.5), then we do a real nudge;
    // otherwise we don't do a nudge but log to the server that we did a
    // fake one so we have a record if it
    OptFrontendSharedSessions.prototype.periodicMaybeChatNudge = function () {
        var _this = this;
        // only do this if you're:
        // - currently in a chat
        // - not idle
        // - NOBODY else is in your sesssion besides you (i.e., no 'live' peers)
        if (!exports.TogetherJS.running || this.isIdle) {
            return;
        }
        var allPeers = exports.TogetherJS.require("peers").getAllPeers();
        var numLivePeers = 0;
        allPeers.forEach(function (e) {
            if (e.status !== "live") { // don't count people who've already left!!!
                return;
            }
            numLivePeers++;
        });
        if (numLivePeers > 0) {
            return;
        }
        // MASSIVE MASSIVE MASSIVE copy-and-paste from getHelpQueue()
        var ghqUrl = exports.TogetherJS.config.get("hubBase").replace(/\/*$/, "") + "/getHelpQueue";
        var curState = this.getAppState();
        $.ajax({
            url: ghqUrl,
            dataType: "json",
            data: { user_uuid: this.userUUID, lang: curState.py, mode: curState.mode, origin: curState.origin },
            error: function () {
                console.log('/getHelpQueue error');
            },
            success: function (resp) {
                if (resp && resp.length > 0) {
                    var myShareId = exports.TogetherJS.shareId();
                    var chatMsgs = [];
                    var idleTimeoutMs = 3 * 60 * 1000; // 3 minutes seems reasonable -- NB: copy-and-paste from getHelpQueue()
                    var selfOnQueue = false;
                    resp.forEach(function (e) {
                        if (e.id === myShareId) {
                            selfOnQueue = true;
                        }
                    });
                    if (!selfOnQueue) {
                        return; // don't bother doing anything if you're not even on the help queue
                    }
                    var otherActiveEntries = []; // what other entries are active so that we can nudge you to join them?
                    resp.forEach(function (e) {
                        // sometimes there are bogus incomplete entries on the queue. if
                        // there's not even a URL, then nobody can join the chat,
                        // so skip right away at the VERY BEGINNING:
                        if (!e.url) {
                            return;
                        }
                        // when testing on localhost, we sometimes use the
                        // production TogetherJS chat server, but we don't want to
                        // show localhost entries on the global queue for people on
                        // the real site since there's no way they can jump in to join
                        //
                        // i.e., if your browser isn't on localhost but the URL of
                        // the help queue entry is on localhost, then *don't* display it
                        if ((window.location.href.indexOf('localhost') < 0) &&
                            (e.url.indexOf('localhost') >= 0)) {
                            return;
                        }
                        // don't bother showing idle entries to the user since these
                        // people are probably away from their computer at the moment:
                        if (e.timeSinceLastMsg >= idleTimeoutMs) {
                            return;
                        }
                        // don't show your own entry!
                        if (e.id === myShareId) {
                            return;
                        }
                        // skip this entry if there's more than 1 person chatting at
                        // the moment, because we want to show only the sessions
                        // waiting on queue with NOBODY helping them out right now:
                        if ((e.numClients > 1) && (e.numChatters > 1)) {
                            return;
                        }
                        otherActiveEntries.push(e);
                    });
                    otherActiveEntries.forEach(function (e) {
                        var curStr = '\n- Help ' + pytutor_1.htmlspecialchars(e.username);
                        var langName = _this.langToEnglish(e.lang);
                        if (e.country && e.city) {
                            // print 'region' (i.e., state) for US addresses:
                            if (e.country === "United States" && e.region) {
                                curStr += ' from ' + e.city + ', ' + e.region + ', US with ' + langName;
                            }
                            else {
                                curStr += ' from ' + e.city + ', ' + e.country + ' with ' + langName;
                            }
                        }
                        else if (e.country) {
                            curStr += ' from ' + e.country + ' with ' + langName;
                        }
                        else if (e.city) {
                            curStr += ' from ' + e.city + ' with ' + langName;
                        }
                        else {
                            curStr += ' with ' + langName;
                        }
                        curStr += ': ' + e.url;
                        chatMsgs.push(curStr);
                    });
                    if (chatMsgs.length > 0) {
                        var finalMsg = 'Please be patient and keep working normally. These other users also need help right now. If you help them, maybe they can help you in return.';
                        chatMsgs.forEach(function (e) {
                            finalMsg += e;
                        });
                        // A/B test: log all nudges but only display it if it's real:
                        var isRealNudge = (_this.abTestSettings && _this.abTestSettings.nudge < 0.5);
                        if (isRealNudge) {
                            _this.chatbotPostMsg(finalMsg);
                        }
                        // regardless of isRealNudge, log an entry on the server to aid in data analysis later:
                        var nudgeUrl = exports.TogetherJS.config.get("hubBase").replace(/\/*$/, "") + "/nudge";
                        $.ajax({
                            url: nudgeUrl,
                            dataType: "json",
                            data: { isRealNudge: isRealNudge, id: myShareId, user_uuid: _this.userUUID, entriesJSON: JSON.stringify(otherActiveEntries) },
                            success: function () { },
                            error: function () { },
                        });
                    }
                }
            },
        });
    };
    // helper chatbot which posts a message in your chat box that *only you can see*
    OptFrontendSharedSessions.prototype.chatbotPostMsg = function (msg) {
        if (!exports.TogetherJS.running) {
            return;
        }
        var ui = exports.TogetherJS.require("ui");
        var sess = exports.TogetherJS.require("session");
        var p = exports.TogetherJS.require("peers");
        // mimic what's in lib/togetherjs/togetherjs/togetherjsPackage.js
        ui.chat.text({ text: 'CHATBOT: ' + msg,
            messageId: sess.clientId + "-" + Date.now(),
            peer: p.Self,
            notify: false });
    };
    // for codcasts:
    OptFrontendSharedSessions.prototype.setPlayPauseButton = function (state) {
        pytutor_1.assert(this.demoVideo);
        var me = $("#demoPlayBtn");
        if (state == 'playing') {
            me.data('status', 'playing');
            me.html('Pause');
            this.demoVideo.playFromCurrentFrame();
        }
        else {
            pytutor_1.assert(state == 'paused');
            me.data('status', 'paused');
            me.html('Play');
            this.demoVideo.pause();
        }
    };
    OptFrontendSharedSessions.prototype.startPlayback = function () {
        var _this = this;
        $("#ssDiv,#surveyHeader").hide(); // hide ASAP!
        $("#togetherjsStatus").html("<div><button id=\"demoPlayBtn\">Play</button></div>\n                                  <div style=\"margin-top: 10px;\" id=\"timeSlider\"/>");
        pytutor_1.assert(this.demoVideo);
        $("#demoPlayBtn").data('status', 'paused');
        $("#demoPlayBtn").click(function () {
            var me = $("#demoPlayBtn");
            if (me.data('status') == 'paused') {
                _this.setPlayPauseButton('playing');
            }
            else {
                pytutor_1.assert(me.data('status') == 'playing');
                _this.setPlayPauseButton('paused');
            }
        });
        var timeSliderDiv = $('#timeSlider');
        timeSliderDiv.css('width', '700px');
        var interruptedPlaying = false; // did we yank the slider while the video was playing?
        var totalNumFrames = this.demoVideo.getTotalNumFrames();
        timeSliderDiv.slider({
            min: 0,
            max: totalNumFrames,
            step: 1,
            // triggers only when the user *manually* slides, *not* when the
            // value has been changed programmatically
            slide: function (evt, ui) {
                if (_this.demoVideo.rafTimerId) {
                    // emulate YouTube by 'jumping' to the given frame and
                    // pausing, then resuming playback when you let go (see
                    // 'change' event handler)
                    _this.demoVideo.pause();
                    interruptedPlaying = true;
                }
                _this.demoVideo.jumpToFrame(ui.value);
            },
            // triggers both when user manually finishes sliding, and also
            // when the slider's value is set programmatically
            change: function (evt, ui) {
                // this is SUPER subtle. if this value was changed programmatically,
                // then evt.originalEvent will be undefined. however, if this value
                // was changed by a user-initiated event, then this code should be
                // executed ...
                if (evt.originalEvent) {
                    // slider value was changed by a user interaction; only do
                    // something special if interruptedPlaying is on, in which
                    // case resume playback. this happens AFTER a user-initiated
                    // 'slide' event is done:
                    if (interruptedPlaying) {
                        // literally an edge case -- if we've slid to the VERY END,
                        // don't resume playing since that will wrap back around to
                        // the beginning
                        if (ui.value < totalNumFrames) {
                            _this.demoVideo.playFromCurrentFrame();
                        }
                        else {
                            // if we've slide the slider to the very end, pause it!
                            _this.setPlayPauseButton('paused');
                        }
                        interruptedPlaying = false;
                    }
                }
                else {
                    // slider value was changed programmatically, so we're
                    // assuming that requestAnimationFrame has been used to schedule
                    // periodic changes to the slider
                    _this.demoVideo.jumpToFrame(ui.value);
                }
            }
        });
        // disable keyboard actions on the slider itself (to prevent double-firing
        // of events), and make skinnier and taller
        timeSliderDiv
            .find(".ui-slider-handle")
            .unbind('keydown')
            .css('width', '0.6em')
            .css('height', '1.5em');
        this.demoVideo.startPlayback(); // do this last
    };
    return OptFrontendSharedSessions;
}(opt_frontend_1.OptFrontend)); // END class OptFrontendSharedSessions
exports.OptFrontendSharedSessions = OptFrontendSharedSessions;

/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0), __webpack_require__(0)))

/***/ }),
/* 34 */
/***/ (function(module, exports, __webpack_require__) {


var content = __webpack_require__(37);

if(typeof content === 'string') content = [[module.i, content, '']];

var transform;
var insertInto;



var options = {"hmr":true}

options.transform = transform
options.insertInto = undefined;

var update = __webpack_require__(3)(content, options);

if(content.locals) module.exports = content.locals;

if(false) {
	module.hot.accept("!!../node_modules/css-loader/index.js!./opt-frontend.css", function() {
		var newContent = require("!!../node_modules/css-loader/index.js!./opt-frontend.css");

		if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];

		var locals = (function(a, b) {
			var key, idx = 0;

			for(key in a) {
				if(!b || a[key] !== b[key]) return false;
				idx++;
			}

			for(key in b) idx--;

			return idx === 0;
		}(content.locals, newContent.locals));

		if(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');

		update(newContent);
	});

	module.hot.dispose(function() { update(); });
}

/***/ }),
/* 35 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
/* WEBPACK VAR INJECTION */(function($) {
// Python Tutor: https://github.com/pgbovine/OnlinePythonTutor/
// Copyright (C) Philip Guo (philip@pgbovine.net)
// LICENSE: https://github.com/pgbovine/OnlinePythonTutor/blob/master/LICENSE.txt
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
__webpack_require__(0);
// just punt and use global script dependencies
__webpack_require__(38);
__webpack_require__(42);
__webpack_require__(41);
__webpack_require__(44);
__webpack_require__(39);
__webpack_require__(40);
__webpack_require__(43);
__webpack_require__(54);
// need to directly import the class for type checking to work
var opt_frontend_common_1 = __webpack_require__(32);
var pytutor_1 = __webpack_require__(4);
__webpack_require__(34);
__webpack_require__(55);
exports.allTabsRE = new RegExp('\t', 'g');
var JAVA_BLANK_TEMPLATE = "public class YourClassNameHere {\n    public static void main(String[] args) {\n\n    }\n}";
var CPP_BLANK_TEMPLATE = "int main() {\n\n  return 0;\n}";
var CODE_SNAPSHOT_DEBOUNCE_MS = 1000;
var SUBMIT_UPDATE_HISTORY_INTERVAL_MS = 1000 * 60;
function sanitizeURL(s) {
    return s.replace(/\(/g, '%28').replace(/\)/g, '%29'); // replace ( with %28 and ) with %29 so that links embed well in Markdown and email clients
}
var OptFrontend = /** @class */ (function (_super) {
    __extends(OptFrontend, _super);
    function OptFrontend(params) {
        if (params === void 0) { params = {}; }
        var _this = _super.call(this, params) || this;
        _this.originFrontendJsFile = 'opt-frontend.js';
        _this.pyInputAceEditor = undefined; // Ace editor object that contains the user's code
        // some subclasses use these, so put them in the superclass
        _this.activateSyntaxErrorSurvey = true;
        _this.activateRuntimeErrorSurvey = true;
        _this.activateEurekaSurvey = false; // taken down on 2019-10-19 because i really haven't looked at the data for a long time; see surveys.ts
        _this.demoMode = false; // if true, then we're giving a live demo, so hide a bunch of excess stuff on page
        _this.preseededCurInstr = undefined;
        $('#genEmbedBtn').bind('click', function () {
            var mod = _this.appMode;
            pytutor_1.assert(mod == 'display' || mod == 'visualize' /* deprecated */);
            var myArgs = _this.getAppState();
            delete myArgs.mode;
            myArgs.codeDivWidth = pytutor_1.ExecutionVisualizer.DEFAULT_EMBEDDED_CODE_DIV_WIDTH;
            myArgs.codeDivHeight = pytutor_1.ExecutionVisualizer.DEFAULT_EMBEDDED_CODE_DIV_HEIGHT;
            var domain = "http://pythontutor.com/"; // for deployment
            var embedUrlStr = $.param.fragment(domain + "iframe-embed.html", myArgs, 2 /* clobber all */);
            embedUrlStr = sanitizeURL(embedUrlStr);
            var iframeStr = '<iframe width="800" height="500" frameborder="0" src="' + embedUrlStr + '"> </iframe>';
            $('#embedCodeOutput').val(iframeStr);
        });
        _this.initAceEditor(420);
        // for some weird reason, jQuery doesn't work here:
        //   $(window).bind("hashchange"
        window.addEventListener("hashchange", function (e) {
            // if you've got some preseeded code, then parse the entire query
            // string from scratch just like a page reload
            if ($.bbq.getState('code')) {
                _this.parseQueryString();
            }
            else {
                // otherwise just do an incremental update
                var newMode = $.bbq.getState('mode');
                _this.updateAppDisplay(newMode);
            }
        });
        // also fires when you resize the jQuery UI slider, interesting!
        $(window).resize(_this.redrawConnectors.bind(_this));
        $('#genUrlBtn').bind('click', function () {
            var myArgs = _this.getAppState();
            var urlStr = $.param.fragment(window.location.href, myArgs, 2); // 2 means 'override'
            urlStr = sanitizeURL(urlStr);
            $('#urlOutput').val(urlStr);
        });
        /* 2019-04-09 took this down since google's URL shortener service shut down :/
        $('#genUrlShortenedBtn').bind('click', () => {
          var myArgs = this.getAppState();
          var urlStr = $.param.fragment(window.location.href, myArgs, 2); // 2 means 'override'
          urlStr = sanitizeURL(urlStr);
          // call goo.gl URL shortener
          //
          // to test this API from command-line, first disable the IP restriction on API credentials, then run:
          // curl https://www.googleapis.com/urlshortener/v1/url?key=AIzaSyCIjtNqfABbRilub1a3Ta7-qKF3bS9_p1M -H 'Content-Type: application/json' -d '{"longUrl": "http://www.google.com/"}'
          $.ajax('https://www.googleapis.com/urlshortener/v1/url?key=AIzaSyCIjtNqfABbRilub1a3Ta7-qKF3bS9_p1M',
                 {type: 'POST',
                 contentType: 'application/json',
                 data: JSON.stringify({longUrl: urlStr}), // encode as a string first! #tricky
                 success: function(dat) {
                   $("#urlOutputShortened").val(dat.id);
                 },
                 error: function() {
                   $("#urlOutputShortened").val("Error in URL shortener :(");
                 }
                 });
        });
        */
        // first initialize options from HTML LocalStorage. very important
        // that this code runs FIRST so that options get overridden by query
        // string options and anything else the user wants to override with.
        if (opt_frontend_common_1.supports_html5_storage() && !params.disableLocalStorageToggles) {
            var lsKeys = ['cumulative',
                'heapPrimitives',
                'py',
                'textReferences'];
            // restore toggleState if available
            var lsOptions = {};
            $.each(lsKeys, function (i, k) {
                var v = localStorage.getItem(k);
                if (v) {
                    lsOptions[k] = v;
                }
            });
            _this.setToggleOptions(lsOptions);
            // store in localStorage whenever user explicitly changes any toggle option:
            $('#cumulativeModeSelector,#heapPrimitivesSelector,#textualMemoryLabelsSelector,#pythonVersionSelector').change(function () {
                var ts = _this.getToggleState();
                $.each(ts, function (k, v) {
                    localStorage.setItem(k, v);
                });
            });
        }
        // when you leave or reload the page, submit an updateHistoryJSON if you
        // have one. beforeunload seems to work better than unload(), but it's
        // still a bit flaky ... TODO: investigate :(
        $(window).on('beforeunload', function () {
            _this.submitUpdateHistory('beforeunload');
            // don't return anything, or a modal dialog box might pop up
        });
        // just do this as well, even though it might be hella redundant
        $(window).on('unload', function () {
            _this.submitUpdateHistory('unload');
            // don't return anything, or a modal dialog box might pop up
        });
        // periodically do submitUpdateHistory() to handle the case when
        // someone is simply idle on the page without reloading it or
        // re-editing code; that way, we can still get some signals rather
        // than nothing.
        var lastSubmittedUpdateHistoryLength = 0;
        setInterval(function () {
            if (_this.myVisualizer) {
                var uh = _this.myVisualizer.updateHistory;
                // don't submit identical entries repeatedly since that's redundant
                if (uh && (uh.length != lastSubmittedUpdateHistoryLength)) {
                    lastSubmittedUpdateHistoryLength = uh.length;
                    _this.submitUpdateHistory('periodic');
                }
            }
        }, SUBMIT_UPDATE_HISTORY_INTERVAL_MS);
        _this.parseQueryString(); // do this at the end after Ace editor initialized
        return _this;
    }
    // Compress updateHistory before encoding and sending to
    // the server so that it takes up less room in the URL. Have each
    // entry except for the first be a delta from the FIRST entry.
    OptFrontend.prototype.compressUpdateHistoryList = function () {
        pytutor_1.assert(this.myVisualizer);
        var uh = this.myVisualizer.updateHistory;
        var encodedUh = [];
        if (uh) {
            encodedUh.push(uh[0]);
            var firstTs = uh[0][1];
            for (var i = 1; i < uh.length; i++) {
                var e = uh[i];
                encodedUh.push([e[0], e[1] - firstTs]);
            }
            // finally push a final entry with the current timestamp delta
            var curTs = new Date().getTime();
            encodedUh.push([this.myVisualizer.curInstr, curTs - firstTs]);
        }
        return encodedUh;
    };
    // this feature was deployed on 2015-09-17, so check logs for
    // viz_interaction.py
    OptFrontend.prototype.submitUpdateHistory = function (why) {
        if (this.myVisualizer) {
            var encodedUh = this.compressUpdateHistoryList();
            var encodedUhJSON = JSON.stringify(encodedUh);
            var myArgs = { session_uuid: this.sessionUUID,
                user_uuid: this.userUUID,
                updateHistoryJSON: encodedUhJSON };
            if (why) {
                myArgs.why = why;
            }
            $.get('viz_interaction.py', myArgs, function (dat) { });
        }
    };
    OptFrontend.prototype.initAceEditor = function (height) {
        var _this = this;
        pytutor_1.assert(!this.pyInputAceEditor);
        this.pyInputAceEditor = ace.edit('codeInputPane');
        var s = this.pyInputAceEditor.getSession();
        // tab -> 4 spaces
        s.setTabSize(4);
        s.setUseSoftTabs(true);
        // disable extraneous indicators:
        s.setFoldStyle('manual'); // no code folding indicators
        s.getDocument().setNewLineMode('unix'); // canonicalize all newlines to unix format
        this.pyInputAceEditor.setHighlightActiveLine(false);
        this.pyInputAceEditor.setShowPrintMargin(false);
        this.pyInputAceEditor.setBehavioursEnabled(false);
        this.pyInputAceEditor.$blockScrolling = Infinity; // kludgy to shut up weird warnings
        // auto-grow height as fit
        this.pyInputAceEditor.setOptions({ minLines: 18, maxLines: 1000 });
        $('#codeInputPane').css('width', '700px');
        $('#codeInputPane').css('height', height + 'px'); // VERY IMPORTANT so that it works on I.E., ugh!
        this.initDeltaObj();
        this.pyInputAceEditor.on('change', function (e) {
            // 2017-11-21: convert all tabs to 4 spaces so that when you paste
            // in code from somewhere else that contains tabs, instantly
            // change all those tabs to spaces. note that all uses of 'tab' key
            // within the Ace editor on this page will result in spaces (i.e.,
            // "soft tabs")
            var curVal = _this.pyInputGetValue();
            if (curVal.indexOf('\t') >= 0) {
                _this.pyInputSetValue(curVal.replace(exports.allTabsRE, '    '));
                console.log("Converted all tabs to spaces");
            }
            $.doTimeout('pyInputAceEditorChange', CODE_SNAPSHOT_DEBOUNCE_MS, _this.snapshotCodeDiff.bind(_this)); // debounce
            // starting on 2018-03-14 -- do NOT clear frontend errors and
            // annotations when you edit the code, since you may still want to
            // see the old error messages ... commented out these two lines:
            //this.clearFrontendError();
            //s.clearAnnotations();
        });
        // don't do real-time syntax checks:
        // https://github.com/ajaxorg/ace/wiki/Syntax-validation
        s.setOption("useWorker", false);
        this.setAceMode();
        this.pyInputAceEditor.focus();
    };
    OptFrontend.prototype.setAceMode = function () {
        var selectorVal = $('#pythonVersionSelector').val();
        var mod;
        var tabSize = 2;
        var editorVal = $.trim(this.pyInputGetValue());
        if (editorVal === JAVA_BLANK_TEMPLATE || editorVal === CPP_BLANK_TEMPLATE) {
            editorVal = '';
            this.pyInputSetValue(editorVal);
        }
        if (selectorVal === 'java') {
            mod = 'java';
            if (editorVal === '') {
                this.pyInputSetValue(JAVA_BLANK_TEMPLATE);
            }
        }
        else if (selectorVal === 'js') {
            mod = 'javascript';
        }
        else if (selectorVal === 'ts') {
            mod = 'typescript';
        }
        else if (selectorVal === 'ruby') {
            mod = 'ruby';
        }
        else if (selectorVal === 'c' || selectorVal == 'cpp') {
            mod = 'c_cpp';
            if (editorVal === '') {
                this.pyInputSetValue(CPP_BLANK_TEMPLATE);
            }
        }
        else {
            pytutor_1.assert(selectorVal === '2' || selectorVal == '3' || selectorVal == 'py3anaconda');
            mod = 'python';
            tabSize = 4; // PEP8 style standards
        }
        pytutor_1.assert(mod);
        var s = this.pyInputAceEditor.getSession();
        s.setMode("ace/mode/" + mod);
        s.setTabSize(tabSize);
        s.setUseSoftTabs(true);
        // clear all error displays when switching modes
        var s = this.pyInputAceEditor.getSession();
        s.clearAnnotations();
        if (selectorVal === 'java') {
            $("#javaOptionsPane").show();
        }
        else {
            $("#javaOptionsPane").hide();
        }
        if (selectorVal === 'js' || selectorVal === '2' || selectorVal === '3') {
            $("#liveModeBtn").show();
        }
        else {
            $("#liveModeBtn").hide();
        }
        this.clearFrontendError();
    };
    OptFrontend.prototype.pyInputGetValue = function () {
        return this.pyInputAceEditor.getValue();
    };
    OptFrontend.prototype.pyInputSetValue = function (dat) {
        this.pyInputAceEditor.setValue(dat.rtrim() /* kill trailing spaces */, -1 /* do NOT select after setting text */);
        $('#urlOutput,#urlOutputShortened,#embedCodeOutput').val('');
        this.clearFrontendError();
        // also scroll to top to make the UI more usable on smaller monitors
        // TODO: this has a global impact on the document, so breaks modularity?
        $(document).scrollTop(0);
    };
    OptFrontend.prototype.pyInputGetScrollTop = function () {
        return this.pyInputAceEditor.getSession().getScrollTop();
    };
    OptFrontend.prototype.pyInputSetScrollTop = function (st) {
        this.pyInputAceEditor.getSession().setScrollTop(st);
    };
    OptFrontend.prototype.executeCodeFromScratch = function () {
        // don't execute empty string:
        if (this.pyInputAceEditor && $.trim(this.pyInputGetValue()) == '') {
            this.setFronendError(["Type in some code to visualize."], true);
            return;
        }
        _super.prototype.executeCodeFromScratch.call(this);
    };
    OptFrontend.prototype.executeCode = function (forceStartingInstr, forceRawInputLst) {
        if (forceStartingInstr === void 0) { forceStartingInstr = 0; }
        if (forceRawInputLst === void 0) { forceRawInputLst = undefined; }
        // if you're in display mode, kick back into edit mode before executing
        // or else the display might not refresh properly ... ugh krufty
        if (this.appMode != 'edit') {
            this.enterEditMode();
        }
        if (forceRawInputLst !== undefined && forceRawInputLst !== null) {
            this.rawInputLst = forceRawInputLst;
        }
        var backendOptionsObj = this.getBaseBackendOptionsObj();
        var frontendOptionsObj = this.getBaseFrontendOptionsObj();
        frontendOptionsObj.startingInstruction = forceStartingInstr;
        this.snapshotCodeDiff(); // do ONE MORE snapshot before we execute, or else
        // we'll miss a diff if the user hits Visualize Execution
        // very shortly after finishing coding
        if (this.deltaObj) {
            this.deltaObj.executeTime = new Date().getTime();
        }
        this.executeCodeAndCreateViz(this.pyInputGetValue(), $('#pythonVersionSelector').val(), backendOptionsObj, frontendOptionsObj, 'pyOutputPane');
        this.initDeltaObj(); // clear deltaObj to start counting over again
    };
    OptFrontend.prototype.finishSuccessfulExecution = function () {
        var _this = this;
        this.enterDisplayMode(); // do this first!
        if (this.myVisualizer) {
            this.myVisualizer.add_pytutor_hook("end_updateOutput", function (args) {
                // TODO: implement for codeopticon
                // debounce to compress a bit ... 250ms feels "right"
                $.doTimeout('updateOutputLogEvent', 250, function () {
                    var obj = { type: 'updateOutput', step: args.myViz.curInstr,
                        curline: args.myViz.curLineNumber,
                        prevline: args.myViz.prevLineNumber };
                    // optional fields
                    if (args.myViz.curLineExceptionMsg) {
                        obj.exception = args.myViz.curLineExceptionMsg;
                    }
                    if (args.myViz.curLineIsReturn) {
                        obj.curLineIsReturn = true;
                    }
                    if (args.myViz.prevLineIsReturn) {
                        obj.prevLineIsReturn = true;
                    }
                    _this.logEventCodeopticon(obj);
                });
                // 2014-05-25: implemented more detailed tracing for surveys
                if (args.myViz.creationTime) {
                    var curTs = new Date().getTime();
                    var uh = args.myViz.updateHistory;
                    pytutor_1.assert(uh.length > 0); // should already be seeded with an initial value
                    if (uh.length > 1) { // don't try to "compress" the very first entry
                        var lastTs = uh[uh.length - 1][1];
                        // (debounce entries that are less than 1 second apart to
                        // compress the logs a bit when there's rapid scrubbing or scrolling)
                        if ((curTs - lastTs) < 1000) {
                            uh.pop(); // get rid of last entry before pushing a new entry
                        }
                    }
                    uh.push([args.myViz.curInstr, curTs]);
                }
                return [false]; // pass through to let other hooks keep handling
            });
        }
        // 2014-05-25: implemented more detailed tracing for surveys
        this.myVisualizer.creationTime = new Date().getTime();
        // each element will be a two-element list consisting of:
        // [step number, timestamp]
        // (debounce entries that are less than 1 second apart to
        // compress the logs a bit when there's rapid scrubbing or scrolling)
        //
        // the first entry has a THIRD field:
        // [step number, timestamp, total # steps]
        //
        // subsequent entries don't need it since it will always be the same.
        // the invariant is that step number < total # steps (since it's
        // zero-indexed
        this.myVisualizer.updateHistory = [];
        this.myVisualizer.updateHistory.push([this.myVisualizer.curInstr,
            this.myVisualizer.creationTime,
            this.myVisualizer.curTrace.length]);
    };
    OptFrontend.prototype.handleUncaughtException = function (trace) {
        if (trace.length == 1 && trace[0].line) {
            var errorLineNo = trace[0].line - 1; /* Ace lines are zero-indexed */
            if (errorLineNo !== undefined && errorLineNo != NaN) {
                // highlight the faulting line
                var s = this.pyInputAceEditor.getSession();
                s.setAnnotations([{ row: errorLineNo,
                        column: null,
                        type: 'error',
                        text: trace[0].exception_msg }]);
                this.pyInputAceEditor.gotoLine(errorLineNo + 1 /* one-indexed */);
                // if we have both a line and column number, then move over to
                // that column. (going to the line first prevents weird
                // highlighting bugs)
                if (trace[0].col !== undefined) {
                    this.pyInputAceEditor.moveCursorTo(errorLineNo, trace[0].col);
                }
                this.pyInputAceEditor.focus();
            }
        }
    };
    OptFrontend.prototype.ignoreAjaxError = function (settings) {
        // other idiosyncratic errors to ignore
        if ((settings.url.indexOf('syntax_err_survey.py') > -1) ||
            (settings.url.indexOf('runtime_err_survey.py') > -1) ||
            (settings.url.indexOf('eureka_survey.py') > -1) ||
            (settings.url.indexOf('error_log.py') > -1) ||
            (settings.url.indexOf('viz_interaction.py') > -1)) {
            return true;
        }
        return false;
    };
    OptFrontend.prototype.initDeltaObj = function () {
        pytutor_1.assert(this.pyInputAceEditor);
        // v is the version number
        //   1 (version 1 was released on 2014-11-05)
        //   2 (version 2 was released on 2015-09-16, added a startTime field)
        this.deltaObj = { start: this.pyInputGetValue(), deltas: [], v: 2,
            startTime: new Date().getTime() };
    };
    OptFrontend.prototype.snapshotCodeDiff = function () {
        pytutor_1.assert(this.deltaObj);
        var newCode = this.pyInputGetValue();
        var timestamp = new Date().getTime();
        if (this.curCode != newCode) {
            var diff = this.dmp.diff_toDelta(this.dmp.diff_main(this.curCode, newCode));
            //var patch = this.dmp.patch_toText(this.dmp.patch_make(this.curCode, newCode));
            var delta = { t: timestamp, d: diff };
            this.deltaObj.deltas.push(delta);
            this.curCode = newCode;
            this.logEditDelta(delta);
        }
    };
    OptFrontend.prototype.logEditDelta = function (delta) {
        this.logEventCodeopticon({ type: 'editCode', delta: delta });
    };
    OptFrontend.prototype.enterDisplayMode = function () {
        this.updateAppDisplay('display');
    };
    OptFrontend.prototype.enterEditMode = function () {
        this.updateAppDisplay('edit');
    };
    // try to make this function as idempotent as possible, so that
    // repeated calls with same params don't do anything bad
    OptFrontend.prototype.updateAppDisplay = function (newAppMode) {
        var _this = this;
        this.appMode = newAppMode;
        if (this.appMode === undefined || this.appMode == 'edit' ||
            !this.myVisualizer /* subtle -- if no visualizer, default to edit mode */) {
            this.appMode = 'edit'; // canonicalize
            $("#pyInputPane").show();
            $("#pyOutputPane,#embedLinkDiv").hide();
            // Potentially controversial: when you enter edit mode, DESTROY any
            // existing visualizer object. note that this simplifies the app's
            // conceptual model but breaks the browser's expected Forward and
            // Back button flow
            $("#pyOutputPane").empty();
            // right before destroying, submit the visualizer's updateHistory
            this.submitUpdateHistory('editMode');
            this.myVisualizer = null; // yikes!
            $(document).scrollTop(0); // scroll to top to make UX better on small monitors
            // *after* the editor is shown, force it to refresh its contents
            // (using the misleadingly-named resize(true) method)
            this.pyInputAceEditor.resize(true);
            var s = { mode: 'edit' };
            // keep these persistent so that they survive page reloads
            // keep these persistent so that they survive page reloads
            if (typeof codeopticonSession !== "undefined") {
                s.cosession = codeopticonSession;
            }
            if (typeof codeopticonUsername !== "undefined") {
                s.couser = codeopticonUsername;
            }
            $.bbq.pushState(s, 2 /* completely override other hash strings to keep URL clean */);
        }
        else if (this.appMode == 'display' || this.appMode == 'visualize' /* 'visualize' is deprecated */) {
            pytutor_1.assert(this.myVisualizer);
            this.appMode = 'display'; // canonicalize
            $("#pyInputPane").hide();
            $("#pyOutputPane,#embedLinkDiv").show();
            this.doneExecutingCode();
            // do this AFTER making #pyOutputPane visible, or else
            // jsPlumb connectors won't render properly
            this.myVisualizer.updateOutput();
            // use .off() to remove all handlers first, to prevent accidental
            // multiple attaches ...
            // customize edit button click functionality AFTER rendering myVisualizer
            $('#pyOutputPane #editCodeLinkDiv').show();
            $('#pyOutputPane #editBtn').off().click(function () {
                _this.enterEditMode();
            });
            var v = $('#pythonVersionSelector').val();
            // 2018-03-15 - removed "Live programming" link from
            // visualization mode to simplify the UI, even if it drives
            // fewer people to live programming mode; they can always click
            // the "Live Programming Mode" button in the code editor:
            /*
            if (v === 'js' || v === '2' || v === '3') {
              var myArgs = this.getAppState();
              var urlStr = $.param.fragment('live.html', myArgs, 2); // clobber all
              $("#pyOutputPane #liveModeSpan").show();
              $('#pyOutputPane #editLiveModeBtn').off().click(this.openLiveModeUrl.bind(this));
            } else {
              $("#pyOutputPane #liveModeSpan").hide();
            }
            */
            $(document).scrollTop(0); // scroll to top to make UX better on small monitors
            var s = { mode: 'display' };
            // keep these persistent so that they survive page reloads
            if (typeof codeopticonSession !== "undefined") {
                s.cosession = codeopticonSession;
            }
            if (typeof codeopticonUsername !== "undefined") {
                s.couser = codeopticonUsername;
            }
            $.bbq.pushState(s, 2 /* completely override other hash strings to keep URL clean */);
        }
        else {
            pytutor_1.assert(false);
        }
        $('#urlOutput,#urlOutputShortened,#embedCodeOutput').val(''); // clear to avoid stale values
        // log at the end after appMode gets canonicalized
        this.logEventCodeopticon({ type: 'updateAppDisplay', mode: this.appMode, appState: this.getAppState() });
        pytutor_1.assert(this.appMode === 'edit' || this.appMode === 'display'); // postcondition
    };
    OptFrontend.prototype.openLiveModeUrl = function () {
        var myArgs = this.getAppState();
        var urlStr = $.param.fragment('live.html', myArgs, 2 /* clobber all */);
        window.open(urlStr); // open in new tab
        return false; // to prevent default "a href" click action
    };
    OptFrontend.prototype.appStateAugmenter = function (x) { };
    ; // NOP
    // get the ENTIRE current state of the app
    OptFrontend.prototype.getAppState = function () {
        pytutor_1.assert(this.originFrontendJsFile);
        var ret = { code: this.pyInputGetValue(),
            mode: this.appMode,
            origin: this.originFrontendJsFile,
            cumulative: $('#cumulativeModeSelector').val(),
            heapPrimitives: $('#heapPrimitivesSelector').val(),
            textReferences: $('#textualMemoryLabelsSelector').val(),
            py: $('#pythonVersionSelector').val(),
            /* ALWAYS JSON serialize rawInputLst, even if it's empty! */
            rawInputLstJSON: JSON.stringify(this.rawInputLst),
            curInstr: this.myVisualizer ? this.myVisualizer.curInstr : undefined };
        // keep this really clean by avoiding undefined values
        if (ret.cumulative === undefined)
            delete ret.cumulative;
        if (ret.heapPrimitives === undefined)
            delete ret.heapPrimitives;
        if (ret.textReferences === undefined)
            delete ret.textReferences;
        if (ret.py === undefined)
            delete ret.py;
        if (ret.rawInputLstJSON === undefined)
            delete ret.rawInputLstJSON;
        if (ret.curInstr === undefined)
            delete ret.curInstr;
        // frontends can optionally AUGMENT the app state with custom fields
        this.appStateAugmenter(ret);
        return ret;
    };
    // strip it down to the bare minimum
    OptFrontend.prototype.getToggleState = function () {
        var x = this.getAppState();
        delete x.code;
        delete x.mode;
        delete x.rawInputLstJSON;
        delete x.curInstr;
        return x;
    };
    OptFrontend.prototype.setToggleOptions = function (dat) {
        // ugh, ugly tristate due to the possibility of each being undefined
        if (dat.py !== undefined) {
            $('#pythonVersionSelector').val(dat.py);
        }
        if (dat.cumulative !== undefined) {
            $('#cumulativeModeSelector').val(dat.cumulative);
        }
        if (dat.heapPrimitives !== undefined) {
            $('#heapPrimitivesSelector').val(dat.heapPrimitives);
        }
        if (dat.textReferences !== undefined) {
            $('#textualMemoryLabelsSelector').val(dat.textReferences);
        }
    };
    OptFrontend.prototype.demoModeChanged = function () { };
    ; // NOP; subclasses need to override
    OptFrontend.prototype.loadCodcastFile = function () { };
    ; // NOP; subclasses need to override
    OptFrontend.prototype.parseQueryString = function () {
        var queryStrOptions = this.getQueryStringOptions();
        this.setToggleOptions(queryStrOptions);
        if (queryStrOptions.preseededCode) {
            this.pyInputSetValue(queryStrOptions.preseededCode);
        }
        this.rawInputLst = queryStrOptions.rawInputLst ? queryStrOptions.rawInputLst : [];
        this.preseededCurInstr = queryStrOptions.preseededCurInstr;
        if (isNaN(this.preseededCurInstr)) {
            this.preseededCurInstr = undefined;
        }
        if (queryStrOptions.demoMode) {
            this.demoMode = true;
            this.demoModeChanged();
        }
        if (queryStrOptions.codcastFile) {
            this.codcastFile = queryStrOptions.codcastFile;
            this.loadCodcastFile();
        }
        if (queryStrOptions.codeopticonSession) {
            pytutor_1.assert(false); // TODO: this won't currently work with Webpack, so fix it later
            codeopticonSession = queryStrOptions.codeopticonSession; // GLOBAL defined in codeopticon-learner.js
            codeopticonUsername = queryStrOptions.codeopticonUsername; // GLOBAL defined in codeopticon-learner.js
        }
        if ((queryStrOptions.appMode == 'display' ||
            queryStrOptions.appMode == 'visualize' /* deprecated */) &&
            queryStrOptions.preseededCode /* jump to 'display' mode only with preseeded code */) {
            this.executeCode(this.preseededCurInstr); // will switch to 'display' mode
        }
        $.bbq.removeState(); // clean up the URL no matter what
    };
    return OptFrontend;
}(opt_frontend_common_1.AbstractBaseFrontend)); // END class OptFrontend
exports.OptFrontend = OptFrontend;

/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0)))

/***/ }),
/* 36 */
/***/ (function(module, exports) {

(function(){function diff_match_patch(){this.Diff_Timeout=1;this.Diff_EditCost=4;this.Match_Threshold=0.5;this.Match_Distance=1E3;this.Patch_DeleteThreshold=0.5;this.Patch_Margin=4;this.Match_MaxBits=32}
diff_match_patch.prototype.diff_main=function(a,b,c,d){"undefined"==typeof d&&(d=0>=this.Diff_Timeout?Number.MAX_VALUE:(new Date).getTime()+1E3*this.Diff_Timeout);if(null==a||null==b)throw Error("Null input. (diff_main)");if(a==b)return a?[[0,a]]:[];"undefined"==typeof c&&(c=!0);var e=c,f=this.diff_commonPrefix(a,b);c=a.substring(0,f);a=a.substring(f);b=b.substring(f);var f=this.diff_commonSuffix(a,b),g=a.substring(a.length-f);a=a.substring(0,a.length-f);b=b.substring(0,b.length-f);a=this.diff_compute_(a,
b,e,d);c&&a.unshift([0,c]);g&&a.push([0,g]);this.diff_cleanupMerge(a);return a};
diff_match_patch.prototype.diff_compute_=function(a,b,c,d){if(!a)return[[1,b]];if(!b)return[[-1,a]];var e=a.length>b.length?a:b,f=a.length>b.length?b:a,g=e.indexOf(f);return-1!=g?(c=[[1,e.substring(0,g)],[0,f],[1,e.substring(g+f.length)]],a.length>b.length&&(c[0][0]=c[2][0]=-1),c):1==f.length?[[-1,a],[1,b]]:(e=this.diff_halfMatch_(a,b))?(f=e[0],a=e[1],g=e[2],b=e[3],e=e[4],f=this.diff_main(f,g,c,d),c=this.diff_main(a,b,c,d),f.concat([[0,e]],c)):c&&100<a.length&&100<b.length?this.diff_lineMode_(a,b,
d):this.diff_bisect_(a,b,d)};
diff_match_patch.prototype.diff_lineMode_=function(a,b,c){var d=this.diff_linesToChars_(a,b);a=d.chars1;b=d.chars2;d=d.lineArray;a=this.diff_main(a,b,!1,c);this.diff_charsToLines_(a,d);this.diff_cleanupSemantic(a);a.push([0,""]);for(var e=d=b=0,f="",g="";b<a.length;){switch(a[b][0]){case 1:e++;g+=a[b][1];break;case -1:d++;f+=a[b][1];break;case 0:if(1<=d&&1<=e){a.splice(b-d-e,d+e);b=b-d-e;d=this.diff_main(f,g,!1,c);for(e=d.length-1;0<=e;e--)a.splice(b,0,d[e]);b+=d.length}d=e=0;g=f=""}b++}a.pop();return a};
diff_match_patch.prototype.diff_bisect_=function(a,b,c){for(var d=a.length,e=b.length,f=Math.ceil((d+e)/2),g=f,h=2*f,j=Array(h),i=Array(h),k=0;k<h;k++)j[k]=-1,i[k]=-1;j[g+1]=0;i[g+1]=0;for(var k=d-e,q=0!=k%2,r=0,t=0,p=0,w=0,v=0;v<f&&!((new Date).getTime()>c);v++){for(var n=-v+r;n<=v-t;n+=2){var l=g+n,m;m=n==-v||n!=v&&j[l-1]<j[l+1]?j[l+1]:j[l-1]+1;for(var s=m-n;m<d&&s<e&&a.charAt(m)==b.charAt(s);)m++,s++;j[l]=m;if(m>d)t+=2;else if(s>e)r+=2;else if(q&&(l=g+k-n,0<=l&&l<h&&-1!=i[l])){var u=d-i[l];if(m>=
u)return this.diff_bisectSplit_(a,b,m,s,c)}}for(n=-v+p;n<=v-w;n+=2){l=g+n;u=n==-v||n!=v&&i[l-1]<i[l+1]?i[l+1]:i[l-1]+1;for(m=u-n;u<d&&m<e&&a.charAt(d-u-1)==b.charAt(e-m-1);)u++,m++;i[l]=u;if(u>d)w+=2;else if(m>e)p+=2;else if(!q&&(l=g+k-n,0<=l&&(l<h&&-1!=j[l])&&(m=j[l],s=g+m-l,u=d-u,m>=u)))return this.diff_bisectSplit_(a,b,m,s,c)}}return[[-1,a],[1,b]]};
diff_match_patch.prototype.diff_bisectSplit_=function(a,b,c,d,e){var f=a.substring(0,c),g=b.substring(0,d);a=a.substring(c);b=b.substring(d);f=this.diff_main(f,g,!1,e);e=this.diff_main(a,b,!1,e);return f.concat(e)};
diff_match_patch.prototype.diff_linesToChars_=function(a,b){function c(a){for(var b="",c=0,f=-1,g=d.length;f<a.length-1;){f=a.indexOf("\n",c);-1==f&&(f=a.length-1);var r=a.substring(c,f+1),c=f+1;(e.hasOwnProperty?e.hasOwnProperty(r):void 0!==e[r])?b+=String.fromCharCode(e[r]):(b+=String.fromCharCode(g),e[r]=g,d[g++]=r)}return b}var d=[],e={};d[0]="";var f=c(a),g=c(b);return{chars1:f,chars2:g,lineArray:d}};
diff_match_patch.prototype.diff_charsToLines_=function(a,b){for(var c=0;c<a.length;c++){for(var d=a[c][1],e=[],f=0;f<d.length;f++)e[f]=b[d.charCodeAt(f)];a[c][1]=e.join("")}};diff_match_patch.prototype.diff_commonPrefix=function(a,b){if(!a||!b||a.charAt(0)!=b.charAt(0))return 0;for(var c=0,d=Math.min(a.length,b.length),e=d,f=0;c<e;)a.substring(f,e)==b.substring(f,e)?f=c=e:d=e,e=Math.floor((d-c)/2+c);return e};
diff_match_patch.prototype.diff_commonSuffix=function(a,b){if(!a||!b||a.charAt(a.length-1)!=b.charAt(b.length-1))return 0;for(var c=0,d=Math.min(a.length,b.length),e=d,f=0;c<e;)a.substring(a.length-e,a.length-f)==b.substring(b.length-e,b.length-f)?f=c=e:d=e,e=Math.floor((d-c)/2+c);return e};
diff_match_patch.prototype.diff_commonOverlap_=function(a,b){var c=a.length,d=b.length;if(0==c||0==d)return 0;c>d?a=a.substring(c-d):c<d&&(b=b.substring(0,c));c=Math.min(c,d);if(a==b)return c;for(var d=0,e=1;;){var f=a.substring(c-e),f=b.indexOf(f);if(-1==f)return d;e+=f;if(0==f||a.substring(c-e)==b.substring(0,e))d=e,e++}};
diff_match_patch.prototype.diff_halfMatch_=function(a,b){function c(a,b,c){for(var d=a.substring(c,c+Math.floor(a.length/4)),e=-1,g="",h,j,n,l;-1!=(e=b.indexOf(d,e+1));){var m=f.diff_commonPrefix(a.substring(c),b.substring(e)),s=f.diff_commonSuffix(a.substring(0,c),b.substring(0,e));g.length<s+m&&(g=b.substring(e-s,e)+b.substring(e,e+m),h=a.substring(0,c-s),j=a.substring(c+m),n=b.substring(0,e-s),l=b.substring(e+m))}return 2*g.length>=a.length?[h,j,n,l,g]:null}if(0>=this.Diff_Timeout)return null;
var d=a.length>b.length?a:b,e=a.length>b.length?b:a;if(4>d.length||2*e.length<d.length)return null;var f=this,g=c(d,e,Math.ceil(d.length/4)),d=c(d,e,Math.ceil(d.length/2)),h;if(!g&&!d)return null;h=d?g?g[4].length>d[4].length?g:d:d:g;var j;a.length>b.length?(g=h[0],d=h[1],e=h[2],j=h[3]):(e=h[0],j=h[1],g=h[2],d=h[3]);h=h[4];return[g,d,e,j,h]};
diff_match_patch.prototype.diff_cleanupSemantic=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=0,h=0,j=0,i=0;f<a.length;)0==a[f][0]?(c[d++]=f,g=j,h=i,i=j=0,e=a[f][1]):(1==a[f][0]?j+=a[f][1].length:i+=a[f][1].length,e&&(e.length<=Math.max(g,h)&&e.length<=Math.max(j,i))&&(a.splice(c[d-1],0,[-1,e]),a[c[d-1]+1][0]=1,d--,d--,f=0<d?c[d-1]:-1,i=j=h=g=0,e=null,b=!0)),f++;b&&this.diff_cleanupMerge(a);this.diff_cleanupSemanticLossless(a);for(f=1;f<a.length;){if(-1==a[f-1][0]&&1==a[f][0]){b=a[f-1][1];c=a[f][1];
d=this.diff_commonOverlap_(b,c);e=this.diff_commonOverlap_(c,b);if(d>=e){if(d>=b.length/2||d>=c.length/2)a.splice(f,0,[0,c.substring(0,d)]),a[f-1][1]=b.substring(0,b.length-d),a[f+1][1]=c.substring(d),f++}else if(e>=b.length/2||e>=c.length/2)a.splice(f,0,[0,b.substring(0,e)]),a[f-1][0]=1,a[f-1][1]=c.substring(0,c.length-e),a[f+1][0]=-1,a[f+1][1]=b.substring(e),f++;f++}f++}};
diff_match_patch.prototype.diff_cleanupSemanticLossless=function(a){function b(a,b){if(!a||!b)return 6;var c=a.charAt(a.length-1),d=b.charAt(0),e=c.match(diff_match_patch.nonAlphaNumericRegex_),f=d.match(diff_match_patch.nonAlphaNumericRegex_),g=e&&c.match(diff_match_patch.whitespaceRegex_),h=f&&d.match(diff_match_patch.whitespaceRegex_),c=g&&c.match(diff_match_patch.linebreakRegex_),d=h&&d.match(diff_match_patch.linebreakRegex_),i=c&&a.match(diff_match_patch.blanklineEndRegex_),j=d&&b.match(diff_match_patch.blanklineStartRegex_);
return i||j?5:c||d?4:e&&!g&&h?3:g||h?2:e||f?1:0}for(var c=1;c<a.length-1;){if(0==a[c-1][0]&&0==a[c+1][0]){var d=a[c-1][1],e=a[c][1],f=a[c+1][1],g=this.diff_commonSuffix(d,e);if(g)var h=e.substring(e.length-g),d=d.substring(0,d.length-g),e=h+e.substring(0,e.length-g),f=h+f;for(var g=d,h=e,j=f,i=b(d,e)+b(e,f);e.charAt(0)===f.charAt(0);){var d=d+e.charAt(0),e=e.substring(1)+f.charAt(0),f=f.substring(1),k=b(d,e)+b(e,f);k>=i&&(i=k,g=d,h=e,j=f)}a[c-1][1]!=g&&(g?a[c-1][1]=g:(a.splice(c-1,1),c--),a[c][1]=
h,j?a[c+1][1]=j:(a.splice(c+1,1),c--))}c++}};diff_match_patch.nonAlphaNumericRegex_=/[^a-zA-Z0-9]/;diff_match_patch.whitespaceRegex_=/\s/;diff_match_patch.linebreakRegex_=/[\r\n]/;diff_match_patch.blanklineEndRegex_=/\n\r?\n$/;diff_match_patch.blanklineStartRegex_=/^\r?\n\r?\n/;
diff_match_patch.prototype.diff_cleanupEfficiency=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=!1,h=!1,j=!1,i=!1;f<a.length;){if(0==a[f][0])a[f][1].length<this.Diff_EditCost&&(j||i)?(c[d++]=f,g=j,h=i,e=a[f][1]):(d=0,e=null),j=i=!1;else if(-1==a[f][0]?i=!0:j=!0,e&&(g&&h&&j&&i||e.length<this.Diff_EditCost/2&&3==g+h+j+i))a.splice(c[d-1],0,[-1,e]),a[c[d-1]+1][0]=1,d--,e=null,g&&h?(j=i=!0,d=0):(d--,f=0<d?c[d-1]:-1,j=i=!1),b=!0;f++}b&&this.diff_cleanupMerge(a)};
diff_match_patch.prototype.diff_cleanupMerge=function(a){a.push([0,""]);for(var b=0,c=0,d=0,e="",f="",g;b<a.length;)switch(a[b][0]){case 1:d++;f+=a[b][1];b++;break;case -1:c++;e+=a[b][1];b++;break;case 0:1<c+d?(0!==c&&0!==d&&(g=this.diff_commonPrefix(f,e),0!==g&&(0<b-c-d&&0==a[b-c-d-1][0]?a[b-c-d-1][1]+=f.substring(0,g):(a.splice(0,0,[0,f.substring(0,g)]),b++),f=f.substring(g),e=e.substring(g)),g=this.diff_commonSuffix(f,e),0!==g&&(a[b][1]=f.substring(f.length-g)+a[b][1],f=f.substring(0,f.length-
g),e=e.substring(0,e.length-g))),0===c?a.splice(b-d,c+d,[1,f]):0===d?a.splice(b-c,c+d,[-1,e]):a.splice(b-c-d,c+d,[-1,e],[1,f]),b=b-c-d+(c?1:0)+(d?1:0)+1):0!==b&&0==a[b-1][0]?(a[b-1][1]+=a[b][1],a.splice(b,1)):b++,c=d=0,f=e=""}""===a[a.length-1][1]&&a.pop();c=!1;for(b=1;b<a.length-1;)0==a[b-1][0]&&0==a[b+1][0]&&(a[b][1].substring(a[b][1].length-a[b-1][1].length)==a[b-1][1]?(a[b][1]=a[b-1][1]+a[b][1].substring(0,a[b][1].length-a[b-1][1].length),a[b+1][1]=a[b-1][1]+a[b+1][1],a.splice(b-1,1),c=!0):a[b][1].substring(0,
a[b+1][1].length)==a[b+1][1]&&(a[b-1][1]+=a[b+1][1],a[b][1]=a[b][1].substring(a[b+1][1].length)+a[b+1][1],a.splice(b+1,1),c=!0)),b++;c&&this.diff_cleanupMerge(a)};diff_match_patch.prototype.diff_xIndex=function(a,b){var c=0,d=0,e=0,f=0,g;for(g=0;g<a.length;g++){1!==a[g][0]&&(c+=a[g][1].length);-1!==a[g][0]&&(d+=a[g][1].length);if(c>b)break;e=c;f=d}return a.length!=g&&-1===a[g][0]?f:f+(b-e)};
diff_match_patch.prototype.diff_prettyHtml=function(a){for(var b=[],c=/&/g,d=/</g,e=/>/g,f=/\n/g,g=0;g<a.length;g++){var h=a[g][0],j=a[g][1],j=j.replace(c,"&amp;").replace(d,"&lt;").replace(e,"&gt;").replace(f,"&para;<br>");switch(h){case 1:b[g]='<ins style="background:#e6ffe6;">'+j+"</ins>";break;case -1:b[g]='<del style="background:#ffe6e6;">'+j+"</del>";break;case 0:b[g]="<span>"+j+"</span>"}}return b.join("")};
diff_match_patch.prototype.diff_text1=function(a){for(var b=[],c=0;c<a.length;c++)1!==a[c][0]&&(b[c]=a[c][1]);return b.join("")};diff_match_patch.prototype.diff_text2=function(a){for(var b=[],c=0;c<a.length;c++)-1!==a[c][0]&&(b[c]=a[c][1]);return b.join("")};diff_match_patch.prototype.diff_levenshtein=function(a){for(var b=0,c=0,d=0,e=0;e<a.length;e++){var f=a[e][0],g=a[e][1];switch(f){case 1:c+=g.length;break;case -1:d+=g.length;break;case 0:b+=Math.max(c,d),d=c=0}}return b+=Math.max(c,d)};
diff_match_patch.prototype.diff_toDelta=function(a){for(var b=[],c=0;c<a.length;c++)switch(a[c][0]){case 1:b[c]="+"+encodeURI(a[c][1]);break;case -1:b[c]="-"+a[c][1].length;break;case 0:b[c]="="+a[c][1].length}return b.join("\t").replace(/%20/g," ")};
diff_match_patch.prototype.diff_fromDelta=function(a,b){for(var c=[],d=0,e=0,f=b.split(/\t/g),g=0;g<f.length;g++){var h=f[g].substring(1);switch(f[g].charAt(0)){case "+":try{c[d++]=[1,decodeURI(h)]}catch(j){throw Error("Illegal escape in diff_fromDelta: "+h);}break;case "-":case "=":var i=parseInt(h,10);if(isNaN(i)||0>i)throw Error("Invalid number in diff_fromDelta: "+h);h=a.substring(e,e+=i);"="==f[g].charAt(0)?c[d++]=[0,h]:c[d++]=[-1,h];break;default:if(f[g])throw Error("Invalid diff operation in diff_fromDelta: "+
f[g]);}}if(e!=a.length)throw Error("Delta length ("+e+") does not equal source text length ("+a.length+").");return c};diff_match_patch.prototype.match_main=function(a,b,c){if(null==a||null==b||null==c)throw Error("Null input. (match_main)");c=Math.max(0,Math.min(c,a.length));return a==b?0:a.length?a.substring(c,c+b.length)==b?c:this.match_bitap_(a,b,c):-1};
diff_match_patch.prototype.match_bitap_=function(a,b,c){function d(a,d){var e=a/b.length,g=Math.abs(c-d);return!f.Match_Distance?g?1:e:e+g/f.Match_Distance}if(b.length>this.Match_MaxBits)throw Error("Pattern too long for this browser.");var e=this.match_alphabet_(b),f=this,g=this.Match_Threshold,h=a.indexOf(b,c);-1!=h&&(g=Math.min(d(0,h),g),h=a.lastIndexOf(b,c+b.length),-1!=h&&(g=Math.min(d(0,h),g)));for(var j=1<<b.length-1,h=-1,i,k,q=b.length+a.length,r,t=0;t<b.length;t++){i=0;for(k=q;i<k;)d(t,c+
k)<=g?i=k:q=k,k=Math.floor((q-i)/2+i);q=k;i=Math.max(1,c-k+1);var p=Math.min(c+k,a.length)+b.length;k=Array(p+2);for(k[p+1]=(1<<t)-1;p>=i;p--){var w=e[a.charAt(p-1)];k[p]=0===t?(k[p+1]<<1|1)&w:(k[p+1]<<1|1)&w|((r[p+1]|r[p])<<1|1)|r[p+1];if(k[p]&j&&(w=d(t,p-1),w<=g))if(g=w,h=p-1,h>c)i=Math.max(1,2*c-h);else break}if(d(t+1,c)>g)break;r=k}return h};
diff_match_patch.prototype.match_alphabet_=function(a){for(var b={},c=0;c<a.length;c++)b[a.charAt(c)]=0;for(c=0;c<a.length;c++)b[a.charAt(c)]|=1<<a.length-c-1;return b};
diff_match_patch.prototype.patch_addContext_=function(a,b){if(0!=b.length){for(var c=b.substring(a.start2,a.start2+a.length1),d=0;b.indexOf(c)!=b.lastIndexOf(c)&&c.length<this.Match_MaxBits-this.Patch_Margin-this.Patch_Margin;)d+=this.Patch_Margin,c=b.substring(a.start2-d,a.start2+a.length1+d);d+=this.Patch_Margin;(c=b.substring(a.start2-d,a.start2))&&a.diffs.unshift([0,c]);(d=b.substring(a.start2+a.length1,a.start2+a.length1+d))&&a.diffs.push([0,d]);a.start1-=c.length;a.start2-=c.length;a.length1+=
c.length+d.length;a.length2+=c.length+d.length}};
diff_match_patch.prototype.patch_make=function(a,b,c){var d;if("string"==typeof a&&"string"==typeof b&&"undefined"==typeof c)d=a,b=this.diff_main(d,b,!0),2<b.length&&(this.diff_cleanupSemantic(b),this.diff_cleanupEfficiency(b));else if(a&&"object"==typeof a&&"undefined"==typeof b&&"undefined"==typeof c)b=a,d=this.diff_text1(b);else if("string"==typeof a&&b&&"object"==typeof b&&"undefined"==typeof c)d=a;else if("string"==typeof a&&"string"==typeof b&&c&&"object"==typeof c)d=a,b=c;else throw Error("Unknown call format to patch_make.");
if(0===b.length)return[];c=[];a=new diff_match_patch.patch_obj;for(var e=0,f=0,g=0,h=d,j=0;j<b.length;j++){var i=b[j][0],k=b[j][1];!e&&0!==i&&(a.start1=f,a.start2=g);switch(i){case 1:a.diffs[e++]=b[j];a.length2+=k.length;d=d.substring(0,g)+k+d.substring(g);break;case -1:a.length1+=k.length;a.diffs[e++]=b[j];d=d.substring(0,g)+d.substring(g+k.length);break;case 0:k.length<=2*this.Patch_Margin&&e&&b.length!=j+1?(a.diffs[e++]=b[j],a.length1+=k.length,a.length2+=k.length):k.length>=2*this.Patch_Margin&&
e&&(this.patch_addContext_(a,h),c.push(a),a=new diff_match_patch.patch_obj,e=0,h=d,f=g)}1!==i&&(f+=k.length);-1!==i&&(g+=k.length)}e&&(this.patch_addContext_(a,h),c.push(a));return c};diff_match_patch.prototype.patch_deepCopy=function(a){for(var b=[],c=0;c<a.length;c++){var d=a[c],e=new diff_match_patch.patch_obj;e.diffs=[];for(var f=0;f<d.diffs.length;f++)e.diffs[f]=d.diffs[f].slice();e.start1=d.start1;e.start2=d.start2;e.length1=d.length1;e.length2=d.length2;b[c]=e}return b};
diff_match_patch.prototype.patch_apply=function(a,b){if(0==a.length)return[b,[]];a=this.patch_deepCopy(a);var c=this.patch_addPadding(a);b=c+b+c;this.patch_splitMax(a);for(var d=0,e=[],f=0;f<a.length;f++){var g=a[f].start2+d,h=this.diff_text1(a[f].diffs),j,i=-1;if(h.length>this.Match_MaxBits){if(j=this.match_main(b,h.substring(0,this.Match_MaxBits),g),-1!=j&&(i=this.match_main(b,h.substring(h.length-this.Match_MaxBits),g+h.length-this.Match_MaxBits),-1==i||j>=i))j=-1}else j=this.match_main(b,h,g);
if(-1==j)e[f]=!1,d-=a[f].length2-a[f].length1;else if(e[f]=!0,d=j-g,g=-1==i?b.substring(j,j+h.length):b.substring(j,i+this.Match_MaxBits),h==g)b=b.substring(0,j)+this.diff_text2(a[f].diffs)+b.substring(j+h.length);else if(g=this.diff_main(h,g,!1),h.length>this.Match_MaxBits&&this.diff_levenshtein(g)/h.length>this.Patch_DeleteThreshold)e[f]=!1;else{this.diff_cleanupSemanticLossless(g);for(var h=0,k,i=0;i<a[f].diffs.length;i++){var q=a[f].diffs[i];0!==q[0]&&(k=this.diff_xIndex(g,h));1===q[0]?b=b.substring(0,
j+k)+q[1]+b.substring(j+k):-1===q[0]&&(b=b.substring(0,j+k)+b.substring(j+this.diff_xIndex(g,h+q[1].length)));-1!==q[0]&&(h+=q[1].length)}}}b=b.substring(c.length,b.length-c.length);return[b,e]};
diff_match_patch.prototype.patch_addPadding=function(a){for(var b=this.Patch_Margin,c="",d=1;d<=b;d++)c+=String.fromCharCode(d);for(d=0;d<a.length;d++)a[d].start1+=b,a[d].start2+=b;var d=a[0],e=d.diffs;if(0==e.length||0!=e[0][0])e.unshift([0,c]),d.start1-=b,d.start2-=b,d.length1+=b,d.length2+=b;else if(b>e[0][1].length){var f=b-e[0][1].length;e[0][1]=c.substring(e[0][1].length)+e[0][1];d.start1-=f;d.start2-=f;d.length1+=f;d.length2+=f}d=a[a.length-1];e=d.diffs;0==e.length||0!=e[e.length-1][0]?(e.push([0,
c]),d.length1+=b,d.length2+=b):b>e[e.length-1][1].length&&(f=b-e[e.length-1][1].length,e[e.length-1][1]+=c.substring(0,f),d.length1+=f,d.length2+=f);return c};
diff_match_patch.prototype.patch_splitMax=function(a){for(var b=this.Match_MaxBits,c=0;c<a.length;c++)if(!(a[c].length1<=b)){var d=a[c];a.splice(c--,1);for(var e=d.start1,f=d.start2,g="";0!==d.diffs.length;){var h=new diff_match_patch.patch_obj,j=!0;h.start1=e-g.length;h.start2=f-g.length;""!==g&&(h.length1=h.length2=g.length,h.diffs.push([0,g]));for(;0!==d.diffs.length&&h.length1<b-this.Patch_Margin;){var g=d.diffs[0][0],i=d.diffs[0][1];1===g?(h.length2+=i.length,f+=i.length,h.diffs.push(d.diffs.shift()),
j=!1):-1===g&&1==h.diffs.length&&0==h.diffs[0][0]&&i.length>2*b?(h.length1+=i.length,e+=i.length,j=!1,h.diffs.push([g,i]),d.diffs.shift()):(i=i.substring(0,b-h.length1-this.Patch_Margin),h.length1+=i.length,e+=i.length,0===g?(h.length2+=i.length,f+=i.length):j=!1,h.diffs.push([g,i]),i==d.diffs[0][1]?d.diffs.shift():d.diffs[0][1]=d.diffs[0][1].substring(i.length))}g=this.diff_text2(h.diffs);g=g.substring(g.length-this.Patch_Margin);i=this.diff_text1(d.diffs).substring(0,this.Patch_Margin);""!==i&&
(h.length1+=i.length,h.length2+=i.length,0!==h.diffs.length&&0===h.diffs[h.diffs.length-1][0]?h.diffs[h.diffs.length-1][1]+=i:h.diffs.push([0,i]));j||a.splice(++c,0,h)}}};diff_match_patch.prototype.patch_toText=function(a){for(var b=[],c=0;c<a.length;c++)b[c]=a[c];return b.join("")};
diff_match_patch.prototype.patch_fromText=function(a){var b=[];if(!a)return b;a=a.split("\n");for(var c=0,d=/^@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@$/;c<a.length;){var e=a[c].match(d);if(!e)throw Error("Invalid patch string: "+a[c]);var f=new diff_match_patch.patch_obj;b.push(f);f.start1=parseInt(e[1],10);""===e[2]?(f.start1--,f.length1=1):"0"==e[2]?f.length1=0:(f.start1--,f.length1=parseInt(e[2],10));f.start2=parseInt(e[3],10);""===e[4]?(f.start2--,f.length2=1):"0"==e[4]?f.length2=0:(f.start2--,f.length2=
parseInt(e[4],10));for(c++;c<a.length;){e=a[c].charAt(0);try{var g=decodeURI(a[c].substring(1))}catch(h){throw Error("Illegal escape in patch_fromText: "+g);}if("-"==e)f.diffs.push([-1,g]);else if("+"==e)f.diffs.push([1,g]);else if(" "==e)f.diffs.push([0,g]);else if("@"==e)break;else if(""!==e)throw Error('Invalid patch mode "'+e+'" in: '+g);c++}}return b};diff_match_patch.patch_obj=function(){this.diffs=[];this.start2=this.start1=null;this.length2=this.length1=0};
diff_match_patch.patch_obj.prototype.toString=function(){var a,b;a=0===this.length1?this.start1+",0":1==this.length1?this.start1+1:this.start1+1+","+this.length1;b=0===this.length2?this.start2+",0":1==this.length2?this.start2+1:this.start2+1+","+this.length2;a=["@@ -"+a+" +"+b+" @@\n"];var c;for(b=0;b<this.diffs.length;b++){switch(this.diffs[b][0]){case 1:c="+";break;case -1:c="-";break;case 0:c=" "}a[b+1]=c+encodeURI(this.diffs[b][1])+"\n"}return a.join("").replace(/%20/g," ")};
this.diff_match_patch=diff_match_patch;this.DIFF_DELETE=-1;this.DIFF_INSERT=1;this.DIFF_EQUAL=0;})()


/***/ }),
/* 37 */
/***/ (function(module, exports, __webpack_require__) {

exports = module.exports = __webpack_require__(2)(false);
// imports


// module
exports.push([module.i, "/* CSS accompanying ../visualize.html */\n\nh1 {\n  font-weight: normal;\n  font-size: 20pt;\n  font-family: georgia, serif;\n  line-height: 1em;  /* enforce single spacing so that Georgia works */\n\n  margin-top: 0px;\n  margin-bottom: 8px;\n}\n\nh2 {\n  font-size: 12pt;\n  font-weight: normal;\n  font-family: georgia, serif;\n  line-height: 1.1em; /* enforce single spacing so that Georgia works */\n\n  margin-top: 2px;\n  margin-bottom: 20px;\n}\n\n\nbody {\n  background-color: white;\n  font-family: verdana, arial, helvetica, sans-serif;\n  font-size: 10pt;\n}\n\na,\na:visited,\na:hover {\n  color: #3D58A2;\n}\n\nspan {\n  padding: 0px;\n}\n\n#optionsPane {\n  margin-top: 15px;\n  margin-bottom: 20px;\n  line-height: 150%;\n}\n\ntable#pyOutputPane {\n  padding: 10px;\n}\n\n#pyInputPane, #loadingPane {\n  margin-top: 10px;\n  margin-bottom: 20px;\n\n  max-width: 700px;\n  /* center align */\n  margin-left: auto;\n  margin-right: auto;\n}\n\n#loadingPane {\n  margin-bottom: 5px;\n}\n\n#codeInputPane {\n  margin-top: 5px;\n  font-size: 12pt;\n  border: 1px solid #ddd;\n}\n\n#codeInputWarnings {\n  margin-bottom: 8px;\n}\n\nbutton.smallBtn {\n  font-size: 10pt;\n  padding: 3px;\n}\n\nbutton.bigBtn {\n  font-size: 12pt;\n  padding: 6px;\n  margin-top: 0px;\n}\n\nbutton.surveyBtn {\n  font-size: 8pt;\n  margin-top: 8px;\n}\n\nbutton.surveyBtnBig {\n  font-size: 11pt;\n  padding: 5px;\n  margin-top: 0px;\n}\n\n#footer {\n  color: #999;\n  font-size: 9pt;\n  border-top: 1px solid #bbbbbb;\n  padding-top: 5px;\n  margin-top: 5px;\n\n  max-width: 700px;\n  /* center align */\n  margin-left: auto;\n  margin-right: auto;\n}\n\n#frontendErrorOutput {\n  color: #e93f34; /* should match brightRed JavaScript variable */\n  font-size: 12pt;\n  line-height: 1.5em;\n  margin-top: 8px;\n}\n\n.togetherjsBtn {\n  /*color: #b80000;*/\n  color: #e93f34;\n  font-size: 9pt;\n  padding: 4px;\n  margin-top: 3px;\n}\n\n/* make this a fixed size with scrollbars for overflow so that the UI doesn't jitter up and down */\n#publicHelpQueue {\n  overflow: auto;\n  height: 95px;\n  margin-bottom: 15px;\n  margin-left: 10px;\n}\n\n.helpQueueSmallText {\n  color: #777;\n  font-size: 8pt;\n}\n\n.redBold {\n  font-weight: bold;\n  color: #e93f34;\n}\n\n#stopRequestHelpBtn {\n  font-size: 9pt;\n  padding: 2px;\n}\n\n#moderationPanel {\n  font-size: 11pt;\n  margin-bottom: 5pt;\n  min-height: 16pt; /* just so things don't jiggle around vertically too much */\n  padding-top: 6px;\n  padding-bottom: 6px;\n  padding-left: 6px;\n  padding-right: 6px;\n  border: 1px solid #e93f34;\n}\n\n.kickLink {\n  font-size: 10pt;\n  margin-right: 4px;\n}\n\n\n#syncBtn {\n font-size: 8pt;\n margin-left: 0px;\n}\n\n#experimentalHeader {\n}\n\n#surveyHeader {\n  margin-left: 100px;\n}\n\n.surveyQ {\n  font-size: 9pt;\n  padding: 2px;\n}\n\n/* necessary for CodeMirror error line highlighting to work! */\n.CodeMirror .errorLine { background: #ffff3f !important; }\n\n\n/* from http://rog.ie/blog/css-star-rater */\n.star-rating {\n  font-size: 0;\n  white-space: nowrap;\n  display: inline-block;\n  /* pgbovine - scale this appropriately with a 5:1 ratio */\n  width: 100px;\n  height: 20px;\n  overflow: hidden;\n  position: relative;\n  background: url('data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMjBweCIgaGVpZ2h0PSIyMHB4IiB2aWV3Qm94PSIwIDAgMjAgMjAiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDIwIDIwIiB4bWw6c3BhY2U9InByZXNlcnZlIj48cG9seWdvbiBmaWxsPSIjREREREREIiBwb2ludHM9IjEwLDAgMTMuMDksNi41ODMgMjAsNy42MzkgMTUsMTIuNzY0IDE2LjE4LDIwIDEwLDE2LjU4MyAzLjgyLDIwIDUsMTIuNzY0IDAsNy42MzkgNi45MSw2LjU4MyAiLz48L3N2Zz4=');\n  background-size: contain;\n}\n.star-rating i {\n  opacity: 0;\n  position: absolute;\n  left: 0;\n  top: 0;\n  height: 100%;\n  width: 20%;\n  z-index: 1;\n  background: url('data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMjBweCIgaGVpZ2h0PSIyMHB4IiB2aWV3Qm94PSIwIDAgMjAgMjAiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDIwIDIwIiB4bWw6c3BhY2U9InByZXNlcnZlIj48cG9seWdvbiBmaWxsPSIjRkZERjg4IiBwb2ludHM9IjEwLDAgMTMuMDksNi41ODMgMjAsNy42MzkgMTUsMTIuNzY0IDE2LjE4LDIwIDEwLDE2LjU4MyAzLjgyLDIwIDUsMTIuNzY0IDAsNy42MzkgNi45MSw2LjU4MyAiLz48L3N2Zz4=');\n  background-size: contain;\n}\n.star-rating input {\n  -moz-appearance: none;\n  -webkit-appearance: none;\n  opacity: 0;\n  display: inline-block;\n  width: 20%;\n  height: 100%;\n  margin: 0;\n  padding: 0;\n  z-index: 2;\n  position: relative;\n}\n.star-rating input:hover + i,\n.star-rating input:checked + i {\n  opacity: 1;\n}\n.star-rating i ~ i {\n  width: 40%;\n}\n.star-rating i ~ i ~ i {\n  width: 60%;\n}\n.star-rating i ~ i ~ i ~ i {\n  width: 80%;\n}\n.star-rating i ~ i ~ i ~ i ~ i {\n  width: 100%;\n}\n\n\n#syntaxErrBubbleContents {\n  font-size: 9.5pt;\n  cursor: default;\n}\n\n#syntaxErrHeader {\n  margin-bottom: 3pt;\n}\n\n#syntaxErrCodeDisplay {\n  border: 1px solid #ddd;\n}\n\n#syntaxErrMsg {\n  color: #e93f34; /* should match brightRed JavaScript variable */\n  font-size: 10pt;\n  margin-top: 3pt;\n  margin-bottom: 2pt;\n}\n\n#syntaxErrQuestion {\n  margin-top: 12px;\n}\n\n#syntaxErrTxtInput {\n  margin-top: 3px;\n  margin-bottom: 6px;\n  padding: 2px;\n}\n\n#syntaxErrSubmitBtn, #syntaxErrCloseBtn {\n  margin-right: 8px;\n}\n\n#syntaxErrHideAllLink {\n  font-size: 8pt;\n}\n\n#testCasesPane {\n margin-top: 5px;\n margin-bottom: 25px;\n}\n\n#exampleSnippets {\n border-top: 1px solid #ccc;\n margin-top: 15px;\n}\n\n#showExampleLink {\n  margin-top: 15px;\n}\n\n#instructionsPane {\n margin-bottom: 10px;\n}\n\n/* for SyntaxErrorSurveyBubble */\n\ntextarea.bubbleInputText {\n  font-family: verdana, arial, helvetica, sans-serif;\n\tfont-size: 9pt;\n\tline-height: 1.3em;\n}\n\n.qtip-content {\n\tcolor: #333;\n\tbackground-color: #ffffff;\n\n\tmax-width: 390px;\n\twidth: 390px;\n\n\tborder: 2px solid #e93f34;\n\n  cursor: pointer;\n\n\t*border-right-width: 2px;\n\t*border-bottom-width: 2px;\n\n\t-webkit-border-radius: 5px;\n\t-moz-border-radius: 5px;\n\tborder-radius: 5px;\n\n\t-webkit-box-shadow: 2px 2px 3px 0px rgba(0, 0, 0, 0.2);\n\t-moz-box-shadow: 2px 2px 3px 0px rgba(0, 0, 0, 0.2);\n\tbox-shadow: 2px 2px 3px 0px rgba(0, 0, 0, 0.2);\n\n\t-webkit-background-clip: padding-box;\n\t-moz-background-clip: padding;\n\tbackground-clip: padding-box;\n}\n", ""]);

// exports


/***/ }),
/* 38 */
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(1)(__webpack_require__(46))

/***/ }),
/* 39 */
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(1)(__webpack_require__(47))

/***/ }),
/* 40 */
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(1)(__webpack_require__(48))

/***/ }),
/* 41 */
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(1)(__webpack_require__(49))

/***/ }),
/* 42 */
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(1)(__webpack_require__(50))

/***/ }),
/* 43 */
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(1)(__webpack_require__(51))

/***/ }),
/* 44 */
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(1)(__webpack_require__(52))

/***/ }),
/* 45 */
/***/ (function(module, exports, __webpack_require__) {

exports = module.exports = __webpack_require__(2)(false);
// imports


// module
exports.push([module.i, ".testCaseEditor {\n  width: 300px;\n  height: 90px; /* VERY IMPORTANT so that it works on I.E., ugh! */\n  border: 1px solid #ddd;\n}\n\n#testCasesTable thead td {\n  padding-bottom: 5px;\n  border-bottom: 1px solid #bbb;\n  text-align: center;\n}\n\n#testCasesTable td {\n  padding-top: 10px;\n  padding-right: 5px;\n  vertical-align: top;\n}\n\n#testCasesTable td.outputTd {\n  text-align: center;\n}\n\n#testCasesTable {\n  margin-bottom: 5px;\n}\n", ""]);

// exports


/***/ }),
/* 46 */
/***/ (function(module, exports) {

module.exports = "(function(){function o(n){var i=e;n&&(e[n]||(e[n]={}),i=e[n]);if(!i.define||!i.define.packaged)t.original=i.define,i.define=t,i.define.packaged=!0;if(!i.require||!i.require.packaged)r.original=i.require,i.require=r,i.require.packaged=!0}var ACE_NAMESPACE = \"ace\",e=function(){return this}();!e&&typeof window!=\"undefined\"&&(e=window);if(!ACE_NAMESPACE&&typeof requirejs!=\"undefined\")return;var t=function(e,n,r){if(typeof e!=\"string\"){t.original?t.original.apply(this,arguments):(console.error(\"dropping module because define wasn't a string.\"),console.trace());return}arguments.length==2&&(r=n),t.modules[e]||(t.payloads[e]=r,t.modules[e]=null)};t.modules={},t.payloads={};var n=function(e,t,n){if(typeof t==\"string\"){var i=s(e,t);if(i!=undefined)return n&&n(),i}else if(Object.prototype.toString.call(t)===\"[object Array]\"){var o=[];for(var u=0,a=t.length;u<a;++u){var f=s(e,t[u]);if(f==undefined&&r.original)return;o.push(f)}return n&&n.apply(null,o)||!0}},r=function(e,t){var i=n(\"\",e,t);return i==undefined&&r.original?r.original.apply(this,arguments):i},i=function(e,t){if(t.indexOf(\"!\")!==-1){var n=t.split(\"!\");return i(e,n[0])+\"!\"+i(e,n[1])}if(t.charAt(0)==\".\"){var r=e.split(\"/\").slice(0,-1).join(\"/\");t=r+\"/\"+t;while(t.indexOf(\".\")!==-1&&s!=t){var s=t;t=t.replace(/\\/\\.\\//,\"/\").replace(/[^\\/]+\\/\\.\\.\\//,\"\")}}return t},s=function(e,r){r=i(e,r);var s=t.modules[r];if(!s){s=t.payloads[r];if(typeof s==\"function\"){var o={},u={id:r,uri:\"\",exports:o,packaged:!0},a=function(e,t){return n(r,e,t)},f=s(a,o,u);o=f||u.exports,t.modules[r]=o,delete t.payloads[r]}s=t.modules[r]=o||s}return s};o(ACE_NAMESPACE)})(),ace.define(\"ace/lib/regexp\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";function o(e){return(e.global?\"g\":\"\")+(e.ignoreCase?\"i\":\"\")+(e.multiline?\"m\":\"\")+(e.extended?\"x\":\"\")+(e.sticky?\"y\":\"\")}function u(e,t,n){if(Array.prototype.indexOf)return e.indexOf(t,n);for(var r=n||0;r<e.length;r++)if(e[r]===t)return r;return-1}var r={exec:RegExp.prototype.exec,test:RegExp.prototype.test,match:String.prototype.match,replace:String.prototype.replace,split:String.prototype.split},i=r.exec.call(/()??/,\"\")[1]===undefined,s=function(){var e=/^/g;return r.test.call(e,\"\"),!e.lastIndex}();if(s&&i)return;RegExp.prototype.exec=function(e){var t=r.exec.apply(this,arguments),n,a;if(typeof e==\"string\"&&t){!i&&t.length>1&&u(t,\"\")>-1&&(a=RegExp(this.source,r.replace.call(o(this),\"g\",\"\")),r.replace.call(e.slice(t.index),a,function(){for(var e=1;e<arguments.length-2;e++)arguments[e]===undefined&&(t[e]=undefined)}));if(this._xregexp&&this._xregexp.captureNames)for(var f=1;f<t.length;f++)n=this._xregexp.captureNames[f-1],n&&(t[n]=t[f]);!s&&this.global&&!t[0].length&&this.lastIndex>t.index&&this.lastIndex--}return t},s||(RegExp.prototype.test=function(e){var t=r.exec.call(this,e);return t&&this.global&&!t[0].length&&this.lastIndex>t.index&&this.lastIndex--,!!t})}),ace.define(\"ace/lib/es5-shim\",[\"require\",\"exports\",\"module\"],function(e,t,n){function r(){}function w(e){try{return Object.defineProperty(e,\"sentinel\",{}),\"sentinel\"in e}catch(t){}}function H(e){return e=+e,e!==e?e=0:e!==0&&e!==1/0&&e!==-1/0&&(e=(e>0||-1)*Math.floor(Math.abs(e))),e}function B(e){var t=typeof e;return e===null||t===\"undefined\"||t===\"boolean\"||t===\"number\"||t===\"string\"}function j(e){var t,n,r;if(B(e))return e;n=e.valueOf;if(typeof n==\"function\"){t=n.call(e);if(B(t))return t}r=e.toString;if(typeof r==\"function\"){t=r.call(e);if(B(t))return t}throw new TypeError}Function.prototype.bind||(Function.prototype.bind=function(t){var n=this;if(typeof n!=\"function\")throw new TypeError(\"Function.prototype.bind called on incompatible \"+n);var i=u.call(arguments,1),s=function(){if(this instanceof s){var e=n.apply(this,i.concat(u.call(arguments)));return Object(e)===e?e:this}return n.apply(t,i.concat(u.call(arguments)))};return n.prototype&&(r.prototype=n.prototype,s.prototype=new r,r.prototype=null),s});var i=Function.prototype.call,s=Array.prototype,o=Object.prototype,u=s.slice,a=i.bind(o.toString),f=i.bind(o.hasOwnProperty),l,c,h,p,d;if(d=f(o,\"__defineGetter__\"))l=i.bind(o.__defineGetter__),c=i.bind(o.__defineSetter__),h=i.bind(o.__lookupGetter__),p=i.bind(o.__lookupSetter__);if([1,2].splice(0).length!=2)if(!function(){function e(e){var t=new Array(e+2);return t[0]=t[1]=0,t}var t=[],n;t.splice.apply(t,e(20)),t.splice.apply(t,e(26)),n=t.length,t.splice(5,0,\"XXX\"),n+1==t.length;if(n+1==t.length)return!0}())Array.prototype.splice=function(e,t){var n=this.length;e>0?e>n&&(e=n):e==void 0?e=0:e<0&&(e=Math.max(n+e,0)),e+t<n||(t=n-e);var r=this.slice(e,e+t),i=u.call(arguments,2),s=i.length;if(e===n)s&&this.push.apply(this,i);else{var o=Math.min(t,n-e),a=e+o,f=a+s-o,l=n-a,c=n-o;if(f<a)for(var h=0;h<l;++h)this[f+h]=this[a+h];else if(f>a)for(h=l;h--;)this[f+h]=this[a+h];if(s&&e===c)this.length=c,this.push.apply(this,i);else{this.length=c+s;for(h=0;h<s;++h)this[e+h]=i[h]}}return r};else{var v=Array.prototype.splice;Array.prototype.splice=function(e,t){return arguments.length?v.apply(this,[e===void 0?0:e,t===void 0?this.length-e:t].concat(u.call(arguments,2))):[]}}Array.isArray||(Array.isArray=function(t){return a(t)==\"[object Array]\"});var m=Object(\"a\"),g=m[0]!=\"a\"||!(0 in m);Array.prototype.forEach||(Array.prototype.forEach=function(t){var n=F(this),r=g&&a(this)==\"[object String]\"?this.split(\"\"):n,i=arguments[1],s=-1,o=r.length>>>0;if(a(t)!=\"[object Function]\")throw new TypeError;while(++s<o)s in r&&t.call(i,r[s],s,n)}),Array.prototype.map||(Array.prototype.map=function(t){var n=F(this),r=g&&a(this)==\"[object String]\"?this.split(\"\"):n,i=r.length>>>0,s=Array(i),o=arguments[1];if(a(t)!=\"[object Function]\")throw new TypeError(t+\" is not a function\");for(var u=0;u<i;u++)u in r&&(s[u]=t.call(o,r[u],u,n));return s}),Array.prototype.filter||(Array.prototype.filter=function(t){var n=F(this),r=g&&a(this)==\"[object String]\"?this.split(\"\"):n,i=r.length>>>0,s=[],o,u=arguments[1];if(a(t)!=\"[object Function]\")throw new TypeError(t+\" is not a function\");for(var f=0;f<i;f++)f in r&&(o=r[f],t.call(u,o,f,n)&&s.push(o));return s}),Array.prototype.every||(Array.prototype.every=function(t){var n=F(this),r=g&&a(this)==\"[object String]\"?this.split(\"\"):n,i=r.length>>>0,s=arguments[1];if(a(t)!=\"[object Function]\")throw new TypeError(t+\" is not a function\");for(var o=0;o<i;o++)if(o in r&&!t.call(s,r[o],o,n))return!1;return!0}),Array.prototype.some||(Array.prototype.some=function(t){var n=F(this),r=g&&a(this)==\"[object String]\"?this.split(\"\"):n,i=r.length>>>0,s=arguments[1];if(a(t)!=\"[object Function]\")throw new TypeError(t+\" is not a function\");for(var o=0;o<i;o++)if(o in r&&t.call(s,r[o],o,n))return!0;return!1}),Array.prototype.reduce||(Array.prototype.reduce=function(t){var n=F(this),r=g&&a(this)==\"[object String]\"?this.split(\"\"):n,i=r.length>>>0;if(a(t)!=\"[object Function]\")throw new TypeError(t+\" is not a function\");if(!i&&arguments.length==1)throw new TypeError(\"reduce of empty array with no initial value\");var s=0,o;if(arguments.length>=2)o=arguments[1];else do{if(s in r){o=r[s++];break}if(++s>=i)throw new TypeError(\"reduce of empty array with no initial value\")}while(!0);for(;s<i;s++)s in r&&(o=t.call(void 0,o,r[s],s,n));return o}),Array.prototype.reduceRight||(Array.prototype.reduceRight=function(t){var n=F(this),r=g&&a(this)==\"[object String]\"?this.split(\"\"):n,i=r.length>>>0;if(a(t)!=\"[object Function]\")throw new TypeError(t+\" is not a function\");if(!i&&arguments.length==1)throw new TypeError(\"reduceRight of empty array with no initial value\");var s,o=i-1;if(arguments.length>=2)s=arguments[1];else do{if(o in r){s=r[o--];break}if(--o<0)throw new TypeError(\"reduceRight of empty array with no initial value\")}while(!0);do o in this&&(s=t.call(void 0,s,r[o],o,n));while(o--);return s});if(!Array.prototype.indexOf||[0,1].indexOf(1,2)!=-1)Array.prototype.indexOf=function(t){var n=g&&a(this)==\"[object String]\"?this.split(\"\"):F(this),r=n.length>>>0;if(!r)return-1;var i=0;arguments.length>1&&(i=H(arguments[1])),i=i>=0?i:Math.max(0,r+i);for(;i<r;i++)if(i in n&&n[i]===t)return i;return-1};if(!Array.prototype.lastIndexOf||[0,1].lastIndexOf(0,-3)!=-1)Array.prototype.lastIndexOf=function(t){var n=g&&a(this)==\"[object String]\"?this.split(\"\"):F(this),r=n.length>>>0;if(!r)return-1;var i=r-1;arguments.length>1&&(i=Math.min(i,H(arguments[1]))),i=i>=0?i:r-Math.abs(i);for(;i>=0;i--)if(i in n&&t===n[i])return i;return-1};Object.getPrototypeOf||(Object.getPrototypeOf=function(t){return t.__proto__||(t.constructor?t.constructor.prototype:o)});if(!Object.getOwnPropertyDescriptor){var y=\"Object.getOwnPropertyDescriptor called on a non-object: \";Object.getOwnPropertyDescriptor=function(t,n){if(typeof t!=\"object\"&&typeof t!=\"function\"||t===null)throw new TypeError(y+t);if(!f(t,n))return;var r,i,s;r={enumerable:!0,configurable:!0};if(d){var u=t.__proto__;t.__proto__=o;var i=h(t,n),s=p(t,n);t.__proto__=u;if(i||s)return i&&(r.get=i),s&&(r.set=s),r}return r.value=t[n],r}}Object.getOwnPropertyNames||(Object.getOwnPropertyNames=function(t){return Object.keys(t)});if(!Object.create){var b;Object.prototype.__proto__===null?b=function(){return{__proto__:null}}:b=function(){var e={};for(var t in e)e[t]=null;return e.constructor=e.hasOwnProperty=e.propertyIsEnumerable=e.isPrototypeOf=e.toLocaleString=e.toString=e.valueOf=e.__proto__=null,e},Object.create=function(t,n){var r;if(t===null)r=b();else{if(typeof t!=\"object\")throw new TypeError(\"typeof prototype[\"+typeof t+\"] != 'object'\");var i=function(){};i.prototype=t,r=new i,r.__proto__=t}return n!==void 0&&Object.defineProperties(r,n),r}}if(Object.defineProperty){var E=w({}),S=typeof document==\"undefined\"||w(document.createElement(\"div\"));if(!E||!S)var x=Object.defineProperty}if(!Object.defineProperty||x){var T=\"Property description must be an object: \",N=\"Object.defineProperty called on non-object: \",C=\"getters & setters can not be defined on this javascript engine\";Object.defineProperty=function(t,n,r){if(typeof t!=\"object\"&&typeof t!=\"function\"||t===null)throw new TypeError(N+t);if(typeof r!=\"object\"&&typeof r!=\"function\"||r===null)throw new TypeError(T+r);if(x)try{return x.call(Object,t,n,r)}catch(i){}if(f(r,\"value\"))if(d&&(h(t,n)||p(t,n))){var s=t.__proto__;t.__proto__=o,delete t[n],t[n]=r.value,t.__proto__=s}else t[n]=r.value;else{if(!d)throw new TypeError(C);f(r,\"get\")&&l(t,n,r.get),f(r,\"set\")&&c(t,n,r.set)}return t}}Object.defineProperties||(Object.defineProperties=function(t,n){for(var r in n)f(n,r)&&Object.defineProperty(t,r,n[r]);return t}),Object.seal||(Object.seal=function(t){return t}),Object.freeze||(Object.freeze=function(t){return t});try{Object.freeze(function(){})}catch(k){Object.freeze=function(t){return function(n){return typeof n==\"function\"?n:t(n)}}(Object.freeze)}Object.preventExtensions||(Object.preventExtensions=function(t){return t}),Object.isSealed||(Object.isSealed=function(t){return!1}),Object.isFrozen||(Object.isFrozen=function(t){return!1}),Object.isExtensible||(Object.isExtensible=function(t){if(Object(t)===t)throw new TypeError;var n=\"\";while(f(t,n))n+=\"?\";t[n]=!0;var r=f(t,n);return delete t[n],r});if(!Object.keys){var L=!0,A=[\"toString\",\"toLocaleString\",\"valueOf\",\"hasOwnProperty\",\"isPrototypeOf\",\"propertyIsEnumerable\",\"constructor\"],O=A.length;for(var M in{toString:null})L=!1;Object.keys=function I(e){if(typeof e!=\"object\"&&typeof e!=\"function\"||e===null)throw new TypeError(\"Object.keys called on a non-object\");var I=[];for(var t in e)f(e,t)&&I.push(t);if(L)for(var n=0,r=O;n<r;n++){var i=A[n];f(e,i)&&I.push(i)}return I}}Date.now||(Date.now=function(){return(new Date).getTime()});var _=\"\t\\n\u000b\\f\\r \\u00a0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029\\ufeff\";if(!String.prototype.trim||_.trim()){_=\"[\"+_+\"]\";var D=new RegExp(\"^\"+_+_+\"*\"),P=new RegExp(_+_+\"*$\");String.prototype.trim=function(){return String(this).replace(D,\"\").replace(P,\"\")}}var F=function(e){if(e==null)throw new TypeError(\"can't convert \"+e+\" to object\");return Object(e)}}),ace.define(\"ace/lib/fixoldbrowsers\",[\"require\",\"exports\",\"module\",\"ace/lib/regexp\",\"ace/lib/es5-shim\"],function(e,t,n){\"use strict\";e(\"./regexp\"),e(\"./es5-shim\")}),ace.define(\"ace/lib/dom\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";var r=\"http://www.w3.org/1999/xhtml\";t.getDocumentHead=function(e){return e||(e=document),e.head||e.getElementsByTagName(\"head\")[0]||e.documentElement},t.createElement=function(e,t){return document.createElementNS?document.createElementNS(t||r,e):document.createElement(e)},t.hasCssClass=function(e,t){var n=(e.className||\"\").split(/\\s+/g);return n.indexOf(t)!==-1},t.addCssClass=function(e,n){t.hasCssClass(e,n)||(e.className+=\" \"+n)},t.removeCssClass=function(e,t){var n=e.className.split(/\\s+/g);for(;;){var r=n.indexOf(t);if(r==-1)break;n.splice(r,1)}e.className=n.join(\" \")},t.toggleCssClass=function(e,t){var n=e.className.split(/\\s+/g),r=!0;for(;;){var i=n.indexOf(t);if(i==-1)break;r=!1,n.splice(i,1)}return r&&n.push(t),e.className=n.join(\" \"),r},t.setCssClass=function(e,n,r){r?t.addCssClass(e,n):t.removeCssClass(e,n)},t.hasCssString=function(e,t){var n=0,r;t=t||document;if(t.createStyleSheet&&(r=t.styleSheets)){while(n<r.length)if(r[n++].owningElement.id===e)return!0}else if(r=t.getElementsByTagName(\"style\"))while(n<r.length)if(r[n++].id===e)return!0;return!1},t.importCssString=function(n,r,i){i=i||document;if(r&&t.hasCssString(r,i))return null;var s;r&&(n+=\"\\n/*# sourceURL=ace/css/\"+r+\" */\"),i.createStyleSheet?(s=i.createStyleSheet(),s.cssText=n,r&&(s.owningElement.id=r)):(s=t.createElement(\"style\"),s.appendChild(i.createTextNode(n)),r&&(s.id=r),t.getDocumentHead(i).appendChild(s))},t.importCssStylsheet=function(e,n){if(n.createStyleSheet)n.createStyleSheet(e);else{var r=t.createElement(\"link\");r.rel=\"stylesheet\",r.href=e,t.getDocumentHead(n).appendChild(r)}},t.getInnerWidth=function(e){return parseInt(t.computedStyle(e,\"paddingLeft\"),10)+parseInt(t.computedStyle(e,\"paddingRight\"),10)+e.clientWidth},t.getInnerHeight=function(e){return parseInt(t.computedStyle(e,\"paddingTop\"),10)+parseInt(t.computedStyle(e,\"paddingBottom\"),10)+e.clientHeight},t.scrollbarWidth=function(e){var n=t.createElement(\"ace_inner\");n.style.width=\"100%\",n.style.minWidth=\"0px\",n.style.height=\"200px\",n.style.display=\"block\";var r=t.createElement(\"ace_outer\"),i=r.style;i.position=\"absolute\",i.left=\"-10000px\",i.overflow=\"hidden\",i.width=\"200px\",i.minWidth=\"0px\",i.height=\"150px\",i.display=\"block\",r.appendChild(n);var s=e.documentElement;s.appendChild(r);var o=n.offsetWidth;i.overflow=\"scroll\";var u=n.offsetWidth;return o==u&&(u=r.clientWidth),s.removeChild(r),o-u};if(typeof document==\"undefined\"){t.importCssString=function(){};return}window.pageYOffset!==undefined?(t.getPageScrollTop=function(){return window.pageYOffset},t.getPageScrollLeft=function(){return window.pageXOffset}):(t.getPageScrollTop=function(){return document.body.scrollTop},t.getPageScrollLeft=function(){return document.body.scrollLeft}),window.getComputedStyle?t.computedStyle=function(e,t){return t?(window.getComputedStyle(e,\"\")||{})[t]||\"\":window.getComputedStyle(e,\"\")||{}}:t.computedStyle=function(e,t){return t?e.currentStyle[t]:e.currentStyle},t.setInnerHtml=function(e,t){var n=e.cloneNode(!1);return n.innerHTML=t,e.parentNode.replaceChild(n,e),n},\"textContent\"in document.documentElement?(t.setInnerText=function(e,t){e.textContent=t},t.getInnerText=function(e){return e.textContent}):(t.setInnerText=function(e,t){e.innerText=t},t.getInnerText=function(e){return e.innerText}),t.getParentWindow=function(e){return e.defaultView||e.parentWindow}}),ace.define(\"ace/lib/oop\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";t.inherits=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})},t.mixin=function(e,t){for(var n in t)e[n]=t[n];return e},t.implement=function(e,n){t.mixin(e,n)}}),ace.define(\"ace/lib/keys\",[\"require\",\"exports\",\"module\",\"ace/lib/fixoldbrowsers\",\"ace/lib/oop\"],function(e,t,n){\"use strict\";e(\"./fixoldbrowsers\");var r=e(\"./oop\"),i=function(){var e={MODIFIER_KEYS:{16:\"Shift\",17:\"Ctrl\",18:\"Alt\",224:\"Meta\"},KEY_MODS:{ctrl:1,alt:2,option:2,shift:4,\"super\":8,meta:8,command:8,cmd:8},FUNCTION_KEYS:{8:\"Backspace\",9:\"Tab\",13:\"Return\",19:\"Pause\",27:\"Esc\",32:\"Space\",33:\"PageUp\",34:\"PageDown\",35:\"End\",36:\"Home\",37:\"Left\",38:\"Up\",39:\"Right\",40:\"Down\",44:\"Print\",45:\"Insert\",46:\"Delete\",96:\"Numpad0\",97:\"Numpad1\",98:\"Numpad2\",99:\"Numpad3\",100:\"Numpad4\",101:\"Numpad5\",102:\"Numpad6\",103:\"Numpad7\",104:\"Numpad8\",105:\"Numpad9\",\"-13\":\"NumpadEnter\",112:\"F1\",113:\"F2\",114:\"F3\",115:\"F4\",116:\"F5\",117:\"F6\",118:\"F7\",119:\"F8\",120:\"F9\",121:\"F10\",122:\"F11\",123:\"F12\",144:\"Numlock\",145:\"Scrolllock\"},PRINTABLE_KEYS:{32:\" \",48:\"0\",49:\"1\",50:\"2\",51:\"3\",52:\"4\",53:\"5\",54:\"6\",55:\"7\",56:\"8\",57:\"9\",59:\";\",61:\"=\",65:\"a\",66:\"b\",67:\"c\",68:\"d\",69:\"e\",70:\"f\",71:\"g\",72:\"h\",73:\"i\",74:\"j\",75:\"k\",76:\"l\",77:\"m\",78:\"n\",79:\"o\",80:\"p\",81:\"q\",82:\"r\",83:\"s\",84:\"t\",85:\"u\",86:\"v\",87:\"w\",88:\"x\",89:\"y\",90:\"z\",107:\"+\",109:\"-\",110:\".\",186:\";\",187:\"=\",188:\",\",189:\"-\",190:\".\",191:\"/\",192:\"`\",219:\"[\",220:\"\\\\\",221:\"]\",222:\"'\",111:\"/\",106:\"*\"}},t,n;for(n in e.FUNCTION_KEYS)t=e.FUNCTION_KEYS[n].toLowerCase(),e[t]=parseInt(n,10);for(n in e.PRINTABLE_KEYS)t=e.PRINTABLE_KEYS[n].toLowerCase(),e[t]=parseInt(n,10);return r.mixin(e,e.MODIFIER_KEYS),r.mixin(e,e.PRINTABLE_KEYS),r.mixin(e,e.FUNCTION_KEYS),e.enter=e[\"return\"],e.escape=e.esc,e.del=e[\"delete\"],e[173]=\"-\",function(){var t=[\"cmd\",\"ctrl\",\"alt\",\"shift\"];for(var n=Math.pow(2,t.length);n--;)e.KEY_MODS[n]=t.filter(function(t){return n&e.KEY_MODS[t]}).join(\"-\")+\"-\"}(),e.KEY_MODS[0]=\"\",e.KEY_MODS[-1]=\"input-\",e}();r.mixin(t,i),t.keyCodeToString=function(e){var t=i[e];return typeof t!=\"string\"&&(t=String.fromCharCode(e)),t.toLowerCase()}}),ace.define(\"ace/lib/useragent\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";t.OS={LINUX:\"LINUX\",MAC:\"MAC\",WINDOWS:\"WINDOWS\"},t.getOS=function(){return t.isMac?t.OS.MAC:t.isLinux?t.OS.LINUX:t.OS.WINDOWS};if(typeof navigator!=\"object\")return;var r=(navigator.platform.match(/mac|win|linux/i)||[\"other\"])[0].toLowerCase(),i=navigator.userAgent;t.isWin=r==\"win\",t.isMac=r==\"mac\",t.isLinux=r==\"linux\",t.isIE=navigator.appName==\"Microsoft Internet Explorer\"||navigator.appName.indexOf(\"MSAppHost\")>=0?parseFloat((i.match(/(?:MSIE |Trident\\/[0-9]+[\\.0-9]+;.*rv:)([0-9]+[\\.0-9]+)/)||[])[1]):parseFloat((i.match(/(?:Trident\\/[0-9]+[\\.0-9]+;.*rv:)([0-9]+[\\.0-9]+)/)||[])[1]),t.isOldIE=t.isIE&&t.isIE<9,t.isGecko=t.isMozilla=(window.Controllers||window.controllers)&&window.navigator.product===\"Gecko\",t.isOldGecko=t.isGecko&&parseInt((i.match(/rv\\:(\\d+)/)||[])[1],10)<4,t.isOpera=window.opera&&Object.prototype.toString.call(window.opera)==\"[object Opera]\",t.isWebKit=parseFloat(i.split(\"WebKit/\")[1])||undefined,t.isChrome=parseFloat(i.split(\" Chrome/\")[1])||undefined,t.isAIR=i.indexOf(\"AdobeAIR\")>=0,t.isIPad=i.indexOf(\"iPad\")>=0,t.isTouchPad=i.indexOf(\"TouchPad\")>=0,t.isChromeOS=i.indexOf(\" CrOS \")>=0}),ace.define(\"ace/lib/event\",[\"require\",\"exports\",\"module\",\"ace/lib/keys\",\"ace/lib/useragent\"],function(e,t,n){\"use strict\";function a(e,t,n){var a=u(t);if(!i.isMac&&s){s.OSKey&&(a|=8);if(s.altGr){if((3&a)==3)return;s.altGr=0}if(n===18||n===17){var f=\"location\"in t?t.location:t.keyLocation;if(n===17&&f===1)s[n]==1&&(o=t.timeStamp);else if(n===18&&a===3&&f===2){var l=t.timeStamp-o;l<50&&(s.altGr=!0)}}}n in r.MODIFIER_KEYS&&(n=-1),a&8&&n>=91&&n<=93&&(n=-1);if(!a&&n===13){var f=\"location\"in t?t.location:t.keyLocation;if(f===3){e(t,a,-n);if(t.defaultPrevented)return}}if(i.isChromeOS&&a&8){e(t,a,n);if(t.defaultPrevented)return;a&=-9}return!!a||n in r.FUNCTION_KEYS||n in r.PRINTABLE_KEYS?e(t,a,n):!1}function f(){s=Object.create(null),s.count=0,s.lastT=0}var r=e(\"./keys\"),i=e(\"./useragent\"),s=null,o=0;t.addListener=function(e,t,n){if(e.addEventListener)return e.addEventListener(t,n,!1);if(e.attachEvent){var r=function(){n.call(e,window.event)};n._wrapper=r,e.attachEvent(\"on\"+t,r)}},t.removeListener=function(e,t,n){if(e.removeEventListener)return e.removeEventListener(t,n,!1);e.detachEvent&&e.detachEvent(\"on\"+t,n._wrapper||n)},t.stopEvent=function(e){return t.stopPropagation(e),t.preventDefault(e),!1},t.stopPropagation=function(e){e.stopPropagation?e.stopPropagation():e.cancelBubble=!0},t.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},t.getButton=function(e){return e.type==\"dblclick\"?0:e.type==\"contextmenu\"||i.isMac&&e.ctrlKey&&!e.altKey&&!e.shiftKey?2:e.preventDefault?e.button:{1:0,2:2,4:1}[e.button]},t.capture=function(e,n,r){function i(e){n&&n(e),r&&r(e),t.removeListener(document,\"mousemove\",n,!0),t.removeListener(document,\"mouseup\",i,!0),t.removeListener(document,\"dragstart\",i,!0)}return t.addListener(document,\"mousemove\",n,!0),t.addListener(document,\"mouseup\",i,!0),t.addListener(document,\"dragstart\",i,!0),i},t.addTouchMoveListener=function(e,n){if(\"ontouchmove\"in e){var r,i;t.addListener(e,\"touchstart\",function(e){var t=e.changedTouches[0];r=t.clientX,i=t.clientY}),t.addListener(e,\"touchmove\",function(e){var t=1,s=e.changedTouches[0];e.wheelX=-(s.clientX-r)/t,e.wheelY=-(s.clientY-i)/t,r=s.clientX,i=s.clientY,n(e)})}},t.addMouseWheelListener=function(e,n){\"onmousewheel\"in e?t.addListener(e,\"mousewheel\",function(e){var t=8;e.wheelDeltaX!==undefined?(e.wheelX=-e.wheelDeltaX/t,e.wheelY=-e.wheelDeltaY/t):(e.wheelX=0,e.wheelY=-e.wheelDelta/t),n(e)}):\"onwheel\"in e?t.addListener(e,\"wheel\",function(e){var t=.35;switch(e.deltaMode){case e.DOM_DELTA_PIXEL:e.wheelX=e.deltaX*t||0,e.wheelY=e.deltaY*t||0;break;case e.DOM_DELTA_LINE:case e.DOM_DELTA_PAGE:e.wheelX=(e.deltaX||0)*5,e.wheelY=(e.deltaY||0)*5}n(e)}):t.addListener(e,\"DOMMouseScroll\",function(e){e.axis&&e.axis==e.HORIZONTAL_AXIS?(e.wheelX=(e.detail||0)*5,e.wheelY=0):(e.wheelX=0,e.wheelY=(e.detail||0)*5),n(e)})},t.addMultiMouseDownListener=function(e,n,r,s){function c(e){t.getButton(e)!==0?o=0:e.detail>1?(o++,o>4&&(o=1)):o=1;if(i.isIE){var c=Math.abs(e.clientX-u)>5||Math.abs(e.clientY-a)>5;if(!f||c)o=1;f&&clearTimeout(f),f=setTimeout(function(){f=null},n[o-1]||600),o==1&&(u=e.clientX,a=e.clientY)}e._clicks=o,r[s](\"mousedown\",e);if(o>4)o=0;else if(o>1)return r[s](l[o],e)}function h(e){o=2,f&&clearTimeout(f),f=setTimeout(function(){f=null},n[o-1]||600),r[s](\"mousedown\",e),r[s](l[o],e)}var o=0,u,a,f,l={2:\"dblclick\",3:\"tripleclick\",4:\"quadclick\"};Array.isArray(e)||(e=[e]),e.forEach(function(e){t.addListener(e,\"mousedown\",c),i.isOldIE&&t.addListener(e,\"dblclick\",h)})};var u=!i.isMac||!i.isOpera||\"KeyboardEvent\"in window?function(e){return 0|(e.ctrlKey?1:0)|(e.altKey?2:0)|(e.shiftKey?4:0)|(e.metaKey?8:0)}:function(e){return 0|(e.metaKey?1:0)|(e.altKey?2:0)|(e.shiftKey?4:0)|(e.ctrlKey?8:0)};t.getModifierString=function(e){return r.KEY_MODS[u(e)]},t.addCommandKeyListener=function(e,n){var r=t.addListener;if(i.isOldGecko||i.isOpera&&!(\"KeyboardEvent\"in window)){var o=null;r(e,\"keydown\",function(e){o=e.keyCode}),r(e,\"keypress\",function(e){return a(n,e,o)})}else{var u=null;r(e,\"keydown\",function(e){var t=e.keyCode;s[t]=(s[t]||0)+1,t==91||t==92?s.OSKey=!0:s.OSKey&&e.timeStamp-s.lastT>200&&s.count==1&&f(),s[t]==1&&s.count++,s.lastT=e.timeStamp;var r=a(n,e,t);return u=e.defaultPrevented,r}),r(e,\"keypress\",function(e){u&&(e.ctrlKey||e.altKey||e.shiftKey||e.metaKey)&&(t.stopEvent(e),u=null)}),r(e,\"keyup\",function(e){var t=e.keyCode;s[t]?s.count=Math.max(s.count-1,0):f();if(t==91||t==92)s.OSKey=!1;s[t]=null}),s||(f(),r(window,\"focus\",f))}};if(typeof window==\"object\"&&window.postMessage&&!i.isOldIE){var l=1;t.nextTick=function(e,n){n=n||window;var r=\"zero-timeout-message-\"+l;t.addListener(n,\"message\",function i(s){s.data==r&&(t.stopPropagation(s),t.removeListener(n,\"message\",i),e())}),n.postMessage(r,\"*\")}}t.nextFrame=typeof window==\"object\"&&(window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame||window.oRequestAnimationFrame),t.nextFrame?t.nextFrame=t.nextFrame.bind(window):t.nextFrame=function(e){setTimeout(e,17)}}),ace.define(\"ace/lib/lang\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";t.last=function(e){return e[e.length-1]},t.stringReverse=function(e){return e.split(\"\").reverse().join(\"\")},t.stringRepeat=function(e,t){var n=\"\";while(t>0){t&1&&(n+=e);if(t>>=1)e+=e}return n};var r=/^\\s\\s*/,i=/\\s\\s*$/;t.stringTrimLeft=function(e){return e.replace(r,\"\")},t.stringTrimRight=function(e){return e.replace(i,\"\")},t.copyObject=function(e){var t={};for(var n in e)t[n]=e[n];return t},t.copyArray=function(e){var t=[];for(var n=0,r=e.length;n<r;n++)e[n]&&typeof e[n]==\"object\"?t[n]=this.copyObject(e[n]):t[n]=e[n];return t},t.deepCopy=function s(e){if(typeof e!=\"object\"||!e)return e;var t;if(Array.isArray(e)){t=[];for(var n=0;n<e.length;n++)t[n]=s(e[n]);return t}var r=e.constructor;if(r===RegExp)return e;t=r();for(var n in e)t[n]=s(e[n]);return t},t.arrayToMap=function(e){var t={};for(var n=0;n<e.length;n++)t[e[n]]=1;return t},t.createMap=function(e){var t=Object.create(null);for(var n in e)t[n]=e[n];return t},t.arrayRemove=function(e,t){for(var n=0;n<=e.length;n++)t===e[n]&&e.splice(n,1)},t.escapeRegExp=function(e){return e.replace(/([.*+?^${}()|[\\]\\/\\\\])/g,\"\\\\$1\")},t.escapeHTML=function(e){return e.replace(/&/g,\"&#38;\").replace(/\"/g,\"&#34;\").replace(/'/g,\"&#39;\").replace(/</g,\"&#60;\")},t.getMatchOffsets=function(e,t){var n=[];return e.replace(t,function(e){n.push({offset:arguments[arguments.length-2],length:e.length})}),n},t.deferredCall=function(e){var t=null,n=function(){t=null,e()},r=function(e){return r.cancel(),t=setTimeout(n,e||0),r};return r.schedule=r,r.call=function(){return this.cancel(),e(),r},r.cancel=function(){return clearTimeout(t),t=null,r},r.isPending=function(){return t},r},t.delayedCall=function(e,t){var n=null,r=function(){n=null,e()},i=function(e){n==null&&(n=setTimeout(r,e||t))};return i.delay=function(e){n&&clearTimeout(n),n=setTimeout(r,e||t)},i.schedule=i,i.call=function(){this.cancel(),e()},i.cancel=function(){n&&clearTimeout(n),n=null},i.isPending=function(){return n},i}}),ace.define(\"ace/keyboard/textinput\",[\"require\",\"exports\",\"module\",\"ace/lib/event\",\"ace/lib/useragent\",\"ace/lib/dom\",\"ace/lib/lang\"],function(e,t,n){\"use strict\";var r=e(\"../lib/event\"),i=e(\"../lib/useragent\"),s=e(\"../lib/dom\"),o=e(\"../lib/lang\"),u=i.isChrome<18,a=i.isIE,f=function(e,t){function b(e){if(h)return;h=!0;if(k)t=0,r=e?0:n.value.length-1;else var t=e?2:1,r=2;try{n.setSelectionRange(t,r)}catch(i){}h=!1}function w(){if(h)return;n.value=f,i.isWebKit&&y.schedule()}function R(){clearTimeout(q),q=setTimeout(function(){p&&(n.style.cssText=p,p=\"\"),t.renderer.$keepTextAreaAtCursor==null&&(t.renderer.$keepTextAreaAtCursor=!0,t.renderer.$moveTextAreaToCursor())},i.isOldIE?200:0)}var n=s.createElement(\"textarea\");n.className=\"ace_text-input\",i.isTouchPad&&n.setAttribute(\"x-palm-disable-auto-cap\",!0),n.setAttribute(\"wrap\",\"off\"),n.setAttribute(\"autocorrect\",\"off\"),n.setAttribute(\"autocapitalize\",\"off\"),n.setAttribute(\"spellcheck\",!1),n.style.opacity=\"0\",i.isOldIE&&(n.style.top=\"-1000px\"),e.insertBefore(n,e.firstChild);var f=\"\u0001\u0001\",l=!1,c=!1,h=!1,p=\"\",d=!0;try{var v=document.activeElement===n}catch(m){}r.addListener(n,\"blur\",function(e){t.onBlur(e),v=!1}),r.addListener(n,\"focus\",function(e){v=!0,t.onFocus(e),b()}),this.focus=function(){if(p)return n.focus();var e=n.style.top;n.style.position=\"fixed\",n.style.top=\"0px\",n.focus(),setTimeout(function(){n.style.position=\"\",n.style.top==\"0px\"&&(n.style.top=e)},0)},this.blur=function(){n.blur()},this.isFocused=function(){return v};var g=o.delayedCall(function(){v&&b(d)}),y=o.delayedCall(function(){h||(n.value=f,v&&b())});i.isWebKit||t.addEventListener(\"changeSelection\",function(){t.selection.isEmpty()!=d&&(d=!d,g.schedule())}),w(),v&&t.onFocus();var E=function(e){return e.selectionStart===0&&e.selectionEnd===e.value.length};!n.setSelectionRange&&n.createTextRange&&(n.setSelectionRange=function(e,t){var n=this.createTextRange();n.collapse(!0),n.moveStart(\"character\",e),n.moveEnd(\"character\",t),n.select()},E=function(e){try{var t=e.ownerDocument.selection.createRange()}catch(n){}return!t||t.parentElement()!=e?!1:t.text==e.value});if(i.isOldIE){var S=!1,x=function(e){if(S)return;var t=n.value;if(h||!t||t==f)return;if(e&&t==f[0])return T.schedule();A(t),S=!0,w(),S=!1},T=o.delayedCall(x);r.addListener(n,\"propertychange\",x);var N={13:1,27:1};r.addListener(n,\"keyup\",function(e){h&&(!n.value||N[e.keyCode])&&setTimeout(F,0);if((n.value.charCodeAt(0)||0)<129)return T.call();h?j():B()}),r.addListener(n,\"keydown\",function(e){T.schedule(50)})}var C=function(e){l?l=!1:E(n)?(t.selectAll(),b()):k&&b(t.selection.isEmpty())},k=null;this.setInputHandler=function(e){k=e},this.getInputHandler=function(){return k};var L=!1,A=function(e){k&&(e=k(e),k=null),c?(b(),e&&t.onPaste(e),c=!1):e==f.charAt(0)?L?t.execCommand(\"del\",{source:\"ace\"}):t.execCommand(\"backspace\",{source:\"ace\"}):(e.substring(0,2)==f?e=e.substr(2):e.charAt(0)==f.charAt(0)?e=e.substr(1):e.charAt(e.length-1)==f.charAt(0)&&(e=e.slice(0,-1)),e.charAt(e.length-1)==f.charAt(0)&&(e=e.slice(0,-1)),e&&t.onTextInput(e)),L&&(L=!1)},O=function(e){if(h)return;var t=n.value;A(t),w()},M=function(e,t){var n=e.clipboardData||window.clipboardData;if(!n||u)return;var r=a?\"Text\":\"text/plain\";return t?n.setData(r,t)!==!1:n.getData(r)},_=function(e,i){var s=t.getCopyText();if(!s)return r.preventDefault(e);M(e,s)?(i?t.onCut():t.onCopy(),r.preventDefault(e)):(l=!0,n.value=s,n.select(),setTimeout(function(){l=!1,w(),b(),i?t.onCut():t.onCopy()}))},D=function(e){_(e,!0)},P=function(e){_(e,!1)},H=function(e){var s=M(e);typeof s==\"string\"?(s&&t.onPaste(s,e),i.isIE&&setTimeout(b),r.preventDefault(e)):(n.value=\"\",c=!0)};r.addCommandKeyListener(n,t.onCommandKey.bind(t)),r.addListener(n,\"select\",C),r.addListener(n,\"input\",O),r.addListener(n,\"cut\",D),r.addListener(n,\"copy\",P),r.addListener(n,\"paste\",H),(!(\"oncut\"in n)||!(\"oncopy\"in n)||!(\"onpaste\"in n))&&r.addListener(e,\"keydown\",function(e){if(i.isMac&&!e.metaKey||!e.ctrlKey)return;switch(e.keyCode){case 67:P(e);break;case 86:H(e);break;case 88:D(e)}});var B=function(e){if(h||!t.onCompositionStart||t.$readOnly)return;h={},t.onCompositionStart(),setTimeout(j,0),t.on(\"mousedown\",F),t.selection.isEmpty()||(t.insert(\"\"),t.session.markUndoGroup(),t.selection.clearSelection()),t.session.markUndoGroup()},j=function(){if(!h||!t.onCompositionUpdate||t.$readOnly)return;var e=n.value.replace(/\\x01/g,\"\");if(h.lastValue===e)return;t.onCompositionUpdate(e),h.lastValue&&t.undo(),h.lastValue=e;if(h.lastValue){var r=t.selection.getRange();t.insert(h.lastValue),t.session.markUndoGroup(),h.range=t.selection.getRange(),t.selection.setRange(r),t.selection.clearSelection()}},F=function(e){if(!t.onCompositionEnd||t.$readOnly)return;var r=h;h=!1;var i=setTimeout(function(){i=null;var e=n.value.replace(/\\x01/g,\"\");if(h)return;e==r.lastValue?w():!r.lastValue&&e&&(w(),A(e))});k=function(n){return i&&clearTimeout(i),n=n.replace(/\\x01/g,\"\"),n==r.lastValue?\"\":(r.lastValue&&i&&t.undo(),n)},t.onCompositionEnd(),t.removeListener(\"mousedown\",F),e.type==\"compositionend\"&&r.range&&t.selection.setRange(r.range)},I=o.delayedCall(j,50);r.addListener(n,\"compositionstart\",B),i.isGecko?r.addListener(n,\"text\",function(){I.schedule()}):(r.addListener(n,\"keyup\",function(){I.schedule()}),r.addListener(n,\"keydown\",function(){I.schedule()})),r.addListener(n,\"compositionend\",F),this.getElement=function(){return n},this.setReadOnly=function(e){n.readOnly=e},this.onContextMenu=function(e){L=!0,b(t.selection.isEmpty()),t._emit(\"nativecontextmenu\",{target:t,domEvent:e}),this.moveToMouse(e,!0)},this.moveToMouse=function(e,o){if(!o&&i.isOldIE)return;p||(p=n.style.cssText),n.style.cssText=(o?\"z-index:100000;\":\"\")+\"height:\"+n.style.height+\";\"+(i.isIE?\"opacity:0.1;\":\"\");var u=t.container.getBoundingClientRect(),a=s.computedStyle(t.container),f=u.top+(parseInt(a.borderTopWidth)||0),l=u.left+(parseInt(u.borderLeftWidth)||0),c=u.bottom-f-n.clientHeight-2,h=function(e){n.style.left=e.clientX-l-2+\"px\",n.style.top=Math.min(e.clientY-f-2,c)+\"px\"};h(e);if(e.type!=\"mousedown\")return;t.renderer.$keepTextAreaAtCursor&&(t.renderer.$keepTextAreaAtCursor=null),clearTimeout(q),i.isWin&&!i.isOldIE&&r.capture(t.container,h,R)},this.onContextMenuClose=R;var q,U=function(e){t.textInput.onContextMenu(e),R()};r.addListener(n,\"mouseup\",U),r.addListener(n,\"mousedown\",function(e){e.preventDefault(),R()}),r.addListener(t.renderer.scroller,\"contextmenu\",U),r.addListener(n,\"contextmenu\",U)};t.TextInput=f}),ace.define(\"ace/mouse/default_handlers\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\",\"ace/lib/event\",\"ace/lib/useragent\"],function(e,t,n){\"use strict\";function u(e){e.$clickSelection=null;var t=e.editor;t.setDefaultHandler(\"mousedown\",this.onMouseDown.bind(e)),t.setDefaultHandler(\"dblclick\",this.onDoubleClick.bind(e)),t.setDefaultHandler(\"tripleclick\",this.onTripleClick.bind(e)),t.setDefaultHandler(\"quadclick\",this.onQuadClick.bind(e)),t.setDefaultHandler(\"mousewheel\",this.onMouseWheel.bind(e)),t.setDefaultHandler(\"touchmove\",this.onTouchMove.bind(e));var n=[\"select\",\"startSelect\",\"selectEnd\",\"selectAllEnd\",\"selectByWordsEnd\",\"selectByLinesEnd\",\"dragWait\",\"dragWaitEnd\",\"focusWait\"];n.forEach(function(t){e[t]=this[t]},this),e.selectByLines=this.extendSelectionBy.bind(e,\"getLineRange\"),e.selectByWords=this.extendSelectionBy.bind(e,\"getWordRange\")}function a(e,t,n,r){return Math.sqrt(Math.pow(n-e,2)+Math.pow(r-t,2))}function f(e,t){if(e.start.row==e.end.row)var n=2*t.column-e.start.column-e.end.column;else if(e.start.row==e.end.row-1&&!e.start.column&&!e.end.column)var n=t.column-4;else var n=2*t.row-e.start.row-e.end.row;return n<0?{cursor:e.start,anchor:e.end}:{cursor:e.end,anchor:e.start}}var r=e(\"../lib/dom\"),i=e(\"../lib/event\"),s=e(\"../lib/useragent\"),o=0;(function(){this.onMouseDown=function(e){var t=e.inSelection(),n=e.getDocumentPosition();this.mousedownEvent=e;var r=this.editor,i=e.getButton();if(i!==0){var s=r.getSelectionRange(),o=s.isEmpty();r.$blockScrolling++,(o||i==1)&&r.selection.moveToPosition(n),r.$blockScrolling--,i==2&&r.textInput.onContextMenu(e.domEvent);return}this.mousedownEvent.time=Date.now();if(t&&!r.isFocused()){r.focus();if(this.$focusTimout&&!this.$clickSelection&&!r.inMultiSelectMode){this.setState(\"focusWait\"),this.captureMouse(e);return}}return this.captureMouse(e),this.startSelect(n,e.domEvent._clicks>1),e.preventDefault()},this.startSelect=function(e,t){e=e||this.editor.renderer.screenToTextCoordinates(this.x,this.y);var n=this.editor;n.$blockScrolling++,this.mousedownEvent.getShiftKey()?n.selection.selectToPosition(e):t||n.selection.moveToPosition(e),t||this.select(),n.renderer.scroller.setCapture&&n.renderer.scroller.setCapture(),n.setStyle(\"ace_selecting\"),this.setState(\"select\"),n.$blockScrolling--},this.select=function(){var e,t=this.editor,n=t.renderer.screenToTextCoordinates(this.x,this.y);t.$blockScrolling++;if(this.$clickSelection){var r=this.$clickSelection.comparePoint(n);if(r==-1)e=this.$clickSelection.end;else if(r==1)e=this.$clickSelection.start;else{var i=f(this.$clickSelection,n);n=i.cursor,e=i.anchor}t.selection.setSelectionAnchor(e.row,e.column)}t.selection.selectToPosition(n),t.$blockScrolling--,t.renderer.scrollCursorIntoView()},this.extendSelectionBy=function(e){var t,n=this.editor,r=n.renderer.screenToTextCoordinates(this.x,this.y),i=n.selection[e](r.row,r.column);n.$blockScrolling++;if(this.$clickSelection){var s=this.$clickSelection.comparePoint(i.start),o=this.$clickSelection.comparePoint(i.end);if(s==-1&&o<=0){t=this.$clickSelection.end;if(i.end.row!=r.row||i.end.column!=r.column)r=i.start}else if(o==1&&s>=0){t=this.$clickSelection.start;if(i.start.row!=r.row||i.start.column!=r.column)r=i.end}else if(s==-1&&o==1)r=i.end,t=i.start;else{var u=f(this.$clickSelection,r);r=u.cursor,t=u.anchor}n.selection.setSelectionAnchor(t.row,t.column)}n.selection.selectToPosition(r),n.$blockScrolling--,n.renderer.scrollCursorIntoView()},this.selectEnd=this.selectAllEnd=this.selectByWordsEnd=this.selectByLinesEnd=function(){this.$clickSelection=null,this.editor.unsetStyle(\"ace_selecting\"),this.editor.renderer.scroller.releaseCapture&&this.editor.renderer.scroller.releaseCapture()},this.focusWait=function(){var e=a(this.mousedownEvent.x,this.mousedownEvent.y,this.x,this.y),t=Date.now();(e>o||t-this.mousedownEvent.time>this.$focusTimout)&&this.startSelect(this.mousedownEvent.getDocumentPosition())},this.onDoubleClick=function(e){var t=e.getDocumentPosition(),n=this.editor,r=n.session,i=r.getBracketRange(t);i?(i.isEmpty()&&(i.start.column--,i.end.column++),this.setState(\"select\")):(i=n.selection.getWordRange(t.row,t.column),this.setState(\"selectByWords\")),this.$clickSelection=i,this.select()},this.onTripleClick=function(e){var t=e.getDocumentPosition(),n=this.editor;this.setState(\"selectByLines\");var r=n.getSelectionRange();r.isMultiLine()&&r.contains(t.row,t.column)?(this.$clickSelection=n.selection.getLineRange(r.start.row),this.$clickSelection.end=n.selection.getLineRange(r.end.row).end):this.$clickSelection=n.selection.getLineRange(t.row),this.select()},this.onQuadClick=function(e){var t=this.editor;t.selectAll(),this.$clickSelection=t.getSelectionRange(),this.setState(\"selectAll\")},this.onMouseWheel=function(e){if(e.getAccelKey())return;e.getShiftKey()&&e.wheelY&&!e.wheelX&&(e.wheelX=e.wheelY,e.wheelY=0);var t=e.domEvent.timeStamp,n=t-(this.$lastScrollTime||0),r=this.editor,i=r.renderer.isScrollableBy(e.wheelX*e.speed,e.wheelY*e.speed);if(i||n<200)return this.$lastScrollTime=t,r.renderer.scrollBy(e.wheelX*e.speed,e.wheelY*e.speed),e.stop()},this.onTouchMove=function(e){var t=e.domEvent.timeStamp,n=t-(this.$lastScrollTime||0),r=this.editor,i=r.renderer.isScrollableBy(e.wheelX*e.speed,e.wheelY*e.speed);if(i||n<200)return this.$lastScrollTime=t,r.renderer.scrollBy(e.wheelX*e.speed,e.wheelY*e.speed),e.stop()}}).call(u.prototype),t.DefaultHandlers=u}),ace.define(\"ace/tooltip\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/dom\"],function(e,t,n){\"use strict\";function s(e){this.isOpen=!1,this.$element=null,this.$parentNode=e}var r=e(\"./lib/oop\"),i=e(\"./lib/dom\");(function(){this.$init=function(){return this.$element=i.createElement(\"div\"),this.$element.className=\"ace_tooltip\",this.$element.style.display=\"none\",this.$parentNode.appendChild(this.$element),this.$element},this.getElement=function(){return this.$element||this.$init()},this.setText=function(e){i.setInnerText(this.getElement(),e)},this.setHtml=function(e){this.getElement().innerHTML=e},this.setPosition=function(e,t){this.getElement().style.left=e+\"px\",this.getElement().style.top=t+\"px\"},this.setClassName=function(e){i.addCssClass(this.getElement(),e)},this.show=function(e,t,n){e!=null&&this.setText(e),t!=null&&n!=null&&this.setPosition(t,n),this.isOpen||(this.getElement().style.display=\"block\",this.isOpen=!0)},this.hide=function(){this.isOpen&&(this.getElement().style.display=\"none\",this.isOpen=!1)},this.getHeight=function(){return this.getElement().offsetHeight},this.getWidth=function(){return this.getElement().offsetWidth}}).call(s.prototype),t.Tooltip=s}),ace.define(\"ace/mouse/default_gutter_handler\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\",\"ace/lib/oop\",\"ace/lib/event\",\"ace/tooltip\"],function(e,t,n){\"use strict\";function u(e){function l(){var r=u.getDocumentPosition().row,s=n.$annotations[r];if(!s)return c();var o=t.session.getLength();if(r==o){var a=t.renderer.pixelToScreenCoordinates(0,u.y).row,l=u.$pos;if(a>t.session.documentToScreenRow(l.row,l.column))return c()}if(f==s)return;f=s.text.join(\"<br/>\"),i.setHtml(f),i.show(),t.on(\"mousewheel\",c);if(e.$tooltipFollowsMouse)h(u);else{var p=u.domEvent.target,d=p.getBoundingClientRect(),v=i.getElement().style;v.left=d.right+\"px\",v.top=d.bottom+\"px\"}}function c(){o&&(o=clearTimeout(o)),f&&(i.hide(),f=null,t.removeEventListener(\"mousewheel\",c))}function h(e){i.setPosition(e.x,e.y)}var t=e.editor,n=t.renderer.$gutterLayer,i=new a(t.container);e.editor.setDefaultHandler(\"guttermousedown\",function(r){if(!t.isFocused()||r.getButton()!=0)return;var i=n.getRegion(r);if(i==\"foldWidgets\")return;var s=r.getDocumentPosition().row,o=t.session.selection;if(r.getShiftKey())o.selectTo(s,0);else{if(r.domEvent.detail==2)return t.selectAll(),r.preventDefault();e.$clickSelection=t.selection.getLineRange(s)}return e.setState(\"selectByLines\"),e.captureMouse(r),r.preventDefault()});var o,u,f;e.editor.setDefaultHandler(\"guttermousemove\",function(t){var n=t.domEvent.target||t.domEvent.srcElement;if(r.hasCssClass(n,\"ace_fold-widget\"))return c();f&&e.$tooltipFollowsMouse&&h(t),u=t;if(o)return;o=setTimeout(function(){o=null,u&&!e.isMousePressed?l():c()},50)}),s.addListener(t.renderer.$gutter,\"mouseout\",function(e){u=null;if(!f||o)return;o=setTimeout(function(){o=null,c()},50)}),t.on(\"changeSession\",c)}function a(e){o.call(this,e)}var r=e(\"../lib/dom\"),i=e(\"../lib/oop\"),s=e(\"../lib/event\"),o=e(\"../tooltip\").Tooltip;i.inherits(a,o),function(){this.setPosition=function(e,t){var n=window.innerWidth||document.documentElement.clientWidth,r=window.innerHeight||document.documentElement.clientHeight,i=this.getWidth(),s=this.getHeight();e+=15,t+=15,e+i>n&&(e-=e+i-n),t+s>r&&(t-=20+s),o.prototype.setPosition.call(this,e,t)}}.call(a.prototype),t.GutterHandler=u}),ace.define(\"ace/mouse/mouse_event\",[\"require\",\"exports\",\"module\",\"ace/lib/event\",\"ace/lib/useragent\"],function(e,t,n){\"use strict\";var r=e(\"../lib/event\"),i=e(\"../lib/useragent\"),s=t.MouseEvent=function(e,t){this.domEvent=e,this.editor=t,this.x=this.clientX=e.clientX,this.y=this.clientY=e.clientY,this.$pos=null,this.$inSelection=null,this.propagationStopped=!1,this.defaultPrevented=!1};(function(){this.stopPropagation=function(){r.stopPropagation(this.domEvent),this.propagationStopped=!0},this.preventDefault=function(){r.preventDefault(this.domEvent),this.defaultPrevented=!0},this.stop=function(){this.stopPropagation(),this.preventDefault()},this.getDocumentPosition=function(){return this.$pos?this.$pos:(this.$pos=this.editor.renderer.screenToTextCoordinates(this.clientX,this.clientY),this.$pos)},this.inSelection=function(){if(this.$inSelection!==null)return this.$inSelection;var e=this.editor,t=e.getSelectionRange();if(t.isEmpty())this.$inSelection=!1;else{var n=this.getDocumentPosition();this.$inSelection=t.contains(n.row,n.column)}return this.$inSelection},this.getButton=function(){return r.getButton(this.domEvent)},this.getShiftKey=function(){return this.domEvent.shiftKey},this.getAccelKey=i.isMac?function(){return this.domEvent.metaKey}:function(){return this.domEvent.ctrlKey}}).call(s.prototype)}),ace.define(\"ace/mouse/dragdrop_handler\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\",\"ace/lib/event\",\"ace/lib/useragent\"],function(e,t,n){\"use strict\";function f(e){function T(e,n){var r=Date.now(),i=!n||e.row!=n.row,s=!n||e.column!=n.column;if(!S||i||s)t.$blockScrolling+=1,t.moveCursorToPosition(e),t.$blockScrolling-=1,S=r,x={x:p,y:d};else{var o=l(x.x,x.y,p,d);o>a?S=null:r-S>=u&&(t.renderer.scrollCursorIntoView(),S=null)}}function N(e,n){var r=Date.now(),i=t.renderer.layerConfig.lineHeight,s=t.renderer.layerConfig.characterWidth,u=t.renderer.scroller.getBoundingClientRect(),a={x:{left:p-u.left,right:u.right-p},y:{top:d-u.top,bottom:u.bottom-d}},f=Math.min(a.x.left,a.x.right),l=Math.min(a.y.top,a.y.bottom),c={row:e.row,column:e.column};f/s<=2&&(c.column+=a.x.left<a.x.right?-3:2),l/i<=1&&(c.row+=a.y.top<a.y.bottom?-1:1);var h=e.row!=c.row,v=e.column!=c.column,m=!n||e.row!=n.row;h||v&&!m?E?r-E>=o&&t.renderer.scrollCursorIntoView(c):E=r:E=null}function C(){var e=g;g=t.renderer.screenToTextCoordinates(p,d),T(g,e),N(g,e)}function k(){m=t.selection.toOrientedRange(),h=t.session.addMarker(m,\"ace_selection\",t.getSelectionStyle()),t.clearSelection(),t.isFocused()&&t.renderer.$cursorLayer.setBlinking(!1),clearInterval(v),C(),v=setInterval(C,20),y=0,i.addListener(document,\"mousemove\",O)}function L(){clearInterval(v),t.session.removeMarker(h),h=null,t.$blockScrolling+=1,t.selection.fromOrientedRange(m),t.$blockScrolling-=1,t.isFocused()&&!w&&t.renderer.$cursorLayer.setBlinking(!t.getReadOnly()),m=null,g=null,y=0,E=null,S=null,i.removeListener(document,\"mousemove\",O)}function O(){A==null&&(A=setTimeout(function(){A!=null&&h&&L()},20))}function M(e){var t=e.types;return!t||Array.prototype.some.call(t,function(e){return e==\"text/plain\"||e==\"Text\"})}function _(e){var t=[\"copy\",\"copymove\",\"all\",\"uninitialized\"],n=[\"move\",\"copymove\",\"linkmove\",\"all\",\"uninitialized\"],r=s.isMac?e.altKey:e.ctrlKey,i=\"uninitialized\";try{i=e.dataTransfer.effectAllowed.toLowerCase()}catch(e){}var o=\"none\";return r&&t.indexOf(i)>=0?o=\"copy\":n.indexOf(i)>=0?o=\"move\":t.indexOf(i)>=0&&(o=\"copy\"),o}var t=e.editor,n=r.createElement(\"img\");n.src=\"data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\",s.isOpera&&(n.style.cssText=\"width:1px;height:1px;position:fixed;top:0;left:0;z-index:2147483647;opacity:0;\");var f=[\"dragWait\",\"dragWaitEnd\",\"startDrag\",\"dragReadyEnd\",\"onMouseDrag\"];f.forEach(function(t){e[t]=this[t]},this),t.addEventListener(\"mousedown\",this.onMouseDown.bind(e));var c=t.container,h,p,d,v,m,g,y=0,b,w,E,S,x;this.onDragStart=function(e){if(this.cancelDrag||!c.draggable){var r=this;return setTimeout(function(){r.startSelect(),r.captureMouse(e)},0),e.preventDefault()}m=t.getSelectionRange();var i=e.dataTransfer;i.effectAllowed=t.getReadOnly()?\"copy\":\"copyMove\",s.isOpera&&(t.container.appendChild(n),n.scrollTop=0),i.setDragImage&&i.setDragImage(n,0,0),s.isOpera&&t.container.removeChild(n),i.clearData(),i.setData(\"Text\",t.session.getTextRange()),w=!0,this.setState(\"drag\")},this.onDragEnd=function(e){c.draggable=!1,w=!1,this.setState(null);if(!t.getReadOnly()){var n=e.dataTransfer.dropEffect;!b&&n==\"move\"&&t.session.remove(t.getSelectionRange()),t.renderer.$cursorLayer.setBlinking(!0)}this.editor.unsetStyle(\"ace_dragging\"),this.editor.renderer.setCursorStyle(\"\")},this.onDragEnter=function(e){if(t.getReadOnly()||!M(e.dataTransfer))return;return p=e.clientX,d=e.clientY,h||k(),y++,e.dataTransfer.dropEffect=b=_(e),i.preventDefault(e)},this.onDragOver=function(e){if(t.getReadOnly()||!M(e.dataTransfer))return;return p=e.clientX,d=e.clientY,h||(k(),y++),A!==null&&(A=null),e.dataTransfer.dropEffect=b=_(e),i.preventDefault(e)},this.onDragLeave=function(e){y--;if(y<=0&&h)return L(),b=null,i.preventDefault(e)},this.onDrop=function(e){if(!g)return;var n=e.dataTransfer;if(w)switch(b){case\"move\":m.contains(g.row,g.column)?m={start:g,end:g}:m=t.moveText(m,g);break;case\"copy\":m=t.moveText(m,g,!0)}else{var r=n.getData(\"Text\");m={start:g,end:t.session.insert(g,r)},t.focus(),b=null}return L(),i.preventDefault(e)},i.addListener(c,\"dragstart\",this.onDragStart.bind(e)),i.addListener(c,\"dragend\",this.onDragEnd.bind(e)),i.addListener(c,\"dragenter\",this.onDragEnter.bind(e)),i.addListener(c,\"dragover\",this.onDragOver.bind(e)),i.addListener(c,\"dragleave\",this.onDragLeave.bind(e)),i.addListener(c,\"drop\",this.onDrop.bind(e));var A=null}function l(e,t,n,r){return Math.sqrt(Math.pow(n-e,2)+Math.pow(r-t,2))}var r=e(\"../lib/dom\"),i=e(\"../lib/event\"),s=e(\"../lib/useragent\"),o=200,u=200,a=5;(function(){this.dragWait=function(){var e=Date.now()-this.mousedownEvent.time;e>this.editor.getDragDelay()&&this.startDrag()},this.dragWaitEnd=function(){var e=this.editor.container;e.draggable=!1,this.startSelect(this.mousedownEvent.getDocumentPosition()),this.selectEnd()},this.dragReadyEnd=function(e){this.editor.renderer.$cursorLayer.setBlinking(!this.editor.getReadOnly()),this.editor.unsetStyle(\"ace_dragging\"),this.editor.renderer.setCursorStyle(\"\"),this.dragWaitEnd()},this.startDrag=function(){this.cancelDrag=!1;var e=this.editor,t=e.container;t.draggable=!0,e.renderer.$cursorLayer.setBlinking(!1),e.setStyle(\"ace_dragging\");var n=s.isWin?\"default\":\"move\";e.renderer.setCursorStyle(n),this.setState(\"dragReady\")},this.onMouseDrag=function(e){var t=this.editor.container;if(s.isIE&&this.state==\"dragReady\"){var n=l(this.mousedownEvent.x,this.mousedownEvent.y,this.x,this.y);n>3&&t.dragDrop()}if(this.state===\"dragWait\"){var n=l(this.mousedownEvent.x,this.mousedownEvent.y,this.x,this.y);n>0&&(t.draggable=!1,this.startSelect(this.mousedownEvent.getDocumentPosition()))}},this.onMouseDown=function(e){if(!this.$dragEnabled)return;this.mousedownEvent=e;var t=this.editor,n=e.inSelection(),r=e.getButton(),i=e.domEvent.detail||1;if(i===1&&r===0&&n){if(e.editor.inMultiSelectMode&&(e.getAccelKey()||e.getShiftKey()))return;this.mousedownEvent.time=Date.now();var o=e.domEvent.target||e.domEvent.srcElement;\"unselectable\"in o&&(o.unselectable=\"on\");if(t.getDragDelay()){if(s.isWebKit){this.cancelDrag=!0;var u=t.container;u.draggable=!0}this.setState(\"dragWait\")}else this.startDrag();this.captureMouse(e,this.onMouseDrag.bind(this)),e.defaultPrevented=!0}}}).call(f.prototype),t.DragdropHandler=f}),ace.define(\"ace/lib/net\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\"],function(e,t,n){\"use strict\";var r=e(\"./dom\");t.get=function(e,t){var n=new XMLHttpRequest;n.open(\"GET\",e,!0),n.onreadystatechange=function(){n.readyState===4&&t(n.responseText)},n.send(null)},t.loadScript=function(e,t){var n=r.getDocumentHead(),i=document.createElement(\"script\");i.src=e,n.appendChild(i),i.onload=i.onreadystatechange=function(e,n){if(n||!i.readyState||i.readyState==\"loaded\"||i.readyState==\"complete\")i=i.onload=i.onreadystatechange=null,n||t()}},t.qualifyURL=function(e){var t=document.createElement(\"a\");return t.href=e,t.href}}),ace.define(\"ace/lib/event_emitter\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";var r={},i=function(){this.propagationStopped=!0},s=function(){this.defaultPrevented=!0};r._emit=r._dispatchEvent=function(e,t){this._eventRegistry||(this._eventRegistry={}),this._defaultHandlers||(this._defaultHandlers={});var n=this._eventRegistry[e]||[],r=this._defaultHandlers[e];if(!n.length&&!r)return;if(typeof t!=\"object\"||!t)t={};t.type||(t.type=e),t.stopPropagation||(t.stopPropagation=i),t.preventDefault||(t.preventDefault=s),n=n.slice();for(var o=0;o<n.length;o++){n[o](t,this);if(t.propagationStopped)break}if(r&&!t.defaultPrevented)return r(t,this)},r._signal=function(e,t){var n=(this._eventRegistry||{})[e];if(!n)return;n=n.slice();for(var r=0;r<n.length;r++)n[r](t,this)},r.once=function(e,t){var n=this;t&&this.addEventListener(e,function r(){n.removeEventListener(e,r),t.apply(null,arguments)})},r.setDefaultHandler=function(e,t){var n=this._defaultHandlers;n||(n=this._defaultHandlers={_disabled_:{}});if(n[e]){var r=n[e],i=n._disabled_[e];i||(n._disabled_[e]=i=[]),i.push(r);var s=i.indexOf(t);s!=-1&&i.splice(s,1)}n[e]=t},r.removeDefaultHandler=function(e,t){var n=this._defaultHandlers;if(!n)return;var r=n._disabled_[e];if(n[e]==t){var i=n[e];r&&this.setDefaultHandler(e,r.pop())}else if(r){var s=r.indexOf(t);s!=-1&&r.splice(s,1)}},r.on=r.addEventListener=function(e,t,n){this._eventRegistry=this._eventRegistry||{};var r=this._eventRegistry[e];return r||(r=this._eventRegistry[e]=[]),r.indexOf(t)==-1&&r[n?\"unshift\":\"push\"](t),t},r.off=r.removeListener=r.removeEventListener=function(e,t){this._eventRegistry=this._eventRegistry||{};var n=this._eventRegistry[e];if(!n)return;var r=n.indexOf(t);r!==-1&&n.splice(r,1)},r.removeAllListeners=function(e){this._eventRegistry&&(this._eventRegistry[e]=[])},t.EventEmitter=r}),ace.define(\"ace/lib/app_config\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/event_emitter\"],function(e,t,n){\"no use strict\";function o(e){typeof console!=\"undefined\"&&console.warn&&console.warn.apply(console,arguments)}function u(e,t){var n=new Error(e);n.data=t,typeof console==\"object\"&&console.error&&console.error(n),setTimeout(function(){throw n})}var r=e(\"./oop\"),i=e(\"./event_emitter\").EventEmitter,s={setOptions:function(e){Object.keys(e).forEach(function(t){this.setOption(t,e[t])},this)},getOptions:function(e){var t={};return e?Array.isArray(e)||(t=e,e=Object.keys(t)):e=Object.keys(this.$options),e.forEach(function(e){t[e]=this.getOption(e)},this),t},setOption:function(e,t){if(this[\"$\"+e]===t)return;var n=this.$options[e];if(!n)return o('misspelled option \"'+e+'\"');if(n.forwardTo)return this[n.forwardTo]&&this[n.forwardTo].setOption(e,t);n.handlesSet||(this[\"$\"+e]=t),n&&n.set&&n.set.call(this,t)},getOption:function(e){var t=this.$options[e];return t?t.forwardTo?this[t.forwardTo]&&this[t.forwardTo].getOption(e):t&&t.get?t.get.call(this):this[\"$\"+e]:o('misspelled option \"'+e+'\"')}},a=function(){this.$defaultOptions={}};(function(){r.implement(this,i),this.defineOptions=function(e,t,n){return e.$options||(this.$defaultOptions[t]=e.$options={}),Object.keys(n).forEach(function(t){var r=n[t];typeof r==\"string\"&&(r={forwardTo:r}),r.name||(r.name=t),e.$options[r.name]=r,\"initialValue\"in r&&(e[\"$\"+r.name]=r.initialValue)}),r.implement(e,s),this},this.resetOptions=function(e){Object.keys(e.$options).forEach(function(t){var n=e.$options[t];\"value\"in n&&e.setOption(t,n.value)})},this.setDefaultValue=function(e,t,n){var r=this.$defaultOptions[e]||(this.$defaultOptions[e]={});r[t]&&(r.forwardTo?this.setDefaultValue(r.forwardTo,t,n):r[t].value=n)},this.setDefaultValues=function(e,t){Object.keys(t).forEach(function(n){this.setDefaultValue(e,n,t[n])},this)},this.warn=o,this.reportError=u}).call(a.prototype),t.AppConfig=a}),ace.define(\"ace/config\",[\"require\",\"exports\",\"module\",\"ace/lib/lang\",\"ace/lib/oop\",\"ace/lib/net\",\"ace/lib/app_config\"],function(e,t,n){\"no use strict\";function f(r){if(!u||!u.document)return;a.packaged=r||e.packaged||n.packaged||u.define&&define.packaged;var i={},s=\"\",o=document.currentScript||document._currentScript,f=o&&o.ownerDocument||document,c=f.getElementsByTagName(\"script\");for(var h=0;h<c.length;h++){var p=c[h],d=p.src||p.getAttribute(\"src\");if(!d)continue;var v=p.attributes;for(var m=0,g=v.length;m<g;m++){var y=v[m];y.name.indexOf(\"data-ace-\")===0&&(i[l(y.name.replace(/^data-ace-/,\"\"))]=y.value)}var b=d.match(/^(.*)\\/ace(\\-\\w+)?\\.js(\\?|$)/);b&&(s=b[1])}s&&(i.base=i.base||s,i.packaged=!0),i.basePath=i.base,i.workerPath=i.workerPath||i.base,i.modePath=i.modePath||i.base,i.themePath=i.themePath||i.base,delete i.base;for(var w in i)typeof i[w]!=\"undefined\"&&t.set(w,i[w])}function l(e){return e.replace(/-(.)/g,function(e,t){return t.toUpperCase()})}var r=e(\"./lib/lang\"),i=e(\"./lib/oop\"),s=e(\"./lib/net\"),o=e(\"./lib/app_config\").AppConfig;n.exports=t=new o;var u=function(){return this||typeof window!=\"undefined\"&&window}(),a={packaged:!1,workerPath:null,modePath:null,themePath:null,basePath:\"\",suffix:\".js\",$moduleUrls:{}};t.get=function(e){if(!a.hasOwnProperty(e))throw new Error(\"Unknown config key: \"+e);return a[e]},t.set=function(e,t){if(!a.hasOwnProperty(e))throw new Error(\"Unknown config key: \"+e);a[e]=t},t.all=function(){return r.copyObject(a)},t.moduleUrl=function(e,t){if(a.$moduleUrls[e])return a.$moduleUrls[e];var n=e.split(\"/\");t=t||n[n.length-2]||\"\";var r=t==\"snippets\"?\"/\":\"-\",i=n[n.length-1];if(t==\"worker\"&&r==\"-\"){var s=new RegExp(\"^\"+t+\"[\\\\-_]|[\\\\-_]\"+t+\"$\",\"g\");i=i.replace(s,\"\")}(!i||i==t)&&n.length>1&&(i=n[n.length-2]);var o=a[t+\"Path\"];return o==null?o=a.basePath:r==\"/\"&&(t=r=\"\"),o&&o.slice(-1)!=\"/\"&&(o+=\"/\"),o+t+r+i+this.get(\"suffix\")},t.setModuleUrl=function(e,t){return a.$moduleUrls[e]=t},t.$loading={},t.loadModule=function(n,r){var i,o;Array.isArray(n)&&(o=n[0],n=n[1]);try{i=e(n)}catch(u){}if(i&&!t.$loading[n])return r&&r(i);t.$loading[n]||(t.$loading[n]=[]),t.$loading[n].push(r);if(t.$loading[n].length>1)return;var a=function(){e([n],function(e){t._emit(\"load.module\",{name:n,module:e});var r=t.$loading[n];t.$loading[n]=null,r.forEach(function(t){t&&t(e)})})};if(!t.get(\"packaged\"))return a();s.loadScript(t.moduleUrl(n,o),a)},t.init=f}),ace.define(\"ace/mouse/mouse_handler\",[\"require\",\"exports\",\"module\",\"ace/lib/event\",\"ace/lib/useragent\",\"ace/mouse/default_handlers\",\"ace/mouse/default_gutter_handler\",\"ace/mouse/mouse_event\",\"ace/mouse/dragdrop_handler\",\"ace/config\"],function(e,t,n){\"use strict\";var r=e(\"../lib/event\"),i=e(\"../lib/useragent\"),s=e(\"./default_handlers\").DefaultHandlers,o=e(\"./default_gutter_handler\").GutterHandler,u=e(\"./mouse_event\").MouseEvent,a=e(\"./dragdrop_handler\").DragdropHandler,f=e(\"../config\"),l=function(e){var t=this;this.editor=e,new s(this),new o(this),new a(this);var n=function(t){var n=!document.hasFocus||!document.hasFocus()||!e.isFocused()&&document.activeElement==(e.textInput&&e.textInput.getElement());n&&window.focus(),e.focus()},u=e.renderer.getMouseEventTarget();r.addListener(u,\"click\",this.onMouseEvent.bind(this,\"click\")),r.addListener(u,\"mousemove\",this.onMouseMove.bind(this,\"mousemove\")),r.addMultiMouseDownListener([u,e.renderer.scrollBarV&&e.renderer.scrollBarV.inner,e.renderer.scrollBarH&&e.renderer.scrollBarH.inner,e.textInput&&e.textInput.getElement()].filter(Boolean),[400,300,250],this,\"onMouseEvent\"),r.addMouseWheelListener(e.container,this.onMouseWheel.bind(this,\"mousewheel\")),r.addTouchMoveListener(e.container,this.onTouchMove.bind(this,\"touchmove\"));var f=e.renderer.$gutter;r.addListener(f,\"mousedown\",this.onMouseEvent.bind(this,\"guttermousedown\")),r.addListener(f,\"click\",this.onMouseEvent.bind(this,\"gutterclick\")),r.addListener(f,\"dblclick\",this.onMouseEvent.bind(this,\"gutterdblclick\")),r.addListener(f,\"mousemove\",this.onMouseEvent.bind(this,\"guttermousemove\")),r.addListener(u,\"mousedown\",n),r.addListener(f,\"mousedown\",n),i.isIE&&e.renderer.scrollBarV&&(r.addListener(e.renderer.scrollBarV.element,\"mousedown\",n),r.addListener(e.renderer.scrollBarH.element,\"mousedown\",n)),e.on(\"mousemove\",function(n){if(t.state||t.$dragDelay||!t.$dragEnabled)return;var r=e.renderer.screenToTextCoordinates(n.x,n.y),i=e.session.selection.getRange(),s=e.renderer;!i.isEmpty()&&i.insideStart(r.row,r.column)?s.setCursorStyle(\"default\"):s.setCursorStyle(\"\")})};(function(){this.onMouseEvent=function(e,t){this.editor._emit(e,new u(t,this.editor))},this.onMouseMove=function(e,t){var n=this.editor._eventRegistry&&this.editor._eventRegistry.mousemove;if(!n||!n.length)return;this.editor._emit(e,new u(t,this.editor))},this.onMouseWheel=function(e,t){var n=new u(t,this.editor);n.speed=this.$scrollSpeed*2,n.wheelX=t.wheelX,n.wheelY=t.wheelY,this.editor._emit(e,n)},this.onTouchMove=function(e,t){var n=new u(t,this.editor);n.speed=1,n.wheelX=t.wheelX,n.wheelY=t.wheelY,this.editor._emit(e,n)},this.setState=function(e){this.state=e},this.captureMouse=function(e,t){this.x=e.x,this.y=e.y,this.isMousePressed=!0;var n=this.editor.renderer;n.$keepTextAreaAtCursor&&(n.$keepTextAreaAtCursor=null);var s=this,o=function(e){if(!e)return;if(i.isWebKit&&!e.which&&s.releaseMouse)return s.releaseMouse();s.x=e.clientX,s.y=e.clientY,t&&t(e),s.mouseEvent=new u(e,s.editor),s.$mouseMoved=!0},a=function(e){clearInterval(l),f(),s[s.state+\"End\"]&&s[s.state+\"End\"](e),s.state=\"\",n.$keepTextAreaAtCursor==null&&(n.$keepTextAreaAtCursor=!0,n.$moveTextAreaToCursor()),s.isMousePressed=!1,s.$onCaptureMouseMove=s.releaseMouse=null,e&&s.onMouseEvent(\"mouseup\",e)},f=function(){s[s.state]&&s[s.state](),s.$mouseMoved=!1};if(i.isOldIE&&e.domEvent.type==\"dblclick\")return setTimeout(function(){a(e)});s.$onCaptureMouseMove=o,s.releaseMouse=r.capture(this.editor.container,o,a);var l=setInterval(f,20)},this.releaseMouse=null,this.cancelContextMenu=function(){var e=function(t){if(t&&t.domEvent&&t.domEvent.type!=\"contextmenu\")return;this.editor.off(\"nativecontextmenu\",e),t&&t.domEvent&&r.stopEvent(t.domEvent)}.bind(this);setTimeout(e,10),this.editor.on(\"nativecontextmenu\",e)}}).call(l.prototype),f.defineOptions(l.prototype,\"mouseHandler\",{scrollSpeed:{initialValue:2},dragDelay:{initialValue:i.isMac?150:0},dragEnabled:{initialValue:!0},focusTimout:{initialValue:0},tooltipFollowsMouse:{initialValue:!0}}),t.MouseHandler=l}),ace.define(\"ace/mouse/fold_handler\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";function r(e){e.on(\"click\",function(t){var n=t.getDocumentPosition(),r=e.session,i=r.getFoldAt(n.row,n.column,1);i&&(t.getAccelKey()?r.removeFold(i):r.expandFold(i),t.stop())}),e.on(\"gutterclick\",function(t){var n=e.renderer.$gutterLayer.getRegion(t);if(n==\"foldWidgets\"){var r=t.getDocumentPosition().row,i=e.session;i.foldWidgets&&i.foldWidgets[r]&&e.session.onFoldWidgetClick(r,t),e.isFocused()||e.focus(),t.stop()}}),e.on(\"gutterdblclick\",function(t){var n=e.renderer.$gutterLayer.getRegion(t);if(n==\"foldWidgets\"){var r=t.getDocumentPosition().row,i=e.session,s=i.getParentFoldRangeData(r,!0),o=s.range||s.firstRange;if(o){r=o.start.row;var u=i.getFoldAt(r,i.getLine(r).length,1);u?i.removeFold(u):(i.addFold(\"...\",o),e.renderer.scrollCursorIntoView({row:o.start.row,column:0}))}t.stop()}})}t.FoldHandler=r}),ace.define(\"ace/keyboard/keybinding\",[\"require\",\"exports\",\"module\",\"ace/lib/keys\",\"ace/lib/event\"],function(e,t,n){\"use strict\";var r=e(\"../lib/keys\"),i=e(\"../lib/event\"),s=function(e){this.$editor=e,this.$data={editor:e},this.$handlers=[],this.setDefaultHandler(e.commands)};(function(){this.setDefaultHandler=function(e){this.removeKeyboardHandler(this.$defaultHandler),this.$defaultHandler=e,this.addKeyboardHandler(e,0)},this.setKeyboardHandler=function(e){var t=this.$handlers;if(t[t.length-1]==e)return;while(t[t.length-1]&&t[t.length-1]!=this.$defaultHandler)this.removeKeyboardHandler(t[t.length-1]);this.addKeyboardHandler(e,1)},this.addKeyboardHandler=function(e,t){if(!e)return;typeof e==\"function\"&&!e.handleKeyboard&&(e.handleKeyboard=e);var n=this.$handlers.indexOf(e);n!=-1&&this.$handlers.splice(n,1),t==undefined?this.$handlers.push(e):this.$handlers.splice(t,0,e),n==-1&&e.attach&&e.attach(this.$editor)},this.removeKeyboardHandler=function(e){var t=this.$handlers.indexOf(e);return t==-1?!1:(this.$handlers.splice(t,1),e.detach&&e.detach(this.$editor),!0)},this.getKeyboardHandler=function(){return this.$handlers[this.$handlers.length-1]},this.getStatusText=function(){var e=this.$data,t=e.editor;return this.$handlers.map(function(n){return n.getStatusText&&n.getStatusText(t,e)||\"\"}).filter(Boolean).join(\" \")},this.$callKeyboardHandlers=function(e,t,n,r){var s,o=!1,u=this.$editor.commands;for(var a=this.$handlers.length;a--;){s=this.$handlers[a].handleKeyboard(this.$data,e,t,n,r);if(!s||!s.command)continue;s.command==\"null\"?o=!0:o=u.exec(s.command,this.$editor,s.args,r),o&&r&&e!=-1&&s.passEvent!=1&&s.command.passEvent!=1&&i.stopEvent(r);if(o)break}return!o&&e==-1&&(s={command:\"insertstring\"},o=u.exec(\"insertstring\",this.$editor,t)),o&&this.$editor._signal(\"keyboardActivity\",s),o},this.onCommandKey=function(e,t,n){var i=r.keyCodeToString(n);this.$callKeyboardHandlers(t,i,n,e)},this.onTextInput=function(e){this.$callKeyboardHandlers(-1,e)}}).call(s.prototype),t.KeyBinding=s}),ace.define(\"ace/range\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";var r=function(e,t){return e.row-t.row||e.column-t.column},i=function(e,t,n,r){this.start={row:e,column:t},this.end={row:n,column:r}};(function(){this.isEqual=function(e){return this.start.row===e.start.row&&this.end.row===e.end.row&&this.start.column===e.start.column&&this.end.column===e.end.column},this.toString=function(){return\"Range: [\"+this.start.row+\"/\"+this.start.column+\"] -> [\"+this.end.row+\"/\"+this.end.column+\"]\"},this.contains=function(e,t){return this.compare(e,t)==0},this.compareRange=function(e){var t,n=e.end,r=e.start;return t=this.compare(n.row,n.column),t==1?(t=this.compare(r.row,r.column),t==1?2:t==0?1:0):t==-1?-2:(t=this.compare(r.row,r.column),t==-1?-1:t==1?42:0)},this.comparePoint=function(e){return this.compare(e.row,e.column)},this.containsRange=function(e){return this.comparePoint(e.start)==0&&this.comparePoint(e.end)==0},this.intersects=function(e){var t=this.compareRange(e);return t==-1||t==0||t==1},this.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},this.isStart=function(e,t){return this.start.row==e&&this.start.column==t},this.setStart=function(e,t){typeof e==\"object\"?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},this.setEnd=function(e,t){typeof e==\"object\"?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},this.inside=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)||this.isStart(e,t)?!1:!0:!1},this.insideStart=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)?!1:!0:!1},this.insideEnd=function(e,t){return this.compare(e,t)==0?this.isStart(e,t)?!1:!0:!1},this.compare=function(e,t){return!this.isMultiLine()&&e===this.start.row?t<this.start.column?-1:t>this.end.column?1:0:e<this.start.row?-1:e>this.end.row?1:this.start.row===e?t>=this.start.column?0:-1:this.end.row===e?t<=this.end.column?0:1:0},this.compareStart=function(e,t){return this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.compareEnd=function(e,t){return this.end.row==e&&this.end.column==t?1:this.compare(e,t)},this.compareInside=function(e,t){return this.end.row==e&&this.end.column==t?1:this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.clipRows=function(e,t){if(this.end.row>t)var n={row:t+1,column:0};else if(this.end.row<e)var n={row:e,column:0};if(this.start.row>t)var r={row:t+1,column:0};else if(this.start.row<e)var r={row:e,column:0};return i.fromPoints(r||this.start,n||this.end)},this.extend=function(e,t){var n=this.compare(e,t);if(n==0)return this;if(n==-1)var r={row:e,column:t};else var s={row:e,column:t};return i.fromPoints(r||this.start,s||this.end)},this.isEmpty=function(){return this.start.row===this.end.row&&this.start.column===this.end.column},this.isMultiLine=function(){return this.start.row!==this.end.row},this.clone=function(){return i.fromPoints(this.start,this.end)},this.collapseRows=function(){return this.end.column==0?new i(this.start.row,0,Math.max(this.start.row,this.end.row-1),0):new i(this.start.row,0,this.end.row,0)},this.toScreenRange=function(e){var t=e.documentToScreenPosition(this.start),n=e.documentToScreenPosition(this.end);return new i(t.row,t.column,n.row,n.column)},this.moveBy=function(e,t){this.start.row+=e,this.start.column+=t,this.end.row+=e,this.end.column+=t}}).call(i.prototype),i.fromPoints=function(e,t){return new i(e.row,e.column,t.row,t.column)},i.comparePoints=r,i.comparePoints=function(e,t){return e.row-t.row||e.column-t.column},t.Range=i}),ace.define(\"ace/selection\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/lang\",\"ace/lib/event_emitter\",\"ace/range\"],function(e,t,n){\"use strict\";var r=e(\"./lib/oop\"),i=e(\"./lib/lang\"),s=e(\"./lib/event_emitter\").EventEmitter,o=e(\"./range\").Range,u=function(e){this.session=e,this.doc=e.getDocument(),this.clearSelection(),this.lead=this.selectionLead=this.doc.createAnchor(0,0),this.anchor=this.selectionAnchor=this.doc.createAnchor(0,0);var t=this;this.lead.on(\"change\",function(e){t._emit(\"changeCursor\"),t.$isEmpty||t._emit(\"changeSelection\"),!t.$keepDesiredColumnOnChange&&e.old.column!=e.value.column&&(t.$desiredColumn=null)}),this.selectionAnchor.on(\"change\",function(){t.$isEmpty||t._emit(\"changeSelection\")})};(function(){r.implement(this,s),this.isEmpty=function(){return this.$isEmpty||this.anchor.row==this.lead.row&&this.anchor.column==this.lead.column},this.isMultiLine=function(){return this.isEmpty()?!1:this.getRange().isMultiLine()},this.getCursor=function(){return this.lead.getPosition()},this.setSelectionAnchor=function(e,t){this.anchor.setPosition(e,t),this.$isEmpty&&(this.$isEmpty=!1,this._emit(\"changeSelection\"))},this.getSelectionAnchor=function(){return this.$isEmpty?this.getSelectionLead():this.anchor.getPosition()},this.getSelectionLead=function(){return this.lead.getPosition()},this.shiftSelection=function(e){if(this.$isEmpty){this.moveCursorTo(this.lead.row,this.lead.column+e);return}var t=this.getSelectionAnchor(),n=this.getSelectionLead(),r=this.isBackwards();(!r||t.column!==0)&&this.setSelectionAnchor(t.row,t.column+e),(r||n.column!==0)&&this.$moveSelection(function(){this.moveCursorTo(n.row,n.column+e)})},this.isBackwards=function(){var e=this.anchor,t=this.lead;return e.row>t.row||e.row==t.row&&e.column>t.column},this.getRange=function(){var e=this.anchor,t=this.lead;return this.isEmpty()?o.fromPoints(t,t):this.isBackwards()?o.fromPoints(t,e):o.fromPoints(e,t)},this.clearSelection=function(){this.$isEmpty||(this.$isEmpty=!0,this._emit(\"changeSelection\"))},this.selectAll=function(){var e=this.doc.getLength()-1;this.setSelectionAnchor(0,0),this.moveCursorTo(e,this.doc.getLine(e).length)},this.setRange=this.setSelectionRange=function(e,t){t?(this.setSelectionAnchor(e.end.row,e.end.column),this.selectTo(e.start.row,e.start.column)):(this.setSelectionAnchor(e.start.row,e.start.column),this.selectTo(e.end.row,e.end.column)),this.getRange().isEmpty()&&(this.$isEmpty=!0),this.$desiredColumn=null},this.$moveSelection=function(e){var t=this.lead;this.$isEmpty&&this.setSelectionAnchor(t.row,t.column),e.call(this)},this.selectTo=function(e,t){this.$moveSelection(function(){this.moveCursorTo(e,t)})},this.selectToPosition=function(e){this.$moveSelection(function(){this.moveCursorToPosition(e)})},this.moveTo=function(e,t){this.clearSelection(),this.moveCursorTo(e,t)},this.moveToPosition=function(e){this.clearSelection(),this.moveCursorToPosition(e)},this.selectUp=function(){this.$moveSelection(this.moveCursorUp)},this.selectDown=function(){this.$moveSelection(this.moveCursorDown)},this.selectRight=function(){this.$moveSelection(this.moveCursorRight)},this.selectLeft=function(){this.$moveSelection(this.moveCursorLeft)},this.selectLineStart=function(){this.$moveSelection(this.moveCursorLineStart)},this.selectLineEnd=function(){this.$moveSelection(this.moveCursorLineEnd)},this.selectFileEnd=function(){this.$moveSelection(this.moveCursorFileEnd)},this.selectFileStart=function(){this.$moveSelection(this.moveCursorFileStart)},this.selectWordRight=function(){this.$moveSelection(this.moveCursorWordRight)},this.selectWordLeft=function(){this.$moveSelection(this.moveCursorWordLeft)},this.getWordRange=function(e,t){if(typeof t==\"undefined\"){var n=e||this.lead;e=n.row,t=n.column}return this.session.getWordRange(e,t)},this.selectWord=function(){this.setSelectionRange(this.getWordRange())},this.selectAWord=function(){var e=this.getCursor(),t=this.session.getAWordRange(e.row,e.column);this.setSelectionRange(t)},this.getLineRange=function(e,t){var n=typeof e==\"number\"?e:this.lead.row,r,i=this.session.getFoldLine(n);return i?(n=i.start.row,r=i.end.row):r=n,t===!0?new o(n,0,r,this.session.getLine(r).length):new o(n,0,r+1,0)},this.selectLine=function(){this.setSelectionRange(this.getLineRange())},this.moveCursorUp=function(){this.moveCursorBy(-1,0)},this.moveCursorDown=function(){this.moveCursorBy(1,0)},this.moveCursorLeft=function(){var e=this.lead.getPosition(),t;if(t=this.session.getFoldAt(e.row,e.column,-1))this.moveCursorTo(t.start.row,t.start.column);else if(e.column===0)e.row>0&&this.moveCursorTo(e.row-1,this.doc.getLine(e.row-1).length);else{var n=this.session.getTabSize();this.session.isTabStop(e)&&this.doc.getLine(e.row).slice(e.column-n,e.column).split(\" \").length-1==n?this.moveCursorBy(0,-n):this.moveCursorBy(0,-1)}},this.moveCursorRight=function(){var e=this.lead.getPosition(),t;if(t=this.session.getFoldAt(e.row,e.column,1))this.moveCursorTo(t.end.row,t.end.column);else if(this.lead.column==this.doc.getLine(this.lead.row).length)this.lead.row<this.doc.getLength()-1&&this.moveCursorTo(this.lead.row+1,0);else{var n=this.session.getTabSize(),e=this.lead;this.session.isTabStop(e)&&this.doc.getLine(e.row).slice(e.column,e.column+n).split(\" \").length-1==n?this.moveCursorBy(0,n):this.moveCursorBy(0,1)}},this.moveCursorLineStart=function(){var e=this.lead.row,t=this.lead.column,n=this.session.documentToScreenRow(e,t),r=this.session.screenToDocumentPosition(n,0),i=this.session.getDisplayLine(e,null,r.row,r.column),s=i.match(/^\\s*/);s[0].length!=t&&!this.session.$useEmacsStyleLineStart&&(r.column+=s[0].length),this.moveCursorToPosition(r)},this.moveCursorLineEnd=function(){var e=this.lead,t=this.session.getDocumentLastRowColumnPosition(e.row,e.column);if(this.lead.column==t.column){var n=this.session.getLine(t.row);if(t.column==n.length){var r=n.search(/\\s+$/);r>0&&(t.column=r)}}this.moveCursorTo(t.row,t.column)},this.moveCursorFileEnd=function(){var e=this.doc.getLength()-1,t=this.doc.getLine(e).length;this.moveCursorTo(e,t)},this.moveCursorFileStart=function(){this.moveCursorTo(0,0)},this.moveCursorLongWordRight=function(){var e=this.lead.row,t=this.lead.column,n=this.doc.getLine(e),r=n.substring(t),i;this.session.nonTokenRe.lastIndex=0,this.session.tokenRe.lastIndex=0;var s=this.session.getFoldAt(e,t,1);if(s){this.moveCursorTo(s.end.row,s.end.column);return}if(i=this.session.nonTokenRe.exec(r))t+=this.session.nonTokenRe.lastIndex,this.session.nonTokenRe.lastIndex=0,r=n.substring(t);if(t>=n.length){this.moveCursorTo(e,n.length),this.moveCursorRight(),e<this.doc.getLength()-1&&this.moveCursorWordRight();return}if(i=this.session.tokenRe.exec(r))t+=this.session.tokenRe.lastIndex,this.session.tokenRe.lastIndex=0;this.moveCursorTo(e,t)},this.moveCursorLongWordLeft=function(){var e=this.lead.row,t=this.lead.column,n;if(n=this.session.getFoldAt(e,t,-1)){this.moveCursorTo(n.start.row,n.start.column);return}var r=this.session.getFoldStringAt(e,t,-1);r==null&&(r=this.doc.getLine(e).substring(0,t));var s=i.stringReverse(r),o;this.session.nonTokenRe.lastIndex=0,this.session.tokenRe.lastIndex=0;if(o=this.session.nonTokenRe.exec(s))t-=this.session.nonTokenRe.lastIndex,s=s.slice(this.session.nonTokenRe.lastIndex),this.session.nonTokenRe.lastIndex=0;if(t<=0){this.moveCursorTo(e,0),this.moveCursorLeft(),e>0&&this.moveCursorWordLeft();return}if(o=this.session.tokenRe.exec(s))t-=this.session.tokenRe.lastIndex,this.session.tokenRe.lastIndex=0;this.moveCursorTo(e,t)},this.$shortWordEndIndex=function(e){var t,n=0,r,i=/\\s/,s=this.session.tokenRe;s.lastIndex=0;if(t=this.session.tokenRe.exec(e))n=this.session.tokenRe.lastIndex;else{while((r=e[n])&&i.test(r))n++;if(n<1){s.lastIndex=0;while((r=e[n])&&!s.test(r)){s.lastIndex=0,n++;if(i.test(r)){if(n>2){n--;break}while((r=e[n])&&i.test(r))n++;if(n>2)break}}}}return s.lastIndex=0,n},this.moveCursorShortWordRight=function(){var e=this.lead.row,t=this.lead.column,n=this.doc.getLine(e),r=n.substring(t),i=this.session.getFoldAt(e,t,1);if(i)return this.moveCursorTo(i.end.row,i.end.column);if(t==n.length){var s=this.doc.getLength();do e++,r=this.doc.getLine(e);while(e<s&&/^\\s*$/.test(r));/^\\s+/.test(r)||(r=\"\"),t=0}var o=this.$shortWordEndIndex(r);this.moveCursorTo(e,t+o)},this.moveCursorShortWordLeft=function(){var e=this.lead.row,t=this.lead.column,n;if(n=this.session.getFoldAt(e,t,-1))return this.moveCursorTo(n.start.row,n.start.column);var r=this.session.getLine(e).substring(0,t);if(t===0){do e--,r=this.doc.getLine(e);while(e>0&&/^\\s*$/.test(r));t=r.length,/\\s+$/.test(r)||(r=\"\")}var s=i.stringReverse(r),o=this.$shortWordEndIndex(s);return this.moveCursorTo(e,t-o)},this.moveCursorWordRight=function(){this.session.$selectLongWords?this.moveCursorLongWordRight():this.moveCursorShortWordRight()},this.moveCursorWordLeft=function(){this.session.$selectLongWords?this.moveCursorLongWordLeft():this.moveCursorShortWordLeft()},this.moveCursorBy=function(e,t){var n=this.session.documentToScreenPosition(this.lead.row,this.lead.column);t===0&&(this.$desiredColumn?n.column=this.$desiredColumn:this.$desiredColumn=n.column);var r=this.session.screenToDocumentPosition(n.row+e,n.column);e!==0&&t===0&&r.row===this.lead.row&&r.column===this.lead.column&&this.session.lineWidgets&&this.session.lineWidgets[r.row]&&(r.row>0||e>0)&&r.row++,this.moveCursorTo(r.row,r.column+t,t===0)},this.moveCursorToPosition=function(e){this.moveCursorTo(e.row,e.column)},this.moveCursorTo=function(e,t,n){var r=this.session.getFoldAt(e,t,1);r&&(e=r.start.row,t=r.start.column),this.$keepDesiredColumnOnChange=!0,this.lead.setPosition(e,t),this.$keepDesiredColumnOnChange=!1,n||(this.$desiredColumn=null)},this.moveCursorToScreen=function(e,t,n){var r=this.session.screenToDocumentPosition(e,t);this.moveCursorTo(r.row,r.column,n)},this.detach=function(){this.lead.detach(),this.anchor.detach(),this.session=this.doc=null},this.fromOrientedRange=function(e){this.setSelectionRange(e,e.cursor==e.start),this.$desiredColumn=e.desiredColumn||this.$desiredColumn},this.toOrientedRange=function(e){var t=this.getRange();return e?(e.start.column=t.start.column,e.start.row=t.start.row,e.end.column=t.end.column,e.end.row=t.end.row):e=t,e.cursor=this.isBackwards()?e.start:e.end,e.desiredColumn=this.$desiredColumn,e},this.getRangeOfMovements=function(e){var t=this.getCursor();try{e(this);var n=this.getCursor();return o.fromPoints(t,n)}catch(r){return o.fromPoints(t,t)}finally{this.moveCursorToPosition(t)}},this.toJSON=function(){if(this.rangeCount)var e=this.ranges.map(function(e){var t=e.clone();return t.isBackwards=e.cursor==e.start,t});else{var e=this.getRange();e.isBackwards=this.isBackwards()}return e},this.fromJSON=function(e){if(e.start==undefined){if(this.rangeList){this.toSingleRange(e[0]);for(var t=e.length;t--;){var n=o.fromPoints(e[t].start,e[t].end);e[t].isBackwards&&(n.cursor=n.start),this.addRange(n,!0)}return}e=e[0]}this.rangeList&&this.toSingleRange(e),this.setSelectionRange(e,e.isBackwards)},this.isEqual=function(e){if((e.length||this.rangeCount)&&e.length!=this.rangeCount)return!1;if(!e.length||!this.ranges)return this.getRange().isEqual(e);for(var t=this.ranges.length;t--;)if(!this.ranges[t].isEqual(e[t]))return!1;return!0}}).call(u.prototype),t.Selection=u}),ace.define(\"ace/tokenizer\",[\"require\",\"exports\",\"module\",\"ace/config\"],function(e,t,n){\"use strict\";var r=e(\"./config\"),i=2e3,s=function(e){this.states=e,this.regExps={},this.matchMappings={};for(var t in this.states){var n=this.states[t],r=[],i=0,s=this.matchMappings[t]={defaultToken:\"text\"},o=\"g\",u=[];for(var a=0;a<n.length;a++){var f=n[a];f.defaultToken&&(s.defaultToken=f.defaultToken),f.caseInsensitive&&(o=\"gi\");if(f.regex==null)continue;f.regex instanceof RegExp&&(f.regex=f.regex.toString().slice(1,-1));var l=f.regex,c=(new RegExp(\"(?:(\"+l+\")|(.))\")).exec(\"a\").length-2;Array.isArray(f.token)?f.token.length==1||c==1?f.token=f.token[0]:c-1!=f.token.length?(this.reportError(\"number of classes and regexp groups doesn't match\",{rule:f,groupCount:c-1}),f.token=f.token[0]):(f.tokenArray=f.token,f.token=null,f.onMatch=this.$arrayTokens):typeof f.token==\"function\"&&!f.onMatch&&(c>1?f.onMatch=this.$applyToken:f.onMatch=f.token),c>1&&(/\\\\\\d/.test(f.regex)?l=f.regex.replace(/\\\\([0-9]+)/g,function(e,t){return\"\\\\\"+(parseInt(t,10)+i+1)}):(c=1,l=this.removeCapturingGroups(f.regex)),!f.splitRegex&&typeof f.token!=\"string\"&&u.push(f)),s[i]=a,i+=c,r.push(l),f.onMatch||(f.onMatch=null)}r.length||(s[0]=0,r.push(\"$\")),u.forEach(function(e){e.splitRegex=this.createSplitterRegexp(e.regex,o)},this),this.regExps[t]=new RegExp(\"(\"+r.join(\")|(\")+\")|($)\",o)}};(function(){this.$setMaxTokenCount=function(e){i=e|0},this.$applyToken=function(e){var t=this.splitRegex.exec(e).slice(1),n=this.token.apply(this,t);if(typeof n==\"string\")return[{type:n,value:e}];var r=[];for(var i=0,s=n.length;i<s;i++)t[i]&&(r[r.length]={type:n[i],value:t[i]});return r},this.$arrayTokens=function(e){if(!e)return[];var t=this.splitRegex.exec(e);if(!t)return\"text\";var n=[],r=this.tokenArray;for(var i=0,s=r.length;i<s;i++)t[i+1]&&(n[n.length]={type:r[i],value:t[i+1]});return n},this.removeCapturingGroups=function(e){var t=e.replace(/\\[(?:\\\\.|[^\\]])*?\\]|\\\\.|\\(\\?[:=!]|(\\()/g,function(e,t){return t?\"(?:\":e});return t},this.createSplitterRegexp=function(e,t){if(e.indexOf(\"(?=\")!=-1){var n=0,r=!1,i={};e.replace(/(\\\\.)|(\\((?:\\?[=!])?)|(\\))|([\\[\\]])/g,function(e,t,s,o,u,a){return r?r=u!=\"]\":u?r=!0:o?(n==i.stack&&(i.end=a+1,i.stack=-1),n--):s&&(n++,s.length!=1&&(i.stack=n,i.start=a)),e}),i.end!=null&&/^\\)*$/.test(e.substr(i.end))&&(e=e.substring(0,i.start)+e.substr(i.end))}return e.charAt(0)!=\"^\"&&(e=\"^\"+e),e.charAt(e.length-1)!=\"$\"&&(e+=\"$\"),new RegExp(e,(t||\"\").replace(\"g\",\"\"))},this.getLineTokens=function(e,t){if(t&&typeof t!=\"string\"){var n=t.slice(0);t=n[0],t===\"#tmp\"&&(n.shift(),t=n.shift())}else var n=[];var r=t||\"start\",s=this.states[r];s||(r=\"start\",s=this.states[r]);var o=this.matchMappings[r],u=this.regExps[r];u.lastIndex=0;var a,f=[],l=0,c=0,h={type:null,value:\"\"};while(a=u.exec(e)){var p=o.defaultToken,d=null,v=a[0],m=u.lastIndex;if(m-v.length>l){var g=e.substring(l,m-v.length);h.type==p?h.value+=g:(h.type&&f.push(h),h={type:p,value:g})}for(var y=0;y<a.length-2;y++){if(a[y+1]===undefined)continue;d=s[o[y]],d.onMatch?p=d.onMatch(v,r,n):p=d.token,d.next&&(typeof d.next==\"string\"?r=d.next:r=d.next(r,n),s=this.states[r],s||(this.reportError(\"state doesn't exist\",r),r=\"start\",s=this.states[r]),o=this.matchMappings[r],l=m,u=this.regExps[r],u.lastIndex=m);break}if(v)if(typeof p==\"string\")!!d&&d.merge===!1||h.type!==p?(h.type&&f.push(h),h={type:p,value:v}):h.value+=v;else if(p){h.type&&f.push(h),h={type:null,value:\"\"};for(var y=0;y<p.length;y++)f.push(p[y])}if(l==e.length)break;l=m;if(c++>i){c>2*e.length&&this.reportError(\"infinite loop with in ace tokenizer\",{startState:t,line:e});while(l<e.length)h.type&&f.push(h),h={value:e.substring(l,l+=2e3),type:\"overflow\"};r=\"start\",n=[];break}}return h.type&&f.push(h),n.length>1&&n[0]!==r&&n.unshift(\"#tmp\",r),{tokens:f,state:n.length?n:r}},this.reportError=r.reportError}).call(s.prototype),t.Tokenizer=s}),ace.define(\"ace/mode/text_highlight_rules\",[\"require\",\"exports\",\"module\",\"ace/lib/lang\"],function(e,t,n){\"use strict\";var r=e(\"../lib/lang\"),i=function(){this.$rules={start:[{token:\"empty_line\",regex:\"^$\"},{defaultToken:\"text\"}]}};(function(){this.addRules=function(e,t){if(!t){for(var n in e)this.$rules[n]=e[n];return}for(var n in e){var r=e[n];for(var i=0;i<r.length;i++){var s=r[i];if(s.next||s.onMatch)typeof s.next==\"string\"&&s.next.indexOf(t)!==0&&(s.next=t+s.next),s.nextState&&s.nextState.indexOf(t)!==0&&(s.nextState=t+s.nextState)}this.$rules[t+n]=r}},this.getRules=function(){return this.$rules},this.embedRules=function(e,t,n,i,s){var o=typeof e==\"function\"?(new e).getRules():e;if(i)for(var u=0;u<i.length;u++)i[u]=t+i[u];else{i=[];for(var a in o)i.push(t+a)}this.addRules(o,t);if(n){var f=Array.prototype[s?\"push\":\"unshift\"];for(var u=0;u<i.length;u++)f.apply(this.$rules[i[u]],r.deepCopy(n))}this.$embeds||(this.$embeds=[]),this.$embeds.push(t)},this.getEmbeds=function(){return this.$embeds};var e=function(e,t){return(e!=\"start\"||t.length)&&t.unshift(this.nextState,e),this.nextState},t=function(e,t){return t.shift(),t.shift()||\"start\"};this.normalizeRules=function(){function i(s){var o=r[s];o.processed=!0;for(var u=0;u<o.length;u++){var a=o[u],f=null;Array.isArray(a)&&(f=a,a={}),!a.regex&&a.start&&(a.regex=a.start,a.next||(a.next=[]),a.next.push({defaultToken:a.token},{token:a.token+\".end\",regex:a.end||a.start,next:\"pop\"}),a.token=a.token+\".start\",a.push=!0);var l=a.next||a.push;if(l&&Array.isArray(l)){var c=a.stateName;c||(c=a.token,typeof c!=\"string\"&&(c=c[0]||\"\"),r[c]&&(c+=n++)),r[c]=l,a.next=c,i(c)}else l==\"pop\"&&(a.next=t);a.push&&(a.nextState=a.next||a.push,a.next=e,delete a.push);if(a.rules)for(var h in a.rules)r[h]?r[h].push&&r[h].push.apply(r[h],a.rules[h]):r[h]=a.rules[h];var p=typeof a==\"string\"?a:typeof a.include==\"string\"?a.include:\"\";p&&(f=r[p]);if(f){var d=[u,1].concat(f);a.noEscape&&(d=d.filter(function(e){return!e.next})),o.splice.apply(o,d),u--}a.keywordMap&&(a.token=this.createKeywordMapper(a.keywordMap,a.defaultToken||\"text\",a.caseInsensitive),delete a.defaultToken)}}var n=0,r=this.$rules;Object.keys(r).forEach(i,this)},this.createKeywordMapper=function(e,t,n,r){var i=Object.create(null);return Object.keys(e).forEach(function(t){var s=e[t];n&&(s=s.toLowerCase());var o=s.split(r||\"|\");for(var u=o.length;u--;)i[o[u]]=t}),Object.getPrototypeOf(i)&&(i.__proto__=null),this.$keywordList=Object.keys(i),e=null,n?function(e){return i[e.toLowerCase()]||t}:function(e){return i[e]||t}},this.getKeywords=function(){return this.$keywords}}).call(i.prototype),t.TextHighlightRules=i}),ace.define(\"ace/mode/behaviour\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";var r=function(){this.$behaviours={}};(function(){this.add=function(e,t,n){switch(undefined){case this.$behaviours:this.$behaviours={};case this.$behaviours[e]:this.$behaviours[e]={}}this.$behaviours[e][t]=n},this.addBehaviours=function(e){for(var t in e)for(var n in e[t])this.add(t,n,e[t][n])},this.remove=function(e){this.$behaviours&&this.$behaviours[e]&&delete this.$behaviours[e]},this.inherit=function(e,t){if(typeof e==\"function\")var n=(new e).getBehaviours(t);else var n=e.getBehaviours(t);this.addBehaviours(n)},this.getBehaviours=function(e){if(!e)return this.$behaviours;var t={};for(var n=0;n<e.length;n++)this.$behaviours[e[n]]&&(t[e[n]]=this.$behaviours[e[n]]);return t}}).call(r.prototype),t.Behaviour=r}),ace.define(\"ace/unicode\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";function r(e){var n=/\\w{4}/g;for(var r in e)t.packages[r]=e[r].replace(n,\"\\\\u$&\")}t.packages={},r({L:\"0041-005A0061-007A00AA00B500BA00C0-00D600D8-00F600F8-02C102C6-02D102E0-02E402EC02EE0370-037403760377037A-037D03860388-038A038C038E-03A103A3-03F503F7-0481048A-05250531-055605590561-058705D0-05EA05F0-05F20621-064A066E066F0671-06D306D506E506E606EE06EF06FA-06FC06FF07100712-072F074D-07A507B107CA-07EA07F407F507FA0800-0815081A082408280904-0939093D09500958-0961097109720979-097F0985-098C098F09900993-09A809AA-09B009B209B6-09B909BD09CE09DC09DD09DF-09E109F009F10A05-0A0A0A0F0A100A13-0A280A2A-0A300A320A330A350A360A380A390A59-0A5C0A5E0A72-0A740A85-0A8D0A8F-0A910A93-0AA80AAA-0AB00AB20AB30AB5-0AB90ABD0AD00AE00AE10B05-0B0C0B0F0B100B13-0B280B2A-0B300B320B330B35-0B390B3D0B5C0B5D0B5F-0B610B710B830B85-0B8A0B8E-0B900B92-0B950B990B9A0B9C0B9E0B9F0BA30BA40BA8-0BAA0BAE-0BB90BD00C05-0C0C0C0E-0C100C12-0C280C2A-0C330C35-0C390C3D0C580C590C600C610C85-0C8C0C8E-0C900C92-0CA80CAA-0CB30CB5-0CB90CBD0CDE0CE00CE10D05-0D0C0D0E-0D100D12-0D280D2A-0D390D3D0D600D610D7A-0D7F0D85-0D960D9A-0DB10DB3-0DBB0DBD0DC0-0DC60E01-0E300E320E330E40-0E460E810E820E840E870E880E8A0E8D0E94-0E970E99-0E9F0EA1-0EA30EA50EA70EAA0EAB0EAD-0EB00EB20EB30EBD0EC0-0EC40EC60EDC0EDD0F000F40-0F470F49-0F6C0F88-0F8B1000-102A103F1050-1055105A-105D106110651066106E-10701075-1081108E10A0-10C510D0-10FA10FC1100-1248124A-124D1250-12561258125A-125D1260-1288128A-128D1290-12B012B2-12B512B8-12BE12C012C2-12C512C8-12D612D8-13101312-13151318-135A1380-138F13A0-13F41401-166C166F-167F1681-169A16A0-16EA1700-170C170E-17111720-17311740-17511760-176C176E-17701780-17B317D717DC1820-18771880-18A818AA18B0-18F51900-191C1950-196D1970-19741980-19AB19C1-19C71A00-1A161A20-1A541AA71B05-1B331B45-1B4B1B83-1BA01BAE1BAF1C00-1C231C4D-1C4F1C5A-1C7D1CE9-1CEC1CEE-1CF11D00-1DBF1E00-1F151F18-1F1D1F20-1F451F48-1F4D1F50-1F571F591F5B1F5D1F5F-1F7D1F80-1FB41FB6-1FBC1FBE1FC2-1FC41FC6-1FCC1FD0-1FD31FD6-1FDB1FE0-1FEC1FF2-1FF41FF6-1FFC2071207F2090-209421022107210A-211321152119-211D212421262128212A-212D212F-2139213C-213F2145-2149214E218321842C00-2C2E2C30-2C5E2C60-2CE42CEB-2CEE2D00-2D252D30-2D652D6F2D80-2D962DA0-2DA62DA8-2DAE2DB0-2DB62DB8-2DBE2DC0-2DC62DC8-2DCE2DD0-2DD62DD8-2DDE2E2F300530063031-3035303B303C3041-3096309D-309F30A1-30FA30FC-30FF3105-312D3131-318E31A0-31B731F0-31FF3400-4DB54E00-9FCBA000-A48CA4D0-A4FDA500-A60CA610-A61FA62AA62BA640-A65FA662-A66EA67F-A697A6A0-A6E5A717-A71FA722-A788A78BA78CA7FB-A801A803-A805A807-A80AA80C-A822A840-A873A882-A8B3A8F2-A8F7A8FBA90A-A925A930-A946A960-A97CA984-A9B2A9CFAA00-AA28AA40-AA42AA44-AA4BAA60-AA76AA7AAA80-AAAFAAB1AAB5AAB6AAB9-AABDAAC0AAC2AADB-AADDABC0-ABE2AC00-D7A3D7B0-D7C6D7CB-D7FBF900-FA2DFA30-FA6DFA70-FAD9FB00-FB06FB13-FB17FB1DFB1F-FB28FB2A-FB36FB38-FB3CFB3EFB40FB41FB43FB44FB46-FBB1FBD3-FD3DFD50-FD8FFD92-FDC7FDF0-FDFBFE70-FE74FE76-FEFCFF21-FF3AFF41-FF5AFF66-FFBEFFC2-FFC7FFCA-FFCFFFD2-FFD7FFDA-FFDC\",Ll:\"0061-007A00AA00B500BA00DF-00F600F8-00FF01010103010501070109010B010D010F01110113011501170119011B011D011F01210123012501270129012B012D012F01310133013501370138013A013C013E014001420144014601480149014B014D014F01510153015501570159015B015D015F01610163016501670169016B016D016F0171017301750177017A017C017E-0180018301850188018C018D019201950199-019B019E01A101A301A501A801AA01AB01AD01B001B401B601B901BA01BD-01BF01C601C901CC01CE01D001D201D401D601D801DA01DC01DD01DF01E101E301E501E701E901EB01ED01EF01F001F301F501F901FB01FD01FF02010203020502070209020B020D020F02110213021502170219021B021D021F02210223022502270229022B022D022F02310233-0239023C023F0240024202470249024B024D024F-02930295-02AF037103730377037B-037D039003AC-03CE03D003D103D5-03D703D903DB03DD03DF03E103E303E503E703E903EB03ED03EF-03F303F503F803FB03FC0430-045F04610463046504670469046B046D046F04710473047504770479047B047D047F0481048B048D048F04910493049504970499049B049D049F04A104A304A504A704A904AB04AD04AF04B104B304B504B704B904BB04BD04BF04C204C404C604C804CA04CC04CE04CF04D104D304D504D704D904DB04DD04DF04E104E304E504E704E904EB04ED04EF04F104F304F504F704F904FB04FD04FF05010503050505070509050B050D050F05110513051505170519051B051D051F0521052305250561-05871D00-1D2B1D62-1D771D79-1D9A1E011E031E051E071E091E0B1E0D1E0F1E111E131E151E171E191E1B1E1D1E1F1E211E231E251E271E291E2B1E2D1E2F1E311E331E351E371E391E3B1E3D1E3F1E411E431E451E471E491E4B1E4D1E4F1E511E531E551E571E591E5B1E5D1E5F1E611E631E651E671E691E6B1E6D1E6F1E711E731E751E771E791E7B1E7D1E7F1E811E831E851E871E891E8B1E8D1E8F1E911E931E95-1E9D1E9F1EA11EA31EA51EA71EA91EAB1EAD1EAF1EB11EB31EB51EB71EB91EBB1EBD1EBF1EC11EC31EC51EC71EC91ECB1ECD1ECF1ED11ED31ED51ED71ED91EDB1EDD1EDF1EE11EE31EE51EE71EE91EEB1EED1EEF1EF11EF31EF51EF71EF91EFB1EFD1EFF-1F071F10-1F151F20-1F271F30-1F371F40-1F451F50-1F571F60-1F671F70-1F7D1F80-1F871F90-1F971FA0-1FA71FB0-1FB41FB61FB71FBE1FC2-1FC41FC61FC71FD0-1FD31FD61FD71FE0-1FE71FF2-1FF41FF61FF7210A210E210F2113212F21342139213C213D2146-2149214E21842C30-2C5E2C612C652C662C682C6A2C6C2C712C732C742C76-2C7C2C812C832C852C872C892C8B2C8D2C8F2C912C932C952C972C992C9B2C9D2C9F2CA12CA32CA52CA72CA92CAB2CAD2CAF2CB12CB32CB52CB72CB92CBB2CBD2CBF2CC12CC32CC52CC72CC92CCB2CCD2CCF2CD12CD32CD52CD72CD92CDB2CDD2CDF2CE12CE32CE42CEC2CEE2D00-2D25A641A643A645A647A649A64BA64DA64FA651A653A655A657A659A65BA65DA65FA663A665A667A669A66BA66DA681A683A685A687A689A68BA68DA68FA691A693A695A697A723A725A727A729A72BA72DA72F-A731A733A735A737A739A73BA73DA73FA741A743A745A747A749A74BA74DA74FA751A753A755A757A759A75BA75DA75FA761A763A765A767A769A76BA76DA76FA771-A778A77AA77CA77FA781A783A785A787A78CFB00-FB06FB13-FB17FF41-FF5A\",Lu:\"0041-005A00C0-00D600D8-00DE01000102010401060108010A010C010E01100112011401160118011A011C011E01200122012401260128012A012C012E01300132013401360139013B013D013F0141014301450147014A014C014E01500152015401560158015A015C015E01600162016401660168016A016C016E017001720174017601780179017B017D018101820184018601870189-018B018E-0191019301940196-0198019C019D019F01A001A201A401A601A701A901AC01AE01AF01B1-01B301B501B701B801BC01C401C701CA01CD01CF01D101D301D501D701D901DB01DE01E001E201E401E601E801EA01EC01EE01F101F401F6-01F801FA01FC01FE02000202020402060208020A020C020E02100212021402160218021A021C021E02200222022402260228022A022C022E02300232023A023B023D023E02410243-02460248024A024C024E03700372037603860388-038A038C038E038F0391-03A103A3-03AB03CF03D2-03D403D803DA03DC03DE03E003E203E403E603E803EA03EC03EE03F403F703F903FA03FD-042F04600462046404660468046A046C046E04700472047404760478047A047C047E0480048A048C048E04900492049404960498049A049C049E04A004A204A404A604A804AA04AC04AE04B004B204B404B604B804BA04BC04BE04C004C104C304C504C704C904CB04CD04D004D204D404D604D804DA04DC04DE04E004E204E404E604E804EA04EC04EE04F004F204F404F604F804FA04FC04FE05000502050405060508050A050C050E05100512051405160518051A051C051E0520052205240531-055610A0-10C51E001E021E041E061E081E0A1E0C1E0E1E101E121E141E161E181E1A1E1C1E1E1E201E221E241E261E281E2A1E2C1E2E1E301E321E341E361E381E3A1E3C1E3E1E401E421E441E461E481E4A1E4C1E4E1E501E521E541E561E581E5A1E5C1E5E1E601E621E641E661E681E6A1E6C1E6E1E701E721E741E761E781E7A1E7C1E7E1E801E821E841E861E881E8A1E8C1E8E1E901E921E941E9E1EA01EA21EA41EA61EA81EAA1EAC1EAE1EB01EB21EB41EB61EB81EBA1EBC1EBE1EC01EC21EC41EC61EC81ECA1ECC1ECE1ED01ED21ED41ED61ED81EDA1EDC1EDE1EE01EE21EE41EE61EE81EEA1EEC1EEE1EF01EF21EF41EF61EF81EFA1EFC1EFE1F08-1F0F1F18-1F1D1F28-1F2F1F38-1F3F1F48-1F4D1F591F5B1F5D1F5F1F68-1F6F1FB8-1FBB1FC8-1FCB1FD8-1FDB1FE8-1FEC1FF8-1FFB21022107210B-210D2110-211221152119-211D212421262128212A-212D2130-2133213E213F214521832C00-2C2E2C602C62-2C642C672C692C6B2C6D-2C702C722C752C7E-2C802C822C842C862C882C8A2C8C2C8E2C902C922C942C962C982C9A2C9C2C9E2CA02CA22CA42CA62CA82CAA2CAC2CAE2CB02CB22CB42CB62CB82CBA2CBC2CBE2CC02CC22CC42CC62CC82CCA2CCC2CCE2CD02CD22CD42CD62CD82CDA2CDC2CDE2CE02CE22CEB2CEDA640A642A644A646A648A64AA64CA64EA650A652A654A656A658A65AA65CA65EA662A664A666A668A66AA66CA680A682A684A686A688A68AA68CA68EA690A692A694A696A722A724A726A728A72AA72CA72EA732A734A736A738A73AA73CA73EA740A742A744A746A748A74AA74CA74EA750A752A754A756A758A75AA75CA75EA760A762A764A766A768A76AA76CA76EA779A77BA77DA77EA780A782A784A786A78BFF21-FF3A\",Lt:\"01C501C801CB01F21F88-1F8F1F98-1F9F1FA8-1FAF1FBC1FCC1FFC\",Lm:\"02B0-02C102C6-02D102E0-02E402EC02EE0374037A0559064006E506E607F407F507FA081A0824082809710E460EC610FC17D718431AA71C78-1C7D1D2C-1D611D781D9B-1DBF2071207F2090-20942C7D2D6F2E2F30053031-3035303B309D309E30FC-30FEA015A4F8-A4FDA60CA67FA717-A71FA770A788A9CFAA70AADDFF70FF9EFF9F\",Lo:\"01BB01C0-01C3029405D0-05EA05F0-05F20621-063F0641-064A066E066F0671-06D306D506EE06EF06FA-06FC06FF07100712-072F074D-07A507B107CA-07EA0800-08150904-0939093D09500958-096109720979-097F0985-098C098F09900993-09A809AA-09B009B209B6-09B909BD09CE09DC09DD09DF-09E109F009F10A05-0A0A0A0F0A100A13-0A280A2A-0A300A320A330A350A360A380A390A59-0A5C0A5E0A72-0A740A85-0A8D0A8F-0A910A93-0AA80AAA-0AB00AB20AB30AB5-0AB90ABD0AD00AE00AE10B05-0B0C0B0F0B100B13-0B280B2A-0B300B320B330B35-0B390B3D0B5C0B5D0B5F-0B610B710B830B85-0B8A0B8E-0B900B92-0B950B990B9A0B9C0B9E0B9F0BA30BA40BA8-0BAA0BAE-0BB90BD00C05-0C0C0C0E-0C100C12-0C280C2A-0C330C35-0C390C3D0C580C590C600C610C85-0C8C0C8E-0C900C92-0CA80CAA-0CB30CB5-0CB90CBD0CDE0CE00CE10D05-0D0C0D0E-0D100D12-0D280D2A-0D390D3D0D600D610D7A-0D7F0D85-0D960D9A-0DB10DB3-0DBB0DBD0DC0-0DC60E01-0E300E320E330E40-0E450E810E820E840E870E880E8A0E8D0E94-0E970E99-0E9F0EA1-0EA30EA50EA70EAA0EAB0EAD-0EB00EB20EB30EBD0EC0-0EC40EDC0EDD0F000F40-0F470F49-0F6C0F88-0F8B1000-102A103F1050-1055105A-105D106110651066106E-10701075-1081108E10D0-10FA1100-1248124A-124D1250-12561258125A-125D1260-1288128A-128D1290-12B012B2-12B512B8-12BE12C012C2-12C512C8-12D612D8-13101312-13151318-135A1380-138F13A0-13F41401-166C166F-167F1681-169A16A0-16EA1700-170C170E-17111720-17311740-17511760-176C176E-17701780-17B317DC1820-18421844-18771880-18A818AA18B0-18F51900-191C1950-196D1970-19741980-19AB19C1-19C71A00-1A161A20-1A541B05-1B331B45-1B4B1B83-1BA01BAE1BAF1C00-1C231C4D-1C4F1C5A-1C771CE9-1CEC1CEE-1CF12135-21382D30-2D652D80-2D962DA0-2DA62DA8-2DAE2DB0-2DB62DB8-2DBE2DC0-2DC62DC8-2DCE2DD0-2DD62DD8-2DDE3006303C3041-3096309F30A1-30FA30FF3105-312D3131-318E31A0-31B731F0-31FF3400-4DB54E00-9FCBA000-A014A016-A48CA4D0-A4F7A500-A60BA610-A61FA62AA62BA66EA6A0-A6E5A7FB-A801A803-A805A807-A80AA80C-A822A840-A873A882-A8B3A8F2-A8F7A8FBA90A-A925A930-A946A960-A97CA984-A9B2AA00-AA28AA40-AA42AA44-AA4BAA60-AA6FAA71-AA76AA7AAA80-AAAFAAB1AAB5AAB6AAB9-AABDAAC0AAC2AADBAADCABC0-ABE2AC00-D7A3D7B0-D7C6D7CB-D7FBF900-FA2DFA30-FA6DFA70-FAD9FB1DFB1F-FB28FB2A-FB36FB38-FB3CFB3EFB40FB41FB43FB44FB46-FBB1FBD3-FD3DFD50-FD8FFD92-FDC7FDF0-FDFBFE70-FE74FE76-FEFCFF66-FF6FFF71-FF9DFFA0-FFBEFFC2-FFC7FFCA-FFCFFFD2-FFD7FFDA-FFDC\",M:\"0300-036F0483-04890591-05BD05BF05C105C205C405C505C70610-061A064B-065E067006D6-06DC06DE-06E406E706E806EA-06ED07110730-074A07A6-07B007EB-07F30816-0819081B-08230825-08270829-082D0900-0903093C093E-094E0951-0955096209630981-098309BC09BE-09C409C709C809CB-09CD09D709E209E30A01-0A030A3C0A3E-0A420A470A480A4B-0A4D0A510A700A710A750A81-0A830ABC0ABE-0AC50AC7-0AC90ACB-0ACD0AE20AE30B01-0B030B3C0B3E-0B440B470B480B4B-0B4D0B560B570B620B630B820BBE-0BC20BC6-0BC80BCA-0BCD0BD70C01-0C030C3E-0C440C46-0C480C4A-0C4D0C550C560C620C630C820C830CBC0CBE-0CC40CC6-0CC80CCA-0CCD0CD50CD60CE20CE30D020D030D3E-0D440D46-0D480D4A-0D4D0D570D620D630D820D830DCA0DCF-0DD40DD60DD8-0DDF0DF20DF30E310E34-0E3A0E47-0E4E0EB10EB4-0EB90EBB0EBC0EC8-0ECD0F180F190F350F370F390F3E0F3F0F71-0F840F860F870F90-0F970F99-0FBC0FC6102B-103E1056-1059105E-10601062-10641067-106D1071-10741082-108D108F109A-109D135F1712-17141732-1734175217531772177317B6-17D317DD180B-180D18A91920-192B1930-193B19B0-19C019C819C91A17-1A1B1A55-1A5E1A60-1A7C1A7F1B00-1B041B34-1B441B6B-1B731B80-1B821BA1-1BAA1C24-1C371CD0-1CD21CD4-1CE81CED1CF21DC0-1DE61DFD-1DFF20D0-20F02CEF-2CF12DE0-2DFF302A-302F3099309AA66F-A672A67CA67DA6F0A6F1A802A806A80BA823-A827A880A881A8B4-A8C4A8E0-A8F1A926-A92DA947-A953A980-A983A9B3-A9C0AA29-AA36AA43AA4CAA4DAA7BAAB0AAB2-AAB4AAB7AAB8AABEAABFAAC1ABE3-ABEAABECABEDFB1EFE00-FE0FFE20-FE26\",Mn:\"0300-036F0483-04870591-05BD05BF05C105C205C405C505C70610-061A064B-065E067006D6-06DC06DF-06E406E706E806EA-06ED07110730-074A07A6-07B007EB-07F30816-0819081B-08230825-08270829-082D0900-0902093C0941-0948094D0951-095509620963098109BC09C1-09C409CD09E209E30A010A020A3C0A410A420A470A480A4B-0A4D0A510A700A710A750A810A820ABC0AC1-0AC50AC70AC80ACD0AE20AE30B010B3C0B3F0B41-0B440B4D0B560B620B630B820BC00BCD0C3E-0C400C46-0C480C4A-0C4D0C550C560C620C630CBC0CBF0CC60CCC0CCD0CE20CE30D41-0D440D4D0D620D630DCA0DD2-0DD40DD60E310E34-0E3A0E47-0E4E0EB10EB4-0EB90EBB0EBC0EC8-0ECD0F180F190F350F370F390F71-0F7E0F80-0F840F860F870F90-0F970F99-0FBC0FC6102D-10301032-10371039103A103D103E10581059105E-10601071-1074108210851086108D109D135F1712-17141732-1734175217531772177317B7-17BD17C617C9-17D317DD180B-180D18A91920-19221927192819321939-193B1A171A181A561A58-1A5E1A601A621A65-1A6C1A73-1A7C1A7F1B00-1B031B341B36-1B3A1B3C1B421B6B-1B731B801B811BA2-1BA51BA81BA91C2C-1C331C361C371CD0-1CD21CD4-1CE01CE2-1CE81CED1DC0-1DE61DFD-1DFF20D0-20DC20E120E5-20F02CEF-2CF12DE0-2DFF302A-302F3099309AA66FA67CA67DA6F0A6F1A802A806A80BA825A826A8C4A8E0-A8F1A926-A92DA947-A951A980-A982A9B3A9B6-A9B9A9BCAA29-AA2EAA31AA32AA35AA36AA43AA4CAAB0AAB2-AAB4AAB7AAB8AABEAABFAAC1ABE5ABE8ABEDFB1EFE00-FE0FFE20-FE26\",Mc:\"0903093E-09400949-094C094E0982098309BE-09C009C709C809CB09CC09D70A030A3E-0A400A830ABE-0AC00AC90ACB0ACC0B020B030B3E0B400B470B480B4B0B4C0B570BBE0BBF0BC10BC20BC6-0BC80BCA-0BCC0BD70C01-0C030C41-0C440C820C830CBE0CC0-0CC40CC70CC80CCA0CCB0CD50CD60D020D030D3E-0D400D46-0D480D4A-0D4C0D570D820D830DCF-0DD10DD8-0DDF0DF20DF30F3E0F3F0F7F102B102C10311038103B103C105610571062-10641067-106D108310841087-108C108F109A-109C17B617BE-17C517C717C81923-19261929-192B193019311933-193819B0-19C019C819C91A19-1A1B1A551A571A611A631A641A6D-1A721B041B351B3B1B3D-1B411B431B441B821BA11BA61BA71BAA1C24-1C2B1C341C351CE11CF2A823A824A827A880A881A8B4-A8C3A952A953A983A9B4A9B5A9BAA9BBA9BD-A9C0AA2FAA30AA33AA34AA4DAA7BABE3ABE4ABE6ABE7ABE9ABEAABEC\",Me:\"0488048906DE20DD-20E020E2-20E4A670-A672\",N:\"0030-003900B200B300B900BC-00BE0660-066906F0-06F907C0-07C90966-096F09E6-09EF09F4-09F90A66-0A6F0AE6-0AEF0B66-0B6F0BE6-0BF20C66-0C6F0C78-0C7E0CE6-0CEF0D66-0D750E50-0E590ED0-0ED90F20-0F331040-10491090-10991369-137C16EE-16F017E0-17E917F0-17F91810-18191946-194F19D0-19DA1A80-1A891A90-1A991B50-1B591BB0-1BB91C40-1C491C50-1C5920702074-20792080-20892150-21822185-21892460-249B24EA-24FF2776-27932CFD30073021-30293038-303A3192-31953220-32293251-325F3280-328932B1-32BFA620-A629A6E6-A6EFA830-A835A8D0-A8D9A900-A909A9D0-A9D9AA50-AA59ABF0-ABF9FF10-FF19\",Nd:\"0030-00390660-066906F0-06F907C0-07C90966-096F09E6-09EF0A66-0A6F0AE6-0AEF0B66-0B6F0BE6-0BEF0C66-0C6F0CE6-0CEF0D66-0D6F0E50-0E590ED0-0ED90F20-0F291040-10491090-109917E0-17E91810-18191946-194F19D0-19DA1A80-1A891A90-1A991B50-1B591BB0-1BB91C40-1C491C50-1C59A620-A629A8D0-A8D9A900-A909A9D0-A9D9AA50-AA59ABF0-ABF9FF10-FF19\",Nl:\"16EE-16F02160-21822185-218830073021-30293038-303AA6E6-A6EF\",No:\"00B200B300B900BC-00BE09F4-09F90BF0-0BF20C78-0C7E0D70-0D750F2A-0F331369-137C17F0-17F920702074-20792080-20892150-215F21892460-249B24EA-24FF2776-27932CFD3192-31953220-32293251-325F3280-328932B1-32BFA830-A835\",P:\"0021-00230025-002A002C-002F003A003B003F0040005B-005D005F007B007D00A100AB00B700BB00BF037E0387055A-055F0589058A05BE05C005C305C605F305F40609060A060C060D061B061E061F066A-066D06D40700-070D07F7-07F90830-083E0964096509700DF40E4F0E5A0E5B0F04-0F120F3A-0F3D0F850FD0-0FD4104A-104F10FB1361-13681400166D166E169B169C16EB-16ED1735173617D4-17D617D8-17DA1800-180A1944194519DE19DF1A1E1A1F1AA0-1AA61AA8-1AAD1B5A-1B601C3B-1C3F1C7E1C7F1CD32010-20272030-20432045-20512053-205E207D207E208D208E2329232A2768-277527C527C627E6-27EF2983-299829D8-29DB29FC29FD2CF9-2CFC2CFE2CFF2E00-2E2E2E302E313001-30033008-30113014-301F3030303D30A030FBA4FEA4FFA60D-A60FA673A67EA6F2-A6F7A874-A877A8CEA8CFA8F8-A8FAA92EA92FA95FA9C1-A9CDA9DEA9DFAA5C-AA5FAADEAADFABEBFD3EFD3FFE10-FE19FE30-FE52FE54-FE61FE63FE68FE6AFE6BFF01-FF03FF05-FF0AFF0C-FF0FFF1AFF1BFF1FFF20FF3B-FF3DFF3FFF5BFF5DFF5F-FF65\",Pd:\"002D058A05BE140018062010-20152E172E1A301C303030A0FE31FE32FE58FE63FF0D\",Ps:\"0028005B007B0F3A0F3C169B201A201E2045207D208D23292768276A276C276E27702772277427C527E627E827EA27EC27EE2983298529872989298B298D298F299129932995299729D829DA29FC2E222E242E262E283008300A300C300E3010301430163018301A301DFD3EFE17FE35FE37FE39FE3BFE3DFE3FFE41FE43FE47FE59FE5BFE5DFF08FF3BFF5BFF5FFF62\",Pe:\"0029005D007D0F3B0F3D169C2046207E208E232A2769276B276D276F27712773277527C627E727E927EB27ED27EF298429862988298A298C298E2990299229942996299829D929DB29FD2E232E252E272E293009300B300D300F3011301530173019301B301E301FFD3FFE18FE36FE38FE3AFE3CFE3EFE40FE42FE44FE48FE5AFE5CFE5EFF09FF3DFF5DFF60FF63\",Pi:\"00AB2018201B201C201F20392E022E042E092E0C2E1C2E20\",Pf:\"00BB2019201D203A2E032E052E0A2E0D2E1D2E21\",Pc:\"005F203F20402054FE33FE34FE4D-FE4FFF3F\",Po:\"0021-00230025-0027002A002C002E002F003A003B003F0040005C00A100B700BF037E0387055A-055F058905C005C305C605F305F40609060A060C060D061B061E061F066A-066D06D40700-070D07F7-07F90830-083E0964096509700DF40E4F0E5A0E5B0F04-0F120F850FD0-0FD4104A-104F10FB1361-1368166D166E16EB-16ED1735173617D4-17D617D8-17DA1800-18051807-180A1944194519DE19DF1A1E1A1F1AA0-1AA61AA8-1AAD1B5A-1B601C3B-1C3F1C7E1C7F1CD3201620172020-20272030-2038203B-203E2041-20432047-205120532055-205E2CF9-2CFC2CFE2CFF2E002E012E06-2E082E0B2E0E-2E162E182E192E1B2E1E2E1F2E2A-2E2E2E302E313001-3003303D30FBA4FEA4FFA60D-A60FA673A67EA6F2-A6F7A874-A877A8CEA8CFA8F8-A8FAA92EA92FA95FA9C1-A9CDA9DEA9DFAA5C-AA5FAADEAADFABEBFE10-FE16FE19FE30FE45FE46FE49-FE4CFE50-FE52FE54-FE57FE5F-FE61FE68FE6AFE6BFF01-FF03FF05-FF07FF0AFF0CFF0EFF0FFF1AFF1BFF1FFF20FF3CFF61FF64FF65\",S:\"0024002B003C-003E005E0060007C007E00A2-00A900AC00AE-00B100B400B600B800D700F702C2-02C502D2-02DF02E5-02EB02ED02EF-02FF03750384038503F604820606-0608060B060E060F06E906FD06FE07F609F209F309FA09FB0AF10B700BF3-0BFA0C7F0CF10CF20D790E3F0F01-0F030F13-0F170F1A-0F1F0F340F360F380FBE-0FC50FC7-0FCC0FCE0FCF0FD5-0FD8109E109F13601390-139917DB194019E0-19FF1B61-1B6A1B74-1B7C1FBD1FBF-1FC11FCD-1FCF1FDD-1FDF1FED-1FEF1FFD1FFE20442052207A-207C208A-208C20A0-20B8210021012103-21062108210921142116-2118211E-2123212521272129212E213A213B2140-2144214A-214D214F2190-2328232B-23E82400-24262440-244A249C-24E92500-26CD26CF-26E126E326E8-26FF2701-27042706-2709270C-27272729-274B274D274F-27522756-275E2761-276727942798-27AF27B1-27BE27C0-27C427C7-27CA27CC27D0-27E527F0-29822999-29D729DC-29FB29FE-2B4C2B50-2B592CE5-2CEA2E80-2E992E9B-2EF32F00-2FD52FF0-2FFB300430123013302030363037303E303F309B309C319031913196-319F31C0-31E33200-321E322A-32503260-327F328A-32B032C0-32FE3300-33FF4DC0-4DFFA490-A4C6A700-A716A720A721A789A78AA828-A82BA836-A839AA77-AA79FB29FDFCFDFDFE62FE64-FE66FE69FF04FF0BFF1C-FF1EFF3EFF40FF5CFF5EFFE0-FFE6FFE8-FFEEFFFCFFFD\",Sm:\"002B003C-003E007C007E00AC00B100D700F703F60606-060820442052207A-207C208A-208C2140-2144214B2190-2194219A219B21A021A321A621AE21CE21CF21D221D421F4-22FF2308-230B23202321237C239B-23B323DC-23E125B725C125F8-25FF266F27C0-27C427C7-27CA27CC27D0-27E527F0-27FF2900-29822999-29D729DC-29FB29FE-2AFF2B30-2B442B47-2B4CFB29FE62FE64-FE66FF0BFF1C-FF1EFF5CFF5EFFE2FFE9-FFEC\",Sc:\"002400A2-00A5060B09F209F309FB0AF10BF90E3F17DB20A0-20B8A838FDFCFE69FF04FFE0FFE1FFE5FFE6\",Sk:\"005E006000A800AF00B400B802C2-02C502D2-02DF02E5-02EB02ED02EF-02FF0375038403851FBD1FBF-1FC11FCD-1FCF1FDD-1FDF1FED-1FEF1FFD1FFE309B309CA700-A716A720A721A789A78AFF3EFF40FFE3\",So:\"00A600A700A900AE00B000B60482060E060F06E906FD06FE07F609FA0B700BF3-0BF80BFA0C7F0CF10CF20D790F01-0F030F13-0F170F1A-0F1F0F340F360F380FBE-0FC50FC7-0FCC0FCE0FCF0FD5-0FD8109E109F13601390-1399194019E0-19FF1B61-1B6A1B74-1B7C210021012103-21062108210921142116-2118211E-2123212521272129212E213A213B214A214C214D214F2195-2199219C-219F21A121A221A421A521A7-21AD21AF-21CD21D021D121D321D5-21F32300-2307230C-231F2322-2328232B-237B237D-239A23B4-23DB23E2-23E82400-24262440-244A249C-24E92500-25B625B8-25C025C2-25F72600-266E2670-26CD26CF-26E126E326E8-26FF2701-27042706-2709270C-27272729-274B274D274F-27522756-275E2761-276727942798-27AF27B1-27BE2800-28FF2B00-2B2F2B452B462B50-2B592CE5-2CEA2E80-2E992E9B-2EF32F00-2FD52FF0-2FFB300430123013302030363037303E303F319031913196-319F31C0-31E33200-321E322A-32503260-327F328A-32B032C0-32FE3300-33FF4DC0-4DFFA490-A4C6A828-A82BA836A837A839AA77-AA79FDFDFFE4FFE8FFEDFFEEFFFCFFFD\",Z:\"002000A01680180E2000-200A20282029202F205F3000\",Zs:\"002000A01680180E2000-200A202F205F3000\",Zl:\"2028\",Zp:\"2029\",C:\"0000-001F007F-009F00AD03780379037F-0383038B038D03A20526-05300557055805600588058B-059005C8-05CF05EB-05EF05F5-0605061C061D0620065F06DD070E070F074B074C07B2-07BF07FB-07FF082E082F083F-08FF093A093B094F095609570973-097809800984098D098E0991099209A909B109B3-09B509BA09BB09C509C609C909CA09CF-09D609D8-09DB09DE09E409E509FC-0A000A040A0B-0A0E0A110A120A290A310A340A370A3A0A3B0A3D0A43-0A460A490A4A0A4E-0A500A52-0A580A5D0A5F-0A650A76-0A800A840A8E0A920AA90AB10AB40ABA0ABB0AC60ACA0ACE0ACF0AD1-0ADF0AE40AE50AF00AF2-0B000B040B0D0B0E0B110B120B290B310B340B3A0B3B0B450B460B490B4A0B4E-0B550B58-0B5B0B5E0B640B650B72-0B810B840B8B-0B8D0B910B96-0B980B9B0B9D0BA0-0BA20BA5-0BA70BAB-0BAD0BBA-0BBD0BC3-0BC50BC90BCE0BCF0BD1-0BD60BD8-0BE50BFB-0C000C040C0D0C110C290C340C3A-0C3C0C450C490C4E-0C540C570C5A-0C5F0C640C650C70-0C770C800C810C840C8D0C910CA90CB40CBA0CBB0CC50CC90CCE-0CD40CD7-0CDD0CDF0CE40CE50CF00CF3-0D010D040D0D0D110D290D3A-0D3C0D450D490D4E-0D560D58-0D5F0D640D650D76-0D780D800D810D840D97-0D990DB20DBC0DBE0DBF0DC7-0DC90DCB-0DCE0DD50DD70DE0-0DF10DF5-0E000E3B-0E3E0E5C-0E800E830E850E860E890E8B0E8C0E8E-0E930E980EA00EA40EA60EA80EA90EAC0EBA0EBE0EBF0EC50EC70ECE0ECF0EDA0EDB0EDE-0EFF0F480F6D-0F700F8C-0F8F0F980FBD0FCD0FD9-0FFF10C6-10CF10FD-10FF1249124E124F12571259125E125F1289128E128F12B112B612B712BF12C112C612C712D7131113161317135B-135E137D-137F139A-139F13F5-13FF169D-169F16F1-16FF170D1715-171F1737-173F1754-175F176D17711774-177F17B417B517DE17DF17EA-17EF17FA-17FF180F181A-181F1878-187F18AB-18AF18F6-18FF191D-191F192C-192F193C-193F1941-1943196E196F1975-197F19AC-19AF19CA-19CF19DB-19DD1A1C1A1D1A5F1A7D1A7E1A8A-1A8F1A9A-1A9F1AAE-1AFF1B4C-1B4F1B7D-1B7F1BAB-1BAD1BBA-1BFF1C38-1C3A1C4A-1C4C1C80-1CCF1CF3-1CFF1DE7-1DFC1F161F171F1E1F1F1F461F471F4E1F4F1F581F5A1F5C1F5E1F7E1F7F1FB51FC51FD41FD51FDC1FF01FF11FF51FFF200B-200F202A-202E2060-206F20722073208F2095-209F20B9-20CF20F1-20FF218A-218F23E9-23FF2427-243F244B-245F26CE26E226E4-26E727002705270A270B2728274C274E2753-2755275F27602795-279727B027BF27CB27CD-27CF2B4D-2B4F2B5A-2BFF2C2F2C5F2CF2-2CF82D26-2D2F2D66-2D6E2D70-2D7F2D97-2D9F2DA72DAF2DB72DBF2DC72DCF2DD72DDF2E32-2E7F2E9A2EF4-2EFF2FD6-2FEF2FFC-2FFF3040309730983100-3104312E-3130318F31B8-31BF31E4-31EF321F32FF4DB6-4DBF9FCC-9FFFA48D-A48FA4C7-A4CFA62C-A63FA660A661A674-A67BA698-A69FA6F8-A6FFA78D-A7FAA82C-A82FA83A-A83FA878-A87FA8C5-A8CDA8DA-A8DFA8FC-A8FFA954-A95EA97D-A97FA9CEA9DA-A9DDA9E0-A9FFAA37-AA3FAA4EAA4FAA5AAA5BAA7C-AA7FAAC3-AADAAAE0-ABBFABEEABEFABFA-ABFFD7A4-D7AFD7C7-D7CAD7FC-F8FFFA2EFA2FFA6EFA6FFADA-FAFFFB07-FB12FB18-FB1CFB37FB3DFB3FFB42FB45FBB2-FBD2FD40-FD4FFD90FD91FDC8-FDEFFDFEFDFFFE1A-FE1FFE27-FE2FFE53FE67FE6C-FE6FFE75FEFD-FF00FFBF-FFC1FFC8FFC9FFD0FFD1FFD8FFD9FFDD-FFDFFFE7FFEF-FFFBFFFEFFFF\",Cc:\"0000-001F007F-009F\",Cf:\"00AD0600-060306DD070F17B417B5200B-200F202A-202E2060-2064206A-206FFEFFFFF9-FFFB\",Co:\"E000-F8FF\",Cs:\"D800-DFFF\",Cn:\"03780379037F-0383038B038D03A20526-05300557055805600588058B-059005C8-05CF05EB-05EF05F5-05FF06040605061C061D0620065F070E074B074C07B2-07BF07FB-07FF082E082F083F-08FF093A093B094F095609570973-097809800984098D098E0991099209A909B109B3-09B509BA09BB09C509C609C909CA09CF-09D609D8-09DB09DE09E409E509FC-0A000A040A0B-0A0E0A110A120A290A310A340A370A3A0A3B0A3D0A43-0A460A490A4A0A4E-0A500A52-0A580A5D0A5F-0A650A76-0A800A840A8E0A920AA90AB10AB40ABA0ABB0AC60ACA0ACE0ACF0AD1-0ADF0AE40AE50AF00AF2-0B000B040B0D0B0E0B110B120B290B310B340B3A0B3B0B450B460B490B4A0B4E-0B550B58-0B5B0B5E0B640B650B72-0B810B840B8B-0B8D0B910B96-0B980B9B0B9D0BA0-0BA20BA5-0BA70BAB-0BAD0BBA-0BBD0BC3-0BC50BC90BCE0BCF0BD1-0BD60BD8-0BE50BFB-0C000C040C0D0C110C290C340C3A-0C3C0C450C490C4E-0C540C570C5A-0C5F0C640C650C70-0C770C800C810C840C8D0C910CA90CB40CBA0CBB0CC50CC90CCE-0CD40CD7-0CDD0CDF0CE40CE50CF00CF3-0D010D040D0D0D110D290D3A-0D3C0D450D490D4E-0D560D58-0D5F0D640D650D76-0D780D800D810D840D97-0D990DB20DBC0DBE0DBF0DC7-0DC90DCB-0DCE0DD50DD70DE0-0DF10DF5-0E000E3B-0E3E0E5C-0E800E830E850E860E890E8B0E8C0E8E-0E930E980EA00EA40EA60EA80EA90EAC0EBA0EBE0EBF0EC50EC70ECE0ECF0EDA0EDB0EDE-0EFF0F480F6D-0F700F8C-0F8F0F980FBD0FCD0FD9-0FFF10C6-10CF10FD-10FF1249124E124F12571259125E125F1289128E128F12B112B612B712BF12C112C612C712D7131113161317135B-135E137D-137F139A-139F13F5-13FF169D-169F16F1-16FF170D1715-171F1737-173F1754-175F176D17711774-177F17DE17DF17EA-17EF17FA-17FF180F181A-181F1878-187F18AB-18AF18F6-18FF191D-191F192C-192F193C-193F1941-1943196E196F1975-197F19AC-19AF19CA-19CF19DB-19DD1A1C1A1D1A5F1A7D1A7E1A8A-1A8F1A9A-1A9F1AAE-1AFF1B4C-1B4F1B7D-1B7F1BAB-1BAD1BBA-1BFF1C38-1C3A1C4A-1C4C1C80-1CCF1CF3-1CFF1DE7-1DFC1F161F171F1E1F1F1F461F471F4E1F4F1F581F5A1F5C1F5E1F7E1F7F1FB51FC51FD41FD51FDC1FF01FF11FF51FFF2065-206920722073208F2095-209F20B9-20CF20F1-20FF218A-218F23E9-23FF2427-243F244B-245F26CE26E226E4-26E727002705270A270B2728274C274E2753-2755275F27602795-279727B027BF27CB27CD-27CF2B4D-2B4F2B5A-2BFF2C2F2C5F2CF2-2CF82D26-2D2F2D66-2D6E2D70-2D7F2D97-2D9F2DA72DAF2DB72DBF2DC72DCF2DD72DDF2E32-2E7F2E9A2EF4-2EFF2FD6-2FEF2FFC-2FFF3040309730983100-3104312E-3130318F31B8-31BF31E4-31EF321F32FF4DB6-4DBF9FCC-9FFFA48D-A48FA4C7-A4CFA62C-A63FA660A661A674-A67BA698-A69FA6F8-A6FFA78D-A7FAA82C-A82FA83A-A83FA878-A87FA8C5-A8CDA8DA-A8DFA8FC-A8FFA954-A95EA97D-A97FA9CEA9DA-A9DDA9E0-A9FFAA37-AA3FAA4EAA4FAA5AAA5BAA7C-AA7FAAC3-AADAAAE0-ABBFABEEABEFABFA-ABFFD7A4-D7AFD7C7-D7CAD7FC-D7FFFA2EFA2FFA6EFA6FFADA-FAFFFB07-FB12FB18-FB1CFB37FB3DFB3FFB42FB45FBB2-FBD2FD40-FD4FFD90FD91FDC8-FDEFFDFEFDFFFE1A-FE1FFE27-FE2FFE53FE67FE6C-FE6FFE75FEFDFEFEFF00FFBF-FFC1FFC8FFC9FFD0FFD1FFD8FFD9FFDD-FFDFFFE7FFEF-FFF8FFFEFFFF\"})}),ace.define(\"ace/token_iterator\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";var r=function(e,t,n){this.$session=e,this.$row=t,this.$rowTokens=e.getTokens(t);var r=e.getTokenAt(t,n);this.$tokenIndex=r?r.index:-1};(function(){this.stepBackward=function(){this.$tokenIndex-=1;while(this.$tokenIndex<0){this.$row-=1;if(this.$row<0)return this.$row=0,null;this.$rowTokens=this.$session.getTokens(this.$row),this.$tokenIndex=this.$rowTokens.length-1}return this.$rowTokens[this.$tokenIndex]},this.stepForward=function(){this.$tokenIndex+=1;var e;while(this.$tokenIndex>=this.$rowTokens.length){this.$row+=1,e||(e=this.$session.getLength());if(this.$row>=e)return this.$row=e-1,null;this.$rowTokens=this.$session.getTokens(this.$row),this.$tokenIndex=0}return this.$rowTokens[this.$tokenIndex]},this.getCurrentToken=function(){return this.$rowTokens[this.$tokenIndex]},this.getCurrentTokenRow=function(){return this.$row},this.getCurrentTokenColumn=function(){var e=this.$rowTokens,t=this.$tokenIndex,n=e[t].start;if(n!==undefined)return n;n=0;while(t>0)t-=1,n+=e[t].value.length;return n},this.getCurrentTokenPosition=function(){return{row:this.$row,column:this.getCurrentTokenColumn()}}}).call(r.prototype),t.TokenIterator=r}),ace.define(\"ace/mode/text\",[\"require\",\"exports\",\"module\",\"ace/tokenizer\",\"ace/mode/text_highlight_rules\",\"ace/mode/behaviour\",\"ace/unicode\",\"ace/lib/lang\",\"ace/token_iterator\",\"ace/range\"],function(e,t,n){\"use strict\";var r=e(\"../tokenizer\").Tokenizer,i=e(\"./text_highlight_rules\").TextHighlightRules,s=e(\"./behaviour\").Behaviour,o=e(\"../unicode\"),u=e(\"../lib/lang\"),a=e(\"../token_iterator\").TokenIterator,f=e(\"../range\").Range,l=function(){this.HighlightRules=i,this.$behaviour=new s};(function(){this.tokenRe=new RegExp(\"^[\"+o.packages.L+o.packages.Mn+o.packages.Mc+o.packages.Nd+o.packages.Pc+\"\\\\$_]+\",\"g\"),this.nonTokenRe=new RegExp(\"^(?:[^\"+o.packages.L+o.packages.Mn+o.packages.Mc+o.packages.Nd+o.packages.Pc+\"\\\\$_]|\\\\s])+\",\"g\"),this.getTokenizer=function(){return this.$tokenizer||(this.$highlightRules=this.$highlightRules||new this.HighlightRules,this.$tokenizer=new r(this.$highlightRules.getRules())),this.$tokenizer},this.lineCommentStart=\"\",this.blockComment=\"\",this.toggleCommentLines=function(e,t,n,r){function w(e){for(var t=n;t<=r;t++)e(i.getLine(t),t)}var i=t.doc,s=!0,o=!0,a=Infinity,f=t.getTabSize(),l=!1;if(!this.lineCommentStart){if(!this.blockComment)return!1;var c=this.blockComment.start,h=this.blockComment.end,p=new RegExp(\"^(\\\\s*)(?:\"+u.escapeRegExp(c)+\")\"),d=new RegExp(\"(?:\"+u.escapeRegExp(h)+\")\\\\s*$\"),v=function(e,t){if(g(e,t))return;if(!s||/\\S/.test(e))i.insertInLine({row:t,column:e.length},h),i.insertInLine({row:t,column:a},c)},m=function(e,t){var n;(n=e.match(d))&&i.removeInLine(t,e.length-n[0].length,e.length),(n=e.match(p))&&i.removeInLine(t,n[1].length,n[0].length)},g=function(e,n){if(p.test(e))return!0;var r=t.getTokens(n);for(var i=0;i<r.length;i++)if(r[i].type===\"comment\")return!0}}else{if(Array.isArray(this.lineCommentStart))var p=this.lineCommentStart.map(u.escapeRegExp).join(\"|\"),c=this.lineCommentStart[0];else var p=u.escapeRegExp(this.lineCommentStart),c=this.lineCommentStart;p=new RegExp(\"^(\\\\s*)(?:\"+p+\") ?\"),l=t.getUseSoftTabs();var m=function(e,t){var n=e.match(p);if(!n)return;var r=n[1].length,s=n[0].length;!b(e,r,s)&&n[0][s-1]==\" \"&&s--,i.removeInLine(t,r,s)},y=c+\" \",v=function(e,t){if(!s||/\\S/.test(e))b(e,a,a)?i.insertInLine({row:t,column:a},y):i.insertInLine({row:t,column:a},c)},g=function(e,t){return p.test(e)},b=function(e,t,n){var r=0;while(t--&&e.charAt(t)==\" \")r++;if(r%f!=0)return!1;var r=0;while(e.charAt(n++)==\" \")r++;return f>2?r%f!=f-1:r%f==0}}var E=Infinity;w(function(e,t){var n=e.search(/\\S/);n!==-1?(n<a&&(a=n),o&&!g(e,t)&&(o=!1)):E>e.length&&(E=e.length)}),a==Infinity&&(a=E,s=!1,o=!1),l&&a%f!=0&&(a=Math.floor(a/f)*f),w(o?m:v)},this.toggleBlockComment=function(e,t,n,r){var i=this.blockComment;if(!i)return;!i.start&&i[0]&&(i=i[0]);var s=new a(t,r.row,r.column),o=s.getCurrentToken(),u=t.selection,l=t.selection.toOrientedRange(),c,h;if(o&&/comment/.test(o.type)){var p,d;while(o&&/comment/.test(o.type)){var v=o.value.indexOf(i.start);if(v!=-1){var m=s.getCurrentTokenRow(),g=s.getCurrentTokenColumn()+v;p=new f(m,g,m,g+i.start.length);break}o=s.stepBackward()}var s=new a(t,r.row,r.column),o=s.getCurrentToken();while(o&&/comment/.test(o.type)){var v=o.value.indexOf(i.end);if(v!=-1){var m=s.getCurrentTokenRow(),g=s.getCurrentTokenColumn()+v;d=new f(m,g,m,g+i.end.length);break}o=s.stepForward()}d&&t.remove(d),p&&(t.remove(p),c=p.start.row,h=-i.start.length)}else h=i.start.length,c=n.start.row,t.insert(n.end,i.end),t.insert(n.start,i.start);l.start.row==c&&(l.start.column+=h),l.end.row==c&&(l.end.column+=h),t.selection.fromOrientedRange(l)},this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.autoOutdent=function(e,t,n){},this.$getIndent=function(e){return e.match(/^\\s*/)[0]},this.createWorker=function(e){return null},this.createModeDelegates=function(e){this.$embeds=[],this.$modes={};for(var t in e)e[t]&&(this.$embeds.push(t),this.$modes[t]=new e[t]);var n=[\"toggleBlockComment\",\"toggleCommentLines\",\"getNextLineIndent\",\"checkOutdent\",\"autoOutdent\",\"transformAction\",\"getCompletions\"];for(var t=0;t<n.length;t++)(function(e){var r=n[t],i=e[r];e[n[t]]=function(){return this.$delegator(r,arguments,i)}})(this)},this.$delegator=function(e,t,n){var r=t[0];typeof r!=\"string\"&&(r=r[0]);for(var i=0;i<this.$embeds.length;i++){if(!this.$modes[this.$embeds[i]])continue;var s=r.split(this.$embeds[i]);if(!s[0]&&s[1]){t[0]=s[1];var o=this.$modes[this.$embeds[i]];return o[e].apply(o,t)}}var u=n.apply(this,t);return n?u:undefined},this.transformAction=function(e,t,n,r,i){if(this.$behaviour){var s=this.$behaviour.getBehaviours();for(var o in s)if(s[o][t]){var u=s[o][t].apply(this,arguments);if(u)return u}}},this.getKeywords=function(e){if(!this.completionKeywords){var t=this.$tokenizer.rules,n=[];for(var r in t){var i=t[r];for(var s=0,o=i.length;s<o;s++)if(typeof i[s].token==\"string\")/keyword|support|storage/.test(i[s].token)&&n.push(i[s].regex);else if(typeof i[s].token==\"object\")for(var u=0,a=i[s].token.length;u<a;u++)if(/keyword|support|storage/.test(i[s].token[u])){var r=i[s].regex.match(/\\(.+?\\)/g)[u];n.push(r.substr(1,r.length-2))}}this.completionKeywords=n}return e?n.concat(this.$keywordList||[]):this.$keywordList},this.$createKeywordList=function(){return this.$highlightRules||this.getTokenizer(),this.$keywordList=this.$highlightRules.$keywordList||[]},this.getCompletions=function(e,t,n,r){var i=this.$keywordList||this.$createKeywordList();return i.map(function(e){return{name:e,value:e,score:0,meta:\"keyword\"}})},this.$id=\"ace/mode/text\"}).call(l.prototype),t.Mode=l}),ace.define(\"ace/apply_delta\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";function r(e,t){throw console.log(\"Invalid Delta:\",e),\"Invalid Delta: \"+t}function i(e,t){return t.row>=0&&t.row<e.length&&t.column>=0&&t.column<=e[t.row].length}function s(e,t){t.action!=\"insert\"&&t.action!=\"remove\"&&r(t,\"delta.action must be 'insert' or 'remove'\"),t.lines instanceof Array||r(t,\"delta.lines must be an Array\"),(!t.start||!t.end)&&r(t,\"delta.start/end must be an present\");var n=t.start;i(e,t.start)||r(t,\"delta.start must be contained in document\");var s=t.end;t.action==\"remove\"&&!i(e,s)&&r(t,\"delta.end must contained in document for 'remove' actions\");var o=s.row-n.row,u=s.column-(o==0?n.column:0);(o!=t.lines.length-1||t.lines[o].length!=u)&&r(t,\"delta.range must match delta lines\")}t.applyDelta=function(e,t,n){var r=t.start.row,i=t.start.column,s=e[r]||\"\";switch(t.action){case\"insert\":var o=t.lines;if(o.length===1)e[r]=s.substring(0,i)+t.lines[0]+s.substring(i);else{var u=[r,1].concat(t.lines);e.splice.apply(e,u),e[r]=s.substring(0,i)+e[r],e[r+t.lines.length-1]+=s.substring(i)}break;case\"remove\":var a=t.end.column,f=t.end.row;r===f?e[r]=s.substring(0,i)+s.substring(a):e.splice(r,f-r+1,s.substring(0,i)+e[f].substring(a))}}}),ace.define(\"ace/anchor\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/event_emitter\"],function(e,t,n){\"use strict\";var r=e(\"./lib/oop\"),i=e(\"./lib/event_emitter\").EventEmitter,s=t.Anchor=function(e,t,n){this.$onChange=this.onChange.bind(this),this.attach(e),typeof n==\"undefined\"?this.setPosition(t.row,t.column):this.setPosition(t,n)};(function(){function e(e,t,n){var r=n?e.column<=t.column:e.column<t.column;return e.row<t.row||e.row==t.row&&r}function t(t,n,r){var i=t.action==\"insert\",s=(i?1:-1)*(t.end.row-t.start.row),o=(i?1:-1)*(t.end.column-t.start.column),u=t.start,a=i?u:t.end;return e(n,u,r)?{row:n.row,column:n.column}:e(a,n,!r)?{row:n.row+s,column:n.column+(n.row==a.row?o:0)}:{row:u.row,column:u.column}}r.implement(this,i),this.getPosition=function(){return this.$clipPositionToDocument(this.row,this.column)},this.getDocument=function(){return this.document},this.$insertRight=!1,this.onChange=function(e){if(e.start.row==e.end.row&&e.start.row!=this.row)return;if(e.start.row>this.row)return;var n=t(e,{row:this.row,column:this.column},this.$insertRight);this.setPosition(n.row,n.column,!0)},this.setPosition=function(e,t,n){var r;n?r={row:e,column:t}:r=this.$clipPositionToDocument(e,t);if(this.row==r.row&&this.column==r.column)return;var i={row:this.row,column:this.column};this.row=r.row,this.column=r.column,this._signal(\"change\",{old:i,value:r})},this.detach=function(){this.document.removeEventListener(\"change\",this.$onChange)},this.attach=function(e){this.document=e||this.document,this.document.on(\"change\",this.$onChange)},this.$clipPositionToDocument=function(e,t){var n={};return e>=this.document.getLength()?(n.row=Math.max(0,this.document.getLength()-1),n.column=this.document.getLine(n.row).length):e<0?(n.row=0,n.column=0):(n.row=e,n.column=Math.min(this.document.getLine(n.row).length,Math.max(0,t))),t<0&&(n.column=0),n}}).call(s.prototype)}),ace.define(\"ace/document\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/apply_delta\",\"ace/lib/event_emitter\",\"ace/range\",\"ace/anchor\"],function(e,t,n){\"use strict\";var r=e(\"./lib/oop\"),i=e(\"./apply_delta\").applyDelta,s=e(\"./lib/event_emitter\").EventEmitter,o=e(\"./range\").Range,u=e(\"./anchor\").Anchor,a=function(e){this.$lines=[\"\"],e.length===0?this.$lines=[\"\"]:Array.isArray(e)?this.insertMergedLines({row:0,column:0},e):this.insert({row:0,column:0},e)};(function(){r.implement(this,s),this.setValue=function(e){var t=this.getLength()-1;this.remove(new o(0,0,t,this.getLine(t).length)),this.insert({row:0,column:0},e)},this.getValue=function(){return this.getAllLines().join(this.getNewLineCharacter())},this.createAnchor=function(e,t){return new u(this,e,t)},\"aaa\".split(/a/).length===0?this.$split=function(e){return e.replace(/\\r\\n|\\r/g,\"\\n\").split(\"\\n\")}:this.$split=function(e){return e.split(/\\r\\n|\\r|\\n/)},this.$detectNewLine=function(e){var t=e.match(/^.*?(\\r\\n|\\r|\\n)/m);this.$autoNewLine=t?t[1]:\"\\n\",this._signal(\"changeNewLineMode\")},this.getNewLineCharacter=function(){switch(this.$newLineMode){case\"windows\":return\"\\r\\n\";case\"unix\":return\"\\n\";default:return this.$autoNewLine||\"\\n\"}},this.$autoNewLine=\"\",this.$newLineMode=\"auto\",this.setNewLineMode=function(e){if(this.$newLineMode===e)return;this.$newLineMode=e,this._signal(\"changeNewLineMode\")},this.getNewLineMode=function(){return this.$newLineMode},this.isNewLine=function(e){return e==\"\\r\\n\"||e==\"\\r\"||e==\"\\n\"},this.getLine=function(e){return this.$lines[e]||\"\"},this.getLines=function(e,t){return this.$lines.slice(e,t+1)},this.getAllLines=function(){return this.getLines(0,this.getLength())},this.getLength=function(){return this.$lines.length},this.getTextRange=function(e){return this.getLinesForRange(e).join(this.getNewLineCharacter())},this.getLinesForRange=function(e){var t;if(e.start.row===e.end.row)t=[this.getLine(e.start.row).substring(e.start.column,e.end.column)];else{t=this.getLines(e.start.row,e.end.row),t[0]=(t[0]||\"\").substring(e.start.column);var n=t.length-1;e.end.row-e.start.row==n&&(t[n]=t[n].substring(0,e.end.column))}return t},this.insertLines=function(e,t){return console.warn(\"Use of document.insertLines is deprecated. Use the insertFullLines method instead.\"),this.insertFullLines(e,t)},this.removeLines=function(e,t){return console.warn(\"Use of document.removeLines is deprecated. Use the removeFullLines method instead.\"),this.removeFullLines(e,t)},this.insertNewLine=function(e){return console.warn(\"Use of document.insertNewLine is deprecated. Use insertMergedLines(position, ['', '']) instead.\"),this.insertMergedLines(e,[\"\",\"\"])},this.insert=function(e,t){return this.getLength()<=1&&this.$detectNewLine(t),this.insertMergedLines(e,this.$split(t))},this.insertInLine=function(e,t){var n=this.clippedPos(e.row,e.column),r=this.pos(e.row,e.column+t.length);return this.applyDelta({start:n,end:r,action:\"insert\",lines:[t]},!0),this.clonePos(r)},this.clippedPos=function(e,t){var n=this.getLength();e===undefined?e=n:e<0?e=0:e>=n&&(e=n-1,t=undefined);var r=this.getLine(e);return t==undefined&&(t=r.length),t=Math.min(Math.max(t,0),r.length),{row:e,column:t}},this.clonePos=function(e){return{row:e.row,column:e.column}},this.pos=function(e,t){return{row:e,column:t}},this.$clipPosition=function(e){var t=this.getLength();return e.row>=t?(e.row=Math.max(0,t-1),e.column=this.getLine(t-1).length):(e.row=Math.max(0,e.row),e.column=Math.min(Math.max(e.column,0),this.getLine(e.row).length)),e},this.insertFullLines=function(e,t){e=Math.min(Math.max(e,0),this.getLength());var n=0;e<this.getLength()?(t=t.concat([\"\"]),n=0):(t=[\"\"].concat(t),e--,n=this.$lines[e].length),this.insertMergedLines({row:e,column:n},t)},this.insertMergedLines=function(e,t){var n=this.clippedPos(e.row,e.column),r={row:n.row+t.length-1,column:(t.length==1?n.column:0)+t[t.length-1].length};return this.applyDelta({start:n,end:r,action:\"insert\",lines:t}),this.clonePos(r)},this.remove=function(e){var t=this.clippedPos(e.start.row,e.start.column),n=this.clippedPos(e.end.row,e.end.column);return this.applyDelta({start:t,end:n,action:\"remove\",lines:this.getLinesForRange({start:t,end:n})}),this.clonePos(t)},this.removeInLine=function(e,t,n){var r=this.clippedPos(e,t),i=this.clippedPos(e,n);return this.applyDelta({start:r,end:i,action:\"remove\",lines:this.getLinesForRange({start:r,end:i})},!0),this.clonePos(r)},this.removeFullLines=function(e,t){e=Math.min(Math.max(0,e),this.getLength()-1),t=Math.min(Math.max(0,t),this.getLength()-1);var n=t==this.getLength()-1&&e>0,r=t<this.getLength()-1,i=n?e-1:e,s=n?this.getLine(i).length:0,u=r?t+1:t,a=r?0:this.getLine(u).length,f=new o(i,s,u,a),l=this.$lines.slice(e,t+1);return this.applyDelta({start:f.start,end:f.end,action:\"remove\",lines:this.getLinesForRange(f)}),l},this.removeNewLine=function(e){e<this.getLength()-1&&e>=0&&this.applyDelta({start:this.pos(e,this.getLine(e).length),end:this.pos(e+1,0),action:\"remove\",lines:[\"\",\"\"]})},this.replace=function(e,t){e instanceof o||(e=o.fromPoints(e.start,e.end));if(t.length===0&&e.isEmpty())return e.start;if(t==this.getTextRange(e))return e.end;this.remove(e);var n;return t?n=this.insert(e.start,t):n=e.start,n},this.applyDeltas=function(e){for(var t=0;t<e.length;t++)this.applyDelta(e[t])},this.revertDeltas=function(e){for(var t=e.length-1;t>=0;t--)this.revertDelta(e[t])},this.applyDelta=function(e,t){var n=e.action==\"insert\";if(n?e.lines.length<=1&&!e.lines[0]:!o.comparePoints(e.start,e.end))return;n&&e.lines.length>2e4&&this.$splitAndapplyLargeDelta(e,2e4),i(this.$lines,e,t),this._signal(\"change\",e)},this.$splitAndapplyLargeDelta=function(e,t){var n=e.lines,r=n.length,i=e.start.row,s=e.start.column,o=0,u=0;do{o=u,u+=t-1;var a=n.slice(o,u);if(u>r){e.lines=a,e.start.row=i+o,e.start.column=s;break}a.push(\"\"),this.applyDelta({start:this.pos(i+o,s),end:this.pos(i+u,s=0),action:e.action,lines:a},!0)}while(!0)},this.revertDelta=function(e){this.applyDelta({start:this.clonePos(e.start),end:this.clonePos(e.end),action:e.action==\"insert\"?\"remove\":\"insert\",lines:e.lines.slice()})},this.indexToPosition=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length;for(var i=t||0,s=n.length;i<s;i++){e-=n[i].length+r;if(e<0)return{row:i,column:e+n[i].length+r}}return{row:s-1,column:n[s-1].length}},this.positionToIndex=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length,i=0,s=Math.min(e.row,n.length);for(var o=t||0;o<s;++o)i+=n[o].length+r;return i+e.column}}).call(a.prototype),t.Document=a}),ace.define(\"ace/background_tokenizer\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/event_emitter\"],function(e,t,n){\"use strict\";var r=e(\"./lib/oop\"),i=e(\"./lib/event_emitter\").EventEmitter,s=function(e,t){this.running=!1,this.lines=[],this.states=[],this.currentLine=0,this.tokenizer=e;var n=this;this.$worker=function(){if(!n.running)return;var e=new Date,t=n.currentLine,r=-1,i=n.doc,s=t;while(n.lines[t])t++;var o=i.getLength(),u=0;n.running=!1;while(t<o){n.$tokenizeRow(t),r=t;do t++;while(n.lines[t]);u++;if(u%5===0&&new Date-e>20){n.running=setTimeout(n.$worker,20);break}}n.currentLine=t,s<=r&&n.fireUpdateEvent(s,r)}};(function(){r.implement(this,i),this.setTokenizer=function(e){this.tokenizer=e,this.lines=[],this.states=[],this.start(0)},this.setDocument=function(e){this.doc=e,this.lines=[],this.states=[],this.stop()},this.fireUpdateEvent=function(e,t){var n={first:e,last:t};this._signal(\"update\",{data:n})},this.start=function(e){this.currentLine=Math.min(e||0,this.currentLine,this.doc.getLength()),this.lines.splice(this.currentLine,this.lines.length),this.states.splice(this.currentLine,this.states.length),this.stop(),this.running=setTimeout(this.$worker,700)},this.scheduleStart=function(){this.running||(this.running=setTimeout(this.$worker,700))},this.$updateOnChange=function(e){var t=e.start.row,n=e.end.row-t;if(n===0)this.lines[t]=null;else if(e.action==\"remove\")this.lines.splice(t,n+1,null),this.states.splice(t,n+1,null);else{var r=Array(n+1);r.unshift(t,1),this.lines.splice.apply(this.lines,r),this.states.splice.apply(this.states,r)}this.currentLine=Math.min(t,this.currentLine,this.doc.getLength()),this.stop()},this.stop=function(){this.running&&clearTimeout(this.running),this.running=!1},this.getTokens=function(e){return this.lines[e]||this.$tokenizeRow(e)},this.getState=function(e){return this.currentLine==e&&this.$tokenizeRow(e),this.states[e]||\"start\"},this.$tokenizeRow=function(e){var t=this.doc.getLine(e),n=this.states[e-1],r=this.tokenizer.getLineTokens(t,n,e);return this.states[e]+\"\"!=r.state+\"\"?(this.states[e]=r.state,this.lines[e+1]=null,this.currentLine>e+1&&(this.currentLine=e+1)):this.currentLine==e&&(this.currentLine=e+1),this.lines[e]=r.tokens}}).call(s.prototype),t.BackgroundTokenizer=s}),ace.define(\"ace/search_highlight\",[\"require\",\"exports\",\"module\",\"ace/lib/lang\",\"ace/lib/oop\",\"ace/range\"],function(e,t,n){\"use strict\";var r=e(\"./lib/lang\"),i=e(\"./lib/oop\"),s=e(\"./range\").Range,o=function(e,t,n){this.setRegexp(e),this.clazz=t,this.type=n||\"text\"};(function(){this.MAX_RANGES=500,this.setRegexp=function(e){if(this.regExp+\"\"==e+\"\")return;this.regExp=e,this.cache=[]},this.update=function(e,t,n,i){if(!this.regExp)return;var o=i.firstRow,u=i.lastRow;for(var a=o;a<=u;a++){var f=this.cache[a];f==null&&(f=r.getMatchOffsets(n.getLine(a),this.regExp),f.length>this.MAX_RANGES&&(f=f.slice(0,this.MAX_RANGES)),f=f.map(function(e){return new s(a,e.offset,a,e.offset+e.length)}),this.cache[a]=f.length?f:\"\");for(var l=f.length;l--;)t.drawSingleLineMarker(e,f[l].toScreenRange(n),this.clazz,i)}}}).call(o.prototype),t.SearchHighlight=o}),ace.define(\"ace/edit_session/fold_line\",[\"require\",\"exports\",\"module\",\"ace/range\"],function(e,t,n){\"use strict\";function i(e,t){this.foldData=e,Array.isArray(t)?this.folds=t:t=this.folds=[t];var n=t[t.length-1];this.range=new r(t[0].start.row,t[0].start.column,n.end.row,n.end.column),this.start=this.range.start,this.end=this.range.end,this.folds.forEach(function(e){e.setFoldLine(this)},this)}var r=e(\"../range\").Range;(function(){this.shiftRow=function(e){this.start.row+=e,this.end.row+=e,this.folds.forEach(function(t){t.start.row+=e,t.end.row+=e})},this.addFold=function(e){if(e.sameRow){if(e.start.row<this.startRow||e.endRow>this.endRow)throw new Error(\"Can't add a fold to this FoldLine as it has no connection\");this.folds.push(e),this.folds.sort(function(e,t){return-e.range.compareEnd(t.start.row,t.start.column)}),this.range.compareEnd(e.start.row,e.start.column)>0?(this.end.row=e.end.row,this.end.column=e.end.column):this.range.compareStart(e.end.row,e.end.column)<0&&(this.start.row=e.start.row,this.start.column=e.start.column)}else if(e.start.row==this.end.row)this.folds.push(e),this.end.row=e.end.row,this.end.column=e.end.column;else{if(e.end.row!=this.start.row)throw new Error(\"Trying to add fold to FoldRow that doesn't have a matching row\");this.folds.unshift(e),this.start.row=e.start.row,this.start.column=e.start.column}e.foldLine=this},this.containsRow=function(e){return e>=this.start.row&&e<=this.end.row},this.walk=function(e,t,n){var r=0,i=this.folds,s,o,u,a=!0;t==null&&(t=this.end.row,n=this.end.column);for(var f=0;f<i.length;f++){s=i[f],o=s.range.compareStart(t,n);if(o==-1){e(null,t,n,r,a);return}u=e(null,s.start.row,s.start.column,r,a),u=!u&&e(s.placeholder,s.start.row,s.start.column,r);if(u||o===0)return;a=!s.sameRow,r=s.end.column}e(null,t,n,r,a)},this.getNextFoldTo=function(e,t){var n,r;for(var i=0;i<this.folds.length;i++){n=this.folds[i],r=n.range.compareEnd(e,t);if(r==-1)return{fold:n,kind:\"after\"};if(r===0)return{fold:n,kind:\"inside\"}}return null},this.addRemoveChars=function(e,t,n){var r=this.getNextFoldTo(e,t),i,s;if(r){i=r.fold;if(r.kind==\"inside\"&&i.start.column!=t&&i.start.row!=e)window.console&&window.console.log(e,t,i);else if(i.start.row==e){s=this.folds;var o=s.indexOf(i);o===0&&(this.start.column+=n);for(o;o<s.length;o++){i=s[o],i.start.column+=n;if(!i.sameRow)return;i.end.column+=n}this.end.column+=n}}},this.split=function(e,t){var n=this.getNextFoldTo(e,t);if(!n||n.kind==\"inside\")return null;var r=n.fold,s=this.folds,o=this.foldData,u=s.indexOf(r),a=s[u-1];this.end.row=a.end.row,this.end.column=a.end.column,s=s.splice(u,s.length-u);var f=new i(o,s);return o.splice(o.indexOf(this)+1,0,f),f},this.merge=function(e){var t=e.folds;for(var n=0;n<t.length;n++)this.addFold(t[n]);var r=this.foldData;r.splice(r.indexOf(e),1)},this.toString=function(){var e=[this.range.toString()+\": [\"];return this.folds.forEach(function(t){e.push(\"  \"+t.toString())}),e.push(\"]\"),e.join(\"\\n\")},this.idxToPosition=function(e){var t=0;for(var n=0;n<this.folds.length;n++){var r=this.folds[n];e-=r.start.column-t;if(e<0)return{row:r.start.row,column:r.start.column+e};e-=r.placeholder.length;if(e<0)return r.start;t=r.end.column}return{row:this.end.row,column:this.end.column+e}}}).call(i.prototype),t.FoldLine=i}),ace.define(\"ace/range_list\",[\"require\",\"exports\",\"module\",\"ace/range\"],function(e,t,n){\"use strict\";var r=e(\"./range\").Range,i=r.comparePoints,s=function(){this.ranges=[]};(function(){this.comparePoints=i,this.pointIndex=function(e,t,n){var r=this.ranges;for(var s=n||0;s<r.length;s++){var o=r[s],u=i(e,o.end);if(u>0)continue;var a=i(e,o.start);return u===0?t&&a!==0?-s-2:s:a>0||a===0&&!t?s:-s-1}return-s-1},this.add=function(e){var t=!e.isEmpty(),n=this.pointIndex(e.start,t);n<0&&(n=-n-1);var r=this.pointIndex(e.end,t,n);return r<0?r=-r-1:r++,this.ranges.splice(n,r-n,e)},this.addList=function(e){var t=[];for(var n=e.length;n--;)t.push.apply(t,this.add(e[n]));return t},this.substractPoint=function(e){var t=this.pointIndex(e);if(t>=0)return this.ranges.splice(t,1)},this.merge=function(){var e=[],t=this.ranges;t=t.sort(function(e,t){return i(e.start,t.start)});var n=t[0],r;for(var s=1;s<t.length;s++){r=n,n=t[s];var o=i(r.end,n.start);if(o<0)continue;if(o==0&&!r.isEmpty()&&!n.isEmpty())continue;i(r.end,n.end)<0&&(r.end.row=n.end.row,r.end.column=n.end.column),t.splice(s,1),e.push(n),n=r,s--}return this.ranges=t,e},this.contains=function(e,t){return this.pointIndex({row:e,column:t})>=0},this.containsPoint=function(e){return this.pointIndex(e)>=0},this.rangeAtPoint=function(e){var t=this.pointIndex(e);if(t>=0)return this.ranges[t]},this.clipRows=function(e,t){var n=this.ranges;if(n[0].start.row>t||n[n.length-1].start.row<e)return[];var r=this.pointIndex({row:e,column:0});r<0&&(r=-r-1);var i=this.pointIndex({row:t,column:0},r);i<0&&(i=-i-1);var s=[];for(var o=r;o<i;o++)s.push(n[o]);return s},this.removeAll=function(){return this.ranges.splice(0,this.ranges.length)},this.attach=function(e){this.session&&this.detach(),this.session=e,this.onChange=this.$onChange.bind(this),this.session.on(\"change\",this.onChange)},this.detach=function(){if(!this.session)return;this.session.removeListener(\"change\",this.onChange),this.session=null},this.$onChange=function(e){if(e.action==\"insert\")var t=e.start,n=e.end;else var n=e.start,t=e.end;var r=t.row,i=n.row,s=i-r,o=-t.column+n.column,u=this.ranges;for(var a=0,f=u.length;a<f;a++){var l=u[a];if(l.end.row<r)continue;if(l.start.row>r)break;l.start.row==r&&l.start.column>=t.column&&(l.start.column!=t.column||!this.$insertRight)&&(l.start.column+=o,l.start.row+=s);if(l.end.row==r&&l.end.column>=t.column){if(l.end.column==t.column&&this.$insertRight)continue;l.end.column==t.column&&o>0&&a<f-1&&l.end.column>l.start.column&&l.end.column==u[a+1].start.column&&(l.end.column-=o),l.end.column+=o,l.end.row+=s}}if(s!=0&&a<f)for(;a<f;a++){var l=u[a];l.start.row+=s,l.end.row+=s}}}).call(s.prototype),t.RangeList=s}),ace.define(\"ace/edit_session/fold\",[\"require\",\"exports\",\"module\",\"ace/range\",\"ace/range_list\",\"ace/lib/oop\"],function(e,t,n){\"use strict\";function u(e,t){e.row-=t.row,e.row==0&&(e.column-=t.column)}function a(e,t){u(e.start,t),u(e.end,t)}function f(e,t){e.row==0&&(e.column+=t.column),e.row+=t.row}function l(e,t){f(e.start,t),f(e.end,t)}var r=e(\"../range\").Range,i=e(\"../range_list\").RangeList,s=e(\"../lib/oop\"),o=t.Fold=function(e,t){this.foldLine=null,this.placeholder=t,this.range=e,this.start=e.start,this.end=e.end,this.sameRow=e.start.row==e.end.row,this.subFolds=this.ranges=[]};s.inherits(o,i),function(){this.toString=function(){return'\"'+this.placeholder+'\" '+this.range.toString()},this.setFoldLine=function(e){this.foldLine=e,this.subFolds.forEach(function(t){t.setFoldLine(e)})},this.clone=function(){var e=this.range.clone(),t=new o(e,this.placeholder);return this.subFolds.forEach(function(e){t.subFolds.push(e.clone())}),t.collapseChildren=this.collapseChildren,t},this.addSubFold=function(e){if(this.range.isEqual(e))return;if(!this.range.containsRange(e))throw new Error(\"A fold can't intersect already existing fold\"+e.range+this.range);a(e,this.start);var t=e.start.row,n=e.start.column;for(var r=0,i=-1;r<this.subFolds.length;r++){i=this.subFolds[r].range.compare(t,n);if(i!=1)break}var s=this.subFolds[r];if(i==0)return s.addSubFold(e);var t=e.range.end.row,n=e.range.end.column;for(var o=r,i=-1;o<this.subFolds.length;o++){i=this.subFolds[o].range.compare(t,n);if(i!=1)break}var u=this.subFolds[o];if(i==0)throw new Error(\"A fold can't intersect already existing fold\"+e.range+this.range);var f=this.subFolds.splice(r,o-r,e);return e.setFoldLine(this.foldLine),e},this.restoreRange=function(e){return l(e,this.start)}}.call(o.prototype)}),ace.define(\"ace/edit_session/folding\",[\"require\",\"exports\",\"module\",\"ace/range\",\"ace/edit_session/fold_line\",\"ace/edit_session/fold\",\"ace/token_iterator\"],function(e,t,n){\"use strict\";function u(){this.getFoldAt=function(e,t,n){var r=this.getFoldLine(e);if(!r)return null;var i=r.folds;for(var s=0;s<i.length;s++){var o=i[s];if(o.range.contains(e,t)){if(n==1&&o.range.isEnd(e,t))continue;if(n==-1&&o.range.isStart(e,t))continue;return o}}},this.getFoldsInRange=function(e){var t=e.start,n=e.end,r=this.$foldData,i=[];t.column+=1,n.column-=1;for(var s=0;s<r.length;s++){var o=r[s].range.compareRange(e);if(o==2)continue;if(o==-2)break;var u=r[s].folds;for(var a=0;a<u.length;a++){var f=u[a];o=f.range.compareRange(e);if(o==-2)break;if(o==2)continue;if(o==42)break;i.push(f)}}return t.column-=1,n.column+=1,i},this.getFoldsInRangeList=function(e){if(Array.isArray(e)){var t=[];e.forEach(function(e){t=t.concat(this.getFoldsInRange(e))},this)}else var t=this.getFoldsInRange(e);return t},this.getAllFolds=function(){var e=[],t=this.$foldData;for(var n=0;n<t.length;n++)for(var r=0;r<t[n].folds.length;r++)e.push(t[n].folds[r]);return e},this.getFoldStringAt=function(e,t,n,r){r=r||this.getFoldLine(e);if(!r)return null;var i={end:{column:0}},s,o;for(var u=0;u<r.folds.length;u++){o=r.folds[u];var a=o.range.compareEnd(e,t);if(a==-1){s=this.getLine(o.start.row).substring(i.end.column,o.start.column);break}if(a===0)return null;i=o}return s||(s=this.getLine(o.start.row).substring(i.end.column)),n==-1?s.substring(0,t-i.end.column):n==1?s.substring(t-i.end.column):s},this.getFoldLine=function(e,t){var n=this.$foldData,r=0;t&&(r=n.indexOf(t)),r==-1&&(r=0);for(r;r<n.length;r++){var i=n[r];if(i.start.row<=e&&i.end.row>=e)return i;if(i.end.row>e)return null}return null},this.getNextFoldLine=function(e,t){var n=this.$foldData,r=0;t&&(r=n.indexOf(t)),r==-1&&(r=0);for(r;r<n.length;r++){var i=n[r];if(i.end.row>=e)return i}return null},this.getFoldedRowCount=function(e,t){var n=this.$foldData,r=t-e+1;for(var i=0;i<n.length;i++){var s=n[i],o=s.end.row,u=s.start.row;if(o>=t){u<t&&(u>=e?r-=t-u:r=0);break}o>=e&&(u>=e?r-=o-u:r-=o-e+1)}return r},this.$addFoldLine=function(e){return this.$foldData.push(e),this.$foldData.sort(function(e,t){return e.start.row-t.start.row}),e},this.addFold=function(e,t){var n=this.$foldData,r=!1,o;e instanceof s?o=e:(o=new s(t,e),o.collapseChildren=t.collapseChildren),this.$clipRangeToDocument(o.range);var u=o.start.row,a=o.start.column,f=o.end.row,l=o.end.column;if(u<f||u==f&&a<=l-2){var c=this.getFoldAt(u,a,1),h=this.getFoldAt(f,l,-1);if(c&&h==c)return c.addSubFold(o);c&&!c.range.isStart(u,a)&&this.removeFold(c),h&&!h.range.isEnd(f,l)&&this.removeFold(h);var p=this.getFoldsInRange(o.range);p.length>0&&(this.removeFolds(p),p.forEach(function(e){o.addSubFold(e)}));for(var d=0;d<n.length;d++){var v=n[d];if(f==v.start.row){v.addFold(o),r=!0;break}if(u==v.end.row){v.addFold(o),r=!0;if(!o.sameRow){var m=n[d+1];if(m&&m.start.row==f){v.merge(m);break}}break}if(f<=v.start.row)break}return r||(v=this.$addFoldLine(new i(this.$foldData,o))),this.$useWrapMode?this.$updateWrapData(v.start.row,v.start.row):this.$updateRowLengthCache(v.start.row,v.start.row),this.$modified=!0,this._signal(\"changeFold\",{data:o,action:\"add\"}),o}throw new Error(\"The range has to be at least 2 characters width\")},this.addFolds=function(e){e.forEach(function(e){this.addFold(e)},this)},this.removeFold=function(e){var t=e.foldLine,n=t.start.row,r=t.end.row,i=this.$foldData,s=t.folds;if(s.length==1)i.splice(i.indexOf(t),1);else if(t.range.isEnd(e.end.row,e.end.column))s.pop(),t.end.row=s[s.length-1].end.row,t.end.column=s[s.length-1].end.column;else if(t.range.isStart(e.start.row,e.start.column))s.shift(),t.start.row=s[0].start.row,t.start.column=s[0].start.column;else if(e.sameRow)s.splice(s.indexOf(e),1);else{var o=t.split(e.start.row,e.start.column);s=o.folds,s.shift(),o.start.row=s[0].start.row,o.start.column=s[0].start.column}this.$updating||(this.$useWrapMode?this.$updateWrapData(n,r):this.$updateRowLengthCache(n,r)),this.$modified=!0,this._signal(\"changeFold\",{data:e,action:\"remove\"})},this.removeFolds=function(e){var t=[];for(var n=0;n<e.length;n++)t.push(e[n]);t.forEach(function(e){this.removeFold(e)},this),this.$modified=!0},this.expandFold=function(e){this.removeFold(e),e.subFolds.forEach(function(t){e.restoreRange(t),this.addFold(t)},this),e.collapseChildren>0&&this.foldAll(e.start.row+1,e.end.row,e.collapseChildren-1),e.subFolds=[]},this.expandFolds=function(e){e.forEach(function(e){this.expandFold(e)},this)},this.unfold=function(e,t){var n,i;e==null?(n=new r(0,0,this.getLength(),0),t=!0):typeof e==\"number\"?n=new r(e,0,e,this.getLine(e).length):\"row\"in e?n=r.fromPoints(e,e):n=e,i=this.getFoldsInRangeList(n);if(t)this.removeFolds(i);else{var s=i;while(s.length)this.expandFolds(s),s=this.getFoldsInRangeList(n)}if(i.length)return i},this.isRowFolded=function(e,t){return!!this.getFoldLine(e,t)},this.getRowFoldEnd=function(e,t){var n=this.getFoldLine(e,t);return n?n.end.row:e},this.getRowFoldStart=function(e,t){var n=this.getFoldLine(e,t);return n?n.start.row:e},this.getFoldDisplayLine=function(e,t,n,r,i){r==null&&(r=e.start.row),i==null&&(i=0),t==null&&(t=e.end.row),n==null&&(n=this.getLine(t).length);var s=this.doc,o=\"\";return e.walk(function(e,t,n,u){if(t<r)return;if(t==r){if(n<i)return;u=Math.max(i,u)}e!=null?o+=e:o+=s.getLine(t).substring(u,n)},t,n),o},this.getDisplayLine=function(e,t,n,r){var i=this.getFoldLine(e);if(!i){var s;return s=this.doc.getLine(e),s.substring(r||0,t||s.length)}return this.getFoldDisplayLine(i,e,t,n,r)},this.$cloneFoldData=function(){var e=[];return e=this.$foldData.map(function(t){var n=t.folds.map(function(e){return e.clone()});return new i(e,n)}),e},this.toggleFold=function(e){var t=this.selection,n=t.getRange(),r,i;if(n.isEmpty()){var s=n.start;r=this.getFoldAt(s.row,s.column);if(r){this.expandFold(r);return}(i=this.findMatchingBracket(s))?n.comparePoint(i)==1?n.end=i:(n.start=i,n.start.column++,n.end.column--):(i=this.findMatchingBracket({row:s.row,column:s.column+1}))?(n.comparePoint(i)==1?n.end=i:n.start=i,n.start.column++):n=this.getCommentFoldRange(s.row,s.column)||n}else{var o=this.getFoldsInRange(n);if(e&&o.length){this.expandFolds(o);return}o.length==1&&(r=o[0])}r||(r=this.getFoldAt(n.start.row,n.start.column));if(r&&r.range.toString()==n.toString()){this.expandFold(r);return}var u=\"...\";if(!n.isMultiLine()){u=this.getTextRange(n);if(u.length<4)return;u=u.trim().substring(0,2)+\"..\"}this.addFold(u,n)},this.getCommentFoldRange=function(e,t,n){var i=new o(this,e,t),s=i.getCurrentToken();if(s&&/^comment|string/.test(s.type)){var u=new r,a=new RegExp(s.type.replace(/\\..*/,\"\\\\.\"));if(n!=1){do s=i.stepBackward();while(s&&a.test(s.type));i.stepForward()}u.start.row=i.getCurrentTokenRow(),u.start.column=i.getCurrentTokenColumn()+2,i=new o(this,e,t);if(n!=-1){do s=i.stepForward();while(s&&a.test(s.type));s=i.stepBackward()}else s=i.getCurrentToken();return u.end.row=i.getCurrentTokenRow(),u.end.column=i.getCurrentTokenColumn()+s.value.length-2,u}},this.foldAll=function(e,t,n){n==undefined&&(n=1e5);var r=this.foldWidgets;if(!r)return;t=t||this.getLength(),e=e||0;for(var i=e;i<t;i++){r[i]==null&&(r[i]=this.getFoldWidget(i));if(r[i]!=\"start\")continue;var s=this.getFoldWidgetRange(i);if(s&&s.isMultiLine()&&s.end.row<=t&&s.start.row>=e){i=s.end.row;try{var o=this.addFold(\"...\",s);o&&(o.collapseChildren=n)}catch(u){}}}},this.$foldStyles={manual:1,markbegin:1,markbeginend:1},this.$foldStyle=\"markbegin\",this.setFoldStyle=function(e){if(!this.$foldStyles[e])throw new Error(\"invalid fold style: \"+e+\"[\"+Object.keys(this.$foldStyles).join(\", \")+\"]\");if(this.$foldStyle==e)return;this.$foldStyle=e,e==\"manual\"&&this.unfold();var t=this.$foldMode;this.$setFolding(null),this.$setFolding(t)},this.$setFolding=function(e){if(this.$foldMode==e)return;this.$foldMode=e,this.off(\"change\",this.$updateFoldWidgets),this.off(\"tokenizerUpdate\",this.$tokenizerUpdateFoldWidgets),this._signal(\"changeAnnotation\");if(!e||this.$foldStyle==\"manual\"){this.foldWidgets=null;return}this.foldWidgets=[],this.getFoldWidget=e.getFoldWidget.bind(e,this,this.$foldStyle),this.getFoldWidgetRange=e.getFoldWidgetRange.bind(e,this,this.$foldStyle),this.$updateFoldWidgets=this.updateFoldWidgets.bind(this),this.$tokenizerUpdateFoldWidgets=this.tokenizerUpdateFoldWidgets.bind(this),this.on(\"change\",this.$updateFoldWidgets),this.on(\"tokenizerUpdate\",this.$tokenizerUpdateFoldWidgets)},this.getParentFoldRangeData=function(e,t){var n=this.foldWidgets;if(!n||t&&n[e])return{};var r=e-1,i;while(r>=0){var s=n[r];s==null&&(s=n[r]=this.getFoldWidget(r));if(s==\"start\"){var o=this.getFoldWidgetRange(r);i||(i=o);if(o&&o.end.row>=e)break}r--}return{range:r!==-1&&o,firstRange:i}},this.onFoldWidgetClick=function(e,t){t=t.domEvent;var n={children:t.shiftKey,all:t.ctrlKey||t.metaKey,siblings:t.altKey},r=this.$toggleFoldWidget(e,n);if(!r){var i=t.target||t.srcElement;i&&/ace_fold-widget/.test(i.className)&&(i.className+=\" ace_invalid\")}},this.$toggleFoldWidget=function(e,t){if(!this.getFoldWidget)return;var n=this.getFoldWidget(e),r=this.getLine(e),i=n===\"end\"?-1:1,s=this.getFoldAt(e,i===-1?0:r.length,i);if(s){t.children||t.all?this.removeFold(s):this.expandFold(s);return}var o=this.getFoldWidgetRange(e,!0);if(o&&!o.isMultiLine()){s=this.getFoldAt(o.start.row,o.start.column,1);if(s&&o.isEqual(s.range)){this.removeFold(s);return}}if(t.siblings){var u=this.getParentFoldRangeData(e);if(u.range)var a=u.range.start.row+1,f=u.range.end.row;this.foldAll(a,f,t.all?1e4:0)}else t.children?(f=o?o.end.row:this.getLength(),this.foldAll(e+1,f,t.all?1e4:0)):o&&(t.all&&(o.collapseChildren=1e4),this.addFold(\"...\",o));return o},this.toggleFoldWidget=function(e){var t=this.selection.getCursor().row;t=this.getRowFoldStart(t);var n=this.$toggleFoldWidget(t,{});if(n)return;var r=this.getParentFoldRangeData(t,!0);n=r.range||r.firstRange;if(n){t=n.start.row;var i=this.getFoldAt(t,this.getLine(t).length,1);i?this.removeFold(i):this.addFold(\"...\",n)}},this.updateFoldWidgets=function(e){var t=e.start.row,n=e.end.row-t;if(n===0)this.foldWidgets[t]=null;else if(e.action==\"remove\")this.foldWidgets.splice(t,n+1,null);else{var r=Array(n+1);r.unshift(t,1),this.foldWidgets.splice.apply(this.foldWidgets,r)}},this.tokenizerUpdateFoldWidgets=function(e){var t=e.data;t.first!=t.last&&this.foldWidgets.length>t.first&&this.foldWidgets.splice(t.first,this.foldWidgets.length)}}var r=e(\"../range\").Range,i=e(\"./fold_line\").FoldLine,s=e(\"./fold\").Fold,o=e(\"../token_iterator\").TokenIterator;t.Folding=u}),ace.define(\"ace/edit_session/bracket_match\",[\"require\",\"exports\",\"module\",\"ace/token_iterator\",\"ace/range\"],function(e,t,n){\"use strict\";function s(){this.findMatchingBracket=function(e,t){if(e.column==0)return null;var n=t||this.getLine(e.row).charAt(e.column-1);if(n==\"\")return null;var r=n.match(/([\\(\\[\\{])|([\\)\\]\\}])/);return r?r[1]?this.$findClosingBracket(r[1],e):this.$findOpeningBracket(r[2],e):null},this.getBracketRange=function(e){var t=this.getLine(e.row),n=!0,r,s=t.charAt(e.column-1),o=s&&s.match(/([\\(\\[\\{])|([\\)\\]\\}])/);o||(s=t.charAt(e.column),e={row:e.row,column:e.column+1},o=s&&s.match(/([\\(\\[\\{])|([\\)\\]\\}])/),n=!1);if(!o)return null;if(o[1]){var u=this.$findClosingBracket(o[1],e);if(!u)return null;r=i.fromPoints(e,u),n||(r.end.column++,r.start.column--),r.cursor=r.end}else{var u=this.$findOpeningBracket(o[2],e);if(!u)return null;r=i.fromPoints(u,e),n||(r.start.column++,r.end.column--),r.cursor=r.start}return r},this.$brackets={\")\":\"(\",\"(\":\")\",\"]\":\"[\",\"[\":\"]\",\"{\":\"}\",\"}\":\"{\"},this.$findOpeningBracket=function(e,t,n){var i=this.$brackets[e],s=1,o=new r(this,t.row,t.column),u=o.getCurrentToken();u||(u=o.stepForward());if(!u)return;n||(n=new RegExp(\"(\\\\.?\"+u.type.replace(\".\",\"\\\\.\").replace(\"rparen\",\".paren\").replace(/\\b(?:end)\\b/,\"(?:start|begin|end)\")+\")+\"));var a=t.column-o.getCurrentTokenColumn()-2,f=u.value;for(;;){while(a>=0){var l=f.charAt(a);if(l==i){s-=1;if(s==0)return{row:o.getCurrentTokenRow(),column:a+o.getCurrentTokenColumn()}}else l==e&&(s+=1);a-=1}do u=o.stepBackward();while(u&&!n.test(u.type));if(u==null)break;f=u.value,a=f.length-1}return null},this.$findClosingBracket=function(e,t,n){var i=this.$brackets[e],s=1,o=new r(this,t.row,t.column),u=o.getCurrentToken();u||(u=o.stepForward());if(!u)return;n||(n=new RegExp(\"(\\\\.?\"+u.type.replace(\".\",\"\\\\.\").replace(\"lparen\",\".paren\").replace(/\\b(?:start|begin)\\b/,\"(?:start|begin|end)\")+\")+\"));var a=t.column-o.getCurrentTokenColumn();for(;;){var f=u.value,l=f.length;while(a<l){var c=f.charAt(a);if(c==i){s-=1;if(s==0)return{row:o.getCurrentTokenRow(),column:a+o.getCurrentTokenColumn()}}else c==e&&(s+=1);a+=1}do u=o.stepForward();while(u&&!n.test(u.type));if(u==null)break;a=0}return null}}var r=e(\"../token_iterator\").TokenIterator,i=e(\"../range\").Range;t.BracketMatch=s}),ace.define(\"ace/edit_session\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/lang\",\"ace/config\",\"ace/lib/event_emitter\",\"ace/selection\",\"ace/mode/text\",\"ace/range\",\"ace/document\",\"ace/background_tokenizer\",\"ace/search_highlight\",\"ace/edit_session/folding\",\"ace/edit_session/bracket_match\"],function(e,t,n){\"use strict\";var r=e(\"./lib/oop\"),i=e(\"./lib/lang\"),s=e(\"./config\"),o=e(\"./lib/event_emitter\").EventEmitter,u=e(\"./selection\").Selection,a=e(\"./mode/text\").Mode,f=e(\"./range\").Range,l=e(\"./document\").Document,c=e(\"./background_tokenizer\").BackgroundTokenizer,h=e(\"./search_highlight\").SearchHighlight,p=function(e,t){this.$breakpoints=[],this.$decorations=[],this.$frontMarkers={},this.$backMarkers={},this.$markerId=1,this.$undoSelect=!0,this.$foldData=[],this.$foldData.toString=function(){return this.join(\"\\n\")},this.on(\"changeFold\",this.onChangeFold.bind(this)),this.$onChange=this.onChange.bind(this);if(typeof e!=\"object\"||!e.getLine)e=new l(e);this.setDocument(e),this.selection=new u(this),s.resetOptions(this),this.setMode(t),s._signal(\"session\",this)};(function(){function m(e){return e<4352?!1:e>=4352&&e<=4447||e>=4515&&e<=4519||e>=4602&&e<=4607||e>=9001&&e<=9002||e>=11904&&e<=11929||e>=11931&&e<=12019||e>=12032&&e<=12245||e>=12272&&e<=12283||e>=12288&&e<=12350||e>=12353&&e<=12438||e>=12441&&e<=12543||e>=12549&&e<=12589||e>=12593&&e<=12686||e>=12688&&e<=12730||e>=12736&&e<=12771||e>=12784&&e<=12830||e>=12832&&e<=12871||e>=12880&&e<=13054||e>=13056&&e<=19903||e>=19968&&e<=42124||e>=42128&&e<=42182||e>=43360&&e<=43388||e>=44032&&e<=55203||e>=55216&&e<=55238||e>=55243&&e<=55291||e>=63744&&e<=64255||e>=65040&&e<=65049||e>=65072&&e<=65106||e>=65108&&e<=65126||e>=65128&&e<=65131||e>=65281&&e<=65376||e>=65504&&e<=65510}r.implement(this,o),this.setDocument=function(e){this.doc&&this.doc.removeListener(\"change\",this.$onChange),this.doc=e,e.on(\"change\",this.$onChange),this.bgTokenizer&&this.bgTokenizer.setDocument(this.getDocument()),this.resetCaches()},this.getDocument=function(){return this.doc},this.$resetRowCache=function(e){if(!e){this.$docRowCache=[],this.$screenRowCache=[];return}var t=this.$docRowCache.length,n=this.$getRowCacheIndex(this.$docRowCache,e)+1;t>n&&(this.$docRowCache.splice(n,t),this.$screenRowCache.splice(n,t))},this.$getRowCacheIndex=function(e,t){var n=0,r=e.length-1;while(n<=r){var i=n+r>>1,s=e[i];if(t>s)n=i+1;else{if(!(t<s))return i;r=i-1}}return n-1},this.resetCaches=function(){this.$modified=!0,this.$wrapData=[],this.$rowLengthCache=[],this.$resetRowCache(0),this.bgTokenizer&&this.bgTokenizer.start(0)},this.onChangeFold=function(e){var t=e.data;this.$resetRowCache(t.start.row)},this.onChange=function(e){this.$modified=!0,this.$resetRowCache(e.start.row);var t=this.$updateInternalDataOnChange(e);!this.$fromUndo&&this.$undoManager&&!e.ignore&&(this.$deltasDoc.push(e),t&&t.length!=0&&this.$deltasFold.push({action:\"removeFolds\",folds:t}),this.$informUndoManager.schedule()),this.bgTokenizer&&this.bgTokenizer.$updateOnChange(e),this._signal(\"change\",e)},this.setValue=function(e){this.doc.setValue(e),this.selection.moveTo(0,0),this.$resetRowCache(0),this.$deltas=[],this.$deltasDoc=[],this.$deltasFold=[],this.setUndoManager(this.$undoManager),this.getUndoManager().reset()},this.getValue=this.toString=function(){return this.doc.getValue()},this.getSelection=function(){return this.selection},this.getState=function(e){return this.bgTokenizer.getState(e)},this.getTokens=function(e){return this.bgTokenizer.getTokens(e)},this.getTokenAt=function(e,t){var n=this.bgTokenizer.getTokens(e),r,i=0;if(t==null)s=n.length-1,i=this.getLine(e).length;else for(var s=0;s<n.length;s++){i+=n[s].value.length;if(i>=t)break}return r=n[s],r?(r.index=s,r.start=i-r.value.length,r):null},this.setUndoManager=function(e){this.$undoManager=e,this.$deltas=[],this.$deltasDoc=[],this.$deltasFold=[],this.$informUndoManager&&this.$informUndoManager.cancel();if(e){var t=this;this.$syncInformUndoManager=function(){t.$informUndoManager.cancel(),t.$deltasFold.length&&(t.$deltas.push({group:\"fold\",deltas:t.$deltasFold}),t.$deltasFold=[]),t.$deltasDoc.length&&(t.$deltas.push({group:\"doc\",deltas:t.$deltasDoc}),t.$deltasDoc=[]),t.$deltas.length>0&&e.execute({action:\"aceupdate\",args:[t.$deltas,t],merge:t.mergeUndoDeltas}),t.mergeUndoDeltas=!1,t.$deltas=[]},this.$informUndoManager=i.delayedCall(this.$syncInformUndoManager)}},this.markUndoGroup=function(){this.$syncInformUndoManager&&this.$syncInformUndoManager()},this.$defaultUndoManager={undo:function(){},redo:function(){},reset:function(){}},this.getUndoManager=function(){return this.$undoManager||this.$defaultUndoManager},this.getTabString=function(){return this.getUseSoftTabs()?i.stringRepeat(\" \",this.getTabSize()):\"\t\"},this.setUseSoftTabs=function(e){this.setOption(\"useSoftTabs\",e)},this.getUseSoftTabs=function(){return this.$useSoftTabs&&!this.$mode.$indentWithTabs},this.setTabSize=function(e){this.setOption(\"tabSize\",e)},this.getTabSize=function(){return this.$tabSize},this.isTabStop=function(e){return this.$useSoftTabs&&e.column%this.$tabSize===0},this.$overwrite=!1,this.setOverwrite=function(e){this.setOption(\"overwrite\",e)},this.getOverwrite=function(){return this.$overwrite},this.toggleOverwrite=function(){this.setOverwrite(!this.$overwrite)},this.addGutterDecoration=function(e,t){this.$decorations[e]||(this.$decorations[e]=\"\"),this.$decorations[e]+=\" \"+t,this._signal(\"changeBreakpoint\",{})},this.removeGutterDecoration=function(e,t){this.$decorations[e]=(this.$decorations[e]||\"\").replace(\" \"+t,\"\"),this._signal(\"changeBreakpoint\",{})},this.getBreakpoints=function(){return this.$breakpoints},this.setBreakpoints=function(e){this.$breakpoints=[];for(var t=0;t<e.length;t++)this.$breakpoints[e[t]]=\"ace_breakpoint\";this._signal(\"changeBreakpoint\",{})},this.clearBreakpoints=function(){this.$breakpoints=[],this._signal(\"changeBreakpoint\",{})},this.setBreakpoint=function(e,t){t===undefined&&(t=\"ace_breakpoint\"),t?this.$breakpoints[e]=t:delete this.$breakpoints[e],this._signal(\"changeBreakpoint\",{})},this.clearBreakpoint=function(e){delete this.$breakpoints[e],this._signal(\"changeBreakpoint\",{})},this.addMarker=function(e,t,n,r){var i=this.$markerId++,s={range:e,type:n||\"line\",renderer:typeof n==\"function\"?n:null,clazz:t,inFront:!!r,id:i};return r?(this.$frontMarkers[i]=s,this._signal(\"changeFrontMarker\")):(this.$backMarkers[i]=s,this._signal(\"changeBackMarker\")),i},this.addDynamicMarker=function(e,t){if(!e.update)return;var n=this.$markerId++;return e.id=n,e.inFront=!!t,t?(this.$frontMarkers[n]=e,this._signal(\"changeFrontMarker\")):(this.$backMarkers[n]=e,this._signal(\"changeBackMarker\")),e},this.removeMarker=function(e){var t=this.$frontMarkers[e]||this.$backMarkers[e];if(!t)return;var n=t.inFront?this.$frontMarkers:this.$backMarkers;t&&(delete n[e],this._signal(t.inFront?\"changeFrontMarker\":\"changeBackMarker\"))},this.getMarkers=function(e){return e?this.$frontMarkers:this.$backMarkers},this.highlight=function(e){if(!this.$searchHighlight){var t=new h(null,\"ace_selected-word\",\"text\");this.$searchHighlight=this.addDynamicMarker(t)}this.$searchHighlight.setRegexp(e)},this.highlightLines=function(e,t,n,r){typeof t!=\"number\"&&(n=t,t=e),n||(n=\"ace_step\");var i=new f(e,0,t,Infinity);return i.id=this.addMarker(i,n,\"fullLine\",r),i},this.setAnnotations=function(e){this.$annotations=e,this._signal(\"changeAnnotation\",{})},this.getAnnotations=function(){return this.$annotations||[]},this.clearAnnotations=function(){this.setAnnotations([])},this.$detectNewLine=function(e){var t=e.match(/^.*?(\\r?\\n)/m);t?this.$autoNewLine=t[1]:this.$autoNewLine=\"\\n\"},this.getWordRange=function(e,t){var n=this.getLine(e),r=!1;t>0&&(r=!!n.charAt(t-1).match(this.tokenRe)),r||(r=!!n.charAt(t).match(this.tokenRe));if(r)var i=this.tokenRe;else if(/^\\s+$/.test(n.slice(t-1,t+1)))var i=/\\s/;else var i=this.nonTokenRe;var s=t;if(s>0){do s--;while(s>=0&&n.charAt(s).match(i));s++}var o=t;while(o<n.length&&n.charAt(o).match(i))o++;return new f(e,s,e,o)},this.getAWordRange=function(e,t){var n=this.getWordRange(e,t),r=this.getLine(n.end.row);while(r.charAt(n.end.column).match(/[ \\t]/))n.end.column+=1;return n},this.setNewLineMode=function(e){this.doc.setNewLineMode(e)},this.getNewLineMode=function(){return this.doc.getNewLineMode()},this.setUseWorker=function(e){this.setOption(\"useWorker\",e)},this.getUseWorker=function(){return this.$useWorker},this.onReloadTokenizer=function(e){var t=e.data;this.bgTokenizer.start(t.first),this._signal(\"tokenizerUpdate\",e)},this.$modes={},this.$mode=null,this.$modeId=null,this.setMode=function(e,t){if(e&&typeof e==\"object\"){if(e.getTokenizer)return this.$onChangeMode(e);var n=e,r=n.path}else r=e||\"ace/mode/text\";this.$modes[\"ace/mode/text\"]||(this.$modes[\"ace/mode/text\"]=new a);if(this.$modes[r]&&!n){this.$onChangeMode(this.$modes[r]),t&&t();return}this.$modeId=r,s.loadModule([\"mode\",r],function(e){if(this.$modeId!==r)return t&&t();this.$modes[r]&&!n?this.$onChangeMode(this.$modes[r]):e&&e.Mode&&(e=new e.Mode(n),n||(this.$modes[r]=e,e.$id=r),this.$onChangeMode(e)),t&&t()}.bind(this)),this.$mode||this.$onChangeMode(this.$modes[\"ace/mode/text\"],!0)},this.$onChangeMode=function(e,t){t||(this.$modeId=e.$id);if(this.$mode===e)return;this.$mode=e,this.$stopWorker(),this.$useWorker&&this.$startWorker();var n=e.getTokenizer();if(n.addEventListener!==undefined){var r=this.onReloadTokenizer.bind(this);n.addEventListener(\"update\",r)}if(!this.bgTokenizer){this.bgTokenizer=new c(n);var i=this;this.bgTokenizer.addEventListener(\"update\",function(e){i._signal(\"tokenizerUpdate\",e)})}else this.bgTokenizer.setTokenizer(n);this.bgTokenizer.setDocument(this.getDocument()),this.tokenRe=e.tokenRe,this.nonTokenRe=e.nonTokenRe,t||(e.attachToSession&&e.attachToSession(this),this.$options.wrapMethod.set.call(this,this.$wrapMethod),this.$setFolding(e.foldingRules),this.bgTokenizer.start(0),this._emit(\"changeMode\"))},this.$stopWorker=function(){this.$worker&&(this.$worker.terminate(),this.$worker=null)},this.$startWorker=function(){try{this.$worker=this.$mode.createWorker(this)}catch(e){s.warn(\"Could not load worker\",e),this.$worker=null}},this.getMode=function(){return this.$mode},this.$scrollTop=0,this.setScrollTop=function(e){if(this.$scrollTop===e||isNaN(e))return;this.$scrollTop=e,this._signal(\"changeScrollTop\",e)},this.getScrollTop=function(){return this.$scrollTop},this.$scrollLeft=0,this.setScrollLeft=function(e){if(this.$scrollLeft===e||isNaN(e))return;this.$scrollLeft=e,this._signal(\"changeScrollLeft\",e)},this.getScrollLeft=function(){return this.$scrollLeft},this.getScreenWidth=function(){return this.$computeWidth(),this.lineWidgets?Math.max(this.getLineWidgetMaxWidth(),this.screenWidth):this.screenWidth},this.getLineWidgetMaxWidth=function(){if(this.lineWidgetsWidth!=null)return this.lineWidgetsWidth;var e=0;return this.lineWidgets.forEach(function(t){t&&t.screenWidth>e&&(e=t.screenWidth)}),this.lineWidgetWidth=e},this.$computeWidth=function(e){if(this.$modified||e){this.$modified=!1;if(this.$useWrapMode)return this.screenWidth=this.$wrapLimit;var t=this.doc.getAllLines(),n=this.$rowLengthCache,r=0,i=0,s=this.$foldData[i],o=s?s.start.row:Infinity,u=t.length;for(var a=0;a<u;a++){if(a>o){a=s.end.row+1;if(a>=u)break;s=this.$foldData[i++],o=s?s.start.row:Infinity}n[a]==null&&(n[a]=this.$getStringScreenWidth(t[a])[0]),n[a]>r&&(r=n[a])}this.screenWidth=r}},this.getLine=function(e){return this.doc.getLine(e)},this.getLines=function(e,t){return this.doc.getLines(e,t)},this.getLength=function(){return this.doc.getLength()},this.getTextRange=function(e){return this.doc.getTextRange(e||this.selection.getRange())},this.insert=function(e,t){return this.doc.insert(e,t)},this.remove=function(e){return this.doc.remove(e)},this.removeFullLines=function(e,t){return this.doc.removeFullLines(e,t)},this.undoChanges=function(e,t){if(!e.length)return;this.$fromUndo=!0;var n=null;for(var r=e.length-1;r!=-1;r--){var i=e[r];i.group==\"doc\"?(this.doc.revertDeltas(i.deltas),n=this.$getUndoSelection(i.deltas,!0,n)):i.deltas.forEach(function(e){this.addFolds(e.folds)},this)}return this.$fromUndo=!1,n&&this.$undoSelect&&!t&&this.selection.setSelectionRange(n),n},this.redoChanges=function(e,t){if(!e.length)return;this.$fromUndo=!0;var n=null;for(var r=0;r<e.length;r++){var i=e[r];i.group==\"doc\"&&(this.doc.applyDeltas(i.deltas),n=this.$getUndoSelection(i.deltas,!1,n))}return this.$fromUndo=!1,n&&this.$undoSelect&&!t&&this.selection.setSelectionRange(n),n},this.setUndoSelect=function(e){this.$undoSelect=e},this.$getUndoSelection=function(e,t,n){function r(e){return t?e.action!==\"insert\":e.action===\"insert\"}var i=e[0],s,o,u=!1;r(i)?(s=f.fromPoints(i.start,i.end),u=!0):(s=f.fromPoints(i.start,i.start),u=!1);for(var a=1;a<e.length;a++)i=e[a],r(i)?(o=i.start,s.compare(o.row,o.column)==-1&&s.setStart(o),o=i.end,s.compare(o.row,o.column)==1&&s.setEnd(o),u=!0):(o=i.start,s.compare(o.row,o.column)==-1&&(s=f.fromPoints(i.start,i.start)),u=!1);if(n!=null){f.comparePoints(n.start,s.start)===0&&(n.start.column+=s.end.column-s.start.column,n.end.column+=s.end.column-s.start.column);var l=n.compareRange(s);l==1?s.setStart(n.start):l==-1&&s.setEnd(n.end)}return s},this.replace=function(e,t){return this.doc.replace(e,t)},this.moveText=function(e,t,n){var r=this.getTextRange(e),i=this.getFoldsInRange(e),s=f.fromPoints(t,t);if(!n){this.remove(e);var o=e.start.row-e.end.row,u=o?-e.end.column:e.start.column-e.end.column;u&&(s.start.row==e.end.row&&s.start.column>e.end.column&&(s.start.column+=u),s.end.row==e.end.row&&s.end.column>e.end.column&&(s.end.column+=u)),o&&s.start.row>=e.end.row&&(s.start.row+=o,s.end.row+=o)}s.end=this.insert(s.start,r);if(i.length){var a=e.start,l=s.start,o=l.row-a.row,u=l.column-a.column;this.addFolds(i.map(function(e){return e=e.clone(),e.start.row==a.row&&(e.start.column+=u),e.end.row==a.row&&(e.end.column+=u),e.start.row+=o,e.end.row+=o,e}))}return s},this.indentRows=function(e,t,n){n=n.replace(/\\t/g,this.getTabString());for(var r=e;r<=t;r++)this.doc.insertInLine({row:r,column:0},n)},this.outdentRows=function(e){var t=e.collapseRows(),n=new f(0,0,0,0),r=this.getTabSize();for(var i=t.start.row;i<=t.end.row;++i){var s=this.getLine(i);n.start.row=i,n.end.row=i;for(var o=0;o<r;++o)if(s.charAt(o)!=\" \")break;o<r&&s.charAt(o)==\"\t\"?(n.start.column=o,n.end.column=o+1):(n.start.column=0,n.end.column=o),this.remove(n)}},this.$moveLines=function(e,t,n){e=this.getRowFoldStart(e),t=this.getRowFoldEnd(t);if(n<0){var r=this.getRowFoldStart(e+n);if(r<0)return 0;var i=r-e}else if(n>0){var r=this.getRowFoldEnd(t+n);if(r>this.doc.getLength()-1)return 0;var i=r-t}else{e=this.$clipRowToDocument(e),t=this.$clipRowToDocument(t);var i=t-e+1}var s=new f(e,0,t,Number.MAX_VALUE),o=this.getFoldsInRange(s).map(function(e){return e=e.clone(),e.start.row+=i,e.end.row+=i,e}),u=n==0?this.doc.getLines(e,t):this.doc.removeFullLines(e,t);return this.doc.insertFullLines(e+i,u),o.length&&this.addFolds(o),i},this.moveLinesUp=function(e,t){return this.$moveLines(e,t,-1)},this.moveLinesDown=function(e,t){return this.$moveLines(e,t,1)},this.duplicateLines=function(e,t){return this.$moveLines(e,t,0)},this.$clipRowToDocument=function(e){return Math.max(0,Math.min(e,this.doc.getLength()-1))},this.$clipColumnToRow=function(e,t){return t<0?0:Math.min(this.doc.getLine(e).length,t)},this.$clipPositionToDocument=function(e,t){t=Math.max(0,t);if(e<0)e=0,t=0;else{var n=this.doc.getLength();e>=n?(e=n-1,t=this.doc.getLine(n-1).length):t=Math.min(this.doc.getLine(e).length,t)}return{row:e,column:t}},this.$clipRangeToDocument=function(e){e.start.row<0?(e.start.row=0,e.start.column=0):e.start.column=this.$clipColumnToRow(e.start.row,e.start.column);var t=this.doc.getLength()-1;return e.end.row>t?(e.end.row=t,e.end.column=this.doc.getLine(t).length):e.end.column=this.$clipColumnToRow(e.end.row,e.end.column),e},this.$wrapLimit=80,this.$useWrapMode=!1,this.$wrapLimitRange={min:null,max:null},this.setUseWrapMode=function(e){if(e!=this.$useWrapMode){this.$useWrapMode=e,this.$modified=!0,this.$resetRowCache(0);if(e){var t=this.getLength();this.$wrapData=Array(t),this.$updateWrapData(0,t-1)}this._signal(\"changeWrapMode\")}},this.getUseWrapMode=function(){return this.$useWrapMode},this.setWrapLimitRange=function(e,t){if(this.$wrapLimitRange.min!==e||this.$wrapLimitRange.max!==t)this.$wrapLimitRange={min:e,max:t},this.$modified=!0,this.$useWrapMode&&this._signal(\"changeWrapMode\")},this.adjustWrapLimit=function(e,t){var n=this.$wrapLimitRange;n.max<0&&(n={min:t,max:t});var r=this.$constrainWrapLimit(e,n.min,n.max);return r!=this.$wrapLimit&&r>1?(this.$wrapLimit=r,this.$modified=!0,this.$useWrapMode&&(this.$updateWrapData(0,this.getLength()-1),this.$resetRowCache(0),this._signal(\"changeWrapLimit\")),!0):!1},this.$constrainWrapLimit=function(e,t,n){return t&&(e=Math.max(t,e)),n&&(e=Math.min(n,e)),e},this.getWrapLimit=function(){return this.$wrapLimit},this.setWrapLimit=function(e){this.setWrapLimitRange(e,e)},this.getWrapLimitRange=function(){return{min:this.$wrapLimitRange.min,max:this.$wrapLimitRange.max}},this.$updateInternalDataOnChange=function(e){var t=this.$useWrapMode,n=e.action,r=e.start,i=e.end,s=r.row,o=i.row,u=o-s,a=null;this.$updating=!0;if(u!=0)if(n===\"remove\"){this[t?\"$wrapData\":\"$rowLengthCache\"].splice(s,u);var f=this.$foldData;a=this.getFoldsInRange(e),this.removeFolds(a);var l=this.getFoldLine(i.row),c=0;if(l){l.addRemoveChars(i.row,i.column,r.column-i.column),l.shiftRow(-u);var h=this.getFoldLine(s);h&&h!==l&&(h.merge(l),l=h),c=f.indexOf(l)+1}for(c;c<f.length;c++){var l=f[c];l.start.row>=i.row&&l.shiftRow(-u)}o=s}else{var p=Array(u);p.unshift(s,0);var d=t?this.$wrapData:this.$rowLengthCache;d.splice.apply(d,p);var f=this.$foldData,l=this.getFoldLine(s),c=0;if(l){var v=l.range.compareInside(r.row,r.column);v==0?(l=l.split(r.row,r.column),l&&(l.shiftRow(u),l.addRemoveChars(o,0,i.column-r.column))):v==-1&&(l.addRemoveChars(s,0,i.column-r.column),l.shiftRow(u)),c=f.indexOf(l)+1}for(c;c<f.length;c++){var l=f[c];l.start.row>=s&&l.shiftRow(u)}}else{u=Math.abs(e.start.column-e.end.column),n===\"remove\"&&(a=this.getFoldsInRange(e),this.removeFolds(a),u=-u);var l=this.getFoldLine(s);l&&l.addRemoveChars(s,r.column,u)}return t&&this.$wrapData.length!=this.doc.getLength()&&console.error(\"doc.getLength() and $wrapData.length have to be the same!\"),this.$updating=!1,t?this.$updateWrapData(s,o):this.$updateRowLengthCache(s,o),a},this.$updateRowLengthCache=function(e,t,n){this.$rowLengthCache[e]=null,this.$rowLengthCache[t]=null},this.$updateWrapData=function(e,t){var r=this.doc.getAllLines(),i=this.getTabSize(),s=this.$wrapData,o=this.$wrapLimit,a,f,l=e;t=Math.min(t,r.length-1);while(l<=t)f=this.getFoldLine(l,f),f?(a=[],f.walk(function(e,t,i,s){var o;if(e!=null){o=this.$getDisplayTokens(e,a.length),o[0]=n;for(var f=1;f<o.length;f++)o[f]=u}else o=this.$getDisplayTokens(r[t].substring(s,i),a.length);a=a.concat(o)}.bind(this),f.end.row,r[f.end.row].length+1),s[f.start.row]=this.$computeWrapSplits(a,o,i),l=f.end.row+1):(a=this.$getDisplayTokens(r[l]),s[l]=this.$computeWrapSplits(a,o,i),l++)};var e=1,t=2,n=3,u=4,l=9,p=10,d=11,v=12;this.$computeWrapSplits=function(e,r,i){function g(){var t=0;if(m===0)return t;if(h)for(var n=0;n<e.length;n++){var r=e[n];if(r==p)t+=1;else{if(r!=d){if(r==v)continue;break}t+=i}}return c&&h!==!1&&(t+=i),Math.min(t,m)}function y(t){var n=e.slice(a,t),r=n.length;n.join(\"\").replace(/12/g,function(){r-=1}).replace(/2/g,function(){r-=1}),s.length||(b=g(),s.indent=b),f+=r,s.push(f),a=t}if(e.length==0)return[];var s=[],o=e.length,a=0,f=0,c=this.$wrapAsCode,h=this.$indentedSoftWrap,m=r<=Math.max(2*i,8)||h===!1?0:Math.floor(r/2),b=0;while(o-a>r-b){var w=a+r-b;if(e[w-1]>=p&&e[w]>=p){y(w);continue}if(e[w]==n||e[w]==u){for(w;w!=a-1;w--)if(e[w]==n)break;if(w>a){y(w);continue}w=a+r;for(w;w<e.length;w++)if(e[w]!=u)break;if(w==e.length)break;y(w);continue}var E=Math.max(w-(r-(r>>2)),a-1);while(w>E&&e[w]<n)w--;if(c){while(w>E&&e[w]<n)w--;while(w>E&&e[w]==l)w--}else while(w>E&&e[w]<p)w--;if(w>E){y(++w);continue}w=a+r,e[w]==t&&w--,y(w-b)}return s},this.$getDisplayTokens=function(n,r){var i=[],s;r=r||0;for(var o=0;o<n.length;o++){var u=n.charCodeAt(o);if(u==9){s=this.getScreenTabSize(i.length+r),i.push(d);for(var a=1;a<s;a++)i.push(v)}else u==32?i.push(p):u>39&&u<48||u>57&&u<64?i.push(l):u>=4352&&m(u)?i.push(e,t):i.push(e)}return i},this.$getStringScreenWidth=function(e,t,n){if(t==0)return[0,0];t==null&&(t=Infinity),n=n||0;var r,i;for(i=0;i<e.length;i++){r=e.charCodeAt(i),r==9?n+=this.getScreenTabSize(n):r>=4352&&m(r)?n+=2:n+=1;if(n>t)break}return[n,i]},this.lineWidgets=null,this.getRowLength=function(e){if(this.lineWidgets)var t=this.lineWidgets[e]&&this.lineWidgets[e].rowCount||0;else t=0;return!this.$useWrapMode||!this.$wrapData[e]?1+t:this.$wrapData[e].length+1+t},this.getRowLineCount=function(e){return!this.$useWrapMode||!this.$wrapData[e]?1:this.$wrapData[e].length+1},this.getRowWrapIndent=function(e){if(this.$useWrapMode){var t=this.screenToDocumentPosition(e,Number.MAX_VALUE),n=this.$wrapData[t.row];return n.length&&n[0]<t.column?n.indent:0}return 0},this.getScreenLastRowColumn=function(e){var t=this.screenToDocumentPosition(e,Number.MAX_VALUE);return this.documentToScreenColumn(t.row,t.column)},this.getDocumentLastRowColumn=function(e,t){var n=this.documentToScreenRow(e,t);return this.getScreenLastRowColumn(n)},this.getDocumentLastRowColumnPosition=function(e,t){var n=this.documentToScreenRow(e,t);return this.screenToDocumentPosition(n,Number.MAX_VALUE/10)},this.getRowSplitData=function(e){return this.$useWrapMode?this.$wrapData[e]:undefined},this.getScreenTabSize=function(e){return this.$tabSize-e%this.$tabSize},this.screenToDocumentRow=function(e,t){return this.screenToDocumentPosition(e,t).row},this.screenToDocumentColumn=function(e,t){return this.screenToDocumentPosition(e,t).column},this.screenToDocumentPosition=function(e,t){if(e<0)return{row:0,column:0};var n,r=0,i=0,s,o=0,u=0,a=this.$screenRowCache,f=this.$getRowCacheIndex(a,e),l=a.length;if(l&&f>=0)var o=a[f],r=this.$docRowCache[f],c=e>a[l-1];else var c=!l;var h=this.getLength()-1,p=this.getNextFoldLine(r),d=p?p.start.row:Infinity;while(o<=e){u=this.getRowLength(r);if(o+u>e||r>=h)break;o+=u,r++,r>d&&(r=p.end.row+1,p=this.getNextFoldLine(r,p),d=p?p.start.row:Infinity),c&&(this.$docRowCache.push(r),this.$screenRowCache.push(o))}if(p&&p.start.row<=r)n=this.getFoldDisplayLine(p),r=p.start.row;else{if(o+u<=e||r>h)return{row:h,column:this.getLine(h).length};n=this.getLine(r),p=null}var v=0;if(this.$useWrapMode){var m=this.$wrapData[r];if(m){var g=Math.floor(e-o);s=m[g],g>0&&m.length&&(v=m.indent,i=m[g-1]||m[m.length-1],n=n.substring(i))}}return i+=this.$getStringScreenWidth(n,t-v)[1],this.$useWrapMode&&i>=s&&(i=s-1),p?p.idxToPosition(i):{row:r,column:i}},this.documentToScreenPosition=function(e,t){if(typeof t==\"undefined\")var n=this.$clipPositionToDocument(e.row,e.column);else n=this.$clipPositionToDocument(e,t);e=n.row,t=n.column;var r=0,i=null,s=null;s=this.getFoldAt(e,t,1),s&&(e=s.start.row,t=s.start.column);var o,u=0,a=this.$docRowCache,f=this.$getRowCacheIndex(a,e),l=a.length;if(l&&f>=0)var u=a[f],r=this.$screenRowCache[f],c=e>a[l-1];else var c=!l;var h=this.getNextFoldLine(u),p=h?h.start.row:Infinity;while(u<e){if(u>=p){o=h.end.row+1;if(o>e)break;h=this.getNextFoldLine(o,h),p=h?h.start.row:Infinity}else o=u+1;r+=this.getRowLength(u),u=o,c&&(this.$docRowCache.push(u),this.$screenRowCache.push(r))}var d=\"\";h&&u>=p?(d=this.getFoldDisplayLine(h,e,t),i=h.start.row):(d=this.getLine(e).substring(0,t),i=e);var v=0;if(this.$useWrapMode){var m=this.$wrapData[i];if(m){var g=0;while(d.length>=m[g])r++,g++;d=d.substring(m[g-1]||0,d.length),v=g>0?m.indent:0}}return{row:r,column:v+this.$getStringScreenWidth(d)[0]}},this.documentToScreenColumn=function(e,t){return this.documentToScreenPosition(e,t).column},this.documentToScreenRow=function(e,t){return this.documentToScreenPosition(e,t).row},this.getScreenLength=function(){var e=0,t=null;if(!this.$useWrapMode){e=this.getLength();var n=this.$foldData;for(var r=0;r<n.length;r++)t=n[r],e-=t.end.row-t.start.row}else{var i=this.$wrapData.length,s=0,r=0,t=this.$foldData[r++],o=t?t.start.row:Infinity;while(s<i){var u=this.$wrapData[s];e+=u?u.length+1:1,s++,s>o&&(s=t.end.row+1,t=this.$foldData[r++],o=t?t.start.row:Infinity)}}return this.lineWidgets&&(e+=this.$getWidgetScreenLength()),e},this.$setFontMetrics=function(e){if(!this.$enableVarChar)return;this.$getStringScreenWidth=function(t,n,r){if(n===0)return[0,0];n||(n=Infinity),r=r||0;var i,s;for(s=0;s<t.length;s++){i=t.charAt(s),i===\"\t\"?r+=this.getScreenTabSize(r):r+=e.getCharacterWidth(i);if(r>n)break}return[r,s]}},this.destroy=function(){this.bgTokenizer&&(this.bgTokenizer.setDocument(null),this.bgTokenizer=null),this.$stopWorker()}}).call(p.prototype),e(\"./edit_session/folding\").Folding.call(p.prototype),e(\"./edit_session/bracket_match\").BracketMatch.call(p.prototype),s.defineOptions(p.prototype,\"session\",{wrap:{set:function(e){!e||e==\"off\"?e=!1:e==\"free\"?e=!0:e==\"printMargin\"?e=-1:typeof e==\"string\"&&(e=parseInt(e,10)||!1);if(this.$wrap==e)return;this.$wrap=e;if(!e)this.setUseWrapMode(!1);else{var t=typeof e==\"number\"?e:null;this.setWrapLimitRange(t,t),this.setUseWrapMode(!0)}},get:function(){return this.getUseWrapMode()?this.$wrap==-1?\"printMargin\":this.getWrapLimitRange().min?this.$wrap:\"free\":\"off\"},handlesSet:!0},wrapMethod:{set:function(e){e=e==\"auto\"?this.$mode.type!=\"text\":e!=\"text\",e!=this.$wrapAsCode&&(this.$wrapAsCode=e,this.$useWrapMode&&(this.$modified=!0,this.$resetRowCache(0),this.$updateWrapData(0,this.getLength()-1)))},initialValue:\"auto\"},indentedSoftWrap:{initialValue:!0},firstLineNumber:{set:function(){this._signal(\"changeBreakpoint\")},initialValue:1},useWorker:{set:function(e){this.$useWorker=e,this.$stopWorker(),e&&this.$startWorker()},initialValue:!0},useSoftTabs:{initialValue:!0},tabSize:{set:function(e){if(isNaN(e)||this.$tabSize===e)return;this.$modified=!0,this.$rowLengthCache=[],this.$tabSize=e,this._signal(\"changeTabSize\")},initialValue:4,handlesSet:!0},overwrite:{set:function(e){this._signal(\"changeOverwrite\")},initialValue:!1},newLineMode:{set:function(e){this.doc.setNewLineMode(e)},get:function(){return this.doc.getNewLineMode()},handlesSet:!0},mode:{set:function(e){this.setMode(e)},get:function(){return this.$modeId}}}),t.EditSession=p}),ace.define(\"ace/search\",[\"require\",\"exports\",\"module\",\"ace/lib/lang\",\"ace/lib/oop\",\"ace/range\"],function(e,t,n){\"use strict\";var r=e(\"./lib/lang\"),i=e(\"./lib/oop\"),s=e(\"./range\").Range,o=function(){this.$options={}};(function(){this.set=function(e){return i.mixin(this.$options,e),this},this.getOptions=function(){return r.copyObject(this.$options)},this.setOptions=function(e){this.$options=e},this.find=function(e){var t=this.$options,n=this.$matchIterator(e,t);if(!n)return!1;var r=null;return n.forEach(function(e,n,i){if(!e.start){var o=e.offset+(i||0);r=new s(n,o,n,o+e.length);if(!e.length&&t.start&&t.start.start&&t.skipCurrent!=0&&r.isEqual(t.start))return r=null,!1}else r=e;return!0}),r},this.findAll=function(e){var t=this.$options;if(!t.needle)return[];this.$assembleRegExp(t);var n=t.range,i=n?e.getLines(n.start.row,n.end.row):e.doc.getAllLines(),o=[],u=t.re;if(t.$isMultiLine){var a=u.length,f=i.length-a,l;e:for(var c=u.offset||0;c<=f;c++){for(var h=0;h<a;h++)if(i[c+h].search(u[h])==-1)continue e;var p=i[c],d=i[c+a-1],v=p.length-p.match(u[0])[0].length,m=d.match(u[a-1])[0].length;if(l&&l.end.row===c&&l.end.column>v)continue;o.push(l=new s(c,v,c+a-1,m)),a>2&&(c=c+a-2)}}else for(var g=0;g<i.length;g++){var y=r.getMatchOffsets(i[g],u);for(var h=0;h<y.length;h++){var b=y[h];o.push(new s(g,b.offset,g,b.offset+b.length))}}if(n){var w=n.start.column,E=n.start.column,g=0,h=o.length-1;while(g<h&&o[g].start.column<w&&o[g].start.row==n.start.row)g++;while(g<h&&o[h].end.column>E&&o[h].end.row==n.end.row)h--;o=o.slice(g,h+1);for(g=0,h=o.length;g<h;g++)o[g].start.row+=n.start.row,o[g].end.row+=n.start.row}return o},this.replace=function(e,t){var n=this.$options,r=this.$assembleRegExp(n);if(n.$isMultiLine)return t;if(!r)return;var i=r.exec(e);if(!i||i[0].length!=e.length)return null;t=e.replace(r,t);if(n.preserveCase){t=t.split(\"\");for(var s=Math.min(e.length,e.length);s--;){var o=e[s];o&&o.toLowerCase()!=o?t[s]=t[s].toUpperCase():t[s]=t[s].toLowerCase()}t=t.join(\"\")}return t},this.$matchIterator=function(e,t){var n=this.$assembleRegExp(t);if(!n)return!1;var i;if(t.$isMultiLine)var o=n.length,u=function(t,r,u){var a=t.search(n[0]);if(a==-1)return;for(var f=1;f<o;f++){t=e.getLine(r+f);if(t.search(n[f])==-1)return}var l=t.match(n[o-1])[0].length,c=new s(r,a,r+o-1,l);n.offset==1?(c.start.row--,c.start.column=Number.MAX_VALUE):u&&(c.start.column+=u);if(i(c))return!0};else if(t.backwards)var u=function(e,t,s){var o=r.getMatchOffsets(e,n);for(var u=o.length-1;u>=0;u--)if(i(o[u],t,s))return!0};else var u=function(e,t,s){var o=r.getMatchOffsets(e,n);for(var u=0;u<o.length;u++)if(i(o[u],t,s))return!0};var a=this.$lineIterator(e,t);return{forEach:function(e){i=e,a.forEach(u)}}},this.$assembleRegExp=function(e,t){if(e.needle instanceof RegExp)return e.re=e.needle;var n=e.needle;if(!e.needle)return e.re=!1;e.regExp||(n=r.escapeRegExp(n)),e.wholeWord&&(n=\"\\\\b\"+n+\"\\\\b\");var i=e.caseSensitive?\"gm\":\"gmi\";e.$isMultiLine=!t&&/[\\n\\r]/.test(n);if(e.$isMultiLine)return e.re=this.$assembleMultilineRegExp(n,i);try{var s=new RegExp(n,i)}catch(o){s=!1}return e.re=s},this.$assembleMultilineRegExp=function(e,t){var n=e.replace(/\\r\\n|\\r|\\n/g,\"$\\n^\").split(\"\\n\"),r=[];for(var i=0;i<n.length;i++)try{r.push(new RegExp(n[i],t))}catch(s){return!1}return n[0]==\"\"?(r.shift(),r.offset=1):r.offset=0,r},this.$lineIterator=function(e,t){var n=t.backwards==1,r=t.skipCurrent!=0,i=t.range,s=t.start;s||(s=i?i[n?\"end\":\"start\"]:e.selection.getRange()),s.start&&(s=s[r!=n?\"end\":\"start\"]);var o=i?i.start.row:0,u=i?i.end.row:e.getLength()-1,a=n?function(n){var r=s.row,i=e.getLine(r).substring(0,s.column);if(n(i,r))return;for(r--;r>=o;r--)if(n(e.getLine(r),r))return;if(t.wrap==0)return;for(r=u,o=s.row;r>=o;r--)if(n(e.getLine(r),r))return}:function(n){var r=s.row,i=e.getLine(r).substr(s.column);if(n(i,r,s.column))return;for(r+=1;r<=u;r++)if(n(e.getLine(r),r))return;if(t.wrap==0)return;for(r=o,u=s.row;r<=u;r++)if(n(e.getLine(r),r))return};return{forEach:a}}}).call(o.prototype),t.Search=o}),ace.define(\"ace/keyboard/hash_handler\",[\"require\",\"exports\",\"module\",\"ace/lib/keys\",\"ace/lib/useragent\"],function(e,t,n){\"use strict\";function o(e,t){this.platform=t||(i.isMac?\"mac\":\"win\"),this.commands={},this.commandKeyBinding={},this.addCommands(e),this.$singleCommand=!0}function u(e,t){o.call(this,e,t),this.$singleCommand=!1}var r=e(\"../lib/keys\"),i=e(\"../lib/useragent\"),s=r.KEY_MODS;u.prototype=o.prototype,function(){function e(e){return typeof e==\"object\"&&e.bindKey&&e.bindKey.position||0}this.addCommand=function(e){this.commands[e.name]&&this.removeCommand(e),this.commands[e.name]=e,e.bindKey&&this._buildKeyHash(e)},this.removeCommand=function(e,t){var n=e&&(typeof e==\"string\"?e:e.name);e=this.commands[n],t||delete this.commands[n];var r=this.commandKeyBinding;for(var i in r){var s=r[i];if(s==e)delete r[i];else if(Array.isArray(s)){var o=s.indexOf(e);o!=-1&&(s.splice(o,1),s.length==1&&(r[i]=s[0]))}}},this.bindKey=function(e,t,n){typeof e==\"object\"&&e&&(n==undefined&&(n=e.position),e=e[this.platform]);if(!e)return;if(typeof t==\"function\")return this.addCommand({exec:t,bindKey:e,name:t.name||e});e.split(\"|\").forEach(function(e){var r=\"\";if(e.indexOf(\" \")!=-1){var i=e.split(/\\s+/);e=i.pop(),i.forEach(function(e){var t=this.parseKeys(e),n=s[t.hashId]+t.key;r+=(r?\" \":\"\")+n,this._addCommandToBinding(r,\"chainKeys\")},this),r+=\" \"}var o=this.parseKeys(e),u=s[o.hashId]+o.key;this._addCommandToBinding(r+u,t,n)},this)},this._addCommandToBinding=function(t,n,r){var i=this.commandKeyBinding,s;if(!n)delete i[t];else if(!i[t]||this.$singleCommand)i[t]=n;else{Array.isArray(i[t])?(s=i[t].indexOf(n))!=-1&&i[t].splice(s,1):i[t]=[i[t]],typeof r!=\"number\"&&(r||n.isDefault?r=-100:r=e(n));var o=i[t];for(s=0;s<o.length;s++){var u=o[s],a=e(u);if(a>r)break}o.splice(s,0,n)}},this.addCommands=function(e){e&&Object.keys(e).forEach(function(t){var n=e[t];if(!n)return;if(typeof n==\"string\")return this.bindKey(n,t);typeof n==\"function\"&&(n={exec:n});if(typeof n!=\"object\")return;n.name||(n.name=t),this.addCommand(n)},this)},this.removeCommands=function(e){Object.keys(e).forEach(function(t){this.removeCommand(e[t])},this)},this.bindKeys=function(e){Object.keys(e).forEach(function(t){this.bindKey(t,e[t])},this)},this._buildKeyHash=function(e){this.bindKey(e.bindKey,e)},this.parseKeys=function(e){var t=e.toLowerCase().split(/[\\-\\+]([\\-\\+])?/).filter(function(e){return e}),n=t.pop(),i=r[n];if(r.FUNCTION_KEYS[i])n=r.FUNCTION_KEYS[i].toLowerCase();else{if(!t.length)return{key:n,hashId:-1};if(t.length==1&&t[0]==\"shift\")return{key:n.toUpperCase(),hashId:-1}}var s=0;for(var o=t.length;o--;){var u=r.KEY_MODS[t[o]];if(u==null)return typeof console!=\"undefined\"&&console.error(\"invalid modifier \"+t[o]+\" in \"+e),!1;s|=u}return{key:n,hashId:s}},this.findKeyCommand=function(t,n){var r=s[t]+n;return this.commandKeyBinding[r]},this.handleKeyboard=function(e,t,n,r){if(r<0)return;var i=s[t]+n,o=this.commandKeyBinding[i];e.$keyChain&&(e.$keyChain+=\" \"+i,o=this.commandKeyBinding[e.$keyChain]||o);if(o)if(o==\"chainKeys\"||o[o.length-1]==\"chainKeys\")return e.$keyChain=e.$keyChain||i,{command:\"null\"};if(e.$keyChain)if(!!t&&t!=4||n.length!=1){if(t==-1||r>0)e.$keyChain=\"\"}else e.$keyChain=e.$keyChain.slice(0,-i.length-1);return{command:o}},this.getStatusText=function(e,t){return t.$keyChain||\"\"}}.call(o.prototype),t.HashHandler=o,t.MultiHashHandler=u}),ace.define(\"ace/commands/command_manager\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/keyboard/hash_handler\",\"ace/lib/event_emitter\"],function(e,t,n){\"use strict\";var r=e(\"../lib/oop\"),i=e(\"../keyboard/hash_handler\").MultiHashHandler,s=e(\"../lib/event_emitter\").EventEmitter,o=function(e,t){i.call(this,t,e),this.byName=this.commands,this.setDefaultHandler(\"exec\",function(e){return e.command.exec(e.editor,e.args||{})})};r.inherits(o,i),function(){r.implement(this,s),this.exec=function(e,t,n){if(Array.isArray(e)){for(var r=e.length;r--;)if(this.exec(e[r],t,n))return!0;return!1}typeof e==\"string\"&&(e=this.commands[e]);if(!e)return!1;if(t&&t.$readOnly&&!e.readOnly)return!1;var i={editor:t,command:e,args:n};return i.returnValue=this._emit(\"exec\",i),this._signal(\"afterExec\",i),i.returnValue===!1?!1:!0},this.toggleRecording=function(e){if(this.$inReplay)return;return e&&e._emit(\"changeStatus\"),this.recording?(this.macro.pop(),this.removeEventListener(\"exec\",this.$addCommandToMacro),this.macro.length||(this.macro=this.oldMacro),this.recording=!1):(this.$addCommandToMacro||(this.$addCommandToMacro=function(e){this.macro.push([e.command,e.args])}.bind(this)),this.oldMacro=this.macro,this.macro=[],this.on(\"exec\",this.$addCommandToMacro),this.recording=!0)},this.replay=function(e){if(this.$inReplay||!this.macro)return;if(this.recording)return this.toggleRecording(e);try{this.$inReplay=!0,this.macro.forEach(function(t){typeof t==\"string\"?this.exec(t,e):this.exec(t[0],e,t[1])},this)}finally{this.$inReplay=!1}},this.trimMacro=function(e){return e.map(function(e){return typeof e[0]!=\"string\"&&(e[0]=e[0].name),e[1]||(e=e[0]),e})}}.call(o.prototype),t.CommandManager=o}),ace.define(\"ace/commands/default_commands\",[\"require\",\"exports\",\"module\",\"ace/lib/lang\",\"ace/config\",\"ace/range\"],function(e,t,n){\"use strict\";function o(e,t){return{win:e,mac:t}}var r=e(\"../lib/lang\"),i=e(\"../config\"),s=e(\"../range\").Range;t.commands=[{name:\"showSettingsMenu\",bindKey:o(\"Ctrl-,\",\"Command-,\"),exec:function(e){i.loadModule(\"ace/ext/settings_menu\",function(t){t.init(e),e.showSettingsMenu()})},readOnly:!0},{name:\"goToNextError\",bindKey:o(\"Alt-E\",\"Ctrl-E\"),exec:function(e){i.loadModule(\"ace/ext/error_marker\",function(t){t.showErrorMarker(e,1)})},scrollIntoView:\"animate\",readOnly:!0},{name:\"goToPreviousError\",bindKey:o(\"Alt-Shift-E\",\"Ctrl-Shift-E\"),exec:function(e){i.loadModule(\"ace/ext/error_marker\",function(t){t.showErrorMarker(e,-1)})},scrollIntoView:\"animate\",readOnly:!0},{name:\"selectall\",bindKey:o(\"Ctrl-A\",\"Command-A\"),exec:function(e){e.selectAll()},readOnly:!0},{name:\"centerselection\",bindKey:o(null,\"Ctrl-L\"),exec:function(e){e.centerSelection()},readOnly:!0},{name:\"gotoline\",bindKey:o(\"Ctrl-L\",\"Command-L\"),exec:function(e){var t=parseInt(prompt(\"Enter line number:\"),10);isNaN(t)||e.gotoLine(t)},readOnly:!0},{name:\"fold\",bindKey:o(\"Alt-L|Ctrl-F1\",\"Command-Alt-L|Command-F1\"),exec:function(e){e.session.toggleFold(!1)},multiSelectAction:\"forEach\",scrollIntoView:\"center\",readOnly:!0},{name:\"unfold\",bindKey:o(\"Alt-Shift-L|Ctrl-Shift-F1\",\"Command-Alt-Shift-L|Command-Shift-F1\"),exec:function(e){e.session.toggleFold(!0)},multiSelectAction:\"forEach\",scrollIntoView:\"center\",readOnly:!0},{name:\"toggleFoldWidget\",bindKey:o(\"F2\",\"F2\"),exec:function(e){e.session.toggleFoldWidget()},multiSelectAction:\"forEach\",scrollIntoView:\"center\",readOnly:!0},{name:\"toggleParentFoldWidget\",bindKey:o(\"Alt-F2\",\"Alt-F2\"),exec:function(e){e.session.toggleFoldWidget(!0)},multiSelectAction:\"forEach\",scrollIntoView:\"center\",readOnly:!0},{name:\"foldall\",bindKey:o(null,\"Ctrl-Command-Option-0\"),exec:function(e){e.session.foldAll()},scrollIntoView:\"center\",readOnly:!0},{name:\"foldOther\",bindKey:o(\"Alt-0\",\"Command-Option-0\"),exec:function(e){e.session.foldAll(),e.session.unfold(e.selection.getAllRanges())},scrollIntoView:\"center\",readOnly:!0},{name:\"unfoldall\",bindKey:o(\"Alt-Shift-0\",\"Command-Option-Shift-0\"),exec:function(e){e.session.unfold()},scrollIntoView:\"center\",readOnly:!0},{name:\"findnext\",bindKey:o(\"Ctrl-K\",\"Command-G\"),exec:function(e){e.findNext()},multiSelectAction:\"forEach\",scrollIntoView:\"center\",readOnly:!0},{name:\"findprevious\",bindKey:o(\"Ctrl-Shift-K\",\"Command-Shift-G\"),exec:function(e){e.findPrevious()},multiSelectAction:\"forEach\",scrollIntoView:\"center\",readOnly:!0},{name:\"selectOrFindNext\",bindKey:o(\"Alt-K\",\"Ctrl-G\"),exec:function(e){e.selection.isEmpty()?e.selection.selectWord():e.findNext()},readOnly:!0},{name:\"selectOrFindPrevious\",bindKey:o(\"Alt-Shift-K\",\"Ctrl-Shift-G\"),exec:function(e){e.selection.isEmpty()?e.selection.selectWord():e.findPrevious()},readOnly:!0},{name:\"find\",bindKey:o(\"Ctrl-F\",\"Command-F\"),exec:function(e){i.loadModule(\"ace/ext/searchbox\",function(t){t.Search(e)})},readOnly:!0},{name:\"overwrite\",bindKey:\"Insert\",exec:function(e){e.toggleOverwrite()},readOnly:!0},{name:\"selecttostart\",bindKey:o(\"Ctrl-Shift-Home\",\"Command-Shift-Up\"),exec:function(e){e.getSelection().selectFileStart()},multiSelectAction:\"forEach\",readOnly:!0,scrollIntoView:\"animate\",aceCommandGroup:\"fileJump\"},{name:\"gotostart\",bindKey:o(\"Ctrl-Home\",\"Command-Home|Command-Up\"),exec:function(e){e.navigateFileStart()},multiSelectAction:\"forEach\",readOnly:!0,scrollIntoView:\"animate\",aceCommandGroup:\"fileJump\"},{name:\"selectup\",bindKey:o(\"Shift-Up\",\"Shift-Up\"),exec:function(e){e.getSelection().selectUp()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"golineup\",bindKey:o(\"Up\",\"Up|Ctrl-P\"),exec:function(e,t){e.navigateUp(t.times)},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"selecttoend\",bindKey:o(\"Ctrl-Shift-End\",\"Command-Shift-Down\"),exec:function(e){e.getSelection().selectFileEnd()},multiSelectAction:\"forEach\",readOnly:!0,scrollIntoView:\"animate\",aceCommandGroup:\"fileJump\"},{name:\"gotoend\",bindKey:o(\"Ctrl-End\",\"Command-End|Command-Down\"),exec:function(e){e.navigateFileEnd()},multiSelectAction:\"forEach\",readOnly:!0,scrollIntoView:\"animate\",aceCommandGroup:\"fileJump\"},{name:\"selectdown\",bindKey:o(\"Shift-Down\",\"Shift-Down\"),exec:function(e){e.getSelection().selectDown()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"golinedown\",bindKey:o(\"Down\",\"Down|Ctrl-N\"),exec:function(e,t){e.navigateDown(t.times)},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"selectwordleft\",bindKey:o(\"Ctrl-Shift-Left\",\"Option-Shift-Left\"),exec:function(e){e.getSelection().selectWordLeft()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"gotowordleft\",bindKey:o(\"Ctrl-Left\",\"Option-Left\"),exec:function(e){e.navigateWordLeft()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"selecttolinestart\",bindKey:o(\"Alt-Shift-Left\",\"Command-Shift-Left\"),exec:function(e){e.getSelection().selectLineStart()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"gotolinestart\",bindKey:o(\"Alt-Left|Home\",\"Command-Left|Home|Ctrl-A\"),exec:function(e){e.navigateLineStart()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"selectleft\",bindKey:o(\"Shift-Left\",\"Shift-Left\"),exec:function(e){e.getSelection().selectLeft()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"gotoleft\",bindKey:o(\"Left\",\"Left|Ctrl-B\"),exec:function(e,t){e.navigateLeft(t.times)},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"selectwordright\",bindKey:o(\"Ctrl-Shift-Right\",\"Option-Shift-Right\"),exec:function(e){e.getSelection().selectWordRight()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"gotowordright\",bindKey:o(\"Ctrl-Right\",\"Option-Right\"),exec:function(e){e.navigateWordRight()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"selecttolineend\",bindKey:o(\"Alt-Shift-Right\",\"Command-Shift-Right\"),exec:function(e){e.getSelection().selectLineEnd()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"gotolineend\",bindKey:o(\"Alt-Right|End\",\"Command-Right|End|Ctrl-E\"),exec:function(e){e.navigateLineEnd()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"selectright\",bindKey:o(\"Shift-Right\",\"Shift-Right\"),exec:function(e){e.getSelection().selectRight()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"gotoright\",bindKey:o(\"Right\",\"Right|Ctrl-F\"),exec:function(e,t){e.navigateRight(t.times)},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"selectpagedown\",bindKey:\"Shift-PageDown\",exec:function(e){e.selectPageDown()},readOnly:!0},{name:\"pagedown\",bindKey:o(null,\"Option-PageDown\"),exec:function(e){e.scrollPageDown()},readOnly:!0},{name:\"gotopagedown\",bindKey:o(\"PageDown\",\"PageDown|Ctrl-V\"),exec:function(e){e.gotoPageDown()},readOnly:!0},{name:\"selectpageup\",bindKey:\"Shift-PageUp\",exec:function(e){e.selectPageUp()},readOnly:!0},{name:\"pageup\",bindKey:o(null,\"Option-PageUp\"),exec:function(e){e.scrollPageUp()},readOnly:!0},{name:\"gotopageup\",bindKey:\"PageUp\",exec:function(e){e.gotoPageUp()},readOnly:!0},{name:\"scrollup\",bindKey:o(\"Ctrl-Up\",null),exec:function(e){e.renderer.scrollBy(0,-2*e.renderer.layerConfig.lineHeight)},readOnly:!0},{name:\"scrolldown\",bindKey:o(\"Ctrl-Down\",null),exec:function(e){e.renderer.scrollBy(0,2*e.renderer.layerConfig.lineHeight)},readOnly:!0},{name:\"selectlinestart\",bindKey:\"Shift-Home\",exec:function(e){e.getSelection().selectLineStart()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"selectlineend\",bindKey:\"Shift-End\",exec:function(e){e.getSelection().selectLineEnd()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"togglerecording\",bindKey:o(\"Ctrl-Alt-E\",\"Command-Option-E\"),exec:function(e){e.commands.toggleRecording(e)},readOnly:!0},{name:\"replaymacro\",bindKey:o(\"Ctrl-Shift-E\",\"Command-Shift-E\"),exec:function(e){e.commands.replay(e)},readOnly:!0},{name:\"jumptomatching\",bindKey:o(\"Ctrl-P\",\"Ctrl-P\"),exec:function(e){e.jumpToMatching()},multiSelectAction:\"forEach\",scrollIntoView:\"animate\",readOnly:!0},{name:\"selecttomatching\",bindKey:o(\"Ctrl-Shift-P\",\"Ctrl-Shift-P\"),exec:function(e){e.jumpToMatching(!0)},multiSelectAction:\"forEach\",scrollIntoView:\"animate\",readOnly:!0},{name:\"expandToMatching\",bindKey:o(\"Ctrl-Shift-M\",\"Ctrl-Shift-M\"),exec:function(e){e.jumpToMatching(!0,!0)},multiSelectAction:\"forEach\",scrollIntoView:\"animate\",readOnly:!0},{name:\"passKeysToBrowser\",bindKey:o(null,null),exec:function(){},passEvent:!0,readOnly:!0},{name:\"copy\",exec:function(e){},readOnly:!0},{name:\"cut\",exec:function(e){var t=e.getSelectionRange();e._emit(\"cut\",t),e.selection.isEmpty()||(e.session.remove(t),e.clearSelection())},scrollIntoView:\"cursor\",multiSelectAction:\"forEach\"},{name:\"paste\",exec:function(e,t){e.$handlePaste(t)},scrollIntoView:\"cursor\"},{name:\"removeline\",bindKey:o(\"Ctrl-D\",\"Command-D\"),exec:function(e){e.removeLines()},scrollIntoView:\"cursor\",multiSelectAction:\"forEachLine\"},{name:\"duplicateSelection\",bindKey:o(\"Ctrl-Shift-D\",\"Command-Shift-D\"),exec:function(e){e.duplicateSelection()},scrollIntoView:\"cursor\",multiSelectAction:\"forEach\"},{name:\"sortlines\",bindKey:o(\"Ctrl-Alt-S\",\"Command-Alt-S\"),exec:function(e){e.sortLines()},scrollIntoView:\"selection\",multiSelectAction:\"forEachLine\"},{name:\"togglecomment\",bindKey:o(\"Ctrl-/\",\"Command-/\"),exec:function(e){e.toggleCommentLines()},multiSelectAction:\"forEachLine\",scrollIntoView:\"selectionPart\"},{name:\"toggleBlockComment\",bindKey:o(\"Ctrl-Shift-/\",\"Command-Shift-/\"),exec:function(e){e.toggleBlockComment()},multiSelectAction:\"forEach\",scrollIntoView:\"selectionPart\"},{name:\"modifyNumberUp\",bindKey:o(\"Ctrl-Shift-Up\",\"Alt-Shift-Up\"),exec:function(e){e.modifyNumber(1)},scrollIntoView:\"cursor\",multiSelectAction:\"forEach\"},{name:\"modifyNumberDown\",bindKey:o(\"Ctrl-Shift-Down\",\"Alt-Shift-Down\"),exec:function(e){e.modifyNumber(-1)},scrollIntoView:\"cursor\",multiSelectAction:\"forEach\"},{name:\"replace\",bindKey:o(\"Ctrl-H\",\"Command-Option-F\"),exec:function(e){i.loadModule(\"ace/ext/searchbox\",function(t){t.Search(e,!0)})}},{name:\"undo\",bindKey:o(\"Ctrl-Z\",\"Command-Z\"),exec:function(e){e.undo()}},{name:\"redo\",bindKey:o(\"Ctrl-Shift-Z|Ctrl-Y\",\"Command-Shift-Z|Command-Y\"),exec:function(e){e.redo()}},{name:\"copylinesup\",bindKey:o(\"Alt-Shift-Up\",\"Command-Option-Up\"),exec:function(e){e.copyLinesUp()},scrollIntoView:\"cursor\"},{name:\"movelinesup\",bindKey:o(\"Alt-Up\",\"Option-Up\"),exec:function(e){e.moveLinesUp()},scrollIntoView:\"cursor\"},{name:\"copylinesdown\",bindKey:o(\"Alt-Shift-Down\",\"Command-Option-Down\"),exec:function(e){e.copyLinesDown()},scrollIntoView:\"cursor\"},{name:\"movelinesdown\",bindKey:o(\"Alt-Down\",\"Option-Down\"),exec:function(e){e.moveLinesDown()},scrollIntoView:\"cursor\"},{name:\"del\",bindKey:o(\"Delete\",\"Delete|Ctrl-D|Shift-Delete\"),exec:function(e){e.remove(\"right\")},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"backspace\",bindKey:o(\"Shift-Backspace|Backspace\",\"Ctrl-Backspace|Shift-Backspace|Backspace|Ctrl-H\"),exec:function(e){e.remove(\"left\")},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"cut_or_delete\",bindKey:o(\"Shift-Delete\",null),exec:function(e){if(!e.selection.isEmpty())return!1;e.remove(\"left\")},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"removetolinestart\",bindKey:o(\"Alt-Backspace\",\"Command-Backspace\"),exec:function(e){e.removeToLineStart()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"removetolineend\",bindKey:o(\"Alt-Delete\",\"Ctrl-K\"),exec:function(e){e.removeToLineEnd()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"removewordleft\",bindKey:o(\"Ctrl-Backspace\",\"Alt-Backspace|Ctrl-Alt-Backspace\"),exec:function(e){e.removeWordLeft()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"removewordright\",bindKey:o(\"Ctrl-Delete\",\"Alt-Delete\"),exec:function(e){e.removeWordRight()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"outdent\",bindKey:o(\"Shift-Tab\",\"Shift-Tab\"),exec:function(e){e.blockOutdent()},multiSelectAction:\"forEach\",scrollIntoView:\"selectionPart\"},{name:\"indent\",bindKey:o(\"Tab\",\"Tab\"),exec:function(e){e.indent()},multiSelectAction:\"forEach\",scrollIntoView:\"selectionPart\"},{name:\"blockoutdent\",bindKey:o(\"Ctrl-[\",\"Ctrl-[\"),exec:function(e){e.blockOutdent()},multiSelectAction:\"forEachLine\",scrollIntoView:\"selectionPart\"},{name:\"blockindent\",bindKey:o(\"Ctrl-]\",\"Ctrl-]\"),exec:function(e){e.blockIndent()},multiSelectAction:\"forEachLine\",scrollIntoView:\"selectionPart\"},{name:\"insertstring\",exec:function(e,t){e.insert(t)},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"inserttext\",exec:function(e,t){e.insert(r.stringRepeat(t.text||\"\",t.times||1))},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"splitline\",bindKey:o(null,\"Ctrl-O\"),exec:function(e){e.splitLine()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"transposeletters\",bindKey:o(\"Ctrl-T\",\"Ctrl-T\"),exec:function(e){e.transposeLetters()},multiSelectAction:function(e){e.transposeSelections(1)},scrollIntoView:\"cursor\"},{name:\"touppercase\",bindKey:o(\"Ctrl-U\",\"Ctrl-U\"),exec:function(e){e.toUpperCase()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"tolowercase\",bindKey:o(\"Ctrl-Shift-U\",\"Ctrl-Shift-U\"),exec:function(e){e.toLowerCase()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"expandtoline\",bindKey:o(\"Ctrl-Shift-L\",\"Command-Shift-L\"),exec:function(e){var t=e.selection.getRange();t.start.column=t.end.column=0,t.end.row++,e.selection.setRange(t,!1)},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"joinlines\",bindKey:o(null,null),exec:function(e){var t=e.selection.isBackwards(),n=t?e.selection.getSelectionLead():e.selection.getSelectionAnchor(),i=t?e.selection.getSelectionAnchor():e.selection.getSelectionLead(),o=e.session.doc.getLine(n.row).length,u=e.session.doc.getTextRange(e.selection.getRange()),a=u.replace(/\\n\\s*/,\" \").length,f=e.session.doc.getLine(n.row);for(var l=n.row+1;l<=i.row+1;l++){var c=r.stringTrimLeft(r.stringTrimRight(e.session.doc.getLine(l)));c.length!==0&&(c=\" \"+c),f+=c}i.row+1<e.session.doc.getLength()-1&&(f+=e.session.doc.getNewLineCharacter()),e.clearSelection(),e.session.doc.replace(new s(n.row,0,i.row+2,0),f),a>0?(e.selection.moveCursorTo(n.row,n.column),e.selection.selectTo(n.row,n.column+a)):(o=e.session.doc.getLine(n.row).length>o?o+1:o,e.selection.moveCursorTo(n.row,o))},multiSelectAction:\"forEach\",readOnly:!0},{name:\"invertSelection\",bindKey:o(null,null),exec:function(e){var t=e.session.doc.getLength()-1,n=e.session.doc.getLine(t).length,r=e.selection.rangeList.ranges,i=[];r.length<1&&(r=[e.selection.getRange()]);for(var o=0;o<r.length;o++)o==r.length-1&&(r[o].end.row!==t||r[o].end.column!==n)&&i.push(new s(r[o].end.row,r[o].end.column,t,n)),o===0?(r[o].start.row!==0||r[o].start.column!==0)&&i.push(new s(0,0,r[o].start.row,r[o].start.column)):i.push(new s(r[o-1].end.row,r[o-1].end.column,r[o].start.row,r[o].start.column));e.exitMultiSelectMode(),e.clearSelection();for(var o=0;o<i.length;o++)e.selection.addRange(i[o],!1)},readOnly:!0,scrollIntoView:\"none\"}]}),ace.define(\"ace/editor\",[\"require\",\"exports\",\"module\",\"ace/lib/fixoldbrowsers\",\"ace/lib/oop\",\"ace/lib/dom\",\"ace/lib/lang\",\"ace/lib/useragent\",\"ace/keyboard/textinput\",\"ace/mouse/mouse_handler\",\"ace/mouse/fold_handler\",\"ace/keyboard/keybinding\",\"ace/edit_session\",\"ace/search\",\"ace/range\",\"ace/lib/event_emitter\",\"ace/commands/command_manager\",\"ace/commands/default_commands\",\"ace/config\",\"ace/token_iterator\"],function(e,t,n){\"use strict\";e(\"./lib/fixoldbrowsers\");var r=e(\"./lib/oop\"),i=e(\"./lib/dom\"),s=e(\"./lib/lang\"),o=e(\"./lib/useragent\"),u=e(\"./keyboard/textinput\").TextInput,a=e(\"./mouse/mouse_handler\").MouseHandler,f=e(\"./mouse/fold_handler\").FoldHandler,l=e(\"./keyboard/keybinding\").KeyBinding,c=e(\"./edit_session\").EditSession,h=e(\"./search\").Search,p=e(\"./range\").Range,d=e(\"./lib/event_emitter\").EventEmitter,v=e(\"./commands/command_manager\").CommandManager,m=e(\"./commands/default_commands\").commands,g=e(\"./config\"),y=e(\"./token_iterator\").TokenIterator,b=function(e,t){var n=e.getContainerElement();this.container=n,this.renderer=e,this.commands=new v(o.isMac?\"mac\":\"win\",m),this.textInput=new u(e.getTextAreaContainer(),this),this.renderer.textarea=this.textInput.getElement(),this.keyBinding=new l(this),this.$mouseHandler=new a(this),new f(this),this.$blockScrolling=0,this.$search=(new h).set({wrap:!0}),this.$historyTracker=this.$historyTracker.bind(this),this.commands.on(\"exec\",this.$historyTracker),this.$initOperationListeners(),this._$emitInputEvent=s.delayedCall(function(){this._signal(\"input\",{}),this.session&&this.session.bgTokenizer&&this.session.bgTokenizer.scheduleStart()}.bind(this)),this.on(\"change\",function(e,t){t._$emitInputEvent.schedule(31)}),this.setSession(t||new c(\"\")),g.resetOptions(this),g._signal(\"editor\",this)};(function(){r.implement(this,d),this.$initOperationListeners=function(){function e(e){return e[e.length-1]}this.selections=[],this.commands.on(\"exec\",this.startOperation.bind(this),!0),this.commands.on(\"afterExec\",this.endOperation.bind(this),!0),this.$opResetTimer=s.delayedCall(this.endOperation.bind(this)),this.on(\"change\",function(){this.curOp||this.startOperation(),this.curOp.docChanged=!0}.bind(this),!0),this.on(\"changeSelection\",function(){this.curOp||this.startOperation(),this.curOp.selectionChanged=!0}.bind(this),!0)},this.curOp=null,this.prevOp={},this.startOperation=function(e){if(this.curOp){if(!e||this.curOp.command)return;this.prevOp=this.curOp}e||(this.previousCommand=null,e={}),this.$opResetTimer.schedule(),this.curOp={command:e.command||{},args:e.args,scrollTop:this.renderer.scrollTop},this.curOp.command.name&&this.curOp.command.scrollIntoView!==undefined&&this.$blockScrolling++},this.endOperation=function(e){if(this.curOp){if(e&&e.returnValue===!1)return this.curOp=null;this._signal(\"beforeEndOperation\");var t=this.curOp.command;t.name&&this.$blockScrolling>0&&this.$blockScrolling--;var n=t&&t.scrollIntoView;if(n){switch(n){case\"center-animate\":n=\"animate\";case\"center\":this.renderer.scrollCursorIntoView(null,.5);break;case\"animate\":case\"cursor\":this.renderer.scrollCursorIntoView();break;case\"selectionPart\":var r=this.selection.getRange(),i=this.renderer.layerConfig;(r.start.row>=i.lastRow||r.end.row<=i.firstRow)&&this.renderer.scrollSelectionIntoView(this.selection.anchor,this.selection.lead);break;default:}n==\"animate\"&&this.renderer.animateScrolling(this.curOp.scrollTop)}this.prevOp=this.curOp,this.curOp=null}},this.$mergeableCommands=[\"backspace\",\"del\",\"insertstring\"],this.$historyTracker=function(e){if(!this.$mergeUndoDeltas)return;var t=this.prevOp,n=this.$mergeableCommands,r=t.command&&e.command.name==t.command.name;if(e.command.name==\"insertstring\"){var i=e.args;this.mergeNextCommand===undefined&&(this.mergeNextCommand=!0),r=r&&this.mergeNextCommand&&(!/\\s/.test(i)||/\\s/.test(t.args)),this.mergeNextCommand=!0}else r=r&&n.indexOf(e.command.name)!==-1;this.$mergeUndoDeltas!=\"always\"&&Date.now()-this.sequenceStartTime>2e3&&(r=!1),r?this.session.mergeUndoDeltas=!0:n.indexOf(e.command.name)!==-1&&(this.sequenceStartTime=Date.now())},this.setKeyboardHandler=function(e,t){if(e&&typeof e==\"string\"){this.$keybindingId=e;var n=this;g.loadModule([\"keybinding\",e],function(r){n.$keybindingId==e&&n.keyBinding.setKeyboardHandler(r&&r.handler),t&&t()})}else this.$keybindingId=null,this.keyBinding.setKeyboardHandler(e),t&&t()},this.getKeyboardHandler=function(){return this.keyBinding.getKeyboardHandler()},this.setSession=function(e){if(this.session==e)return;this.curOp&&this.endOperation(),this.curOp={};var t=this.session;if(t){this.session.off(\"change\",this.$onDocumentChange),this.session.off(\"changeMode\",this.$onChangeMode),this.session.off(\"tokenizerUpdate\",this.$onTokenizerUpdate),this.session.off(\"changeTabSize\",this.$onChangeTabSize),this.session.off(\"changeWrapLimit\",this.$onChangeWrapLimit),this.session.off(\"changeWrapMode\",this.$onChangeWrapMode),this.session.off(\"changeFold\",this.$onChangeFold),this.session.off(\"changeFrontMarker\",this.$onChangeFrontMarker),this.session.off(\"changeBackMarker\",this.$onChangeBackMarker),this.session.off(\"changeBreakpoint\",this.$onChangeBreakpoint),this.session.off(\"changeAnnotation\",this.$onChangeAnnotation),this.session.off(\"changeOverwrite\",this.$onCursorChange),this.session.off(\"changeScrollTop\",this.$onScrollTopChange),this.session.off(\"changeScrollLeft\",this.$onScrollLeftChange);var n=this.session.getSelection();n.off(\"changeCursor\",this.$onCursorChange),n.off(\"changeSelection\",this.$onSelectionChange)}this.session=e,e?(this.$onDocumentChange=this.onDocumentChange.bind(this),e.on(\"change\",this.$onDocumentChange),this.renderer.setSession(e),this.$onChangeMode=this.onChangeMode.bind(this),e.on(\"changeMode\",this.$onChangeMode),this.$onTokenizerUpdate=this.onTokenizerUpdate.bind(this),e.on(\"tokenizerUpdate\",this.$onTokenizerUpdate),this.$onChangeTabSize=this.renderer.onChangeTabSize.bind(this.renderer),e.on(\"changeTabSize\",this.$onChangeTabSize),this.$onChangeWrapLimit=this.onChangeWrapLimit.bind(this),e.on(\"changeWrapLimit\",this.$onChangeWrapLimit),this.$onChangeWrapMode=this.onChangeWrapMode.bind(this),e.on(\"changeWrapMode\",this.$onChangeWrapMode),this.$onChangeFold=this.onChangeFold.bind(this),e.on(\"changeFold\",this.$onChangeFold),this.$onChangeFrontMarker=this.onChangeFrontMarker.bind(this),this.session.on(\"changeFrontMarker\",this.$onChangeFrontMarker),this.$onChangeBackMarker=this.onChangeBackMarker.bind(this),this.session.on(\"changeBackMarker\",this.$onChangeBackMarker),this.$onChangeBreakpoint=this.onChangeBreakpoint.bind(this),this.session.on(\"changeBreakpoint\",this.$onChangeBreakpoint),this.$onChangeAnnotation=this.onChangeAnnotation.bind(this),this.session.on(\"changeAnnotation\",this.$onChangeAnnotation),this.$onCursorChange=this.onCursorChange.bind(this),this.session.on(\"changeOverwrite\",this.$onCursorChange),this.$onScrollTopChange=this.onScrollTopChange.bind(this),this.session.on(\"changeScrollTop\",this.$onScrollTopChange),this.$onScrollLeftChange=this.onScrollLeftChange.bind(this),this.session.on(\"changeScrollLeft\",this.$onScrollLeftChange),this.selection=e.getSelection(),this.selection.on(\"changeCursor\",this.$onCursorChange),this.$onSelectionChange=this.onSelectionChange.bind(this),this.selection.on(\"changeSelection\",this.$onSelectionChange),this.onChangeMode(),this.$blockScrolling+=1,this.onCursorChange(),this.$blockScrolling-=1,this.onScrollTopChange(),this.onScrollLeftChange(),this.onSelectionChange(),this.onChangeFrontMarker(),this.onChangeBackMarker(),this.onChangeBreakpoint(),this.onChangeAnnotation(),this.session.getUseWrapMode()&&this.renderer.adjustWrapLimit(),this.renderer.updateFull()):(this.selection=null,this.renderer.setSession(e)),this._signal(\"changeSession\",{session:e,oldSession:t}),this.curOp=null,t&&t._signal(\"changeEditor\",{oldEditor:this}),e&&e._signal(\"changeEditor\",{editor:this})},this.getSession=function(){return this.session},this.setValue=function(e,t){return this.session.doc.setValue(e),t?t==1?this.navigateFileEnd():t==-1&&this.navigateFileStart():this.selectAll(),e},this.getValue=function(){return this.session.getValue()},this.getSelection=function(){return this.selection},this.resize=function(e){this.renderer.onResize(e)},this.setTheme=function(e,t){this.renderer.setTheme(e,t)},this.getTheme=function(){return this.renderer.getTheme()},this.setStyle=function(e){this.renderer.setStyle(e)},this.unsetStyle=function(e){this.renderer.unsetStyle(e)},this.getFontSize=function(){return this.getOption(\"fontSize\")||i.computedStyle(this.container,\"fontSize\")},this.setFontSize=function(e){this.setOption(\"fontSize\",e)},this.$highlightBrackets=function(){this.session.$bracketHighlight&&(this.session.removeMarker(this.session.$bracketHighlight),this.session.$bracketHighlight=null);if(this.$highlightPending)return;var e=this;this.$highlightPending=!0,setTimeout(function(){e.$highlightPending=!1;var t=e.session;if(!t||!t.bgTokenizer)return;var n=t.findMatchingBracket(e.getCursorPosition());if(n)var r=new p(n.row,n.column,n.row,n.column+1);else if(t.$mode.getMatching)var r=t.$mode.getMatching(e.session);r&&(t.$bracketHighlight=t.addMarker(r,\"ace_bracket\",\"text\"))},50)},this.$highlightTags=function(){if(this.$highlightTagPending)return;var e=this;this.$highlightTagPending=!0,setTimeout(function(){e.$highlightTagPending=!1;var t=e.session;if(!t||!t.bgTokenizer)return;var n=e.getCursorPosition(),r=new y(e.session,n.row,n.column),i=r.getCurrentToken();if(!i||!/\\b(?:tag-open|tag-name)/.test(i.type)){t.removeMarker(t.$tagHighlight),t.$tagHighlight=null;return}if(i.type.indexOf(\"tag-open\")!=-1){i=r.stepForward();if(!i)return}var s=i.value,o=0,u=r.stepBackward();if(u.value==\"<\"){do u=i,i=r.stepForward(),i&&i.value===s&&i.type.indexOf(\"tag-name\")!==-1&&(u.value===\"<\"?o++:u.value===\"</\"&&o--);while(i&&o>=0)}else{do i=u,u=r.stepBackward(),i&&i.value===s&&i.type.indexOf(\"tag-name\")!==-1&&(u.value===\"<\"?o++:u.value===\"</\"&&o--);while(u&&o<=0);r.stepForward()}if(!i){t.removeMarker(t.$tagHighlight),t.$tagHighlight=null;return}var a=r.getCurrentTokenRow(),f=r.getCurrentTokenColumn(),l=new p(a,f,a,f+i.value.length);t.$tagHighlight&&l.compareRange(t.$backMarkers[t.$tagHighlight].range)!==0&&(t.removeMarker(t.$tagHighlight),t.$tagHighlight=null),l&&!t.$tagHighlight&&(t.$tagHighlight=t.addMarker(l,\"ace_bracket\",\"text\"))},50)},this.focus=function(){var e=this;setTimeout(function(){e.textInput.focus()}),this.textInput.focus()},this.isFocused=function(){return this.textInput.isFocused()},this.blur=function(){this.textInput.blur()},this.onFocus=function(e){if(this.$isFocused)return;this.$isFocused=!0,this.renderer.showCursor(),this.renderer.visualizeFocus(),this._emit(\"focus\",e)},this.onBlur=function(e){if(!this.$isFocused)return;this.$isFocused=!1,this.renderer.hideCursor(),this.renderer.visualizeBlur(),this._emit(\"blur\",e)},this.$cursorChange=function(){this.renderer.updateCursor()},this.onDocumentChange=function(e){var t=this.session.$useWrapMode,n=e.start.row==e.end.row?e.end.row:Infinity;this.renderer.updateLines(e.start.row,n,t),this._signal(\"change\",e),this.$cursorChange(),this.$updateHighlightActiveLine()},this.onTokenizerUpdate=function(e){var t=e.data;this.renderer.updateLines(t.first,t.last)},this.onScrollTopChange=function(){this.renderer.scrollToY(this.session.getScrollTop())},this.onScrollLeftChange=function(){this.renderer.scrollToX(this.session.getScrollLeft())},this.onCursorChange=function(){this.$cursorChange(),this.$blockScrolling||(g.warn(\"Automatically scrolling cursor into view after selection change\",\"this will be disabled in the next version\",\"set editor.$blockScrolling = Infinity to disable this message\"),this.renderer.scrollCursorIntoView()),this.$highlightBrackets(),this.$highlightTags(),this.$updateHighlightActiveLine(),this._signal(\"changeSelection\")},this.$updateHighlightActiveLine=function(){var e=this.getSession(),t;if(this.$highlightActiveLine){if(this.$selectionStyle!=\"line\"||!this.selection.isMultiLine())t=this.getCursorPosition();this.renderer.$maxLines&&this.session.getLength()===1&&!(this.renderer.$minLines>1)&&(t=!1)}if(e.$highlightLineMarker&&!t)e.removeMarker(e.$highlightLineMarker.id),e.$highlightLineMarker=null;else if(!e.$highlightLineMarker&&t){var n=new p(t.row,t.column,t.row,Infinity);n.id=e.addMarker(n,\"ace_active-line\",\"screenLine\"),e.$highlightLineMarker=n}else t&&(e.$highlightLineMarker.start.row=t.row,e.$highlightLineMarker.end.row=t.row,e.$highlightLineMarker.start.column=t.column,e._signal(\"changeBackMarker\"))},this.onSelectionChange=function(e){var t=this.session;t.$selectionMarker&&t.removeMarker(t.$selectionMarker),t.$selectionMarker=null;if(!this.selection.isEmpty()){var n=this.selection.getRange(),r=this.getSelectionStyle();t.$selectionMarker=t.addMarker(n,\"ace_selection\",r)}else this.$updateHighlightActiveLine();var i=this.$highlightSelectedWord&&this.$getSelectionHighLightRegexp();this.session.highlight(i),this._signal(\"changeSelection\")},this.$getSelectionHighLightRegexp=function(){var e=this.session,t=this.getSelectionRange();if(t.isEmpty()||t.isMultiLine())return;var n=t.start.column-1,r=t.end.column+1,i=e.getLine(t.start.row),s=i.length,o=i.substring(Math.max(n,0),Math.min(r,s));if(n>=0&&/^[\\w\\d]/.test(o)||r<=s&&/[\\w\\d]$/.test(o))return;o=i.substring(t.start.column,t.end.column);if(!/^[\\w\\d]+$/.test(o))return;var u=this.$search.$assembleRegExp({wholeWord:!0,caseSensitive:!0,needle:o});return u},this.onChangeFrontMarker=function(){this.renderer.updateFrontMarkers()},this.onChangeBackMarker=function(){this.renderer.updateBackMarkers()},this.onChangeBreakpoint=function(){this.renderer.updateBreakpoints()},this.onChangeAnnotation=function(){this.renderer.setAnnotations(this.session.getAnnotations())},this.onChangeMode=function(e){this.renderer.updateText(),this._emit(\"changeMode\",e)},this.onChangeWrapLimit=function(){this.renderer.updateFull()},this.onChangeWrapMode=function(){this.renderer.onResize(!0)},this.onChangeFold=function(){this.$updateHighlightActiveLine(),this.renderer.updateFull()},this.getSelectedText=function(){return this.session.getTextRange(this.getSelectionRange())},this.getCopyText=function(){var e=this.getSelectedText();return this._signal(\"copy\",e),e},this.onCopy=function(){this.commands.exec(\"copy\",this)},this.onCut=function(){this.commands.exec(\"cut\",this)},this.onPaste=function(e,t){var n={text:e,event:t};this.commands.exec(\"paste\",this,n)},this.$handlePaste=function(e){typeof e==\"string\"&&(e={text:e}),this._signal(\"paste\",e);var t=e.text;if(!this.inMultiSelectMode||this.inVirtualSelectionMode)this.insert(t);else{var n=t.split(/\\r\\n|\\r|\\n/),r=this.selection.rangeList.ranges;if(n.length>r.length||n.length<2||!n[1])return this.commands.exec(\"insertstring\",this,t);for(var i=r.length;i--;){var s=r[i];s.isEmpty()||this.session.remove(s),this.session.insert(s.start,n[i])}}},this.execCommand=function(e,t){return this.commands.exec(e,this,t)},this.insert=function(e,t){var n=this.session,r=n.getMode(),i=this.getCursorPosition();if(this.getBehavioursEnabled()&&!t){var s=r.transformAction(n.getState(i.row),\"insertion\",this,n,e);s&&(e!==s.text&&(this.session.mergeUndoDeltas=!1,this.$mergeNextCommand=!1),e=s.text)}e==\"\t\"&&(e=this.session.getTabString());if(!this.selection.isEmpty()){var o=this.getSelectionRange();i=this.session.remove(o),this.clearSelection()}else if(this.session.getOverwrite()){var o=new p.fromPoints(i,i);o.end.column+=e.length,this.session.remove(o)}if(e==\"\\n\"||e==\"\\r\\n\"){var u=n.getLine(i.row);if(i.column>u.search(/\\S|$/)){var a=u.substr(i.column).search(/\\S|$/);n.doc.removeInLine(i.row,i.column,i.column+a)}}this.clearSelection();var f=i.column,l=n.getState(i.row),u=n.getLine(i.row),c=r.checkOutdent(l,u,e),h=n.insert(i,e);s&&s.selection&&(s.selection.length==2?this.selection.setSelectionRange(new p(i.row,f+s.selection[0],i.row,f+s.selection[1])):this.selection.setSelectionRange(new p(i.row+s.selection[0],s.selection[1],i.row+s.selection[2],s.selection[3])));if(n.getDocument().isNewLine(e)){var d=r.getNextLineIndent(l,u.slice(0,i.column),n.getTabString());n.insert({row:i.row+1,column:0},d)}c&&r.autoOutdent(l,n,i.row)},this.onTextInput=function(e){this.keyBinding.onTextInput(e)},this.onCommandKey=function(e,t,n){this.keyBinding.onCommandKey(e,t,n)},this.setOverwrite=function(e){this.session.setOverwrite(e)},this.getOverwrite=function(){return this.session.getOverwrite()},this.toggleOverwrite=function(){this.session.toggleOverwrite()},this.setScrollSpeed=function(e){this.setOption(\"scrollSpeed\",e)},this.getScrollSpeed=function(){return this.getOption(\"scrollSpeed\")},this.setDragDelay=function(e){this.setOption(\"dragDelay\",e)},this.getDragDelay=function(){return this.getOption(\"dragDelay\")},this.setSelectionStyle=function(e){this.setOption(\"selectionStyle\",e)},this.getSelectionStyle=function(){return this.getOption(\"selectionStyle\")},this.setHighlightActiveLine=function(e){this.setOption(\"highlightActiveLine\",e)},this.getHighlightActiveLine=function(){return this.getOption(\"highlightActiveLine\")},this.setHighlightGutterLine=function(e){this.setOption(\"highlightGutterLine\",e)},this.getHighlightGutterLine=function(){return this.getOption(\"highlightGutterLine\")},this.setHighlightSelectedWord=function(e){this.setOption(\"highlightSelectedWord\",e)},this.getHighlightSelectedWord=function(){return this.$highlightSelectedWord},this.setAnimatedScroll=function(e){this.renderer.setAnimatedScroll(e)},this.getAnimatedScroll=function(){return this.renderer.getAnimatedScroll()},this.setShowInvisibles=function(e){this.renderer.setShowInvisibles(e)},this.getShowInvisibles=function(){return this.renderer.getShowInvisibles()},this.setDisplayIndentGuides=function(e){this.renderer.setDisplayIndentGuides(e)},this.getDisplayIndentGuides=function(){return this.renderer.getDisplayIndentGuides()},this.setShowPrintMargin=function(e){this.renderer.setShowPrintMargin(e)},this.getShowPrintMargin=function(){return this.renderer.getShowPrintMargin()},this.setPrintMarginColumn=function(e){this.renderer.setPrintMarginColumn(e)},this.getPrintMarginColumn=function(){return this.renderer.getPrintMarginColumn()},this.setReadOnly=function(e){this.setOption(\"readOnly\",e)},this.getReadOnly=function(){return this.getOption(\"readOnly\")},this.setBehavioursEnabled=function(e){this.setOption(\"behavioursEnabled\",e)},this.getBehavioursEnabled=function(){return this.getOption(\"behavioursEnabled\")},this.setWrapBehavioursEnabled=function(e){this.setOption(\"wrapBehavioursEnabled\",e)},this.getWrapBehavioursEnabled=function(){return this.getOption(\"wrapBehavioursEnabled\")},this.setShowFoldWidgets=function(e){this.setOption(\"showFoldWidgets\",e)},this.getShowFoldWidgets=function(){return this.getOption(\"showFoldWidgets\")},this.setFadeFoldWidgets=function(e){this.setOption(\"fadeFoldWidgets\",e)},this.getFadeFoldWidgets=function(){return this.getOption(\"fadeFoldWidgets\")},this.remove=function(e){this.selection.isEmpty()&&(e==\"left\"?this.selection.selectLeft():this.selection.selectRight());var t=this.getSelectionRange();if(this.getBehavioursEnabled()){var n=this.session,r=n.getState(t.start.row),i=n.getMode().transformAction(r,\"deletion\",this,n,t);if(t.end.column===0){var s=n.getTextRange(t);if(s[s.length-1]==\"\\n\"){var o=n.getLine(t.end.row);/^\\s+$/.test(o)&&(t.end.column=o.length)}}i&&(t=i)}this.session.remove(t),this.clearSelection()},this.removeWordRight=function(){this.selection.isEmpty()&&this.selection.selectWordRight(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeWordLeft=function(){this.selection.isEmpty()&&this.selection.selectWordLeft(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeToLineStart=function(){this.selection.isEmpty()&&this.selection.selectLineStart(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeToLineEnd=function(){this.selection.isEmpty()&&this.selection.selectLineEnd();var e=this.getSelectionRange();e.start.column==e.end.column&&e.start.row==e.end.row&&(e.end.column=0,e.end.row++),this.session.remove(e),this.clearSelection()},this.splitLine=function(){this.selection.isEmpty()||(this.session.remove(this.getSelectionRange()),this.clearSelection());var e=this.getCursorPosition();this.insert(\"\\n\"),this.moveCursorToPosition(e)},this.transposeLetters=function(){if(!this.selection.isEmpty())return;var e=this.getCursorPosition(),t=e.column;if(t===0)return;var n=this.session.getLine(e.row),r,i;t<n.length?(r=n.charAt(t)+n.charAt(t-1),i=new p(e.row,t-1,e.row,t+1)):(r=n.charAt(t-1)+n.charAt(t-2),i=new p(e.row,t-2,e.row,t)),this.session.replace(i,r)},this.toLowerCase=function(){var e=this.getSelectionRange();this.selection.isEmpty()&&this.selection.selectWord();var t=this.getSelectionRange(),n=this.session.getTextRange(t);this.session.replace(t,n.toLowerCase()),this.selection.setSelectionRange(e)},this.toUpperCase=function(){var e=this.getSelectionRange();this.selection.isEmpty()&&this.selection.selectWord();var t=this.getSelectionRange(),n=this.session.getTextRange(t);this.session.replace(t,n.toUpperCase()),this.selection.setSelectionRange(e)},this.indent=function(){var e=this.session,t=this.getSelectionRange();if(t.start.row<t.end.row){var n=this.$getSelectedRows();e.indentRows(n.first,n.last,\"\t\");return}if(t.start.column<t.end.column){var r=e.getTextRange(t);if(!/^\\s+$/.test(r)){var n=this.$getSelectedRows();e.indentRows(n.first,n.last,\"\t\");return}}var i=e.getLine(t.start.row),o=t.start,u=e.getTabSize(),a=e.documentToScreenColumn(o.row,o.column);if(this.session.getUseSoftTabs())var f=u-a%u,l=s.stringRepeat(\" \",f);else{var f=a%u;while(i[t.start.column]==\" \"&&f)t.start.column--,f--;this.selection.setSelectionRange(t),l=\"\t\"}return this.insert(l)},this.blockIndent=function(){var e=this.$getSelectedRows();this.session.indentRows(e.first,e.last,\"\t\")},this.blockOutdent=function(){var e=this.session.getSelection();this.session.outdentRows(e.getRange())},this.sortLines=function(){var e=this.$getSelectedRows(),t=this.session,n=[];for(i=e.first;i<=e.last;i++)n.push(t.getLine(i));n.sort(function(e,t){return e.toLowerCase()<t.toLowerCase()?-1:e.toLowerCase()>t.toLowerCase()?1:0});var r=new p(0,0,0,0);for(var i=e.first;i<=e.last;i++){var s=t.getLine(i);r.start.row=i,r.end.row=i,r.end.column=s.length,t.replace(r,n[i-e.first])}},this.toggleCommentLines=function(){var e=this.session.getState(this.getCursorPosition().row),t=this.$getSelectedRows();this.session.getMode().toggleCommentLines(e,this.session,t.first,t.last)},this.toggleBlockComment=function(){var e=this.getCursorPosition(),t=this.session.getState(e.row),n=this.getSelectionRange();this.session.getMode().toggleBlockComment(t,this.session,n,e)},this.getNumberAt=function(e,t){var n=/[\\-]?[0-9]+(?:\\.[0-9]+)?/g;n.lastIndex=0;var r=this.session.getLine(e);while(n.lastIndex<t){var i=n.exec(r);if(i.index<=t&&i.index+i[0].length>=t){var s={value:i[0],start:i.index,end:i.index+i[0].length};return s}}return null},this.modifyNumber=function(e){var t=this.selection.getCursor().row,n=this.selection.getCursor().column,r=new p(t,n-1,t,n),i=this.session.getTextRange(r);if(!isNaN(parseFloat(i))&&isFinite(i)){var s=this.getNumberAt(t,n);if(s){var o=s.value.indexOf(\".\")>=0?s.start+s.value.indexOf(\".\")+1:s.end,u=s.start+s.value.length-o,a=parseFloat(s.value);a*=Math.pow(10,u),o!==s.end&&n<o?e*=Math.pow(10,s.end-n-1):e*=Math.pow(10,s.end-n),a+=e,a/=Math.pow(10,u);var f=a.toFixed(u),l=new p(t,s.start,t,s.end);this.session.replace(l,f),this.moveCursorTo(t,Math.max(s.start+1,n+f.length-s.value.length))}}},this.removeLines=function(){var e=this.$getSelectedRows();this.session.removeFullLines(e.first,e.last),this.clearSelection()},this.duplicateSelection=function(){var e=this.selection,t=this.session,n=e.getRange(),r=e.isBackwards();if(n.isEmpty()){var i=n.start.row;t.duplicateLines(i,i)}else{var s=r?n.start:n.end,o=t.insert(s,t.getTextRange(n),!1);n.start=s,n.end=o,e.setSelectionRange(n,r)}},this.moveLinesDown=function(){this.$moveLines(1,!1)},this.moveLinesUp=function(){this.$moveLines(-1,!1)},this.moveText=function(e,t,n){return this.session.moveText(e,t,n)},this.copyLinesUp=function(){this.$moveLines(-1,!0)},this.copyLinesDown=function(){this.$moveLines(1,!0)},this.$moveLines=function(e,t){var n,r,i=this.selection;if(!i.inMultiSelectMode||this.inVirtualSelectionMode){var s=i.toOrientedRange();n=this.$getSelectedRows(s),r=this.session.$moveLines(n.first,n.last,t?0:e),t&&e==-1&&(r=0),s.moveBy(r,0),i.fromOrientedRange(s)}else{var o=i.rangeList.ranges;i.rangeList.detach(this.session),this.inVirtualSelectionMode=!0;var u=0,a=0,f=o.length;for(var l=0;l<f;l++){var c=l;o[l].moveBy(u,0),n=this.$getSelectedRows(o[l]);var h=n.first,p=n.last;while(++l<f){a&&o[l].moveBy(a,0);var d=this.$getSelectedRows(o[l]);if(t&&d.first!=p)break;if(!t&&d.first>p+1)break;p=d.last}l--,u=this.session.$moveLines(h,p,t?0:e),t&&e==-1&&(c=l+1);while(c<=l)o[c].moveBy(u,0),c++;t||(u=0),a+=u}i.fromOrientedRange(i.ranges[0]),i.rangeList.attach(this.session),this.inVirtualSelectionMode=!1}},this.$getSelectedRows=function(e){return e=(e||this.getSelectionRange()).collapseRows(),{first:this.session.getRowFoldStart(e.start.row),last:this.session.getRowFoldEnd(e.end.row)}},this.onCompositionStart=function(e){this.renderer.showComposition(this.getCursorPosition())},this.onCompositionUpdate=function(e){this.renderer.setCompositionText(e)},this.onCompositionEnd=function(){this.renderer.hideComposition()},this.getFirstVisibleRow=function(){return this.renderer.getFirstVisibleRow()},this.getLastVisibleRow=function(){return this.renderer.getLastVisibleRow()},this.isRowVisible=function(e){return e>=this.getFirstVisibleRow()&&e<=this.getLastVisibleRow()},this.isRowFullyVisible=function(e){return e>=this.renderer.getFirstFullyVisibleRow()&&e<=this.renderer.getLastFullyVisibleRow()},this.$getVisibleRowCount=function(){return this.renderer.getScrollBottomRow()-this.renderer.getScrollTopRow()+1},this.$moveByPage=function(e,t){var n=this.renderer,r=this.renderer.layerConfig,i=e*Math.floor(r.height/r.lineHeight);this.$blockScrolling++,t===!0?this.selection.$moveSelection(function(){this.moveCursorBy(i,0)}):t===!1&&(this.selection.moveCursorBy(i,0),this.selection.clearSelection()),this.$blockScrolling--;var s=n.scrollTop;n.scrollBy(0,i*r.lineHeight),t!=null&&n.scrollCursorIntoView(null,.5),n.animateScrolling(s)},this.selectPageDown=function(){this.$moveByPage(1,!0)},this.selectPageUp=function(){this.$moveByPage(-1,!0)},this.gotoPageDown=function(){this.$moveByPage(1,!1)},this.gotoPageUp=function(){this.$moveByPage(-1,!1)},this.scrollPageDown=function(){this.$moveByPage(1)},this.scrollPageUp=function(){this.$moveByPage(-1)},this.scrollToRow=function(e){this.renderer.scrollToRow(e)},this.scrollToLine=function(e,t,n,r){this.renderer.scrollToLine(e,t,n,r)},this.centerSelection=function(){var e=this.getSelectionRange(),t={row:Math.floor(e.start.row+(e.end.row-e.start.row)/2),column:Math.floor(e.start.column+(e.end.column-e.start.column)/2)};this.renderer.alignCursor(t,.5)},this.getCursorPosition=function(){return this.selection.getCursor()},this.getCursorPositionScreen=function(){return this.session.documentToScreenPosition(this.getCursorPosition())},this.getSelectionRange=function(){return this.selection.getRange()},this.selectAll=function(){this.$blockScrolling+=1,this.selection.selectAll(),this.$blockScrolling-=1},this.clearSelection=function(){this.selection.clearSelection()},this.moveCursorTo=function(e,t){this.selection.moveCursorTo(e,t)},this.moveCursorToPosition=function(e){this.selection.moveCursorToPosition(e)},this.jumpToMatching=function(e,t){var n=this.getCursorPosition(),r=new y(this.session,n.row,n.column),i=r.getCurrentToken(),s=i||r.stepForward();if(!s)return;var o,u=!1,a={},f=n.column-s.start,l,c={\")\":\"(\",\"(\":\"(\",\"]\":\"[\",\"[\":\"[\",\"{\":\"{\",\"}\":\"{\"};do{if(s.value.match(/[{}()\\[\\]]/g))for(;f<s.value.length&&!u;f++){if(!c[s.value[f]])continue;l=c[s.value[f]]+\".\"+s.type.replace(\"rparen\",\"lparen\"),isNaN(a[l])&&(a[l]=0);switch(s.value[f]){case\"(\":case\"[\":case\"{\":a[l]++;break;case\")\":case\"]\":case\"}\":a[l]--,a[l]===-1&&(o=\"bracket\",u=!0)}}else s&&s.type.indexOf(\"tag-name\")!==-1&&(isNaN(a[s.value])&&(a[s.value]=0),i.value===\"<\"?a[s.value]++:i.value===\"</\"&&a[s.value]--,a[s.value]===-1&&(o=\"tag\",u=!0));u||(i=s,s=r.stepForward(),f=0)}while(s&&!u);if(!o)return;var h,d;if(o===\"bracket\"){h=this.session.getBracketRange(n);if(!h){h=new p(r.getCurrentTokenRow(),r.getCurrentTokenColumn()+f-1,r.getCurrentTokenRow(),r.getCurrentTokenColumn()+f-1),d=h.start;if(t||d.row===n.row&&Math.abs(d.column-n.column)<2)h=this.session.getBracketRange(d)}}else if(o===\"tag\"){if(!s||s.type.indexOf(\"tag-name\")===-1)return;var v=s.value;h=new p(r.getCurrentTokenRow(),r.getCurrentTokenColumn()-2,r.getCurrentTokenRow(),r.getCurrentTokenColumn()-2);if(h.compare(n.row,n.column)===0){u=!1;do s=i,i=r.stepBackward(),i&&(i.type.indexOf(\"tag-close\")!==-1&&h.setEnd(r.getCurrentTokenRow(),r.getCurrentTokenColumn()+1),s.value===v&&s.type.indexOf(\"tag-name\")!==-1&&(i.value===\"<\"?a[v]++:i.value===\"</\"&&a[v]--,a[v]===0&&(u=!0)));while(i&&!u)}s&&s.type.indexOf(\"tag-name\")&&(d=h.start,d.row==n.row&&Math.abs(d.column-n.column)<2&&(d=h.end))}d=h&&h.cursor||d,d&&(e?h&&t?this.selection.setRange(h):h&&h.isEqual(this.getSelectionRange())?this.clearSelection():this.selection.selectTo(d.row,d.column):this.selection.moveTo(d.row,d.column))},this.gotoLine=function(e,t,n){this.selection.clearSelection(),this.session.unfold({row:e-1,column:t||0}),this.$blockScrolling+=1,this.exitMultiSelectMode&&this.exitMultiSelectMode(),this.moveCursorTo(e-1,t||0),this.$blockScrolling-=1,this.isRowFullyVisible(e-1)||this.scrollToLine(e-1,!0,n)},this.navigateTo=function(e,t){this.selection.moveTo(e,t)},this.navigateUp=function(e){if(this.selection.isMultiLine()&&!this.selection.isBackwards()){var t=this.selection.anchor.getPosition();return this.moveCursorToPosition(t)}this.selection.clearSelection(),this.selection.moveCursorBy(-e||-1,0)},this.navigateDown=function(e){if(this.selection.isMultiLine()&&this.selection.isBackwards()){var t=this.selection.anchor.getPosition();return this.moveCursorToPosition(t)}this.selection.clearSelection(),this.selection.moveCursorBy(e||1,0)},this.navigateLeft=function(e){if(!this.selection.isEmpty()){var t=this.getSelectionRange().start;this.moveCursorToPosition(t)}else{e=e||1;while(e--)this.selection.moveCursorLeft()}this.clearSelection()},this.navigateRight=function(e){if(!this.selection.isEmpty()){var t=this.getSelectionRange().end;this.moveCursorToPosition(t)}else{e=e||1;while(e--)this.selection.moveCursorRight()}this.clearSelection()},this.navigateLineStart=function(){this.selection.moveCursorLineStart(),this.clearSelection()},this.navigateLineEnd=function(){this.selection.moveCursorLineEnd(),this.clearSelection()},this.navigateFileEnd=function(){this.selection.moveCursorFileEnd(),this.clearSelection()},this.navigateFileStart=function(){this.selection.moveCursorFileStart(),this.clearSelection()},this.navigateWordRight=function(){this.selection.moveCursorWordRight(),this.clearSelection()},this.navigateWordLeft=function(){this.selection.moveCursorWordLeft(),this.clearSelection()},this.replace=function(e,t){t&&this.$search.set(t);var n=this.$search.find(this.session),r=0;return n?(this.$tryReplace(n,e)&&(r=1),n!==null&&(this.selection.setSelectionRange(n),this.renderer.scrollSelectionIntoView(n.start,n.end)),r):r},this.replaceAll=function(e,t){t&&this.$search.set(t);var n=this.$search.findAll(this.session),r=0;if(!n.length)return r;this.$blockScrolling+=1;var i=this.getSelectionRange();this.selection.moveTo(0,0);for(var s=n.length-1;s>=0;--s)this.$tryReplace(n[s],e)&&r++;return this.selection.setSelectionRange(i),this.$blockScrolling-=1,r},this.$tryReplace=function(e,t){var n=this.session.getTextRange(e);return t=this.$search.replace(n,t),t!==null?(e.end=this.session.replace(e,t),e):null},this.getLastSearchOptions=function(){return this.$search.getOptions()},this.find=function(e,t,n){t||(t={}),typeof e==\"string\"||e instanceof RegExp?t.needle=e:typeof e==\"object\"&&r.mixin(t,e);var i=this.selection.getRange();t.needle==null&&(e=this.session.getTextRange(i)||this.$search.$options.needle,e||(i=this.session.getWordRange(i.start.row,i.start.column),e=this.session.getTextRange(i)),this.$search.set({needle:e})),this.$search.set(t),t.start||this.$search.set({start:i});var s=this.$search.find(this.session);if(t.preventScroll)return s;if(s)return this.revealRange(s,n),s;t.backwards?i.start=i.end:i.end=i.start,this.selection.setRange(i)},this.findNext=function(e,t){this.find({skipCurrent:!0,backwards:!1},e,t)},this.findPrevious=function(e,t){this.find(e,{skipCurrent:!0,backwards:!0},t)},this.revealRange=function(e,t){this.$blockScrolling+=1,this.session.unfold(e),this.selection.setSelectionRange(e),this.$blockScrolling-=1;var n=this.renderer.scrollTop;this.renderer.scrollSelectionIntoView(e.start,e.end,.5),t!==!1&&this.renderer.animateScrolling(n)},this.undo=function(){this.$blockScrolling++,this.session.getUndoManager().undo(),this.$blockScrolling--,this.renderer.scrollCursorIntoView(null,.5)},this.redo=function(){this.$blockScrolling++,this.session.getUndoManager().redo(),this.$blockScrolling--,this.renderer.scrollCursorIntoView(null,.5)},this.destroy=function(){this.renderer.destroy(),this._signal(\"destroy\",this),this.session&&this.session.destroy()},this.setAutoScrollEditorIntoView=function(e){if(!e)return;var t,n=this,r=!1;this.$scrollAnchor||(this.$scrollAnchor=document.createElement(\"div\"));var i=this.$scrollAnchor;i.style.cssText=\"position:absolute\",this.container.insertBefore(i,this.container.firstChild);var s=this.on(\"changeSelection\",function(){r=!0}),o=this.renderer.on(\"beforeRender\",function(){r&&(t=n.renderer.container.getBoundingClientRect())}),u=this.renderer.on(\"afterRender\",function(){if(r&&t&&(n.isFocused()||n.searchBox&&n.searchBox.isFocused())){var e=n.renderer,s=e.$cursorLayer.$pixelPos,o=e.layerConfig,u=s.top-o.offset;s.top>=0&&u+t.top<0?r=!0:s.top<o.height&&s.top+t.top+o.lineHeight>window.innerHeight?r=!1:r=null,r!=null&&(i.style.top=u+\"px\",i.style.left=s.left+\"px\",i.style.height=o.lineHeight+\"px\",i.scrollIntoView(r)),r=t=null}});this.setAutoScrollEditorIntoView=function(e){if(e)return;delete this.setAutoScrollEditorIntoView,this.off(\"changeSelection\",s),this.renderer.off(\"afterRender\",u),this.renderer.off(\"beforeRender\",o)}},this.$resetCursorStyle=function(){var e=this.$cursorStyle||\"ace\",t=this.renderer.$cursorLayer;if(!t)return;t.setSmoothBlinking(/smooth/.test(e)),t.isBlinking=!this.$readOnly&&e!=\"wide\",i.setCssClass(t.element,\"ace_slim-cursors\",/slim/.test(e))}}).call(b.prototype),g.defineOptions(b.prototype,\"editor\",{selectionStyle:{set:function(e){this.onSelectionChange(),this._signal(\"changeSelectionStyle\",{data:e})},initialValue:\"line\"},highlightActiveLine:{set:function(){this.$updateHighlightActiveLine()},initialValue:!0},highlightSelectedWord:{set:function(e){this.$onSelectionChange()},initialValue:!0},readOnly:{set:function(e){this.$resetCursorStyle()},initialValue:!1},cursorStyle:{set:function(e){this.$resetCursorStyle()},values:[\"ace\",\"slim\",\"smooth\",\"wide\"],initialValue:\"ace\"},mergeUndoDeltas:{values:[!1,!0,\"always\"],initialValue:!0},behavioursEnabled:{initialValue:!0},wrapBehavioursEnabled:{initialValue:!0},autoScrollEditorIntoView:{set:function(e){this.setAutoScrollEditorIntoView(e)}},keyboardHandler:{set:function(e){this.setKeyboardHandler(e)},get:function(){return this.keybindingId},handlesSet:!0},hScrollBarAlwaysVisible:\"renderer\",vScrollBarAlwaysVisible:\"renderer\",highlightGutterLine:\"renderer\",animatedScroll:\"renderer\",showInvisibles:\"renderer\",showPrintMargin:\"renderer\",printMarginColumn:\"renderer\",printMargin:\"renderer\",fadeFoldWidgets:\"renderer\",showFoldWidgets:\"renderer\",showLineNumbers:\"renderer\",showGutter:\"renderer\",displayIndentGuides:\"renderer\",fontSize:\"renderer\",fontFamily:\"renderer\",maxLines:\"renderer\",minLines:\"renderer\",scrollPastEnd:\"renderer\",fixedWidthGutter:\"renderer\",theme:\"renderer\",scrollSpeed:\"$mouseHandler\",dragDelay:\"$mouseHandler\",dragEnabled:\"$mouseHandler\",focusTimout:\"$mouseHandler\",tooltipFollowsMouse:\"$mouseHandler\",firstLineNumber:\"session\",overwrite:\"session\",newLineMode:\"session\",useWorker:\"session\",useSoftTabs:\"session\",tabSize:\"session\",wrap:\"session\",indentedSoftWrap:\"session\",foldStyle:\"session\",mode:\"session\"}),t.Editor=b}),ace.define(\"ace/undomanager\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";var r=function(){this.reset()};(function(){function e(e){return{action:e.action,start:e.start,end:e.end,lines:e.lines.length==1?null:e.lines,text:e.lines.length==1?e.lines[0]:null}}function t(e){return{action:e.action,start:e.start,end:e.end,lines:e.lines||[e.text]}}function n(e,t){var n=new Array(e.length);for(var r=0;r<e.length;r++){var i=e[r],s={group:i.group,deltas:new Array(i.length)};for(var o=0;o<i.deltas.length;o++){var u=i.deltas[o];s.deltas[o]=t(u)}n[r]=s}return n}this.execute=function(e){var t=e.args[0];this.$doc=e.args[1],e.merge&&this.hasUndo()&&(this.dirtyCounter--,t=this.$undoStack.pop().concat(t)),this.$undoStack.push(t),this.$redoStack=[],this.dirtyCounter<0&&(this.dirtyCounter=NaN),this.dirtyCounter++},this.undo=function(e){var t=this.$undoStack.pop(),n=null;return t&&(n=this.$doc.undoChanges(t,e),this.$redoStack.push(t),this.dirtyCounter--),n},this.redo=function(e){var t=this.$redoStack.pop(),n=null;return t&&(n=this.$doc.redoChanges(this.$deserializeDeltas(t),e),this.$undoStack.push(t),this.dirtyCounter++),n},this.reset=function(){this.$undoStack=[],this.$redoStack=[],this.dirtyCounter=0},this.hasUndo=function(){return this.$undoStack.length>0},this.hasRedo=function(){return this.$redoStack.length>0},this.markClean=function(){this.dirtyCounter=0},this.isClean=function(){return this.dirtyCounter===0},this.$serializeDeltas=function(t){return n(t,e)},this.$deserializeDeltas=function(e){return n(e,t)}}).call(r.prototype),t.UndoManager=r}),ace.define(\"ace/layer/gutter\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\",\"ace/lib/oop\",\"ace/lib/lang\",\"ace/lib/event_emitter\"],function(e,t,n){\"use strict\";var r=e(\"../lib/dom\"),i=e(\"../lib/oop\"),s=e(\"../lib/lang\"),o=e(\"../lib/event_emitter\").EventEmitter,u=function(e){this.element=r.createElement(\"div\"),this.element.className=\"ace_layer ace_gutter-layer\",e.appendChild(this.element),this.setShowFoldWidgets(this.$showFoldWidgets),this.gutterWidth=0,this.$annotations=[],this.$updateAnnotations=this.$updateAnnotations.bind(this),this.$cells=[]};(function(){i.implement(this,o),this.setSession=function(e){this.session&&this.session.removeEventListener(\"change\",this.$updateAnnotations),this.session=e,e&&e.on(\"change\",this.$updateAnnotations)},this.addGutterDecoration=function(e,t){window.console&&console.warn&&console.warn(\"deprecated use session.addGutterDecoration\"),this.session.addGutterDecoration(e,t)},this.removeGutterDecoration=function(e,t){window.console&&console.warn&&console.warn(\"deprecated use session.removeGutterDecoration\"),this.session.removeGutterDecoration(e,t)},this.setAnnotations=function(e){this.$annotations=[];for(var t=0;t<e.length;t++){var n=e[t],r=n.row,i=this.$annotations[r];i||(i=this.$annotations[r]={text:[]});var o=n.text;o=o?s.escapeHTML(o):n.html||\"\",i.text.indexOf(o)===-1&&i.text.push(o);var u=n.type;u==\"error\"?i.className=\" ace_error\":u==\"warning\"&&i.className!=\" ace_error\"?i.className=\" ace_warning\":u==\"info\"&&!i.className&&(i.className=\" ace_info\")}},this.$updateAnnotations=function(e){if(!this.$annotations.length)return;var t=e.start.row,n=e.end.row-t;if(n!==0)if(e.action==\"remove\")this.$annotations.splice(t,n+1,null);else{var r=new Array(n+1);r.unshift(t,1),this.$annotations.splice.apply(this.$annotations,r)}},this.update=function(e){var t=this.session,n=e.firstRow,i=Math.min(e.lastRow+e.gutterOffset,t.getLength()-1),s=t.getNextFoldLine(n),o=s?s.start.row:Infinity,u=this.$showFoldWidgets&&t.foldWidgets,a=t.$breakpoints,f=t.$decorations,l=t.$firstLineNumber,c=0,h=t.gutterRenderer||this.$renderer,p=null,d=-1,v=n;for(;;){v>o&&(v=s.end.row+1,s=t.getNextFoldLine(v,s),o=s?s.start.row:Infinity);if(v>i){while(this.$cells.length>d+1)p=this.$cells.pop(),this.element.removeChild(p.element);break}p=this.$cells[++d],p||(p={element:null,textNode:null,foldWidget:null},p.element=r.createElement(\"div\"),p.textNode=document.createTextNode(\"\"),p.element.appendChild(p.textNode),this.element.appendChild(p.element),this.$cells[d]=p);var m=\"ace_gutter-cell \";a[v]&&(m+=a[v]),f[v]&&(m+=f[v]),this.$annotations[v]&&(m+=this.$annotations[v].className),p.element.className!=m&&(p.element.className=m);var g=t.getRowLength(v)*e.lineHeight+\"px\";g!=p.element.style.height&&(p.element.style.height=g);if(u){var y=u[v];y==null&&(y=u[v]=t.getFoldWidget(v))}if(y){p.foldWidget||(p.foldWidget=r.createElement(\"span\"),p.element.appendChild(p.foldWidget));var m=\"ace_fold-widget ace_\"+y;y==\"start\"&&v==o&&v<s.end.row?m+=\" ace_closed\":m+=\" ace_open\",p.foldWidget.className!=m&&(p.foldWidget.className=m);var g=e.lineHeight+\"px\";p.foldWidget.style.height!=g&&(p.foldWidget.style.height=g)}else p.foldWidget&&(p.element.removeChild(p.foldWidget),p.foldWidget=null);var b=c=h?h.getText(t,v):v+l;b!=p.textNode.data&&(p.textNode.data=b),v++}this.element.style.height=e.minHeight+\"px\";if(this.$fixedWidth||t.$useWrapMode)c=t.getLength()+l;var w=h?h.getWidth(t,c,e):c.toString().length*e.characterWidth,E=this.$padding||this.$computePadding();w+=E.left+E.right,w!==this.gutterWidth&&!isNaN(w)&&(this.gutterWidth=w,this.element.style.width=Math.ceil(this.gutterWidth)+\"px\",this._emit(\"changeGutterWidth\",w))},this.$fixedWidth=!1,this.$showLineNumbers=!0,this.$renderer=\"\",this.setShowLineNumbers=function(e){this.$renderer=!e&&{getWidth:function(){return\"\"},getText:function(){return\"\"}}},this.getShowLineNumbers=function(){return this.$showLineNumbers},this.$showFoldWidgets=!0,this.setShowFoldWidgets=function(e){e?r.addCssClass(this.element,\"ace_folding-enabled\"):r.removeCssClass(this.element,\"ace_folding-enabled\"),this.$showFoldWidgets=e,this.$padding=null},this.getShowFoldWidgets=function(){return this.$showFoldWidgets},this.$computePadding=function(){if(!this.element.firstChild)return{left:0,right:0};var e=r.computedStyle(this.element.firstChild);return this.$padding={},this.$padding.left=parseInt(e.paddingLeft)+1||0,this.$padding.right=parseInt(e.paddingRight)||0,this.$padding},this.getRegion=function(e){var t=this.$padding||this.$computePadding(),n=this.element.getBoundingClientRect();if(e.x<t.left+n.left)return\"markers\";if(this.$showFoldWidgets&&e.x>n.right-t.right)return\"foldWidgets\"}}).call(u.prototype),t.Gutter=u}),ace.define(\"ace/layer/marker\",[\"require\",\"exports\",\"module\",\"ace/range\",\"ace/lib/dom\"],function(e,t,n){\"use strict\";var r=e(\"../range\").Range,i=e(\"../lib/dom\"),s=function(e){this.element=i.createElement(\"div\"),this.element.className=\"ace_layer ace_marker-layer\",e.appendChild(this.element)};(function(){function e(e,t,n,r){return(e?1:0)|(t?2:0)|(n?4:0)|(r?8:0)}this.$padding=0,this.setPadding=function(e){this.$padding=e},this.setSession=function(e){this.session=e},this.setMarkers=function(e){this.markers=e},this.update=function(e){var e=e||this.config;if(!e)return;this.config=e;var t=[];for(var n in this.markers){var r=this.markers[n];if(!r.range){r.update(t,this,this.session,e);continue}var i=r.range.clipRows(e.firstRow,e.lastRow);if(i.isEmpty())continue;i=i.toScreenRange(this.session);if(r.renderer){var s=this.$getTop(i.start.row,e),o=this.$padding+i.start.column*e.characterWidth;r.renderer(t,i,o,s,e)}else r.type==\"fullLine\"?this.drawFullLineMarker(t,i,r.clazz,e):r.type==\"screenLine\"?this.drawScreenLineMarker(t,i,r.clazz,e):i.isMultiLine()?r.type==\"text\"?this.drawTextMarker(t,i,r.clazz,e):this.drawMultiLineMarker(t,i,r.clazz,e):this.drawSingleLineMarker(t,i,r.clazz+\" ace_start\"+\" ace_br15\",e)}this.element.innerHTML=t.join(\"\")},this.$getTop=function(e,t){return(e-t.firstRowScreen)*t.lineHeight},this.drawTextMarker=function(t,n,i,s,o){var u=this.session,a=n.start.row,f=n.end.row,l=a,c=0,h=0,p=u.getScreenLastRowColumn(l),d=new r(l,n.start.column,l,h);for(;l<=f;l++)d.start.row=d.end.row=l,d.start.column=l==a?n.start.column:u.getRowWrapIndent(l),d.end.column=p,c=h,h=p,p=l+1<f?u.getScreenLastRowColumn(l+1):l==f?0:n.end.column,this.drawSingleLineMarker(t,d,i+(l==a?\" ace_start\":\"\")+\" ace_br\"+e(l==a||l==a+1&&n.start.column,c<h,h>p,l==f),s,l==f?0:1,o)},this.drawMultiLineMarker=function(e,t,n,r,i){var s=this.$padding,o=r.lineHeight,u=this.$getTop(t.start.row,r),a=s+t.start.column*r.characterWidth;i=i||\"\",e.push(\"<div class='\",n,\" ace_br1 ace_start' style='\",\"height:\",o,\"px;\",\"right:0;\",\"top:\",u,\"px;\",\"left:\",a,\"px;\",i,\"'></div>\"),u=this.$getTop(t.end.row,r);var f=t.end.column*r.characterWidth;e.push(\"<div class='\",n,\" ace_br12' style='\",\"height:\",o,\"px;\",\"width:\",f,\"px;\",\"top:\",u,\"px;\",\"left:\",s,\"px;\",i,\"'></div>\"),o=(t.end.row-t.start.row-1)*r.lineHeight;if(o<=0)return;u=this.$getTop(t.start.row+1,r);var l=(t.start.column?1:0)|(t.end.column?0:8);e.push(\"<div class='\",n,l?\" ace_br\"+l:\"\",\"' style='\",\"height:\",o,\"px;\",\"right:0;\",\"top:\",u,\"px;\",\"left:\",s,\"px;\",i,\"'></div>\")},this.drawSingleLineMarker=function(e,t,n,r,i,s){var o=r.lineHeight,u=(t.end.column+(i||0)-t.start.column)*r.characterWidth,a=this.$getTop(t.start.row,r),f=this.$padding+t.start.column*r.characterWidth;e.push(\"<div class='\",n,\"' style='\",\"height:\",o,\"px;\",\"width:\",u,\"px;\",\"top:\",a,\"px;\",\"left:\",f,\"px;\",s||\"\",\"'></div>\")},this.drawFullLineMarker=function(e,t,n,r,i){var s=this.$getTop(t.start.row,r),o=r.lineHeight;t.start.row!=t.end.row&&(o+=this.$getTop(t.end.row,r)-s),e.push(\"<div class='\",n,\"' style='\",\"height:\",o,\"px;\",\"top:\",s,\"px;\",\"left:0;right:0;\",i||\"\",\"'></div>\")},this.drawScreenLineMarker=function(e,t,n,r,i){var s=this.$getTop(t.start.row,r),o=r.lineHeight;e.push(\"<div class='\",n,\"' style='\",\"height:\",o,\"px;\",\"top:\",s,\"px;\",\"left:0;right:0;\",i||\"\",\"'></div>\")}}).call(s.prototype),t.Marker=s}),ace.define(\"ace/layer/text\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/dom\",\"ace/lib/lang\",\"ace/lib/useragent\",\"ace/lib/event_emitter\"],function(e,t,n){\"use strict\";var r=e(\"../lib/oop\"),i=e(\"../lib/dom\"),s=e(\"../lib/lang\"),o=e(\"../lib/useragent\"),u=e(\"../lib/event_emitter\").EventEmitter,a=function(e){this.element=i.createElement(\"div\"),this.element.className=\"ace_layer ace_text-layer\",e.appendChild(this.element),this.$updateEolChar=this.$updateEolChar.bind(this)};(function(){r.implement(this,u),this.EOF_CHAR=\"\\u00b6\",this.EOL_CHAR_LF=\"\\u00ac\",this.EOL_CHAR_CRLF=\"\\u00a4\",this.EOL_CHAR=this.EOL_CHAR_LF,this.TAB_CHAR=\"\\u2014\",this.SPACE_CHAR=\"\\u00b7\",this.$padding=0,this.$updateEolChar=function(){var e=this.session.doc.getNewLineCharacter()==\"\\n\"?this.EOL_CHAR_LF:this.EOL_CHAR_CRLF;if(this.EOL_CHAR!=e)return this.EOL_CHAR=e,!0},this.setPadding=function(e){this.$padding=e,this.element.style.padding=\"0 \"+e+\"px\"},this.getLineHeight=function(){return this.$fontMetrics.$characterSize.height||0},this.getCharacterWidth=function(){return this.$fontMetrics.$characterSize.width||0},this.$setFontMetrics=function(e){this.$fontMetrics=e,this.$fontMetrics.on(\"changeCharacterSize\",function(e){this._signal(\"changeCharacterSize\",e)}.bind(this)),this.$pollSizeChanges()},this.checkForSizeChanges=function(){this.$fontMetrics.checkForSizeChanges()},this.$pollSizeChanges=function(){return this.$pollSizeChangesTimer=this.$fontMetrics.$pollSizeChanges()},this.setSession=function(e){this.session=e,e&&this.$computeTabString()},this.showInvisibles=!1,this.setShowInvisibles=function(e){return this.showInvisibles==e?!1:(this.showInvisibles=e,this.$computeTabString(),!0)},this.displayIndentGuides=!0,this.setDisplayIndentGuides=function(e){return this.displayIndentGuides==e?!1:(this.displayIndentGuides=e,this.$computeTabString(),!0)},this.$tabStrings=[],this.onChangeTabSize=this.$computeTabString=function(){var e=this.session.getTabSize();this.tabSize=e;var t=this.$tabStrings=[0];for(var n=1;n<e+1;n++)this.showInvisibles?t.push(\"<span class='ace_invisible ace_invisible_tab'>\"+s.stringRepeat(this.TAB_CHAR,n)+\"</span>\"):t.push(s.stringRepeat(\" \",n));if(this.displayIndentGuides){this.$indentGuideRe=/\\s\\S| \\t|\\t |\\s$/;var r=\"ace_indent-guide\",i=\"\",o=\"\";if(this.showInvisibles){r+=\" ace_invisible\",i=\" ace_invisible_space\",o=\" ace_invisible_tab\";var u=s.stringRepeat(this.SPACE_CHAR,this.tabSize),a=s.stringRepeat(this.TAB_CHAR,this.tabSize)}else var u=s.stringRepeat(\" \",this.tabSize),a=u;this.$tabStrings[\" \"]=\"<span class='\"+r+i+\"'>\"+u+\"</span>\",this.$tabStrings[\"\t\"]=\"<span class='\"+r+o+\"'>\"+a+\"</span>\"}},this.updateLines=function(e,t,n){(this.config.lastRow!=e.lastRow||this.config.firstRow!=e.firstRow)&&this.scrollLines(e),this.config=e;var r=Math.max(t,e.firstRow),i=Math.min(n,e.lastRow),s=this.element.childNodes,o=0;for(var u=e.firstRow;u<r;u++){var a=this.session.getFoldLine(u);if(a){if(a.containsRow(r)){r=a.start.row;break}u=a.end.row}o++}var u=r,a=this.session.getNextFoldLine(u),f=a?a.start.row:Infinity;for(;;){u>f&&(u=a.end.row+1,a=this.session.getNextFoldLine(u,a),f=a?a.start.row:Infinity);if(u>i)break;var l=s[o++];if(l){var c=[];this.$renderLine(c,u,!this.$useLineGroups(),u==f?a:!1),l.style.height=e.lineHeight*this.session.getRowLength(u)+\"px\",l.innerHTML=c.join(\"\")}u++}},this.scrollLines=function(e){var t=this.config;this.config=e;if(!t||t.lastRow<e.firstRow)return this.update(e);if(e.lastRow<t.firstRow)return this.update(e);var n=this.element;if(t.firstRow<e.firstRow)for(var r=this.session.getFoldedRowCount(t.firstRow,e.firstRow-1);r>0;r--)n.removeChild(n.firstChild);if(t.lastRow>e.lastRow)for(var r=this.session.getFoldedRowCount(e.lastRow+1,t.lastRow);r>0;r--)n.removeChild(n.lastChild);if(e.firstRow<t.firstRow){var i=this.$renderLinesFragment(e,e.firstRow,t.firstRow-1);n.firstChild?n.insertBefore(i,n.firstChild):n.appendChild(i)}if(e.lastRow>t.lastRow){var i=this.$renderLinesFragment(e,t.lastRow+1,e.lastRow);n.appendChild(i)}},this.$renderLinesFragment=function(e,t,n){var r=this.element.ownerDocument.createDocumentFragment(),s=t,o=this.session.getNextFoldLine(s),u=o?o.start.row:Infinity;for(;;){s>u&&(s=o.end.row+1,o=this.session.getNextFoldLine(s,o),u=o?o.start.row:Infinity);if(s>n)break;var a=i.createElement(\"div\"),f=[];this.$renderLine(f,s,!1,s==u?o:!1),a.innerHTML=f.join(\"\");if(this.$useLineGroups())a.className=\"ace_line_group\",r.appendChild(a),a.style.height=e.lineHeight*this.session.getRowLength(s)+\"px\";else while(a.firstChild)r.appendChild(a.firstChild);s++}return r},this.update=function(e){this.config=e;var t=[],n=e.firstRow,r=e.lastRow,i=n,s=this.session.getNextFoldLine(i),o=s?s.start.row:Infinity;for(;;){i>o&&(i=s.end.row+1,s=this.session.getNextFoldLine(i,s),o=s?s.start.row:Infinity);if(i>r)break;this.$useLineGroups()&&t.push(\"<div class='ace_line_group' style='height:\",e.lineHeight*this.session.getRowLength(i),\"px'>\"),this.$renderLine(t,i,!1,i==o?s:!1),this.$useLineGroups()&&t.push(\"</div>\"),i++}this.element.innerHTML=t.join(\"\")},this.$textToken={text:!0,rparen:!0,lparen:!0},this.$renderToken=function(e,t,n,r){var i=this,o=/\\t|&|<|>|( +)|([\\x00-\\x1f\\x80-\\xa0\\xad\\u1680\\u180E\\u2000-\\u200f\\u2028\\u2029\\u202F\\u205F\\u3000\\uFEFF\\uFFF9-\\uFFFC])|[\\u1100-\\u115F\\u11A3-\\u11A7\\u11FA-\\u11FF\\u2329-\\u232A\\u2E80-\\u2E99\\u2E9B-\\u2EF3\\u2F00-\\u2FD5\\u2FF0-\\u2FFB\\u3000-\\u303E\\u3041-\\u3096\\u3099-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u3190-\\u31BA\\u31C0-\\u31E3\\u31F0-\\u321E\\u3220-\\u3247\\u3250-\\u32FE\\u3300-\\u4DBF\\u4E00-\\uA48C\\uA490-\\uA4C6\\uA960-\\uA97C\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFAFF\\uFE10-\\uFE19\\uFE30-\\uFE52\\uFE54-\\uFE66\\uFE68-\\uFE6B\\uFF01-\\uFF60\\uFFE0-\\uFFE6]/g,u=function(e,n,r,o,u){if(n)return i.showInvisibles?\"<span class='ace_invisible ace_invisible_space'>\"+s.stringRepeat(i.SPACE_CHAR,e.length)+\"</span>\":e;if(e==\"&\")return\"&#38;\";if(e==\"<\")return\"&#60;\";if(e==\">\")return\"&#62;\";if(e==\"\t\"){var a=i.session.getScreenTabSize(t+o);return t+=a-1,i.$tabStrings[a]}if(e==\"\\u3000\"){var f=i.showInvisibles?\"ace_cjk ace_invisible ace_invisible_space\":\"ace_cjk\",l=i.showInvisibles?i.SPACE_CHAR:\"\";return t+=1,\"<span class='\"+f+\"' style='width:\"+i.config.characterWidth*2+\"px'>\"+l+\"</span>\"}return r?\"<span class='ace_invisible ace_invisible_space ace_invalid'>\"+i.SPACE_CHAR+\"</span>\":(t+=1,\"<span class='ace_cjk' style='width:\"+i.config.characterWidth*2+\"px'>\"+e+\"</span>\")},a=r.replace(o,u);if(!this.$textToken[n.type]){var f=\"ace_\"+n.type.replace(/\\./g,\" ace_\"),l=\"\";n.type==\"fold\"&&(l=\" style='width:\"+n.value.length*this.config.characterWidth+\"px;' \"),e.push(\"<span class='\",f,\"'\",l,\">\",a,\"</span>\")}else e.push(a);return t+r.length},this.renderIndentGuide=function(e,t,n){var r=t.search(this.$indentGuideRe);return r<=0||r>=n?t:t[0]==\" \"?(r-=r%this.tabSize,e.push(s.stringRepeat(this.$tabStrings[\" \"],r/this.tabSize)),t.substr(r)):t[0]==\"\t\"?(e.push(s.stringRepeat(this.$tabStrings[\"\t\"],r)),t.substr(r)):t},this.$renderWrappedLine=function(e,t,n,r){var i=0,o=0,u=n[0],a=0;for(var f=0;f<t.length;f++){var l=t[f],c=l.value;if(f==0&&this.displayIndentGuides){i=c.length,c=this.renderIndentGuide(e,c,u);if(!c)continue;i-=c.length}if(i+c.length<u)a=this.$renderToken(e,a,l,c),i+=c.length;else{while(i+c.length>=u)a=this.$renderToken(e,a,l,c.substring(0,u-i)),c=c.substring(u-i),i=u,r||e.push(\"</div>\",\"<div class='ace_line' style='height:\",this.config.lineHeight,\"px'>\"),e.push(s.stringRepeat(\"\\u00a0\",n.indent)),o++,a=0,u=n[o]||Number.MAX_VALUE;c.length!=0&&(i+=c.length,a=this.$renderToken(e,a,l,c))}}},this.$renderSimpleLine=function(e,t){var n=0,r=t[0],i=r.value;this.displayIndentGuides&&(i=this.renderIndentGuide(e,i)),i&&(n=this.$renderToken(e,n,r,i));for(var s=1;s<t.length;s++)r=t[s],i=r.value,n=this.$renderToken(e,n,r,i)},this.$renderLine=function(e,t,n,r){!r&&r!=0&&(r=this.session.getFoldLine(t));if(r)var i=this.$getFoldLineTokens(t,r);else var i=this.session.getTokens(t);n||e.push(\"<div class='ace_line' style='height:\",this.config.lineHeight*(this.$useLineGroups()?1:this.session.getRowLength(t)),\"px'>\");if(i.length){var s=this.session.getRowSplitData(t);s&&s.length?this.$renderWrappedLine(e,i,s,n):this.$renderSimpleLine(e,i)}this.showInvisibles&&(r&&(t=r.end.row),e.push(\"<span class='ace_invisible ace_invisible_eol'>\",t==this.session.getLength()-1?this.EOF_CHAR:this.EOL_CHAR,\"</span>\")),n||e.push(\"</div>\")},this.$getFoldLineTokens=function(e,t){function i(e,t,n){var i=0,s=0;while(s+e[i].value.length<t){s+=e[i].value.length,i++;if(i==e.length)return}if(s!=t){var o=e[i].value.substring(t-s);o.length>n-t&&(o=o.substring(0,n-t)),r.push({type:e[i].type,value:o}),s=t+o.length,i+=1}while(s<n&&i<e.length){var o=e[i].value;o.length+s>n?r.push({type:e[i].type,value:o.substring(0,n-s)}):r.push(e[i]),s+=o.length,i+=1}}var n=this.session,r=[],s=n.getTokens(e);return t.walk(function(e,t,o,u,a){e!=null?r.push({type:\"fold\",value:e}):(a&&(s=n.getTokens(t)),s.length&&i(s,u,o))},t.end.row,this.session.getLine(t.end.row).length),r},this.$useLineGroups=function(){return this.session.getUseWrapMode()},this.destroy=function(){clearInterval(this.$pollSizeChangesTimer),this.$measureNode&&this.$measureNode.parentNode.removeChild(this.$measureNode),delete this.$measureNode}}).call(a.prototype),t.Text=a}),ace.define(\"ace/layer/cursor\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\"],function(e,t,n){\"use strict\";var r=e(\"../lib/dom\"),i,s=function(e){this.element=r.createElement(\"div\"),this.element.className=\"ace_layer ace_cursor-layer\",e.appendChild(this.element),i===undefined&&(i=!(\"opacity\"in this.element.style)),this.isVisible=!1,this.isBlinking=!0,this.blinkInterval=1e3,this.smoothBlinking=!1,this.cursors=[],this.cursor=this.addCursor(),r.addCssClass(this.element,\"ace_hidden-cursors\"),this.$updateCursors=(i?this.$updateVisibility:this.$updateOpacity).bind(this)};(function(){this.$updateVisibility=function(e){var t=this.cursors;for(var n=t.length;n--;)t[n].style.visibility=e?\"\":\"hidden\"},this.$updateOpacity=function(e){var t=this.cursors;for(var n=t.length;n--;)t[n].style.opacity=e?\"\":\"0\"},this.$padding=0,this.setPadding=function(e){this.$padding=e},this.setSession=function(e){this.session=e},this.setBlinking=function(e){e!=this.isBlinking&&(this.isBlinking=e,this.restartTimer())},this.setBlinkInterval=function(e){e!=this.blinkInterval&&(this.blinkInterval=e,this.restartTimer())},this.setSmoothBlinking=function(e){e!=this.smoothBlinking&&!i&&(this.smoothBlinking=e,r.setCssClass(this.element,\"ace_smooth-blinking\",e),this.$updateCursors(!0),this.$updateCursors=this.$updateOpacity.bind(this),this.restartTimer())},this.addCursor=function(){var e=r.createElement(\"div\");return e.className=\"ace_cursor\",this.element.appendChild(e),this.cursors.push(e),e},this.removeCursor=function(){if(this.cursors.length>1){var e=this.cursors.pop();return e.parentNode.removeChild(e),e}},this.hideCursor=function(){this.isVisible=!1,r.addCssClass(this.element,\"ace_hidden-cursors\"),this.restartTimer()},this.showCursor=function(){this.isVisible=!0,r.removeCssClass(this.element,\"ace_hidden-cursors\"),this.restartTimer()},this.restartTimer=function(){var e=this.$updateCursors;clearInterval(this.intervalId),clearTimeout(this.timeoutId),this.smoothBlinking&&r.removeCssClass(this.element,\"ace_smooth-blinking\"),e(!0);if(!this.isBlinking||!this.blinkInterval||!this.isVisible)return;this.smoothBlinking&&setTimeout(function(){r.addCssClass(this.element,\"ace_smooth-blinking\")}.bind(this));var t=function(){this.timeoutId=setTimeout(function(){e(!1)},.6*this.blinkInterval)}.bind(this);this.intervalId=setInterval(function(){e(!0),t()},this.blinkInterval),t()},this.getPixelPosition=function(e,t){if(!this.config||!this.session)return{left:0,top:0};e||(e=this.session.selection.getCursor());var n=this.session.documentToScreenPosition(e),r=this.$padding+n.column*this.config.characterWidth,i=(n.row-(t?this.config.firstRowScreen:0))*this.config.lineHeight;return{left:r,top:i}},this.update=function(e){this.config=e;var t=this.session.$selectionMarkers,n=0,r=0;if(t===undefined||t.length===0)t=[{cursor:null}];for(var n=0,i=t.length;n<i;n++){var s=this.getPixelPosition(t[n].cursor,!0);if((s.top>e.height+e.offset||s.top<0)&&n>1)continue;var o=(this.cursors[r++]||this.addCursor()).style;this.drawCursor?this.drawCursor(o,s,e,t[n],this.session):(o.left=s.left+\"px\",o.top=s.top+\"px\",o.width=e.characterWidth+\"px\",o.height=e.lineHeight+\"px\")}while(this.cursors.length>r)this.removeCursor();var u=this.session.getOverwrite();this.$setOverwrite(u),this.$pixelPos=s,this.restartTimer()},this.drawCursor=null,this.$setOverwrite=function(e){e!=this.overwrite&&(this.overwrite=e,e?r.addCssClass(this.element,\"ace_overwrite-cursors\"):r.removeCssClass(this.element,\"ace_overwrite-cursors\"))},this.destroy=function(){clearInterval(this.intervalId),clearTimeout(this.timeoutId)}}).call(s.prototype),t.Cursor=s}),ace.define(\"ace/scrollbar\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/dom\",\"ace/lib/event\",\"ace/lib/event_emitter\"],function(e,t,n){\"use strict\";var r=e(\"./lib/oop\"),i=e(\"./lib/dom\"),s=e(\"./lib/event\"),o=e(\"./lib/event_emitter\").EventEmitter,u=function(e){this.element=i.createElement(\"div\"),this.element.className=\"ace_scrollbar ace_scrollbar\"+this.classSuffix,this.inner=i.createElement(\"div\"),this.inner.className=\"ace_scrollbar-inner\",this.element.appendChild(this.inner),e.appendChild(this.element),this.setVisible(!1),this.skipEvent=!1,s.addListener(this.element,\"scroll\",this.onScroll.bind(this)),s.addListener(this.element,\"mousedown\",s.preventDefault)};(function(){r.implement(this,o),this.setVisible=function(e){this.element.style.display=e?\"\":\"none\",this.isVisible=e}}).call(u.prototype);var a=function(e,t){u.call(this,e),this.scrollTop=0,t.$scrollbarWidth=this.width=i.scrollbarWidth(e.ownerDocument),this.inner.style.width=this.element.style.width=(this.width||15)+5+\"px\"};r.inherits(a,u),function(){this.classSuffix=\"-v\",this.onScroll=function(){this.skipEvent||(this.scrollTop=this.element.scrollTop,this._emit(\"scroll\",{data:this.scrollTop})),this.skipEvent=!1},this.getWidth=function(){return this.isVisible?this.width:0},this.setHeight=function(e){this.element.style.height=e+\"px\"},this.setInnerHeight=function(e){this.inner.style.height=e+\"px\"},this.setScrollHeight=function(e){this.inner.style.height=e+\"px\"},this.setScrollTop=function(e){this.scrollTop!=e&&(this.skipEvent=!0,this.scrollTop=this.element.scrollTop=e)}}.call(a.prototype);var f=function(e,t){u.call(this,e),this.scrollLeft=0,this.height=t.$scrollbarWidth,this.inner.style.height=this.element.style.height=(this.height||15)+5+\"px\"};r.inherits(f,u),function(){this.classSuffix=\"-h\",this.onScroll=function(){this.skipEvent||(this.scrollLeft=this.element.scrollLeft,this._emit(\"scroll\",{data:this.scrollLeft})),this.skipEvent=!1},this.getHeight=function(){return this.isVisible?this.height:0},this.setWidth=function(e){this.element.style.width=e+\"px\"},this.setInnerWidth=function(e){this.inner.style.width=e+\"px\"},this.setScrollWidth=function(e){this.inner.style.width=e+\"px\"},this.setScrollLeft=function(e){this.scrollLeft!=e&&(this.skipEvent=!0,this.scrollLeft=this.element.scrollLeft=e)}}.call(f.prototype),t.ScrollBar=a,t.ScrollBarV=a,t.ScrollBarH=f,t.VScrollBar=a,t.HScrollBar=f}),ace.define(\"ace/renderloop\",[\"require\",\"exports\",\"module\",\"ace/lib/event\"],function(e,t,n){\"use strict\";var r=e(\"./lib/event\"),i=function(e,t){this.onRender=e,this.pending=!1,this.changes=0,this.window=t||window};(function(){this.schedule=function(e){this.changes=this.changes|e;if(!this.pending&&this.changes){this.pending=!0;var t=this;r.nextFrame(function(){t.pending=!1;var e;while(e=t.changes)t.changes=0,t.onRender(e)},this.window)}}}).call(i.prototype),t.RenderLoop=i}),ace.define(\"ace/layer/font_metrics\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/dom\",\"ace/lib/lang\",\"ace/lib/useragent\",\"ace/lib/event_emitter\"],function(e,t,n){var r=e(\"../lib/oop\"),i=e(\"../lib/dom\"),s=e(\"../lib/lang\"),o=e(\"../lib/useragent\"),u=e(\"../lib/event_emitter\").EventEmitter,a=0,f=t.FontMetrics=function(e){this.el=i.createElement(\"div\"),this.$setMeasureNodeStyles(this.el.style,!0),this.$main=i.createElement(\"div\"),this.$setMeasureNodeStyles(this.$main.style),this.$measureNode=i.createElement(\"div\"),this.$setMeasureNodeStyles(this.$measureNode.style),this.el.appendChild(this.$main),this.el.appendChild(this.$measureNode),e.appendChild(this.el),a||this.$testFractionalRect(),this.$measureNode.innerHTML=s.stringRepeat(\"X\",a),this.$characterSize={width:0,height:0},this.checkForSizeChanges()};(function(){r.implement(this,u),this.$characterSize={width:0,height:0},this.$testFractionalRect=function(){var e=i.createElement(\"div\");this.$setMeasureNodeStyles(e.style),e.style.width=\"0.2px\",document.documentElement.appendChild(e);var t=e.getBoundingClientRect().width;t>0&&t<1?a=50:a=100,e.parentNode.removeChild(e)},this.$setMeasureNodeStyles=function(e,t){e.width=e.height=\"auto\",e.left=e.top=\"0px\",e.visibility=\"hidden\",e.position=\"absolute\",e.whiteSpace=\"pre\",o.isIE<8?e[\"font-family\"]=\"inherit\":e.font=\"inherit\",e.overflow=t?\"hidden\":\"visible\"},this.checkForSizeChanges=function(){var e=this.$measureSizes();if(e&&(this.$characterSize.width!==e.width||this.$characterSize.height!==e.height)){this.$measureNode.style.fontWeight=\"bold\";var t=this.$measureSizes();this.$measureNode.style.fontWeight=\"\",this.$characterSize=e,this.charSizes=Object.create(null),this.allowBoldFonts=t&&t.width===e.width&&t.height===e.height,this._emit(\"changeCharacterSize\",{data:e})}},this.$pollSizeChanges=function(){if(this.$pollSizeChangesTimer)return this.$pollSizeChangesTimer;var e=this;return this.$pollSizeChangesTimer=setInterval(function(){e.checkForSizeChanges()},500)},this.setPolling=function(e){e?this.$pollSizeChanges():this.$pollSizeChangesTimer&&(clearInterval(this.$pollSizeChangesTimer),this.$pollSizeChangesTimer=0)},this.$measureSizes=function(){if(a===50){var e=null;try{e=this.$measureNode.getBoundingClientRect()}catch(t){e={width:0,height:0}}var n={height:e.height,width:e.width/a}}else var n={height:this.$measureNode.clientHeight,width:this.$measureNode.clientWidth/a};return n.width===0||n.height===0?null:n},this.$measureCharWidth=function(e){this.$main.innerHTML=s.stringRepeat(e,a);var t=this.$main.getBoundingClientRect();return t.width/a},this.getCharacterWidth=function(e){var t=this.charSizes[e];return t===undefined&&(t=this.charSizes[e]=this.$measureCharWidth(e)/this.$characterSize.width),t},this.destroy=function(){clearInterval(this.$pollSizeChangesTimer),this.el&&this.el.parentNode&&this.el.parentNode.removeChild(this.el)}}).call(f.prototype)}),ace.define(\"ace/virtual_renderer\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/dom\",\"ace/config\",\"ace/lib/useragent\",\"ace/layer/gutter\",\"ace/layer/marker\",\"ace/layer/text\",\"ace/layer/cursor\",\"ace/scrollbar\",\"ace/scrollbar\",\"ace/renderloop\",\"ace/layer/font_metrics\",\"ace/lib/event_emitter\"],function(e,t,n){\"use strict\";var r=e(\"./lib/oop\"),i=e(\"./lib/dom\"),s=e(\"./config\"),o=e(\"./lib/useragent\"),u=e(\"./layer/gutter\").Gutter,a=e(\"./layer/marker\").Marker,f=e(\"./layer/text\").Text,l=e(\"./layer/cursor\").Cursor,c=e(\"./scrollbar\").HScrollBar,h=e(\"./scrollbar\").VScrollBar,p=e(\"./renderloop\").RenderLoop,d=e(\"./layer/font_metrics\").FontMetrics,v=e(\"./lib/event_emitter\").EventEmitter,m='.ace_editor {position: relative;overflow: hidden;font: 12px/normal \\'Monaco\\', \\'Menlo\\', \\'Ubuntu Mono\\', \\'Consolas\\', \\'source-code-pro\\', monospace;direction: ltr;}.ace_scroller {position: absolute;overflow: hidden;top: 0;bottom: 0;background-color: inherit;-ms-user-select: none;-moz-user-select: none;-webkit-user-select: none;user-select: none;cursor: text;}.ace_content {position: absolute;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;min-width: 100%;}.ace_dragging .ace_scroller:before{position: absolute;top: 0;left: 0;right: 0;bottom: 0;content: \\'\\';background: rgba(250, 250, 250, 0.01);z-index: 1000;}.ace_dragging.ace_dark .ace_scroller:before{background: rgba(0, 0, 0, 0.01);}.ace_selecting, .ace_selecting * {cursor: text !important;}.ace_gutter {position: absolute;overflow : hidden;width: auto;top: 0;bottom: 0;left: 0;cursor: default;z-index: 4;-ms-user-select: none;-moz-user-select: none;-webkit-user-select: none;user-select: none;}.ace_gutter-active-line {position: absolute;left: 0;right: 0;}.ace_scroller.ace_scroll-left {box-shadow: 17px 0 16px -16px rgba(0, 0, 0, 0.4) inset;}.ace_gutter-cell {padding-left: 19px;padding-right: 6px;background-repeat: no-repeat;}.ace_gutter-cell.ace_error {background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABOFBMVEX/////////QRswFAb/Ui4wFAYwFAYwFAaWGAfDRymzOSH/PxswFAb/SiUwFAYwFAbUPRvjQiDllog5HhHdRybsTi3/Tyv9Tir+Syj/UC3////XurebMBIwFAb/RSHbPx/gUzfdwL3kzMivKBAwFAbbvbnhPx66NhowFAYwFAaZJg8wFAaxKBDZurf/RB6mMxb/SCMwFAYwFAbxQB3+RB4wFAb/Qhy4Oh+4QifbNRcwFAYwFAYwFAb/QRzdNhgwFAYwFAbav7v/Uy7oaE68MBK5LxLewr/r2NXewLswFAaxJw4wFAbkPRy2PyYwFAaxKhLm1tMwFAazPiQwFAaUGAb/QBrfOx3bvrv/VC/maE4wFAbRPBq6MRO8Qynew8Dp2tjfwb0wFAbx6eju5+by6uns4uH9/f36+vr/GkHjAAAAYnRSTlMAGt+64rnWu/bo8eAA4InH3+DwoN7j4eLi4xP99Nfg4+b+/u9B/eDs1MD1mO7+4PHg2MXa347g7vDizMLN4eG+Pv7i5evs/v79yu7S3/DV7/498Yv24eH+4ufQ3Ozu/v7+y13sRqwAAADLSURBVHjaZc/XDsFgGIBhtDrshlitmk2IrbHFqL2pvXf/+78DPokj7+Fz9qpU/9UXJIlhmPaTaQ6QPaz0mm+5gwkgovcV6GZzd5JtCQwgsxoHOvJO15kleRLAnMgHFIESUEPmawB9ngmelTtipwwfASilxOLyiV5UVUyVAfbG0cCPHig+GBkzAENHS0AstVF6bacZIOzgLmxsHbt2OecNgJC83JERmePUYq8ARGkJx6XtFsdddBQgZE2nPR6CICZhawjA4Fb/chv+399kfR+MMMDGOQAAAABJRU5ErkJggg==\");background-repeat: no-repeat;background-position: 2px center;}.ace_gutter-cell.ace_warning {background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAmVBMVEX///8AAAD///8AAAAAAABPSzb/5sAAAAB/blH/73z/ulkAAAAAAAD85pkAAAAAAAACAgP/vGz/rkDerGbGrV7/pkQICAf////e0IsAAAD/oED/qTvhrnUAAAD/yHD/njcAAADuv2r/nz//oTj/p064oGf/zHAAAAA9Nir/tFIAAAD/tlTiuWf/tkIAAACynXEAAAAAAAAtIRW7zBpBAAAAM3RSTlMAABR1m7RXO8Ln31Z36zT+neXe5OzooRDfn+TZ4p3h2hTf4t3k3ucyrN1K5+Xaks52Sfs9CXgrAAAAjklEQVR42o3PbQ+CIBQFYEwboPhSYgoYunIqqLn6/z8uYdH8Vmdnu9vz4WwXgN/xTPRD2+sgOcZjsge/whXZgUaYYvT8QnuJaUrjrHUQreGczuEafQCO/SJTufTbroWsPgsllVhq3wJEk2jUSzX3CUEDJC84707djRc5MTAQxoLgupWRwW6UB5fS++NV8AbOZgnsC7BpEAAAAABJRU5ErkJggg==\");background-position: 2px center;}.ace_gutter-cell.ace_info {background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAAAAAA6mKC9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAJ0Uk5TAAB2k804AAAAPklEQVQY02NgIB68QuO3tiLznjAwpKTgNyDbMegwisCHZUETUZV0ZqOquBpXj2rtnpSJT1AEnnRmL2OgGgAAIKkRQap2htgAAAAASUVORK5CYII=\");background-position: 2px center;}.ace_dark .ace_gutter-cell.ace_info {background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAChoaGAgIAqKiq+vr6tra1ZWVmUlJSbm5s8PDxubm56enrdgzg3AAAAAXRSTlMAQObYZgAAAClJREFUeNpjYMAPdsMYHegyJZFQBlsUlMFVCWUYKkAZMxZAGdxlDMQBAG+TBP4B6RyJAAAAAElFTkSuQmCC\");}.ace_scrollbar {position: absolute;right: 0;bottom: 0;z-index: 6;}.ace_scrollbar-inner {position: absolute;cursor: text;left: 0;top: 0;}.ace_scrollbar-v{overflow-x: hidden;overflow-y: scroll;top: 0;}.ace_scrollbar-h {overflow-x: scroll;overflow-y: hidden;left: 0;}.ace_print-margin {position: absolute;height: 100%;}.ace_text-input {position: absolute;z-index: 0;width: 0.5em;height: 1em;opacity: 0;background: transparent;-moz-appearance: none;appearance: none;border: none;resize: none;outline: none;overflow: hidden;font: inherit;padding: 0 1px;margin: 0 -1px;text-indent: -1em;-ms-user-select: text;-moz-user-select: text;-webkit-user-select: text;user-select: text;white-space: pre!important;}.ace_text-input.ace_composition {background: inherit;color: inherit;z-index: 1000;opacity: 1;text-indent: 0;}.ace_layer {z-index: 1;position: absolute;overflow: hidden;word-wrap: normal;white-space: pre;height: 100%;width: 100%;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;pointer-events: none;}.ace_gutter-layer {position: relative;width: auto;text-align: right;pointer-events: auto;}.ace_text-layer {font: inherit !important;}.ace_cjk {display: inline-block;text-align: center;}.ace_cursor-layer {z-index: 4;}.ace_cursor {z-index: 4;position: absolute;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;border-left: 2px solid;transform: translatez(0);}.ace_slim-cursors .ace_cursor {border-left-width: 1px;}.ace_overwrite-cursors .ace_cursor {border-left-width: 0;border-bottom: 1px solid;}.ace_hidden-cursors .ace_cursor {opacity: 0.2;}.ace_smooth-blinking .ace_cursor {-webkit-transition: opacity 0.18s;transition: opacity 0.18s;}.ace_editor.ace_multiselect .ace_cursor {border-left-width: 1px;}.ace_marker-layer .ace_step, .ace_marker-layer .ace_stack {position: absolute;z-index: 3;}.ace_marker-layer .ace_selection {position: absolute;z-index: 5;}.ace_marker-layer .ace_bracket {position: absolute;z-index: 6;}.ace_marker-layer .ace_active-line {position: absolute;z-index: 2;}.ace_marker-layer .ace_selected-word {position: absolute;z-index: 4;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;}.ace_line .ace_fold {-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;display: inline-block;height: 11px;margin-top: -2px;vertical-align: middle;background-image:url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII=\"),url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACJJREFUeNpi+P//fxgTAwPDBxDxD078RSX+YeEyDFMCIMAAI3INmXiwf2YAAAAASUVORK5CYII=\");background-repeat: no-repeat, repeat-x;background-position: center center, top left;color: transparent;border: 1px solid black;border-radius: 2px;cursor: pointer;pointer-events: auto;}.ace_dark .ace_fold {}.ace_fold:hover{background-image:url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII=\"),url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACBJREFUeNpi+P//fz4TAwPDZxDxD5X4i5fLMEwJgAADAEPVDbjNw87ZAAAAAElFTkSuQmCC\");}.ace_tooltip {background-color: #FFF;background-image: -webkit-linear-gradient(top, transparent, rgba(0, 0, 0, 0.1));background-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.1));border: 1px solid gray;border-radius: 1px;box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);color: black;max-width: 100%;padding: 3px 4px;position: fixed;z-index: 999999;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;cursor: default;white-space: pre;word-wrap: break-word;line-height: normal;font-style: normal;font-weight: normal;letter-spacing: normal;pointer-events: none;}.ace_folding-enabled > .ace_gutter-cell {padding-right: 13px;}.ace_fold-widget {-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;margin: 0 -12px 0 1px;display: none;width: 11px;vertical-align: top;background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42mWKsQ0AMAzC8ixLlrzQjzmBiEjp0A6WwBCSPgKAXoLkqSot7nN3yMwR7pZ32NzpKkVoDBUxKAAAAABJRU5ErkJggg==\");background-repeat: no-repeat;background-position: center;border-radius: 3px;border: 1px solid transparent;cursor: pointer;}.ace_folding-enabled .ace_fold-widget {display: inline-block;   }.ace_fold-widget.ace_end {background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42m3HwQkAMAhD0YzsRchFKI7sAikeWkrxwScEB0nh5e7KTPWimZki4tYfVbX+MNl4pyZXejUO1QAAAABJRU5ErkJggg==\");}.ace_fold-widget.ace_closed {background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAGCAYAAAAG5SQMAAAAOUlEQVR42jXKwQkAMAgDwKwqKD4EwQ26sSOkVWjgIIHAzPiCgaqiqnJHZnKICBERHN194O5b9vbLuAVRL+l0YWnZAAAAAElFTkSuQmCCXA==\");}.ace_fold-widget:hover {border: 1px solid rgba(0, 0, 0, 0.3);background-color: rgba(255, 255, 255, 0.2);box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);}.ace_fold-widget:active {border: 1px solid rgba(0, 0, 0, 0.4);background-color: rgba(0, 0, 0, 0.05);box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);}.ace_dark .ace_fold-widget {background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHklEQVQIW2P4//8/AzoGEQ7oGCaLLAhWiSwB146BAQCSTPYocqT0AAAAAElFTkSuQmCC\");}.ace_dark .ace_fold-widget.ace_end {background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAH0lEQVQIW2P4//8/AxQ7wNjIAjDMgC4AxjCVKBirIAAF0kz2rlhxpAAAAABJRU5ErkJggg==\");}.ace_dark .ace_fold-widget.ace_closed {background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAHElEQVQIW2P4//+/AxAzgDADlOOAznHAKgPWAwARji8UIDTfQQAAAABJRU5ErkJggg==\");}.ace_dark .ace_fold-widget:hover {box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);background-color: rgba(255, 255, 255, 0.1);}.ace_dark .ace_fold-widget:active {box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);}.ace_fold-widget.ace_invalid {background-color: #FFB4B4;border-color: #DE5555;}.ace_fade-fold-widgets .ace_fold-widget {-webkit-transition: opacity 0.4s ease 0.05s;transition: opacity 0.4s ease 0.05s;opacity: 0;}.ace_fade-fold-widgets:hover .ace_fold-widget {-webkit-transition: opacity 0.05s ease 0.05s;transition: opacity 0.05s ease 0.05s;opacity:1;}.ace_underline {text-decoration: underline;}.ace_bold {font-weight: bold;}.ace_nobold .ace_bold {font-weight: normal;}.ace_italic {font-style: italic;}.ace_error-marker {background-color: rgba(255, 0, 0,0.2);position: absolute;z-index: 9;}.ace_highlight-marker {background-color: rgba(255, 255, 0,0.2);position: absolute;z-index: 8;}.ace_br1 {border-top-left-radius    : 3px;}.ace_br2 {border-top-right-radius   : 3px;}.ace_br3 {border-top-left-radius    : 3px; border-top-right-radius:    3px;}.ace_br4 {border-bottom-right-radius: 3px;}.ace_br5 {border-top-left-radius    : 3px; border-bottom-right-radius: 3px;}.ace_br6 {border-top-right-radius   : 3px; border-bottom-right-radius: 3px;}.ace_br7 {border-top-left-radius    : 3px; border-top-right-radius:    3px; border-bottom-right-radius: 3px;}.ace_br8 {border-bottom-left-radius : 3px;}.ace_br9 {border-top-left-radius    : 3px; border-bottom-left-radius:  3px;}.ace_br10{border-top-right-radius   : 3px; border-bottom-left-radius:  3px;}.ace_br11{border-top-left-radius    : 3px; border-top-right-radius:    3px; border-bottom-left-radius:  3px;}.ace_br12{border-bottom-right-radius: 3px; border-bottom-left-radius:  3px;}.ace_br13{border-top-left-radius    : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius:  3px;}.ace_br14{border-top-right-radius   : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius:  3px;}.ace_br15{border-top-left-radius    : 3px; border-top-right-radius:    3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}';i.importCssString(m,\"ace_editor.css\");var g=function(e,t){var n=this;this.container=e||i.createElement(\"div\"),this.$keepTextAreaAtCursor=!o.isOldIE,i.addCssClass(this.container,\"ace_editor\"),this.setTheme(t),this.$gutter=i.createElement(\"div\"),this.$gutter.className=\"ace_gutter\",this.container.appendChild(this.$gutter),this.scroller=i.createElement(\"div\"),this.scroller.className=\"ace_scroller\",this.container.appendChild(this.scroller),this.content=i.createElement(\"div\"),this.content.className=\"ace_content\",this.scroller.appendChild(this.content),this.$gutterLayer=new u(this.$gutter),this.$gutterLayer.on(\"changeGutterWidth\",this.onGutterResize.bind(this)),this.$markerBack=new a(this.content);var r=this.$textLayer=new f(this.content);this.canvas=r.element,this.$markerFront=new a(this.content),this.$cursorLayer=new l(this.content),this.$horizScroll=!1,this.$vScroll=!1,this.scrollBar=this.scrollBarV=new h(this.container,this),this.scrollBarH=new c(this.container,this),this.scrollBarV.addEventListener(\"scroll\",function(e){n.$scrollAnimation||n.session.setScrollTop(e.data-n.scrollMargin.top)}),this.scrollBarH.addEventListener(\"scroll\",function(e){n.$scrollAnimation||n.session.setScrollLeft(e.data-n.scrollMargin.left)}),this.scrollTop=0,this.scrollLeft=0,this.cursorPos={row:0,column:0},this.$fontMetrics=new d(this.container),this.$textLayer.$setFontMetrics(this.$fontMetrics),this.$textLayer.addEventListener(\"changeCharacterSize\",function(e){n.updateCharacterSize(),n.onResize(!0,n.gutterWidth,n.$size.width,n.$size.height),n._signal(\"changeCharacterSize\",e)}),this.$size={width:0,height:0,scrollerHeight:0,scrollerWidth:0,$dirty:!0},this.layerConfig={width:1,padding:0,firstRow:0,firstRowScreen:0,lastRow:0,lineHeight:0,characterWidth:0,minHeight:1,maxHeight:1,offset:0,height:1,gutterOffset:1},this.scrollMargin={left:0,right:0,top:0,bottom:0,v:0,h:0},this.$loop=new p(this.$renderChanges.bind(this),this.container.ownerDocument.defaultView),this.$loop.schedule(this.CHANGE_FULL),this.updateCharacterSize(),this.setPadding(4),s.resetOptions(this),s._emit(\"renderer\",this)};(function(){this.CHANGE_CURSOR=1,this.CHANGE_MARKER=2,this.CHANGE_GUTTER=4,this.CHANGE_SCROLL=8,this.CHANGE_LINES=16,this.CHANGE_TEXT=32,this.CHANGE_SIZE=64,this.CHANGE_MARKER_BACK=128,this.CHANGE_MARKER_FRONT=256,this.CHANGE_FULL=512,this.CHANGE_H_SCROLL=1024,r.implement(this,v),this.updateCharacterSize=function(){this.$textLayer.allowBoldFonts!=this.$allowBoldFonts&&(this.$allowBoldFonts=this.$textLayer.allowBoldFonts,this.setStyle(\"ace_nobold\",!this.$allowBoldFonts)),this.layerConfig.characterWidth=this.characterWidth=this.$textLayer.getCharacterWidth(),this.layerConfig.lineHeight=this.lineHeight=this.$textLayer.getLineHeight(),this.$updatePrintMargin()},this.setSession=function(e){this.session&&this.session.doc.off(\"changeNewLineMode\",this.onChangeNewLineMode),this.session=e,e&&this.scrollMargin.top&&e.getScrollTop()<=0&&e.setScrollTop(-this.scrollMargin.top),this.$cursorLayer.setSession(e),this.$markerBack.setSession(e),this.$markerFront.setSession(e),this.$gutterLayer.setSession(e),this.$textLayer.setSession(e);if(!e)return;this.$loop.schedule(this.CHANGE_FULL),this.session.$setFontMetrics(this.$fontMetrics),this.onChangeNewLineMode=this.onChangeNewLineMode.bind(this),this.onChangeNewLineMode(),this.session.doc.on(\"changeNewLineMode\",this.onChangeNewLineMode)},this.updateLines=function(e,t,n){t===undefined&&(t=Infinity),this.$changedLines?(this.$changedLines.firstRow>e&&(this.$changedLines.firstRow=e),this.$changedLines.lastRow<t&&(this.$changedLines.lastRow=t)):this.$changedLines={firstRow:e,lastRow:t};if(this.$changedLines.lastRow<this.layerConfig.firstRow){if(!n)return;this.$changedLines.lastRow=this.layerConfig.lastRow}if(this.$changedLines.firstRow>this.layerConfig.lastRow)return;this.$loop.schedule(this.CHANGE_LINES)},this.onChangeNewLineMode=function(){this.$loop.schedule(this.CHANGE_TEXT),this.$textLayer.$updateEolChar()},this.onChangeTabSize=function(){this.$loop.schedule(this.CHANGE_TEXT|this.CHANGE_MARKER),this.$textLayer.onChangeTabSize()},this.updateText=function(){this.$loop.schedule(this.CHANGE_TEXT)},this.updateFull=function(e){e?this.$renderChanges(this.CHANGE_FULL,!0):this.$loop.schedule(this.CHANGE_FULL)},this.updateFontSize=function(){this.$textLayer.checkForSizeChanges()},this.$changes=0,this.$updateSizeAsync=function(){this.$loop.pending?this.$size.$dirty=!0:this.onResize()},this.onResize=function(e,t,n,r){if(this.resizing>2)return;this.resizing>0?this.resizing++:this.resizing=e?1:0;var i=this.container;r||(r=i.clientHeight||i.scrollHeight),n||(n=i.clientWidth||i.scrollWidth);var s=this.$updateCachedSize(e,t,n,r);if(!this.$size.scrollerHeight||!n&&!r)return this.resizing=0;e&&(this.$gutterLayer.$padding=null),e?this.$renderChanges(s|this.$changes,!0):this.$loop.schedule(s|this.$changes),this.resizing&&(this.resizing=0),this.scrollBarV.scrollLeft=this.scrollBarV.scrollTop=null},this.$updateCachedSize=function(e,t,n,r){r-=this.$extraHeight||0;var i=0,s=this.$size,o={width:s.width,height:s.height,scrollerHeight:s.scrollerHeight,scrollerWidth:s.scrollerWidth};r&&(e||s.height!=r)&&(s.height=r,i|=this.CHANGE_SIZE,s.scrollerHeight=s.height,this.$horizScroll&&(s.scrollerHeight-=this.scrollBarH.getHeight()),this.scrollBarV.element.style.bottom=this.scrollBarH.getHeight()+\"px\",i|=this.CHANGE_SCROLL);if(n&&(e||s.width!=n)){i|=this.CHANGE_SIZE,s.width=n,t==null&&(t=this.$showGutter?this.$gutter.offsetWidth:0),this.gutterWidth=t,this.scrollBarH.element.style.left=this.scroller.style.left=t+\"px\",s.scrollerWidth=Math.max(0,n-t-this.scrollBarV.getWidth()),this.scrollBarH.element.style.right=this.scroller.style.right=this.scrollBarV.getWidth()+\"px\",this.scroller.style.bottom=this.scrollBarH.getHeight()+\"px\";if(this.session&&this.session.getUseWrapMode()&&this.adjustWrapLimit()||e)i|=this.CHANGE_FULL}return s.$dirty=!n||!r,i&&this._signal(\"resize\",o),i},this.onGutterResize=function(){var e=this.$showGutter?this.$gutter.offsetWidth:0;e!=this.gutterWidth&&(this.$changes|=this.$updateCachedSize(!0,e,this.$size.width,this.$size.height)),this.session.getUseWrapMode()&&this.adjustWrapLimit()?this.$loop.schedule(this.CHANGE_FULL):this.$size.$dirty?this.$loop.schedule(this.CHANGE_FULL):(this.$computeLayerConfig(),this.$loop.schedule(this.CHANGE_MARKER))},this.adjustWrapLimit=function(){var e=this.$size.scrollerWidth-this.$padding*2,t=Math.floor(e/this.characterWidth);return this.session.adjustWrapLimit(t,this.$showPrintMargin&&this.$printMarginColumn)},this.setAnimatedScroll=function(e){this.setOption(\"animatedScroll\",e)},this.getAnimatedScroll=function(){return this.$animatedScroll},this.setShowInvisibles=function(e){this.setOption(\"showInvisibles\",e)},this.getShowInvisibles=function(){return this.getOption(\"showInvisibles\")},this.getDisplayIndentGuides=function(){return this.getOption(\"displayIndentGuides\")},this.setDisplayIndentGuides=function(e){this.setOption(\"displayIndentGuides\",e)},this.setShowPrintMargin=function(e){this.setOption(\"showPrintMargin\",e)},this.getShowPrintMargin=function(){return this.getOption(\"showPrintMargin\")},this.setPrintMarginColumn=function(e){this.setOption(\"printMarginColumn\",e)},this.getPrintMarginColumn=function(){return this.getOption(\"printMarginColumn\")},this.getShowGutter=function(){return this.getOption(\"showGutter\")},this.setShowGutter=function(e){return this.setOption(\"showGutter\",e)},this.getFadeFoldWidgets=function(){return this.getOption(\"fadeFoldWidgets\")},this.setFadeFoldWidgets=function(e){this.setOption(\"fadeFoldWidgets\",e)},this.setHighlightGutterLine=function(e){this.setOption(\"highlightGutterLine\",e)},this.getHighlightGutterLine=function(){return this.getOption(\"highlightGutterLine\")},this.$updateGutterLineHighlight=function(){var e=this.$cursorLayer.$pixelPos,t=this.layerConfig.lineHeight;if(this.session.getUseWrapMode()){var n=this.session.selection.getCursor();n.column=0,e=this.$cursorLayer.getPixelPosition(n,!0),t*=this.session.getRowLength(n.row)}this.$gutterLineHighlight.style.top=e.top-this.layerConfig.offset+\"px\",this.$gutterLineHighlight.style.height=t+\"px\"},this.$updatePrintMargin=function(){if(!this.$showPrintMargin&&!this.$printMarginEl)return;if(!this.$printMarginEl){var e=i.createElement(\"div\");e.className=\"ace_layer ace_print-margin-layer\",this.$printMarginEl=i.createElement(\"div\"),this.$printMarginEl.className=\"ace_print-margin\",e.appendChild(this.$printMarginEl),this.content.insertBefore(e,this.content.firstChild)}var t=this.$printMarginEl.style;t.left=this.characterWidth*this.$printMarginColumn+this.$padding+\"px\",t.visibility=this.$showPrintMargin?\"visible\":\"hidden\",this.session&&this.session.$wrap==-1&&this.adjustWrapLimit()},this.getContainerElement=function(){return this.container},this.getMouseEventTarget=function(){return this.scroller},this.getTextAreaContainer=function(){return this.container},this.$moveTextAreaToCursor=function(){if(!this.$keepTextAreaAtCursor)return;var e=this.layerConfig,t=this.$cursorLayer.$pixelPos.top,n=this.$cursorLayer.$pixelPos.left;t-=e.offset;var r=this.textarea.style,i=this.lineHeight;if(t<0||t>e.height-i){r.top=r.left=\"0\";return}var s=this.characterWidth;if(this.$composition){var o=this.textarea.value.replace(/^\\x01+/,\"\");s*=this.session.$getStringScreenWidth(o)[0]+2,i+=2}n-=this.scrollLeft,n>this.$size.scrollerWidth-s&&(n=this.$size.scrollerWidth-s),n+=this.gutterWidth,r.height=i+\"px\",r.width=s+\"px\",r.left=Math.min(n,this.$size.scrollerWidth-s)+\"px\",r.top=Math.min(t,this.$size.height-i)+\"px\"},this.getFirstVisibleRow=function(){return this.layerConfig.firstRow},this.getFirstFullyVisibleRow=function(){return this.layerConfig.firstRow+(this.layerConfig.offset===0?0:1)},this.getLastFullyVisibleRow=function(){var e=this.layerConfig,t=e.lastRow,n=this.session.documentToScreenRow(t,0)*e.lineHeight;return n-this.session.getScrollTop()>e.height-e.lineHeight?t-1:t},this.getLastVisibleRow=function(){return this.layerConfig.lastRow},this.$padding=null,this.setPadding=function(e){this.$padding=e,this.$textLayer.setPadding(e),this.$cursorLayer.setPadding(e),this.$markerFront.setPadding(e),this.$markerBack.setPadding(e),this.$loop.schedule(this.CHANGE_FULL),this.$updatePrintMargin()},this.setScrollMargin=function(e,t,n,r){var i=this.scrollMargin;i.top=e|0,i.bottom=t|0,i.right=r|0,i.left=n|0,i.v=i.top+i.bottom,i.h=i.left+i.right,i.top&&this.scrollTop<=0&&this.session&&this.session.setScrollTop(-i.top),this.updateFull()},this.getHScrollBarAlwaysVisible=function(){return this.$hScrollBarAlwaysVisible},this.setHScrollBarAlwaysVisible=function(e){this.setOption(\"hScrollBarAlwaysVisible\",e)},this.getVScrollBarAlwaysVisible=function(){return this.$vScrollBarAlwaysVisible},this.setVScrollBarAlwaysVisible=function(e){this.setOption(\"vScrollBarAlwaysVisible\",e)},this.$updateScrollBarV=function(){var e=this.layerConfig.maxHeight,t=this.$size.scrollerHeight;!this.$maxLines&&this.$scrollPastEnd&&(e-=(t-this.lineHeight)*this.$scrollPastEnd,this.scrollTop>e-t&&(e=this.scrollTop+t,this.scrollBarV.scrollTop=null)),this.scrollBarV.setScrollHeight(e+this.scrollMargin.v),this.scrollBarV.setScrollTop(this.scrollTop+this.scrollMargin.top)},this.$updateScrollBarH=function(){this.scrollBarH.setScrollWidth(this.layerConfig.width+2*this.$padding+this.scrollMargin.h),this.scrollBarH.setScrollLeft(this.scrollLeft+this.scrollMargin.left)},this.$frozen=!1,this.freeze=function(){this.$frozen=!0},this.unfreeze=function(){this.$frozen=!1},this.$renderChanges=function(e,t){this.$changes&&(e|=this.$changes,this.$changes=0);if(!this.session||!this.container.offsetWidth||this.$frozen||!e&&!t){this.$changes|=e;return}if(this.$size.$dirty)return this.$changes|=e,this.onResize(!0);this.lineHeight||this.$textLayer.checkForSizeChanges(),this._signal(\"beforeRender\");var n=this.layerConfig;if(e&this.CHANGE_FULL||e&this.CHANGE_SIZE||e&this.CHANGE_TEXT||e&this.CHANGE_LINES||e&this.CHANGE_SCROLL||e&this.CHANGE_H_SCROLL){e|=this.$computeLayerConfig();if(n.firstRow!=this.layerConfig.firstRow&&n.firstRowScreen==this.layerConfig.firstRowScreen){var r=this.scrollTop+(n.firstRow-this.layerConfig.firstRow)*this.lineHeight;r>0&&(this.scrollTop=r,e|=this.CHANGE_SCROLL,e|=this.$computeLayerConfig())}n=this.layerConfig,this.$updateScrollBarV(),e&this.CHANGE_H_SCROLL&&this.$updateScrollBarH(),this.$gutterLayer.element.style.marginTop=-n.offset+\"px\",this.content.style.marginTop=-n.offset+\"px\",this.content.style.width=n.width+2*this.$padding+\"px\",this.content.style.height=n.minHeight+\"px\"}e&this.CHANGE_H_SCROLL&&(this.content.style.marginLeft=-this.scrollLeft+\"px\",this.scroller.className=this.scrollLeft<=0?\"ace_scroller\":\"ace_scroller ace_scroll-left\");if(e&this.CHANGE_FULL){this.$textLayer.update(n),this.$showGutter&&this.$gutterLayer.update(n),this.$markerBack.update(n),this.$markerFront.update(n),this.$cursorLayer.update(n),this.$moveTextAreaToCursor(),this.$highlightGutterLine&&this.$updateGutterLineHighlight(),this._signal(\"afterRender\");return}if(e&this.CHANGE_SCROLL){e&this.CHANGE_TEXT||e&this.CHANGE_LINES?this.$textLayer.update(n):this.$textLayer.scrollLines(n),this.$showGutter&&this.$gutterLayer.update(n),this.$markerBack.update(n),this.$markerFront.update(n),this.$cursorLayer.update(n),this.$highlightGutterLine&&this.$updateGutterLineHighlight(),this.$moveTextAreaToCursor(),this._signal(\"afterRender\");return}e&this.CHANGE_TEXT?(this.$textLayer.update(n),this.$showGutter&&this.$gutterLayer.update(n)):e&this.CHANGE_LINES?(this.$updateLines()||e&this.CHANGE_GUTTER&&this.$showGutter)&&this.$gutterLayer.update(n):(e&this.CHANGE_TEXT||e&this.CHANGE_GUTTER)&&this.$showGutter&&this.$gutterLayer.update(n),e&this.CHANGE_CURSOR&&(this.$cursorLayer.update(n),this.$moveTextAreaToCursor(),this.$highlightGutterLine&&this.$updateGutterLineHighlight()),e&(this.CHANGE_MARKER|this.CHANGE_MARKER_FRONT)&&this.$markerFront.update(n),e&(this.CHANGE_MARKER|this.CHANGE_MARKER_BACK)&&this.$markerBack.update(n),this._signal(\"afterRender\")},this.$autosize=function(){var e=this.session.getScreenLength()*this.lineHeight,t=this.$maxLines*this.lineHeight,n=Math.min(t,Math.max((this.$minLines||1)*this.lineHeight,e))+this.scrollMargin.v+(this.$extraHeight||0);this.$horizScroll&&(n+=this.scrollBarH.getHeight()),this.$maxPixelHeight&&n>this.$maxPixelHeight&&(n=this.$maxPixelHeight);var r=e>t;if(n!=this.desiredHeight||this.$size.height!=this.desiredHeight||r!=this.$vScroll){r!=this.$vScroll&&(this.$vScroll=r,this.scrollBarV.setVisible(r));var i=this.container.clientWidth;this.container.style.height=n+\"px\",this.$updateCachedSize(!0,this.$gutterWidth,i,n),this.desiredHeight=n,this._signal(\"autosize\")}},this.$computeLayerConfig=function(){var e=this.session,t=this.$size,n=t.height<=2*this.lineHeight,r=this.session.getScreenLength(),i=r*this.lineHeight,s=this.$getLongestLine(),o=!n&&(this.$hScrollBarAlwaysVisible||t.scrollerWidth-s-2*this.$padding<0),u=this.$horizScroll!==o;u&&(this.$horizScroll=o,this.scrollBarH.setVisible(o));var a=this.$vScroll;this.$maxLines&&this.lineHeight>1&&this.$autosize();var f=this.scrollTop%this.lineHeight,l=t.scrollerHeight+this.lineHeight,c=!this.$maxLines&&this.$scrollPastEnd?(t.scrollerHeight-this.lineHeight)*this.$scrollPastEnd:0;i+=c;var h=this.scrollMargin;this.session.setScrollTop(Math.max(-h.top,Math.min(this.scrollTop,i-t.scrollerHeight+h.bottom))),this.session.setScrollLeft(Math.max(-h.left,Math.min(this.scrollLeft,s+2*this.$padding-t.scrollerWidth+h.right)));var p=!n&&(this.$vScrollBarAlwaysVisible||t.scrollerHeight-i+c<0||this.scrollTop>h.top),d=a!==p;d&&(this.$vScroll=p,this.scrollBarV.setVisible(p));var v=Math.ceil(l/this.lineHeight)-1,m=Math.max(0,Math.round((this.scrollTop-f)/this.lineHeight)),g=m+v,y,b,w=this.lineHeight;m=e.screenToDocumentRow(m,0);var E=e.getFoldLine(m);E&&(m=E.start.row),y=e.documentToScreenRow(m,0),b=e.getRowLength(m)*w,g=Math.min(e.screenToDocumentRow(g,0),e.getLength()-1),l=t.scrollerHeight+e.getRowLength(g)*w+b,f=this.scrollTop-y*w;var S=0;this.layerConfig.width!=s&&(S=this.CHANGE_H_SCROLL);if(u||d)S=this.$updateCachedSize(!0,this.gutterWidth,t.width,t.height),this._signal(\"scrollbarVisibilityChanged\"),d&&(s=this.$getLongestLine());return this.layerConfig={width:s,padding:this.$padding,firstRow:m,firstRowScreen:y,lastRow:g,lineHeight:w,characterWidth:this.characterWidth,minHeight:l,maxHeight:i,offset:f,gutterOffset:Math.max(0,Math.ceil((f+t.height-t.scrollerHeight)/w)),height:this.$size.scrollerHeight},S},this.$updateLines=function(){var e=this.$changedLines.firstRow,t=this.$changedLines.lastRow;this.$changedLines=null;var n=this.layerConfig;if(e>n.lastRow+1)return;if(t<n.firstRow)return;if(t===Infinity){this.$showGutter&&this.$gutterLayer.update(n),this.$textLayer.update(n);return}return this.$textLayer.updateLines(n,e,t),!0},this.$getLongestLine=function(){var e=this.session.getScreenWidth();return this.showInvisibles&&!this.session.$useWrapMode&&(e+=1),Math.max(this.$size.scrollerWidth-2*this.$padding,Math.round(e*this.characterWidth))},this.updateFrontMarkers=function(){this.$markerFront.setMarkers(this.session.getMarkers(!0)),this.$loop.schedule(this.CHANGE_MARKER_FRONT)},this.updateBackMarkers=function(){this.$markerBack.setMarkers(this.session.getMarkers()),this.$loop.schedule(this.CHANGE_MARKER_BACK)},this.addGutterDecoration=function(e,t){this.$gutterLayer.addGutterDecoration(e,t)},this.removeGutterDecoration=function(e,t){this.$gutterLayer.removeGutterDecoration(e,t)},this.updateBreakpoints=function(e){this.$loop.schedule(this.CHANGE_GUTTER)},this.setAnnotations=function(e){this.$gutterLayer.setAnnotations(e),this.$loop.schedule(this.CHANGE_GUTTER)},this.updateCursor=function(){this.$loop.schedule(this.CHANGE_CURSOR)},this.hideCursor=function(){this.$cursorLayer.hideCursor()},this.showCursor=function(){this.$cursorLayer.showCursor()},this.scrollSelectionIntoView=function(e,t,n){this.scrollCursorIntoView(e,n),this.scrollCursorIntoView(t,n)},this.scrollCursorIntoView=function(e,t,n){if(this.$size.scrollerHeight===0)return;var r=this.$cursorLayer.getPixelPosition(e),i=r.left,s=r.top,o=n&&n.top||0,u=n&&n.bottom||0,a=this.$scrollAnimation?this.session.getScrollTop():this.scrollTop;a+o>s?(t&&a+o>s+this.lineHeight&&(s-=t*this.$size.scrollerHeight),s===0&&(s=-this.scrollMargin.top),this.session.setScrollTop(s)):a+this.$size.scrollerHeight-u<s+this.lineHeight&&(t&&a+this.$size.scrollerHeight-u<s-this.lineHeight&&(s+=t*this.$size.scrollerHeight),this.session.setScrollTop(s+this.lineHeight-this.$size.scrollerHeight));var f=this.scrollLeft;f>i?(i<this.$padding+2*this.layerConfig.characterWidth&&(i=-this.scrollMargin.left),this.session.setScrollLeft(i)):f+this.$size.scrollerWidth<i+this.characterWidth?this.session.setScrollLeft(Math.round(i+this.characterWidth-this.$size.scrollerWidth)):f<=this.$padding&&i-f<this.characterWidth&&this.session.setScrollLeft(0)},this.getScrollTop=function(){return this.session.getScrollTop()},this.getScrollLeft=function(){return this.session.getScrollLeft()},this.getScrollTopRow=function(){return this.scrollTop/this.lineHeight},this.getScrollBottomRow=function(){return Math.max(0,Math.floor((this.scrollTop+this.$size.scrollerHeight)/this.lineHeight)-1)},this.scrollToRow=function(e){this.session.setScrollTop(e*this.lineHeight)},this.alignCursor=function(e,t){typeof e==\"number\"&&(e={row:e,column:0});var n=this.$cursorLayer.getPixelPosition(e),r=this.$size.scrollerHeight-this.lineHeight,i=n.top-r*(t||0);return this.session.setScrollTop(i),i},this.STEPS=8,this.$calcSteps=function(e,t){var n=0,r=this.STEPS,i=[],s=function(e,t,n){return n*(Math.pow(e-1,3)+1)+t};for(n=0;n<r;++n)i.push(s(n/this.STEPS,e,t-e));return i},this.scrollToLine=function(e,t,n,r){var i=this.$cursorLayer.getPixelPosition({row:e,column:0}),s=i.top;t&&(s-=this.$size.scrollerHeight/2);var o=this.scrollTop;this.session.setScrollTop(s),n!==!1&&this.animateScrolling(o,r)},this.animateScrolling=function(e,t){var n=this.scrollTop;if(!this.$animatedScroll)return;var r=this;if(e==n)return;if(this.$scrollAnimation){var i=this.$scrollAnimation.steps;if(i.length){e=i[0];if(e==n)return}}var s=r.$calcSteps(e,n);this.$scrollAnimation={from:e,to:n,steps:s},clearInterval(this.$timer),r.session.setScrollTop(s.shift()),r.session.$scrollTop=n,this.$timer=setInterval(function(){s.length?(r.session.setScrollTop(s.shift()),r.session.$scrollTop=n):n!=null?(r.session.$scrollTop=-1,r.session.setScrollTop(n),n=null):(r.$timer=clearInterval(r.$timer),r.$scrollAnimation=null,t&&t())},10)},this.scrollToY=function(e){this.scrollTop!==e&&(this.$loop.schedule(this.CHANGE_SCROLL),this.scrollTop=e)},this.scrollToX=function(e){this.scrollLeft!==e&&(this.scrollLeft=e),this.$loop.schedule(this.CHANGE_H_SCROLL)},this.scrollTo=function(e,t){this.session.setScrollTop(t),this.session.setScrollLeft(t)},this.scrollBy=function(e,t){t&&this.session.setScrollTop(this.session.getScrollTop()+t),e&&this.session.setScrollLeft(this.session.getScrollLeft()+e)},this.isScrollableBy=function(e,t){if(t<0&&this.session.getScrollTop()>=1-this.scrollMargin.top)return!0;if(t>0&&this.session.getScrollTop()+this.$size.scrollerHeight-this.layerConfig.maxHeight<-1+this.scrollMargin.bottom)return!0;if(e<0&&this.session.getScrollLeft()>=1-this.scrollMargin.left)return!0;if(e>0&&this.session.getScrollLeft()+this.$size.scrollerWidth-this.layerConfig.width<-1+this.scrollMargin.right)return!0},this.pixelToScreenCoordinates=function(e,t){var n=this.scroller.getBoundingClientRect(),r=(e+this.scrollLeft-n.left-this.$padding)/this.characterWidth,i=Math.floor((t+this.scrollTop-n.top)/this.lineHeight),s=Math.round(r);return{row:i,column:s,side:r-s>0?1:-1}},this.screenToTextCoordinates=function(e,t){var n=this.scroller.getBoundingClientRect(),r=Math.round((e+this.scrollLeft-n.left-this.$padding)/this.characterWidth),i=(t+this.scrollTop-n.top)/this.lineHeight;return this.session.screenToDocumentPosition(i,Math.max(r,0))},this.textToScreenCoordinates=function(e,t){var n=this.scroller.getBoundingClientRect(),r=this.session.documentToScreenPosition(e,t),i=this.$padding+Math.round(r.column*this.characterWidth),s=r.row*this.lineHeight;return{pageX:n.left+i-this.scrollLeft,pageY:n.top+s-this.scrollTop}},this.visualizeFocus=function(){i.addCssClass(this.container,\"ace_focus\")},this.visualizeBlur=function(){i.removeCssClass(this.container,\"ace_focus\")},this.showComposition=function(e){this.$composition||(this.$composition={keepTextAreaAtCursor:this.$keepTextAreaAtCursor,cssText:this.textarea.style.cssText}),this.$keepTextAreaAtCursor=!0,i.addCssClass(this.textarea,\"ace_composition\"),this.textarea.style.cssText=\"\",this.$moveTextAreaToCursor()},this.setCompositionText=function(e){this.$moveTextAreaToCursor()},this.hideComposition=function(){if(!this.$composition)return;i.removeCssClass(this.textarea,\"ace_composition\"),this.$keepTextAreaAtCursor=this.$composition.keepTextAreaAtCursor,this.textarea.style.cssText=this.$composition.cssText,this.$composition=null},this.setTheme=function(e,t){function o(r){if(n.$themeId!=e)return t&&t();if(!r.cssClass)return;i.importCssString(r.cssText,r.cssClass,n.container.ownerDocument),n.theme&&i.removeCssClass(n.container,n.theme.cssClass);var s=\"padding\"in r?r.padding:\"padding\"in(n.theme||{})?4:n.$padding;n.$padding&&s!=n.$padding&&n.setPadding(s),n.$theme=r.cssClass,n.theme=r,i.addCssClass(n.container,r.cssClass),i.setCssClass(n.container,\"ace_dark\",r.isDark),n.$size&&(n.$size.width=0,n.$updateSizeAsync()),n._dispatchEvent(\"themeLoaded\",{theme:r}),t&&t()}var n=this;this.$themeId=e,n._dispatchEvent(\"themeChange\",{theme:e});if(!e||typeof e==\"string\"){var r=e||this.$options.theme.initialValue;s.loadModule([\"theme\",r],o)}else o(e)},this.getTheme=function(){return this.$themeId},this.setStyle=function(e,t){i.setCssClass(this.container,e,t!==!1)},this.unsetStyle=function(e){i.removeCssClass(this.container,e)},this.setCursorStyle=function(e){this.scroller.style.cursor!=e&&(this.scroller.style.cursor=e)},this.setMouseCursor=function(e){this.scroller.style.cursor=e},this.destroy=function(){this.$textLayer.destroy(),this.$cursorLayer.destroy()}}).call(g.prototype),s.defineOptions(g.prototype,\"renderer\",{animatedScroll:{initialValue:!1},showInvisibles:{set:function(e){this.$textLayer.setShowInvisibles(e)&&this.$loop.schedule(this.CHANGE_TEXT)},initialValue:!1},showPrintMargin:{set:function(){this.$updatePrintMargin()},initialValue:!0},printMarginColumn:{set:function(){this.$updatePrintMargin()},initialValue:80},printMargin:{set:function(e){typeof e==\"number\"&&(this.$printMarginColumn=e),this.$showPrintMargin=!!e,this.$updatePrintMargin()},get:function(){return this.$showPrintMargin&&this.$printMarginColumn}},showGutter:{set:function(e){this.$gutter.style.display=e?\"block\":\"none\",this.$loop.schedule(this.CHANGE_FULL),this.onGutterResize()},initialValue:!0},fadeFoldWidgets:{set:function(e){i.setCssClass(this.$gutter,\"ace_fade-fold-widgets\",e)},initialValue:!1},showFoldWidgets:{set:function(e){this.$gutterLayer.setShowFoldWidgets(e)},initialValue:!0},showLineNumbers:{set:function(e){this.$gutterLayer.setShowLineNumbers(e),this.$loop.schedule(this.CHANGE_GUTTER)},initialValue:!0},displayIndentGuides:{set:function(e){this.$textLayer.setDisplayIndentGuides(e)&&this.$loop.schedule(this.CHANGE_TEXT)},initialValue:!0},highlightGutterLine:{set:function(e){if(!this.$gutterLineHighlight){this.$gutterLineHighlight=i.createElement(\"div\"),this.$gutterLineHighlight.className=\"ace_gutter-active-line\",this.$gutter.appendChild(this.$gutterLineHighlight);return}this.$gutterLineHighlight.style.display=e?\"\":\"none\",this.$cursorLayer.$pixelPos&&this.$updateGutterLineHighlight()},initialValue:!1,value:!0},hScrollBarAlwaysVisible:{set:function(e){(!this.$hScrollBarAlwaysVisible||!this.$horizScroll)&&this.$loop.schedule(this.CHANGE_SCROLL)},initialValue:!1},vScrollBarAlwaysVisible:{set:function(e){(!this.$vScrollBarAlwaysVisible||!this.$vScroll)&&this.$loop.schedule(this.CHANGE_SCROLL)},initialValue:!1},fontSize:{set:function(e){typeof e==\"number\"&&(e+=\"px\"),this.container.style.fontSize=e,this.updateFontSize()},initialValue:12},fontFamily:{set:function(e){this.container.style.fontFamily=e,this.updateFontSize()}},maxLines:{set:function(e){this.updateFull()}},minLines:{set:function(e){this.updateFull()}},maxPixelHeight:{set:function(e){this.updateFull()},initialValue:0},scrollPastEnd:{set:function(e){e=+e||0;if(this.$scrollPastEnd==e)return;this.$scrollPastEnd=e,this.$loop.schedule(this.CHANGE_SCROLL)},initialValue:0,handlesSet:!0},fixedWidthGutter:{set:function(e){this.$gutterLayer.$fixedWidth=!!e,this.$loop.schedule(this.CHANGE_GUTTER)}},theme:{set:function(e){this.setTheme(e)},get:function(){return this.$themeId||this.theme},initialValue:\"./theme/textmate\",handlesSet:!0}}),t.VirtualRenderer=g}),ace.define(\"ace/worker/worker_client\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/net\",\"ace/lib/event_emitter\",\"ace/config\"],function(e,t,n){\"use strict\";var r=e(\"../lib/oop\"),i=e(\"../lib/net\"),s=e(\"../lib/event_emitter\").EventEmitter,o=e(\"../config\"),u=function(t,n,r,i){this.$sendDeltaQueue=this.$sendDeltaQueue.bind(this),this.changeListener=this.changeListener.bind(this),this.onMessage=this.onMessage.bind(this),e.nameToUrl&&!e.toUrl&&(e.toUrl=e.nameToUrl);if(o.get(\"packaged\")||!e.toUrl)i=i||o.moduleUrl(n,\"worker\");else{var s=this.$normalizePath;i=i||s(e.toUrl(\"ace/worker/worker.js\",null,\"_\"));var u={};t.forEach(function(t){u[t]=s(e.toUrl(t,null,\"_\").replace(/(\\.js)?(\\?.*)?$/,\"\"))})}try{this.$worker=new Worker(i)}catch(a){if(!(a instanceof window.DOMException))throw a;var f=this.$workerBlob(i),l=window.URL||window.webkitURL,c=l.createObjectURL(f);this.$worker=new Worker(c),l.revokeObjectURL(c)}this.$worker.postMessage({init:!0,tlns:u,module:n,classname:r}),this.callbackId=1,this.callbacks={},this.$worker.onmessage=this.onMessage};(function(){r.implement(this,s),this.onMessage=function(e){var t=e.data;switch(t.type){case\"event\":this._signal(t.name,{data:t.data});break;case\"call\":var n=this.callbacks[t.id];n&&(n(t.data),delete this.callbacks[t.id]);break;case\"error\":this.reportError(t.data);break;case\"log\":window.console&&console.log&&console.log.apply(console,t.data)}},this.reportError=function(e){window.console&&console.error&&console.error(e)},this.$normalizePath=function(e){return i.qualifyURL(e)},this.terminate=function(){this._signal(\"terminate\",{}),this.deltaQueue=null,this.$worker.terminate(),this.$worker=null,this.$doc&&this.$doc.off(\"change\",this.changeListener),this.$doc=null},this.send=function(e,t){this.$worker.postMessage({command:e,args:t})},this.call=function(e,t,n){if(n){var r=this.callbackId++;this.callbacks[r]=n,t.push(r)}this.send(e,t)},this.emit=function(e,t){try{this.$worker.postMessage({event:e,data:{data:t.data}})}catch(n){console.error(n.stack)}},this.attachToDocument=function(e){this.$doc&&this.terminate(),this.$doc=e,this.call(\"setValue\",[e.getValue()]),e.on(\"change\",this.changeListener)},this.changeListener=function(e){this.deltaQueue||(this.deltaQueue=[],setTimeout(this.$sendDeltaQueue,0)),e.action==\"insert\"?this.deltaQueue.push(e.start,e.lines):this.deltaQueue.push(e.start,e.end)},this.$sendDeltaQueue=function(){var e=this.deltaQueue;if(!e)return;this.deltaQueue=null,e.length>50&&e.length>this.$doc.getLength()>>1?this.call(\"setValue\",[this.$doc.getValue()]):this.emit(\"change\",{data:e})},this.$workerBlob=function(e){var t=\"importScripts('\"+i.qualifyURL(e)+\"');\";try{return new Blob([t],{type:\"application/javascript\"})}catch(n){var r=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder,s=new r;return s.append(t),s.getBlob(\"application/javascript\")}}}).call(u.prototype);var a=function(e,t,n){this.$sendDeltaQueue=this.$sendDeltaQueue.bind(this),this.changeListener=this.changeListener.bind(this),this.callbackId=1,this.callbacks={},this.messageBuffer=[];var r=null,i=!1,u=Object.create(s),a=this;this.$worker={},this.$worker.terminate=function(){},this.$worker.postMessage=function(e){a.messageBuffer.push(e),r&&(i?setTimeout(f):f())},this.setEmitSync=function(e){i=e};var f=function(){var e=a.messageBuffer.shift();e.command?r[e.command].apply(r,e.args):e.event&&u._signal(e.event,e.data)};u.postMessage=function(e){a.onMessage({data:e})},u.callback=function(e,t){this.postMessage({type:\"call\",id:t,data:e})},u.emit=function(e,t){this.postMessage({type:\"event\",name:e,data:t})},o.loadModule([\"worker\",t],function(e){r=new e[n](u);while(a.messageBuffer.length)f()})};a.prototype=u.prototype,t.UIWorkerClient=a,t.WorkerClient=u}),ace.define(\"ace/placeholder\",[\"require\",\"exports\",\"module\",\"ace/range\",\"ace/lib/event_emitter\",\"ace/lib/oop\"],function(e,t,n){\"use strict\";var r=e(\"./range\").Range,i=e(\"./lib/event_emitter\").EventEmitter,s=e(\"./lib/oop\"),o=function(e,t,n,r,i,s){var o=this;this.length=t,this.session=e,this.doc=e.getDocument(),this.mainClass=i,this.othersClass=s,this.$onUpdate=this.onUpdate.bind(this),this.doc.on(\"change\",this.$onUpdate),this.$others=r,this.$onCursorChange=function(){setTimeout(function(){o.onCursorChange()})},this.$pos=n;var u=e.getUndoManager().$undoStack||e.getUndoManager().$undostack||{length:-1};this.$undoStackDepth=u.length,this.setup(),e.selection.on(\"changeCursor\",this.$onCursorChange)};(function(){s.implement(this,i),this.setup=function(){var e=this,t=this.doc,n=this.session;this.selectionBefore=n.selection.toJSON(),n.selection.inMultiSelectMode&&n.selection.toSingleRange(),this.pos=t.createAnchor(this.$pos.row,this.$pos.column);var i=this.pos;i.$insertRight=!0,i.detach(),i.markerId=n.addMarker(new r(i.row,i.column,i.row,i.column+this.length),this.mainClass,null,!1),this.others=[],this.$others.forEach(function(n){var r=t.createAnchor(n.row,n.column);r.$insertRight=!0,r.detach(),e.others.push(r)}),n.setUndoSelect(!1)},this.showOtherMarkers=function(){if(this.othersActive)return;var e=this.session,t=this;this.othersActive=!0,this.others.forEach(function(n){n.markerId=e.addMarker(new r(n.row,n.column,n.row,n.column+t.length),t.othersClass,null,!1)})},this.hideOtherMarkers=function(){if(!this.othersActive)return;this.othersActive=!1;for(var e=0;e<this.others.length;e++)this.session.removeMarker(this.others[e].markerId)},this.onUpdate=function(e){if(this.$updating)return this.updateAnchors(e);var t=e;if(t.start.row!==t.end.row)return;if(t.start.row!==this.pos.row)return;this.$updating=!0;var n=e.action===\"insert\"?t.end.column-t.start.column:t.start.column-t.end.column,i=t.start.column>=this.pos.column&&t.start.column<=this.pos.column+this.length+1,s=t.start.column-this.pos.column;this.updateAnchors(e),i&&(this.length+=n);if(i&&!this.session.$fromUndo)if(e.action===\"insert\")for(var o=this.others.length-1;o>=0;o--){var u=this.others[o],a={row:u.row,column:u.column+s};this.doc.insertMergedLines(a,e.lines)}else if(e.action===\"remove\")for(var o=this.others.length-1;o>=0;o--){var u=this.others[o],a={row:u.row,column:u.column+s};this.doc.remove(new r(a.row,a.column,a.row,a.column-n))}this.$updating=!1,this.updateMarkers()},this.updateAnchors=function(e){this.pos.onChange(e);for(var t=this.others.length;t--;)this.others[t].onChange(e);this.updateMarkers()},this.updateMarkers=function(){if(this.$updating)return;var e=this,t=this.session,n=function(n,i){t.removeMarker(n.markerId),n.markerId=t.addMarker(new r(n.row,n.column,n.row,n.column+e.length),i,null,!1)};n(this.pos,this.mainClass);for(var i=this.others.length;i--;)n(this.others[i],this.othersClass)},this.onCursorChange=function(e){if(this.$updating||!this.session)return;var t=this.session.selection.getCursor();t.row===this.pos.row&&t.column>=this.pos.column&&t.column<=this.pos.column+this.length?(this.showOtherMarkers(),this._emit(\"cursorEnter\",e)):(this.hideOtherMarkers(),this._emit(\"cursorLeave\",e))},this.detach=function(){this.session.removeMarker(this.pos&&this.pos.markerId),this.hideOtherMarkers(),this.doc.removeEventListener(\"change\",this.$onUpdate),this.session.selection.removeEventListener(\"changeCursor\",this.$onCursorChange),this.session.setUndoSelect(!0),this.session=null},this.cancel=function(){if(this.$undoStackDepth===-1)return;var e=this.session.getUndoManager(),t=(e.$undoStack||e.$undostack).length-this.$undoStackDepth;for(var n=0;n<t;n++)e.undo(!0);this.selectionBefore&&this.session.selection.fromJSON(this.selectionBefore)}}).call(o.prototype),t.PlaceHolder=o}),ace.define(\"ace/mouse/multi_select_handler\",[\"require\",\"exports\",\"module\",\"ace/lib/event\",\"ace/lib/useragent\"],function(e,t,n){function s(e,t){return e.row==t.row&&e.column==t.column}function o(e){var t=e.domEvent,n=t.altKey,o=t.shiftKey,u=t.ctrlKey,a=e.getAccelKey(),f=e.getButton();u&&i.isMac&&(f=t.button);if(e.editor.inMultiSelectMode&&f==2){e.editor.textInput.onContextMenu(e.domEvent);return}if(!u&&!n&&!a){f===0&&e.editor.inMultiSelectMode&&e.editor.exitMultiSelectMode();return}if(f!==0)return;var l=e.editor,c=l.selection,h=l.inMultiSelectMode,p=e.getDocumentPosition(),d=c.getCursor(),v=e.inSelection()||c.isEmpty()&&s(p,d),m=e.x,g=e.y,y=function(e){m=e.clientX,g=e.clientY},b=l.session,w=l.renderer.pixelToScreenCoordinates(m,g),E=w,S;if(l.$mouseHandler.$enableJumpToDef)u&&n||a&&n?S=o?\"block\":\"add\":n&&l.$blockSelectEnabled&&(S=\"block\");else if(a&&!n){S=\"add\";if(!h&&o)return}else n&&l.$blockSelectEnabled&&(S=\"block\");S&&i.isMac&&t.ctrlKey&&l.$mouseHandler.cancelContextMenu();if(S==\"add\"){if(!h&&v)return;if(!h){var x=c.toOrientedRange();l.addSelectionMarker(x)}var T=c.rangeList.rangeAtPoint(p);l.$blockScrolling++,l.inVirtualSelectionMode=!0,o&&(T=null,x=c.ranges[0]||x,l.removeSelectionMarker(x)),l.once(\"mouseup\",function(){var e=c.toOrientedRange();T&&e.isEmpty()&&s(T.cursor,e.cursor)?c.substractPoint(e.cursor):(o?c.substractPoint(x.cursor):x&&(l.removeSelectionMarker(x),c.addRange(x)),c.addRange(e)),l.$blockScrolling--,l.inVirtualSelectionMode=!1})}else if(S==\"block\"){e.stop(),l.inVirtualSelectionMode=!0;var N,C=[],k=function(){var e=l.renderer.pixelToScreenCoordinates(m,g),t=b.screenToDocumentPosition(e.row,e.column);if(s(E,e)&&s(t,c.lead))return;E=e,l.$blockScrolling++,l.selection.moveToPosition(t),l.renderer.scrollCursorIntoView(),l.removeSelectionMarkers(C),C=c.rectangularRangeBlock(E,w),l.$mouseHandler.$clickSelection&&C.length==1&&C[0].isEmpty()&&(C[0]=l.$mouseHandler.$clickSelection.clone()),C.forEach(l.addSelectionMarker,l),l.updateSelectionMarkers(),l.$blockScrolling--};l.$blockScrolling++,h&&!a?c.toSingleRange():!h&&a&&(N=c.toOrientedRange(),l.addSelectionMarker(N)),o?w=b.documentToScreenPosition(c.lead):c.moveToPosition(p),l.$blockScrolling--,E={row:-1,column:-1};var L=function(e){clearInterval(O),l.removeSelectionMarkers(C),C.length||(C=[c.toOrientedRange()]),l.$blockScrolling++,N&&(l.removeSelectionMarker(N),c.toSingleRange(N));for(var t=0;t<C.length;t++)c.addRange(C[t]);l.inVirtualSelectionMode=!1,l.$mouseHandler.$clickSelection=null,l.$blockScrolling--},A=k;r.capture(l.container,y,L);var O=setInterval(function(){A()},20);return e.preventDefault()}}var r=e(\"../lib/event\"),i=e(\"../lib/useragent\");t.onMouseDown=o}),ace.define(\"ace/commands/multi_select_commands\",[\"require\",\"exports\",\"module\",\"ace/keyboard/hash_handler\"],function(e,t,n){t.defaultCommands=[{name:\"addCursorAbove\",exec:function(e){e.selectMoreLines(-1)},bindKey:{win:\"Ctrl-Alt-Up\",mac:\"Ctrl-Alt-Up\"},scrollIntoView:\"cursor\",readOnly:!0},{name:\"addCursorBelow\",exec:function(e){e.selectMoreLines(1)},bindKey:{win:\"Ctrl-Alt-Down\",mac:\"Ctrl-Alt-Down\"},scrollIntoView:\"cursor\",readOnly:!0},{name:\"addCursorAboveSkipCurrent\",exec:function(e){e.selectMoreLines(-1,!0)},bindKey:{win:\"Ctrl-Alt-Shift-Up\",mac:\"Ctrl-Alt-Shift-Up\"},scrollIntoView:\"cursor\",readOnly:!0},{name:\"addCursorBelowSkipCurrent\",exec:function(e){e.selectMoreLines(1,!0)},bindKey:{win:\"Ctrl-Alt-Shift-Down\",mac:\"Ctrl-Alt-Shift-Down\"},scrollIntoView:\"cursor\",readOnly:!0},{name:\"selectMoreBefore\",exec:function(e){e.selectMore(-1)},bindKey:{win:\"Ctrl-Alt-Left\",mac:\"Ctrl-Alt-Left\"},scrollIntoView:\"cursor\",readOnly:!0},{name:\"selectMoreAfter\",exec:function(e){e.selectMore(1)},bindKey:{win:\"Ctrl-Alt-Right\",mac:\"Ctrl-Alt-Right\"},scrollIntoView:\"cursor\",readOnly:!0},{name:\"selectNextBefore\",exec:function(e){e.selectMore(-1,!0)},bindKey:{win:\"Ctrl-Alt-Shift-Left\",mac:\"Ctrl-Alt-Shift-Left\"},scrollIntoView:\"cursor\",readOnly:!0},{name:\"selectNextAfter\",exec:function(e){e.selectMore(1,!0)},bindKey:{win:\"Ctrl-Alt-Shift-Right\",mac:\"Ctrl-Alt-Shift-Right\"},scrollIntoView:\"cursor\",readOnly:!0},{name:\"splitIntoLines\",exec:function(e){e.multiSelect.splitIntoLines()},bindKey:{win:\"Ctrl-Alt-L\",mac:\"Ctrl-Alt-L\"},readOnly:!0},{name:\"alignCursors\",exec:function(e){e.alignCursors()},bindKey:{win:\"Ctrl-Alt-A\",mac:\"Ctrl-Alt-A\"},scrollIntoView:\"cursor\"},{name:\"findAll\",exec:function(e){e.findAll()},bindKey:{win:\"Ctrl-Alt-K\",mac:\"Ctrl-Alt-G\"},scrollIntoView:\"cursor\",readOnly:!0}],t.multiSelectCommands=[{name:\"singleSelection\",bindKey:\"esc\",exec:function(e){e.exitMultiSelectMode()},scrollIntoView:\"cursor\",readOnly:!0,isAvailable:function(e){return e&&e.inMultiSelectMode}}];var r=e(\"../keyboard/hash_handler\").HashHandler;t.keyboardHandler=new r(t.multiSelectCommands)}),ace.define(\"ace/multi_select\",[\"require\",\"exports\",\"module\",\"ace/range_list\",\"ace/range\",\"ace/selection\",\"ace/mouse/multi_select_handler\",\"ace/lib/event\",\"ace/lib/lang\",\"ace/commands/multi_select_commands\",\"ace/search\",\"ace/edit_session\",\"ace/editor\",\"ace/config\"],function(e,t,n){function h(e,t,n){return c.$options.wrap=!0,c.$options.needle=t,c.$options.backwards=n==-1,c.find(e)}function v(e,t){return e.row==t.row&&e.column==t.column}function m(e){if(e.$multiselectOnSessionChange)return;e.$onAddRange=e.$onAddRange.bind(e),e.$onRemoveRange=e.$onRemoveRange.bind(e),e.$onMultiSelect=e.$onMultiSelect.bind(e),e.$onSingleSelect=e.$onSingleSelect.bind(e),e.$multiselectOnSessionChange=t.onSessionChange.bind(e),e.$checkMultiselectChange=e.$checkMultiselectChange.bind(e),e.$multiselectOnSessionChange(e),e.on(\"changeSession\",e.$multiselectOnSessionChange),e.on(\"mousedown\",o),e.commands.addCommands(f.defaultCommands),g(e)}function g(e){function r(t){n&&(e.renderer.setMouseCursor(\"\"),n=!1)}var t=e.textInput.getElement(),n=!1;u.addListener(t,\"keydown\",function(t){var i=t.keyCode==18&&!(t.ctrlKey||t.shiftKey||t.metaKey);e.$blockSelectEnabled&&i?n||(e.renderer.setMouseCursor(\"crosshair\"),n=!0):n&&r()}),u.addListener(t,\"keyup\",r),u.addListener(t,\"blur\",r)}var r=e(\"./range_list\").RangeList,i=e(\"./range\").Range,s=e(\"./selection\").Selection,o=e(\"./mouse/multi_select_handler\").onMouseDown,u=e(\"./lib/event\"),a=e(\"./lib/lang\"),f=e(\"./commands/multi_select_commands\");t.commands=f.defaultCommands.concat(f.multiSelectCommands);var l=e(\"./search\").Search,c=new l,p=e(\"./edit_session\").EditSession;(function(){this.getSelectionMarkers=function(){return this.$selectionMarkers}}).call(p.prototype),function(){this.ranges=null,this.rangeList=null,this.addRange=function(e,t){if(!e)return;if(!this.inMultiSelectMode&&this.rangeCount===0){var n=this.toOrientedRange();this.rangeList.add(n),this.rangeList.add(e);if(this.rangeList.ranges.length!=2)return this.rangeList.removeAll(),t||this.fromOrientedRange(e);this.rangeList.removeAll(),this.rangeList.add(n),this.$onAddRange(n)}e.cursor||(e.cursor=e.end);var r=this.rangeList.add(e);return this.$onAddRange(e),r.length&&this.$onRemoveRange(r),this.rangeCount>1&&!this.inMultiSelectMode&&(this._signal(\"multiSelect\"),this.inMultiSelectMode=!0,this.session.$undoSelect=!1,this.rangeList.attach(this.session)),t||this.fromOrientedRange(e)},this.toSingleRange=function(e){e=e||this.ranges[0];var t=this.rangeList.removeAll();t.length&&this.$onRemoveRange(t),e&&this.fromOrientedRange(e)},this.substractPoint=function(e){var t=this.rangeList.substractPoint(e);if(t)return this.$onRemoveRange(t),t[0]},this.mergeOverlappingRanges=function(){var e=this.rangeList.merge();e.length?this.$onRemoveRange(e):this.ranges[0]&&this.fromOrientedRange(this.ranges[0])},this.$onAddRange=function(e){this.rangeCount=this.rangeList.ranges.length,this.ranges.unshift(e),this._signal(\"addRange\",{range:e})},this.$onRemoveRange=function(e){this.rangeCount=this.rangeList.ranges.length;if(this.rangeCount==1&&this.inMultiSelectMode){var t=this.rangeList.ranges.pop();e.push(t),this.rangeCount=0}for(var n=e.length;n--;){var r=this.ranges.indexOf(e[n]);this.ranges.splice(r,1)}this._signal(\"removeRange\",{ranges:e}),this.rangeCount===0&&this.inMultiSelectMode&&(this.inMultiSelectMode=!1,this._signal(\"singleSelect\"),this.session.$undoSelect=!0,this.rangeList.detach(this.session)),t=t||this.ranges[0],t&&!t.isEqual(this.getRange())&&this.fromOrientedRange(t)},this.$initRangeList=function(){if(this.rangeList)return;this.rangeList=new r,this.ranges=[],this.rangeCount=0},this.getAllRanges=function(){return this.rangeCount?this.rangeList.ranges.concat():[this.getRange()]},this.splitIntoLines=function(){if(this.rangeCount>1){var e=this.rangeList.ranges,t=e[e.length-1],n=i.fromPoints(e[0].start,t.end);this.toSingleRange(),this.setSelectionRange(n,t.cursor==t.start)}else{var n=this.getRange(),r=this.isBackwards(),s=n.start.row,o=n.end.row;if(s==o){if(r)var u=n.end,a=n.start;else var u=n.start,a=n.end;this.addRange(i.fromPoints(a,a)),this.addRange(i.fromPoints(u,u));return}var f=[],l=this.getLineRange(s,!0);l.start.column=n.start.column,f.push(l);for(var c=s+1;c<o;c++)f.push(this.getLineRange(c,!0));l=this.getLineRange(o,!0),l.end.column=n.end.column,f.push(l),f.forEach(this.addRange,this)}},this.toggleBlockSelection=function(){if(this.rangeCount>1){var e=this.rangeList.ranges,t=e[e.length-1],n=i.fromPoints(e[0].start,t.end);this.toSingleRange(),this.setSelectionRange(n,t.cursor==t.start)}else{var r=this.session.documentToScreenPosition(this.selectionLead),s=this.session.documentToScreenPosition(this.selectionAnchor),o=this.rectangularRangeBlock(r,s);o.forEach(this.addRange,this)}},this.rectangularRangeBlock=function(e,t,n){var r=[],s=e.column<t.column;if(s)var o=e.column,u=t.column;else var o=t.column,u=e.column;var a=e.row<t.row;if(a)var f=e.row,l=t.row;else var f=t.row,l=e.row;o<0&&(o=0),f<0&&(f=0),f==l&&(n=!0);for(var c=f;c<=l;c++){var h=i.fromPoints(this.session.screenToDocumentPosition(c,o),this.session.screenToDocumentPosition(c,u));if(h.isEmpty()){if(p&&v(h.end,p))break;var p=h.end}h.cursor=s?h.start:h.end,r.push(h)}a&&r.reverse();if(!n){var d=r.length-1;while(r[d].isEmpty()&&d>0)d--;if(d>0){var m=0;while(r[m].isEmpty())m++}for(var g=d;g>=m;g--)r[g].isEmpty()&&r.splice(g,1)}return r}}.call(s.prototype);var d=e(\"./editor\").Editor;(function(){this.updateSelectionMarkers=function(){this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.addSelectionMarker=function(e){e.cursor||(e.cursor=e.end);var t=this.getSelectionStyle();return e.marker=this.session.addMarker(e,\"ace_selection\",t),this.session.$selectionMarkers.push(e),this.session.selectionMarkerCount=this.session.$selectionMarkers.length,e},this.removeSelectionMarker=function(e){if(!e.marker)return;this.session.removeMarker(e.marker);var t=this.session.$selectionMarkers.indexOf(e);t!=-1&&this.session.$selectionMarkers.splice(t,1),this.session.selectionMarkerCount=this.session.$selectionMarkers.length},this.removeSelectionMarkers=function(e){var t=this.session.$selectionMarkers;for(var n=e.length;n--;){var r=e[n];if(!r.marker)continue;this.session.removeMarker(r.marker);var i=t.indexOf(r);i!=-1&&t.splice(i,1)}this.session.selectionMarkerCount=t.length},this.$onAddRange=function(e){this.addSelectionMarker(e.range),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onRemoveRange=function(e){this.removeSelectionMarkers(e.ranges),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onMultiSelect=function(e){if(this.inMultiSelectMode)return;this.inMultiSelectMode=!0,this.setStyle(\"ace_multiselect\"),this.keyBinding.addKeyboardHandler(f.keyboardHandler),this.commands.setDefaultHandler(\"exec\",this.$onMultiSelectExec),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onSingleSelect=function(e){if(this.session.multiSelect.inVirtualMode)return;this.inMultiSelectMode=!1,this.unsetStyle(\"ace_multiselect\"),this.keyBinding.removeKeyboardHandler(f.keyboardHandler),this.commands.removeDefaultHandler(\"exec\",this.$onMultiSelectExec),this.renderer.updateCursor(),this.renderer.updateBackMarkers(),this._emit(\"changeSelection\")},this.$onMultiSelectExec=function(e){var t=e.command,n=e.editor;if(!n.multiSelect)return;if(!t.multiSelectAction){var r=t.exec(n,e.args||{});n.multiSelect.addRange(n.multiSelect.toOrientedRange()),n.multiSelect.mergeOverlappingRanges()}else t.multiSelectAction==\"forEach\"?r=n.forEachSelection(t,e.args):t.multiSelectAction==\"forEachLine\"?r=n.forEachSelection(t,e.args,!0):t.multiSelectAction==\"single\"?(n.exitMultiSelectMode(),r=t.exec(n,e.args||{})):r=t.multiSelectAction(n,e.args||{});return r},this.forEachSelection=function(e,t,n){if(this.inVirtualSelectionMode)return;var r=n&&n.keepOrder,i=n==1||n&&n.$byLines,o=this.session,u=this.selection,a=u.rangeList,f=(r?u:a).ranges,l;if(!f.length)return e.exec?e.exec(this,t||{}):e(this,t||{});var c=u._eventRegistry;u._eventRegistry={};var h=new s(o);this.inVirtualSelectionMode=!0;for(var p=f.length;p--;){if(i)while(p>0&&f[p].start.row==f[p-1].end.row)p--;h.fromOrientedRange(f[p]),h.index=p,this.selection=o.selection=h;var d=e.exec?e.exec(this,t||{}):e(this,t||{});!l&&d!==undefined&&(l=d),h.toOrientedRange(f[p])}h.detach(),this.selection=o.selection=u,this.inVirtualSelectionMode=!1,u._eventRegistry=c,u.mergeOverlappingRanges();var v=this.renderer.$scrollAnimation;return this.onCursorChange(),this.onSelectionChange(),v&&v.from==v.to&&this.renderer.animateScrolling(v.from),l},this.exitMultiSelectMode=function(){if(!this.inMultiSelectMode||this.inVirtualSelectionMode)return;this.multiSelect.toSingleRange()},this.getSelectedText=function(){var e=\"\";if(this.inMultiSelectMode&&!this.inVirtualSelectionMode){var t=this.multiSelect.rangeList.ranges,n=[];for(var r=0;r<t.length;r++)n.push(this.session.getTextRange(t[r]));var i=this.session.getDocument().getNewLineCharacter();e=n.join(i),e.length==(n.length-1)*i.length&&(e=\"\")}else this.selection.isEmpty()||(e=this.session.getTextRange(this.getSelectionRange()));return e},this.$checkMultiselectChange=function(e,t){if(this.inMultiSelectMode&&!this.inVirtualSelectionMode){var n=this.multiSelect.ranges[0];if(this.multiSelect.isEmpty()&&t==this.multiSelect.anchor)return;var r=t==this.multiSelect.anchor?n.cursor==n.start?n.end:n.start:n.cursor;(r.row!=t.row||this.session.$clipPositionToDocument(r.row,r.column).column!=t.column)&&this.multiSelect.toSingleRange(this.multiSelect.toOrientedRange())}},this.findAll=function(e,t,n){t=t||{},t.needle=e||t.needle;if(t.needle==undefined){var r=this.selection.isEmpty()?this.selection.getWordRange():this.selection.getRange();t.needle=this.session.getTextRange(r)}this.$search.set(t);var i=this.$search.findAll(this.session);if(!i.length)return 0;this.$blockScrolling+=1;var s=this.multiSelect;n||s.toSingleRange(i[0]);for(var o=i.length;o--;)s.addRange(i[o],!0);return r&&s.rangeList.rangeAtPoint(r.start)&&s.addRange(r,!0),this.$blockScrolling-=1,i.length},this.selectMoreLines=function(e,t){var n=this.selection.toOrientedRange(),r=n.cursor==n.end,s=this.session.documentToScreenPosition(n.cursor);this.selection.$desiredColumn&&(s.column=this.selection.$desiredColumn);var o=this.session.screenToDocumentPosition(s.row+e,s.column);if(!n.isEmpty())var u=this.session.documentToScreenPosition(r?n.end:n.start),a=this.session.screenToDocumentPosition(u.row+e,u.column);else var a=o;if(r){var f=i.fromPoints(o,a);f.cursor=f.start}else{var f=i.fromPoints(a,o);f.cursor=f.end}f.desiredColumn=s.column;if(!this.selection.inMultiSelectMode)this.selection.addRange(n);else if(t)var l=n.cursor;this.selection.addRange(f),l&&this.selection.substractPoint(l)},this.transposeSelections=function(e){var t=this.session,n=t.multiSelect,r=n.ranges;for(var i=r.length;i--;){var s=r[i];if(s.isEmpty()){var o=t.getWordRange(s.start.row,s.start.column);s.start.row=o.start.row,s.start.column=o.start.column,s.end.row=o.end.row,s.end.column=o.end.column}}n.mergeOverlappingRanges();var u=[];for(var i=r.length;i--;){var s=r[i];u.unshift(t.getTextRange(s))}e<0?u.unshift(u.pop()):u.push(u.shift());for(var i=r.length;i--;){var s=r[i],o=s.clone();t.replace(s,u[i]),s.start.row=o.start.row,s.start.column=o.start.column}},this.selectMore=function(e,t,n){var r=this.session,i=r.multiSelect,s=i.toOrientedRange();if(s.isEmpty()){s=r.getWordRange(s.start.row,s.start.column),s.cursor=e==-1?s.start:s.end,this.multiSelect.addRange(s);if(n)return}var o=r.getTextRange(s),u=h(r,o,e);u&&(u.cursor=e==-1?u.start:u.end,this.$blockScrolling+=1,this.session.unfold(u),this.multiSelect.addRange(u),this.$blockScrolling-=1,this.renderer.scrollCursorIntoView(null,.5)),t&&this.multiSelect.substractPoint(s.cursor)},this.alignCursors=function(){var e=this.session,t=e.multiSelect,n=t.ranges,r=-1,s=n.filter(function(e){if(e.cursor.row==r)return!0;r=e.cursor.row});if(!n.length||s.length==n.length-1){var o=this.selection.getRange(),u=o.start.row,f=o.end.row,l=u==f;if(l){var c=this.session.getLength(),h;do h=this.session.getLine(f);while(/[=:]/.test(h)&&++f<c);do h=this.session.getLine(u);while(/[=:]/.test(h)&&--u>0);u<0&&(u=0),f>=c&&(f=c-1)}var p=this.session.removeFullLines(u,f);p=this.$reAlignText(p,l),this.session.insert({row:u,column:0},p.join(\"\\n\")+\"\\n\"),l||(o.start.column=0,o.end.column=p[p.length-1].length),this.selection.setRange(o)}else{s.forEach(function(e){t.substractPoint(e.cursor)});var d=0,v=Infinity,m=n.map(function(t){var n=t.cursor,r=e.getLine(n.row),i=r.substr(n.column).search(/\\S/g);return i==-1&&(i=0),n.column>d&&(d=n.column),i<v&&(v=i),i});n.forEach(function(t,n){var r=t.cursor,s=d-r.column,o=m[n]-v;s>o?e.insert(r,a.stringRepeat(\" \",s-o)):e.remove(new i(r.row,r.column,r.row,r.column-s+o)),t.start.column=t.end.column=d,t.start.row=t.end.row=r.row,t.cursor=t.end}),t.fromOrientedRange(n[0]),this.renderer.updateCursor(),this.renderer.updateBackMarkers()}},this.$reAlignText=function(e,t){function u(e){return a.stringRepeat(\" \",e)}function f(e){return e[2]?u(i)+e[2]+u(s-e[2].length+o)+e[4].replace(/^([=:])\\s+/,\"$1 \"):e[0]}function l(e){return e[2]?u(i+s-e[2].length)+e[2]+u(o,\" \")+e[4].replace(/^([=:])\\s+/,\"$1 \"):e[0]}function c(e){return e[2]?u(i)+e[2]+u(o)+e[4].replace(/^([=:])\\s+/,\"$1 \"):e[0]}var n=!0,r=!0,i,s,o;return e.map(function(e){var t=e.match(/(\\s*)(.*?)(\\s*)([=:].*)/);return t?i==null?(i=t[1].length,s=t[2].length,o=t[3].length,t):(i+s+o!=t[1].length+t[2].length+t[3].length&&(r=!1),i!=t[1].length&&(n=!1),i>t[1].length&&(i=t[1].length),s<t[2].length&&(s=t[2].length),o>t[3].length&&(o=t[3].length),t):[e]}).map(t?f:n?r?l:f:c)}}).call(d.prototype),t.onSessionChange=function(e){var t=e.session;t&&!t.multiSelect&&(t.$selectionMarkers=[],t.selection.$initRangeList(),t.multiSelect=t.selection),this.multiSelect=t&&t.multiSelect;var n=e.oldSession;n&&(n.multiSelect.off(\"addRange\",this.$onAddRange),n.multiSelect.off(\"removeRange\",this.$onRemoveRange),n.multiSelect.off(\"multiSelect\",this.$onMultiSelect),n.multiSelect.off(\"singleSelect\",this.$onSingleSelect),n.multiSelect.lead.off(\"change\",this.$checkMultiselectChange),n.multiSelect.anchor.off(\"change\",this.$checkMultiselectChange)),t&&(t.multiSelect.on(\"addRange\",this.$onAddRange),t.multiSelect.on(\"removeRange\",this.$onRemoveRange),t.multiSelect.on(\"multiSelect\",this.$onMultiSelect),t.multiSelect.on(\"singleSelect\",this.$onSingleSelect),t.multiSelect.lead.on(\"change\",this.$checkMultiselectChange),t.multiSelect.anchor.on(\"change\",this.$checkMultiselectChange)),t&&this.inMultiSelectMode!=t.selection.inMultiSelectMode&&(t.selection.inMultiSelectMode?this.$onMultiSelect():this.$onSingleSelect())},t.MultiSelect=m,e(\"./config\").defineOptions(d.prototype,\"editor\",{enableMultiselect:{set:function(e){m(this),e?(this.on(\"changeSession\",this.$multiselectOnSessionChange),this.on(\"mousedown\",o)):(this.off(\"changeSession\",this.$multiselectOnSessionChange),this.off(\"mousedown\",o))},value:!0},enableBlockSelect:{set:function(e){this.$blockSelectEnabled=e},value:!0}})}),ace.define(\"ace/mode/folding/fold_mode\",[\"require\",\"exports\",\"module\",\"ace/range\"],function(e,t,n){\"use strict\";var r=e(\"../../range\").Range,i=t.FoldMode=function(){};(function(){this.foldingStartMarker=null,this.foldingStopMarker=null,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);return this.foldingStartMarker.test(r)?\"start\":t==\"markbeginend\"&&this.foldingStopMarker&&this.foldingStopMarker.test(r)?\"end\":\"\"},this.getFoldWidgetRange=function(e,t,n){return null},this.indentationBlock=function(e,t,n){var i=/\\S/,s=e.getLine(t),o=s.search(i);if(o==-1)return;var u=n||s.length,a=e.getLength(),f=t,l=t;while(++t<a){var c=e.getLine(t).search(i);if(c==-1)continue;if(c<=o)break;l=t}if(l>f){var h=e.getLine(l).length;return new r(f,u,l,h)}},this.openingBracketBlock=function(e,t,n,i,s){var o={row:n,column:i+1},u=e.$findClosingBracket(t,o,s);if(!u)return;var a=e.foldWidgets[u.row];return a==null&&(a=e.getFoldWidget(u.row)),a==\"start\"&&u.row>o.row&&(u.row--,u.column=e.getLine(u.row).length),r.fromPoints(o,u)},this.closingBracketBlock=function(e,t,n,i,s){var o={row:n,column:i},u=e.$findOpeningBracket(t,o);if(!u)return;return u.column++,o.column--,r.fromPoints(u,o)}}).call(i.prototype)}),ace.define(\"ace/theme/textmate\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\"],function(e,t,n){\"use strict\";t.isDark=!1,t.cssClass=\"ace-tm\",t.cssText='.ace-tm .ace_gutter {background: #f0f0f0;color: #333;}.ace-tm .ace_print-margin {width: 1px;background: #e8e8e8;}.ace-tm .ace_fold {background-color: #6B72E6;}.ace-tm {background-color: #FFFFFF;color: black;}.ace-tm .ace_cursor {color: black;}.ace-tm .ace_invisible {color: rgb(191, 191, 191);}.ace-tm .ace_storage,.ace-tm .ace_keyword {color: blue;}.ace-tm .ace_constant {color: rgb(197, 6, 11);}.ace-tm .ace_constant.ace_buildin {color: rgb(88, 72, 246);}.ace-tm .ace_constant.ace_language {color: rgb(88, 92, 246);}.ace-tm .ace_constant.ace_library {color: rgb(6, 150, 14);}.ace-tm .ace_invalid {background-color: rgba(255, 0, 0, 0.1);color: red;}.ace-tm .ace_support.ace_function {color: rgb(60, 76, 114);}.ace-tm .ace_support.ace_constant {color: rgb(6, 150, 14);}.ace-tm .ace_support.ace_type,.ace-tm .ace_support.ace_class {color: rgb(109, 121, 222);}.ace-tm .ace_keyword.ace_operator {color: rgb(104, 118, 135);}.ace-tm .ace_string {color: rgb(3, 106, 7);}.ace-tm .ace_comment {color: rgb(76, 136, 107);}.ace-tm .ace_comment.ace_doc {color: rgb(0, 102, 255);}.ace-tm .ace_comment.ace_doc.ace_tag {color: rgb(128, 159, 191);}.ace-tm .ace_constant.ace_numeric {color: rgb(0, 0, 205);}.ace-tm .ace_variable {color: rgb(49, 132, 149);}.ace-tm .ace_xml-pe {color: rgb(104, 104, 91);}.ace-tm .ace_entity.ace_name.ace_function {color: #0000A2;}.ace-tm .ace_heading {color: rgb(12, 7, 255);}.ace-tm .ace_list {color:rgb(185, 6, 144);}.ace-tm .ace_meta.ace_tag {color:rgb(0, 22, 142);}.ace-tm .ace_string.ace_regex {color: rgb(255, 0, 0)}.ace-tm .ace_marker-layer .ace_selection {background: rgb(181, 213, 255);}.ace-tm.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px white;}.ace-tm .ace_marker-layer .ace_step {background: rgb(252, 255, 0);}.ace-tm .ace_marker-layer .ace_stack {background: rgb(164, 229, 101);}.ace-tm .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgb(192, 192, 192);}.ace-tm .ace_marker-layer .ace_active-line {background: rgba(0, 0, 0, 0.07);}.ace-tm .ace_gutter-active-line {background-color : #dcdcdc;}.ace-tm .ace_marker-layer .ace_selected-word {background: rgb(250, 250, 255);border: 1px solid rgb(200, 200, 250);}.ace-tm .ace_indent-guide {background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;}';var r=e(\"../lib/dom\");r.importCssString(t.cssText,t.cssClass)}),ace.define(\"ace/line_widgets\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/dom\",\"ace/range\"],function(e,t,n){\"use strict\";function o(e){this.session=e,this.session.widgetManager=this,this.session.getRowLength=this.getRowLength,this.session.$getWidgetScreenLength=this.$getWidgetScreenLength,this.updateOnChange=this.updateOnChange.bind(this),this.renderWidgets=this.renderWidgets.bind(this),this.measureWidgets=this.measureWidgets.bind(this),this.session._changedWidgets=[],this.$onChangeEditor=this.$onChangeEditor.bind(this),this.session.on(\"change\",this.updateOnChange),this.session.on(\"changeFold\",this.updateOnFold),this.session.on(\"changeEditor\",this.$onChangeEditor)}var r=e(\"./lib/oop\"),i=e(\"./lib/dom\"),s=e(\"./range\").Range;(function(){this.getRowLength=function(e){var t;return this.lineWidgets?t=this.lineWidgets[e]&&this.lineWidgets[e].rowCount||0:t=0,!this.$useWrapMode||!this.$wrapData[e]?1+t:this.$wrapData[e].length+1+t},this.$getWidgetScreenLength=function(){var e=0;return this.lineWidgets.forEach(function(t){t&&t.rowCount&&!t.hidden&&(e+=t.rowCount)}),e},this.$onChangeEditor=function(e){this.attach(e.editor)},this.attach=function(e){e&&e.widgetManager&&e.widgetManager!=this&&e.widgetManager.detach();if(this.editor==e)return;this.detach(),this.editor=e,e&&(e.widgetManager=this,e.renderer.on(\"beforeRender\",this.measureWidgets),e.renderer.on(\"afterRender\",this.renderWidgets))},this.detach=function(e){var t=this.editor;if(!t)return;this.editor=null,t.widgetManager=null,t.renderer.off(\"beforeRender\",this.measureWidgets),t.renderer.off(\"afterRender\",this.renderWidgets);var n=this.session.lineWidgets;n&&n.forEach(function(e){e&&e.el&&e.el.parentNode&&(e._inDocument=!1,e.el.parentNode.removeChild(e.el))})},this.updateOnFold=function(e,t){var n=t.lineWidgets;if(!n||!e.action)return;var r=e.data,i=r.start.row,s=r.end.row,o=e.action==\"add\";for(var u=i+1;u<s;u++)n[u]&&(n[u].hidden=o);n[s]&&(o?n[i]?n[s].hidden=o:n[i]=n[s]:(n[i]==n[s]&&(n[i]=undefined),n[s].hidden=o))},this.updateOnChange=function(e){var t=this.session.lineWidgets;if(!t)return;var n=e.start.row,r=e.end.row-n;if(r!==0)if(e.action==\"remove\"){var i=t.splice(n+1,r);i.forEach(function(e){e&&this.removeLineWidget(e)},this),this.$updateRows()}else{var s=new Array(r);s.unshift(n,0),t.splice.apply(t,s),this.$updateRows()}},this.$updateRows=function(){var e=this.session.lineWidgets;if(!e)return;var t=!0;e.forEach(function(e,n){if(e){t=!1,e.row=n;while(e.$oldWidget)e.$oldWidget.row=n,e=e.$oldWidget}}),t&&(this.session.lineWidgets=null)},this.addLineWidget=function(e){this.session.lineWidgets||(this.session.lineWidgets=new Array(this.session.getLength()));var t=this.session.lineWidgets[e.row];t&&(e.$oldWidget=t,t.el&&t.el.parentNode&&(t.el.parentNode.removeChild(t.el),t._inDocument=!1)),this.session.lineWidgets[e.row]=e,e.session=this.session;var n=this.editor.renderer;e.html&&!e.el&&(e.el=i.createElement(\"div\"),e.el.innerHTML=e.html),e.el&&(i.addCssClass(e.el,\"ace_lineWidgetContainer\"),e.el.style.position=\"absolute\",e.el.style.zIndex=5,n.container.appendChild(e.el),e._inDocument=!0),e.coverGutter||(e.el.style.zIndex=3),e.pixelHeight||(e.pixelHeight=e.el.offsetHeight),e.rowCount==null&&(e.rowCount=e.pixelHeight/n.layerConfig.lineHeight);var r=this.session.getFoldAt(e.row,0);e.$fold=r;if(r){var s=this.session.lineWidgets;e.row==r.end.row&&!s[r.start.row]?s[r.start.row]=e:e.hidden=!0}return this.session._emit(\"changeFold\",{data:{start:{row:e.row}}}),this.$updateRows(),this.renderWidgets(null,n),this.onWidgetChanged(e),e},this.removeLineWidget=function(e){e._inDocument=!1,e.session=null,e.el&&e.el.parentNode&&e.el.parentNode.removeChild(e.el);if(e.editor&&e.editor.destroy)try{e.editor.destroy()}catch(t){}if(this.session.lineWidgets){var n=this.session.lineWidgets[e.row];if(n==e)this.session.lineWidgets[e.row]=e.$oldWidget,e.$oldWidget&&this.onWidgetChanged(e.$oldWidget);else while(n){if(n.$oldWidget==e){n.$oldWidget=e.$oldWidget;break}n=n.$oldWidget}}this.session._emit(\"changeFold\",{data:{start:{row:e.row}}}),this.$updateRows()},this.getWidgetsAtRow=function(e){var t=this.session.lineWidgets,n=t&&t[e],r=[];while(n)r.push(n),n=n.$oldWidget;return r},this.onWidgetChanged=function(e){this.session._changedWidgets.push(e),this.editor&&this.editor.renderer.updateFull()},this.measureWidgets=function(e,t){var n=this.session._changedWidgets,r=t.layerConfig;if(!n||!n.length)return;var i=Infinity;for(var s=0;s<n.length;s++){var o=n[s];if(!o||!o.el)continue;if(o.session!=this.session)continue;if(!o._inDocument){if(this.session.lineWidgets[o.row]!=o)continue;o._inDocument=!0,t.container.appendChild(o.el)}o.h=o.el.offsetHeight,o.fixedWidth||(o.w=o.el.offsetWidth,o.screenWidth=Math.ceil(o.w/r.characterWidth));var u=o.h/r.lineHeight;o.coverLine&&(u-=this.session.getRowLineCount(o.row),u<0&&(u=0)),o.rowCount!=u&&(o.rowCount=u,o.row<i&&(i=o.row))}i!=Infinity&&(this.session._emit(\"changeFold\",{data:{start:{row:i}}}),this.session.lineWidgetWidth=null),this.session._changedWidgets=[]},this.renderWidgets=function(e,t){var n=t.layerConfig,r=this.session.lineWidgets;if(!r)return;var i=Math.min(this.firstRow,n.firstRow),s=Math.max(this.lastRow,n.lastRow,r.length);while(i>0&&!r[i])i--;this.firstRow=n.firstRow,this.lastRow=n.lastRow,t.$cursorLayer.config=n;for(var o=i;o<=s;o++){var u=r[o];if(!u||!u.el)continue;if(u.hidden){u.el.style.top=-100-(u.pixelHeight||0)+\"px\";continue}u._inDocument||(u._inDocument=!0,t.container.appendChild(u.el));var a=t.$cursorLayer.getPixelPosition({row:o,column:0},!0).top;u.coverLine||(a+=n.lineHeight*this.session.getRowLineCount(u.row)),u.el.style.top=a-n.offset+\"px\";var f=u.coverGutter?0:t.gutterWidth;u.fixedWidth||(f-=t.scrollLeft),u.el.style.left=f+\"px\",u.fullWidth&&u.screenWidth&&(u.el.style.minWidth=n.width+2*n.padding+\"px\"),u.fixedWidth?u.el.style.right=t.scrollBar.getWidth()+\"px\":u.el.style.right=\"\"}}}).call(o.prototype),t.LineWidgets=o}),ace.define(\"ace/ext/error_marker\",[\"require\",\"exports\",\"module\",\"ace/line_widgets\",\"ace/lib/dom\",\"ace/range\"],function(e,t,n){\"use strict\";function o(e,t,n){var r=0,i=e.length-1;while(r<=i){var s=r+i>>1,o=n(t,e[s]);if(o>0)r=s+1;else{if(!(o<0))return s;i=s-1}}return-(r+1)}function u(e,t,n){var r=e.getAnnotations().sort(s.comparePoints);if(!r.length)return;var i=o(r,{row:t,column:-1},s.comparePoints);i<0&&(i=-i-1),i>=r.length?i=n>0?0:r.length-1:i===0&&n<0&&(i=r.length-1);var u=r[i];if(!u||!n)return;if(u.row===t){do u=r[i+=n];while(u&&u.row===t);if(!u)return r.slice()}var a=[];t=u.row;do a[n<0?\"unshift\":\"push\"](u),u=r[i+=n];while(u&&u.row==t);return a.length&&a}var r=e(\"../line_widgets\").LineWidgets,i=e(\"../lib/dom\"),s=e(\"../range\").Range;t.showErrorMarker=function(e,t){var n=e.session;n.widgetManager||(n.widgetManager=new r(n),n.widgetManager.attach(e));var s=e.getCursorPosition(),o=s.row,a=n.widgetManager.getWidgetsAtRow(o).filter(function(e){return e.type==\"errorMarker\"})[0];a?a.destroy():o-=t;var f=u(n,o,t),l;if(f){var c=f[0];s.column=(c.pos&&typeof c.column!=\"number\"?c.pos.sc:c.column)||0,s.row=c.row,l=e.renderer.$gutterLayer.$annotations[s.row]}else{if(a)return;l={text:[\"Looks good!\"],className:\"ace_ok\"}}e.session.unfold(s.row),e.selection.moveToPosition(s);var h={row:s.row,fixedWidth:!0,coverGutter:!0,el:i.createElement(\"div\"),type:\"errorMarker\"},p=h.el.appendChild(i.createElement(\"div\")),d=h.el.appendChild(i.createElement(\"div\"));d.className=\"error_widget_arrow \"+l.className;var v=e.renderer.$cursorLayer.getPixelPosition(s).left;d.style.left=v+e.renderer.gutterWidth-5+\"px\",h.el.className=\"error_widget_wrapper\",p.className=\"error_widget \"+l.className,p.innerHTML=l.text.join(\"<br>\"),p.appendChild(i.createElement(\"div\"));var m=function(e,t,n){if(t===0&&(n===\"esc\"||n===\"return\"))return h.destroy(),{command:\"null\"}};h.destroy=function(){if(e.$mouseHandler.isMousePressed)return;e.keyBinding.removeKeyboardHandler(m),n.widgetManager.removeLineWidget(h),e.off(\"changeSelection\",h.destroy),e.off(\"changeSession\",h.destroy),e.off(\"mouseup\",h.destroy),e.off(\"change\",h.destroy)},e.keyBinding.addKeyboardHandler(m),e.on(\"changeSelection\",h.destroy),e.on(\"changeSession\",h.destroy),e.on(\"mouseup\",h.destroy),e.on(\"change\",h.destroy),e.session.widgetManager.addLineWidget(h),h.el.onmousedown=e.focus.bind(e),e.renderer.scrollCursorIntoView(null,.5,{bottom:h.el.offsetHeight})},i.importCssString(\"    .error_widget_wrapper {        background: inherit;        color: inherit;        border:none    }    .error_widget {        border-top: solid 2px;        border-bottom: solid 2px;        margin: 5px 0;        padding: 10px 40px;        white-space: pre-wrap;    }    .error_widget.ace_error, .error_widget_arrow.ace_error{        border-color: #ff5a5a    }    .error_widget.ace_warning, .error_widget_arrow.ace_warning{        border-color: #F1D817    }    .error_widget.ace_info, .error_widget_arrow.ace_info{        border-color: #5a5a5a    }    .error_widget.ace_ok, .error_widget_arrow.ace_ok{        border-color: #5aaa5a    }    .error_widget_arrow {        position: absolute;        border: solid 5px;        border-top-color: transparent!important;        border-right-color: transparent!important;        border-left-color: transparent!important;        top: -5px;    }\",\"\")}),ace.define(\"ace/ace\",[\"require\",\"exports\",\"module\",\"ace/lib/fixoldbrowsers\",\"ace/lib/dom\",\"ace/lib/event\",\"ace/editor\",\"ace/edit_session\",\"ace/undomanager\",\"ace/virtual_renderer\",\"ace/worker/worker_client\",\"ace/keyboard/hash_handler\",\"ace/placeholder\",\"ace/multi_select\",\"ace/mode/folding/fold_mode\",\"ace/theme/textmate\",\"ace/ext/error_marker\",\"ace/config\"],function(e,t,n){\"use strict\";e(\"./lib/fixoldbrowsers\");var r=e(\"./lib/dom\"),i=e(\"./lib/event\"),s=e(\"./editor\").Editor,o=e(\"./edit_session\").EditSession,u=e(\"./undomanager\").UndoManager,a=e(\"./virtual_renderer\").VirtualRenderer;e(\"./worker/worker_client\"),e(\"./keyboard/hash_handler\"),e(\"./placeholder\"),e(\"./multi_select\"),e(\"./mode/folding/fold_mode\"),e(\"./theme/textmate\"),e(\"./ext/error_marker\"),t.config=e(\"./config\"),t.require=e,t.edit=function(e){if(typeof e==\"string\"){var n=e;e=document.getElementById(n);if(!e)throw new Error(\"ace.edit can't find div #\"+n)}if(e&&e.env&&e.env.editor instanceof s)return e.env.editor;var o=\"\";if(e&&/input|textarea/i.test(e.tagName)){var u=e;o=u.value,e=r.createElement(\"pre\"),u.parentNode.replaceChild(e,u)}else e&&(o=r.getInnerText(e),e.innerHTML=\"\");var f=t.createEditSession(o),l=new s(new a(e));l.setSession(f);var c={document:f,editor:l,onResize:l.resize.bind(l,null)};return u&&(c.textarea=u),i.addListener(window,\"resize\",c.onResize),l.on(\"destroy\",function(){i.removeListener(window,\"resize\",c.onResize),c.editor.container.env=null}),l.container.env=l.env=c,l},t.createEditSession=function(e,t){var n=new o(e,t);return n.setUndoManager(new u),n},t.EditSession=o,t.UndoManager=u,t.version=\"1.2.3\"});\n            (function() {\n                ace.require([\"ace/ace\"], function(a) {\n                    a && a.config.init(true);\n                    if (!window.ace)\n                        window.ace = a;\n                    for (var key in a) if (a.hasOwnProperty(key))\n                        window.ace[key] = a[key];\n                });\n            })();\n        "

/***/ }),
/* 47 */
/***/ (function(module, exports) {

module.exports = "ace.define(\"ace/mode/doc_comment_highlight_rules\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/text_highlight_rules\"],function(e,t,n){\"use strict\";var r=e(\"../lib/oop\"),i=e(\"./text_highlight_rules\").TextHighlightRules,s=function(){this.$rules={start:[{token:\"comment.doc.tag\",regex:\"@[\\\\w\\\\d_]+\"},s.getTagRule(),{defaultToken:\"comment.doc\",caseInsensitive:!0}]}};r.inherits(s,i),s.getTagRule=function(e){return{token:\"comment.doc.tag.storage.type\",regex:\"\\\\b(?:TODO|FIXME|XXX|HACK)\\\\b\"}},s.getStartRule=function(e){return{token:\"comment.doc\",regex:\"\\\\/\\\\*(?=\\\\*)\",next:e}},s.getEndRule=function(e){return{token:\"comment.doc\",regex:\"\\\\*\\\\/\",next:e}},t.DocCommentHighlightRules=s}),ace.define(\"ace/mode/c_cpp_highlight_rules\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/doc_comment_highlight_rules\",\"ace/mode/text_highlight_rules\"],function(e,t,n){\"use strict\";var r=e(\"../lib/oop\"),i=e(\"./doc_comment_highlight_rules\").DocCommentHighlightRules,s=e(\"./text_highlight_rules\").TextHighlightRules,o=t.cFunctions=\"\\\\b(?:hypot(?:f|l)?|s(?:scanf|ystem|nprintf|ca(?:nf|lb(?:n(?:f|l)?|ln(?:f|l)?))|i(?:n(?:h(?:f|l)?|f|l)?|gn(?:al|bit))|tr(?:s(?:tr|pn)|nc(?:py|at|mp)|c(?:spn|hr|oll|py|at|mp)|to(?:imax|d|u(?:l(?:l)?|max)|k|f|l(?:d|l)?)|error|pbrk|ftime|len|rchr|xfrm)|printf|et(?:jmp|vbuf|locale|buf)|qrt(?:f|l)?|w(?:scanf|printf)|rand)|n(?:e(?:arbyint(?:f|l)?|xt(?:toward(?:f|l)?|after(?:f|l)?))|an(?:f|l)?)|c(?:s(?:in(?:h(?:f|l)?|f|l)?|qrt(?:f|l)?)|cos(?:h(?:f)?|f|l)?|imag(?:f|l)?|t(?:ime|an(?:h(?:f|l)?|f|l)?)|o(?:s(?:h(?:f|l)?|f|l)?|nj(?:f|l)?|pysign(?:f|l)?)|p(?:ow(?:f|l)?|roj(?:f|l)?)|e(?:il(?:f|l)?|xp(?:f|l)?)|l(?:o(?:ck|g(?:f|l)?)|earerr)|a(?:sin(?:h(?:f|l)?|f|l)?|cos(?:h(?:f|l)?|f|l)?|tan(?:h(?:f|l)?|f|l)?|lloc|rg(?:f|l)?|bs(?:f|l)?)|real(?:f|l)?|brt(?:f|l)?)|t(?:ime|o(?:upper|lower)|an(?:h(?:f|l)?|f|l)?|runc(?:f|l)?|gamma(?:f|l)?|mp(?:nam|file))|i(?:s(?:space|n(?:ormal|an)|cntrl|inf|digit|u(?:nordered|pper)|p(?:unct|rint)|finite|w(?:space|c(?:ntrl|type)|digit|upper|p(?:unct|rint)|lower|al(?:num|pha)|graph|xdigit|blank)|l(?:ower|ess(?:equal|greater)?)|al(?:num|pha)|gr(?:eater(?:equal)?|aph)|xdigit|blank)|logb(?:f|l)?|max(?:div|abs))|di(?:v|fftime)|_Exit|unget(?:c|wc)|p(?:ow(?:f|l)?|ut(?:s|c(?:har)?|wc(?:har)?)|error|rintf)|e(?:rf(?:c(?:f|l)?|f|l)?|x(?:it|p(?:2(?:f|l)?|f|l|m1(?:f|l)?)?))|v(?:s(?:scanf|nprintf|canf|printf|w(?:scanf|printf))|printf|f(?:scanf|printf|w(?:scanf|printf))|w(?:scanf|printf)|a_(?:start|copy|end|arg))|qsort|f(?:s(?:canf|e(?:tpos|ek))|close|tell|open|dim(?:f|l)?|p(?:classify|ut(?:s|c|w(?:s|c))|rintf)|e(?:holdexcept|set(?:e(?:nv|xceptflag)|round)|clearexcept|testexcept|of|updateenv|r(?:aiseexcept|ror)|get(?:e(?:nv|xceptflag)|round))|flush|w(?:scanf|ide|printf|rite)|loor(?:f|l)?|abs(?:f|l)?|get(?:s|c|pos|w(?:s|c))|re(?:open|e|ad|xp(?:f|l)?)|m(?:in(?:f|l)?|od(?:f|l)?|a(?:f|l|x(?:f|l)?)?))|l(?:d(?:iv|exp(?:f|l)?)|o(?:ngjmp|cal(?:time|econv)|g(?:1(?:p(?:f|l)?|0(?:f|l)?)|2(?:f|l)?|f|l|b(?:f|l)?)?)|abs|l(?:div|abs|r(?:int(?:f|l)?|ound(?:f|l)?))|r(?:int(?:f|l)?|ound(?:f|l)?)|gamma(?:f|l)?)|w(?:scanf|c(?:s(?:s(?:tr|pn)|nc(?:py|at|mp)|c(?:spn|hr|oll|py|at|mp)|to(?:imax|d|u(?:l(?:l)?|max)|k|f|l(?:d|l)?|mbs)|pbrk|ftime|len|r(?:chr|tombs)|xfrm)|to(?:b|mb)|rtomb)|printf|mem(?:set|c(?:hr|py|mp)|move))|a(?:s(?:sert|ctime|in(?:h(?:f|l)?|f|l)?)|cos(?:h(?:f|l)?|f|l)?|t(?:o(?:i|f|l(?:l)?)|exit|an(?:h(?:f|l)?|2(?:f|l)?|f|l)?)|b(?:s|ort))|g(?:et(?:s|c(?:har)?|env|wc(?:har)?)|mtime)|r(?:int(?:f|l)?|ound(?:f|l)?|e(?:name|alloc|wind|m(?:ove|quo(?:f|l)?|ainder(?:f|l)?))|a(?:nd|ise))|b(?:search|towc)|m(?:odf(?:f|l)?|em(?:set|c(?:hr|py|mp)|move)|ktime|alloc|b(?:s(?:init|towcs|rtowcs)|towc|len|r(?:towc|len))))\\\\b\",u=function(){var e=\"break|case|continue|default|do|else|for|goto|if|_Pragma|return|switch|while|catch|operator|try|throw|using\",t=\"asm|__asm__|auto|bool|_Bool|char|_Complex|double|enum|float|_Imaginary|int|long|short|signed|struct|typedef|union|unsigned|void|class|wchar_t|template|char16_t|char32_t\",n=\"const|extern|register|restrict|static|volatile|inline|private|protected|public|friend|explicit|virtual|export|mutable|typename|constexpr|new|delete|alignas|alignof|decltype|noexcept|thread_local\",r=\"and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|typeid|xor|xor_eqconst_cast|dynamic_cast|reinterpret_cast|static_cast|sizeof|namespace\",s=\"NULL|true|false|TRUE|FALSE|nullptr\",u=this.$keywords=this.createKeywordMapper({\"keyword.control\":e,\"storage.type\":t,\"storage.modifier\":n,\"keyword.operator\":r,\"variable.language\":\"this\",\"constant.language\":s},\"identifier\"),a=\"[a-zA-Z\\\\$_\\u00a1-\\uffff][a-zA-Zd\\\\$_\\u00a1-\\uffff]*\\\\b\",f=/\\\\(?:['\"?\\\\abfnrtv]|[0-7]{1,3}|x[a-fA-F\\d]{2}|u[a-fA-F\\d]{4}U[a-fA-F\\d]{8}|.)/.source;this.$rules={start:[{token:\"comment\",regex:\"//$\",next:\"start\"},{token:\"comment\",regex:\"//\",next:\"singleLineComment\"},i.getStartRule(\"doc-start\"),{token:\"comment\",regex:\"\\\\/\\\\*\",next:\"comment\"},{token:\"string\",regex:\"'(?:\"+f+\"|.)'\"},{token:\"string.start\",regex:'\"',stateName:\"qqstring\",next:[{token:\"string\",regex:/\\\\\\s*$/,next:\"qqstring\"},{token:\"constant.language.escape\",regex:f},{token:\"constant.language.escape\",regex:/%[^'\"\\\\]/},{token:\"string.end\",regex:'\"|$',next:\"start\"},{defaultToken:\"string\"}]},{token:\"string.start\",regex:'R\"\\\\(',stateName:\"rawString\",next:[{token:\"string.end\",regex:'\\\\)\"',next:\"start\"},{defaultToken:\"string\"}]},{token:\"constant.numeric\",regex:\"0[xX][0-9a-fA-F]+(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\\\b\"},{token:\"constant.numeric\",regex:\"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\\\b\"},{token:\"keyword\",regex:\"#\\\\s*(?:include|import|pragma|line|define|undef)\\\\b\",next:\"directive\"},{token:\"keyword\",regex:\"#\\\\s*(?:endif|if|ifdef|else|elif|ifndef)\\\\b\"},{token:\"support.function.C99.c\",regex:o},{token:u,regex:\"[a-zA-Z_$][a-zA-Z0-9_$]*\"},{token:\"keyword.operator\",regex:/--|\\+\\+|<<=|>>=|>>>=|<>|&&|\\|\\||\\?:|[*%\\/+\\-&\\^|~!<>=]=?/},{token:\"punctuation.operator\",regex:\"\\\\?|\\\\:|\\\\,|\\\\;|\\\\.\"},{token:\"paren.lparen\",regex:\"[[({]\"},{token:\"paren.rparen\",regex:\"[\\\\])}]\"},{token:\"text\",regex:\"\\\\s+\"}],comment:[{token:\"comment\",regex:\".*?\\\\*\\\\/\",next:\"start\"},{token:\"comment\",regex:\".+\"}],singleLineComment:[{token:\"comment\",regex:/\\\\$/,next:\"singleLineComment\"},{token:\"comment\",regex:/$/,next:\"start\"},{defaultToken:\"comment\"}],directive:[{token:\"constant.other.multiline\",regex:/\\\\/},{token:\"constant.other.multiline\",regex:/.*\\\\/},{token:\"constant.other\",regex:\"\\\\s*<.+?>\",next:\"start\"},{token:\"constant.other\",regex:'\\\\s*[\"](?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?[\"]',next:\"start\"},{token:\"constant.other\",regex:\"\\\\s*['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\",next:\"start\"},{token:\"constant.other\",regex:/[^\\\\\\/]+/,next:\"start\"}]},this.embedRules(i,\"doc-\",[i.getEndRule(\"start\")]),this.normalizeRules()};r.inherits(u,s),t.c_cppHighlightRules=u}),ace.define(\"ace/mode/matching_brace_outdent\",[\"require\",\"exports\",\"module\",\"ace/range\"],function(e,t,n){\"use strict\";var r=e(\"../range\").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\\s+$/.test(e)?/^\\s*\\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\\s*\\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define(\"ace/mode/behaviour/cstyle\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/behaviour\",\"ace/token_iterator\",\"ace/lib/lang\"],function(e,t,n){\"use strict\";var r=e(\"../../lib/oop\"),i=e(\"../behaviour\").Behaviour,s=e(\"../../token_iterator\").TokenIterator,o=e(\"../../lib/lang\"),u=[\"text\",\"paren.rparen\",\"punctuation.operator\"],a=[\"text\",\"paren.rparen\",\"punctuation.operator\",\"comment\"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.index,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:\"\",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:\"\",maybeInsertedLineEnd:\"\"}},h=function(e,t,n,r){var i=e.end.row-e.start.row;return{text:n+t+r,selection:[0,e.start.column+1,i,e.end.column+(i?0:1)]}},p=function(){this.add(\"braces\",\"insertion\",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i==\"{\"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==\"\"&&l!==\"{\"&&n.getWrapBehavioursEnabled())return h(a,l,\"{\",\"}\");if(p.isSaneInsertion(n,r))return/[\\]\\}\\)]/.test(u[s.column])||n.inMultiSelectMode?(p.recordAutoInsert(n,r,\"}\"),{text:\"{}\",selection:[1,1]}):(p.recordMaybeInsert(n,r,\"{\"),{text:\"{\",selection:[1,1]})}else if(i==\"}\"){c(n);var d=u.substring(s.column,s.column+1);if(d==\"}\"){var v=r.$findOpeningBracket(\"}\",{column:s.column+1,row:s.row});if(v!==null&&p.isAutoInsertedClosing(s,u,i))return p.popAutoInsertedClosing(),{text:\"\",selection:[1,1]}}}else{if(i==\"\\n\"||i==\"\\r\\n\"){c(n);var m=\"\";p.isMaybeInsertedClosing(s,u)&&(m=o.stringRepeat(\"}\",f.maybeInsertedBrackets),p.clearMaybeInsertedClosing());var d=u.substring(s.column,s.column+1);if(d===\"}\"){var g=r.findMatchingBracket({row:s.row,column:s.column+1},\"}\");if(!g)return null;var y=this.$getIndent(r.getLine(g.row))}else{if(!m){p.clearMaybeInsertedClosing();return}var y=this.$getIndent(u)}var b=y+r.getTabString();return{text:\"\\n\"+b+\"\\n\"+y+m,selection:[1,b.length,1,b.length]}}p.clearMaybeInsertedClosing()}}),this.add(\"braces\",\"deletion\",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s==\"{\"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u==\"}\")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add(\"parens\",\"insertion\",function(e,t,n,r,i){if(i==\"(\"){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==\"\"&&n.getWrapBehavioursEnabled())return h(s,o,\"(\",\")\");if(p.isSaneInsertion(n,r))return p.recordAutoInsert(n,r,\")\"),{text:\"()\",selection:[1,1]}}else if(i==\")\"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==\")\"){var l=r.$findOpeningBracket(\")\",{column:u.column+1,row:u.row});if(l!==null&&p.isAutoInsertedClosing(u,a,i))return p.popAutoInsertedClosing(),{text:\"\",selection:[1,1]}}}}),this.add(\"parens\",\"deletion\",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s==\"(\"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==\")\")return i.end.column++,i}}),this.add(\"brackets\",\"insertion\",function(e,t,n,r,i){if(i==\"[\"){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==\"\"&&n.getWrapBehavioursEnabled())return h(s,o,\"[\",\"]\");if(p.isSaneInsertion(n,r))return p.recordAutoInsert(n,r,\"]\"),{text:\"[]\",selection:[1,1]}}else if(i==\"]\"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==\"]\"){var l=r.$findOpeningBracket(\"]\",{column:u.column+1,row:u.row});if(l!==null&&p.isAutoInsertedClosing(u,a,i))return p.popAutoInsertedClosing(),{text:\"\",selection:[1,1]}}}}),this.add(\"brackets\",\"deletion\",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s==\"[\"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==\"]\")return i.end.column++,i}}),this.add(\"string_dquotes\",\"insertion\",function(e,t,n,r,i){if(i=='\"'||i==\"'\"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==\"\"&&u!==\"'\"&&u!='\"'&&n.getWrapBehavioursEnabled())return h(o,u,s,s);if(!u){var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column),p=f.substring(a.column,a.column+1),d=r.getTokenAt(a.row,a.column),v=r.getTokenAt(a.row,a.column+1);if(l==\"\\\\\"&&d&&/escape/.test(d.type))return null;var m=d&&/string|escape/.test(d.type),g=!v||/string|escape/.test(v.type),y;if(p==s)y=m!==g;else{if(m&&!g)return null;if(m&&g)return null;var b=r.$mode.tokenRe;b.lastIndex=0;var w=b.test(l);b.lastIndex=0;var E=b.test(l);if(w||E)return null;if(p&&!/[\\s;,.})\\]\\\\]/.test(p))return null;y=!0}return{text:y?s+s:\"\",selection:[1,1]}}}}),this.add(\"string_dquotes\",\"deletion\",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='\"'||s==\"'\")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};p.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||\"text\",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||\"text\",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||\"text\",a)},p.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},p.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},p.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},p.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},p.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},p.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},p.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(p,i),t.CstyleBehaviour=p}),ace.define(\"ace/mode/folding/cstyle\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/range\",\"ace/mode/folding/fold_mode\"],function(e,t,n){\"use strict\";var r=e(\"../../lib/oop\"),i=e(\"../../range\").Range,s=e(\"./fold_mode\").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\\|[^|]*?$/,\"|\"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\\|[^|]*?$/,\"|\"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\\{|\\[)[^\\}\\]]*$|^\\s*(\\/\\*)/,this.foldingStopMarker=/^[^\\[\\{]*(\\}|\\])|^[\\s\\*]*(\\*\\/)/,this.singleLineBlockCommentRe=/^\\s*(\\/\\*).*\\*\\/\\s*$/,this.tripleStarBlockCommentRe=/^\\s*(\\/\\*\\*\\*).*\\*\\/\\s*$/,this.startRegionRe=/^\\s*(\\/\\*|\\/\\/)#?region\\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);if(this.singleLineBlockCommentRe.test(r)&&!this.startRegionRe.test(r)&&!this.tripleStarBlockCommentRe.test(r))return\"\";var i=this._getFoldWidgetBase(e,t,n);return!i&&this.startRegionRe.test(r)?\"start\":i},this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n);if(this.startRegionRe.test(i))return this.getCommentRegionBlock(e,i,n);var s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!=\"all\"&&(u=null)),u}if(t===\"markbegin\")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,\"all\",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)},this.getCommentRegionBlock=function(e,t,n){var r=t.search(/\\s*$/),s=e.getLength(),o=n,u=/^\\s*(?:\\/\\*|\\/\\/|--)#?(end)?region\\b/,a=1;while(++n<s){t=e.getLine(n);var f=u.exec(t);if(!f)continue;f[1]?a--:a++;if(!a)break}var l=n;if(l>o)return new i(o,r,l,t.length)}}.call(o.prototype)}),ace.define(\"ace/mode/c_cpp\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/text\",\"ace/mode/c_cpp_highlight_rules\",\"ace/mode/matching_brace_outdent\",\"ace/range\",\"ace/mode/behaviour/cstyle\",\"ace/mode/folding/cstyle\"],function(e,t,n){\"use strict\";var r=e(\"../lib/oop\"),i=e(\"./text\").Mode,s=e(\"./c_cpp_highlight_rules\").c_cppHighlightRules,o=e(\"./matching_brace_outdent\").MatchingBraceOutdent,u=e(\"../range\").Range,a=e(\"./behaviour/cstyle\").CstyleBehaviour,f=e(\"./folding/cstyle\").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.lineCommentStart=\"//\",this.blockComment={start:\"/*\",end:\"*/\"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type==\"comment\")return r;if(e==\"start\"){var u=t.match(/^.*[\\{\\(\\[]\\s*$/);u&&(r+=n)}else if(e==\"doc-start\"){if(o==\"start\")return\"\";var u=t.match(/^\\s*(\\/?)\\*/);u&&(u[1]&&(r+=\" \"),r+=\"* \")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id=\"ace/mode/c_cpp\"}.call(l.prototype),t.Mode=l})"

/***/ }),
/* 48 */
/***/ (function(module, exports) {

module.exports = "ace.define(\"ace/mode/doc_comment_highlight_rules\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/text_highlight_rules\"],function(e,t,n){\"use strict\";var r=e(\"../lib/oop\"),i=e(\"./text_highlight_rules\").TextHighlightRules,s=function(){this.$rules={start:[{token:\"comment.doc.tag\",regex:\"@[\\\\w\\\\d_]+\"},s.getTagRule(),{defaultToken:\"comment.doc\",caseInsensitive:!0}]}};r.inherits(s,i),s.getTagRule=function(e){return{token:\"comment.doc.tag.storage.type\",regex:\"\\\\b(?:TODO|FIXME|XXX|HACK)\\\\b\"}},s.getStartRule=function(e){return{token:\"comment.doc\",regex:\"\\\\/\\\\*(?=\\\\*)\",next:e}},s.getEndRule=function(e){return{token:\"comment.doc\",regex:\"\\\\*\\\\/\",next:e}},t.DocCommentHighlightRules=s}),ace.define(\"ace/mode/javascript_highlight_rules\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/doc_comment_highlight_rules\",\"ace/mode/text_highlight_rules\"],function(e,t,n){\"use strict\";function a(){var e=o.replace(\"\\\\d\",\"\\\\d\\\\-\"),t={onMatch:function(e,t,n){var r=e.charAt(1)==\"/\"?2:1;if(r==1)t!=this.nextState?n.unshift(this.next,this.nextState,0):n.unshift(this.next),n[2]++;else if(r==2&&t==this.nextState){n[1]--;if(!n[1]||n[1]<0)n.shift(),n.shift()}return[{type:\"meta.tag.punctuation.\"+(r==1?\"\":\"end-\")+\"tag-open.xml\",value:e.slice(0,r)},{type:\"meta.tag.tag-name.xml\",value:e.substr(r)}]},regex:\"</?\"+e+\"\",next:\"jsxAttributes\",nextState:\"jsx\"};this.$rules.start.unshift(t);var n={regex:\"{\",token:\"paren.quasi.start\",push:\"start\"};this.$rules.jsx=[n,t,{include:\"reference\"},{defaultToken:\"string\"}],this.$rules.jsxAttributes=[{token:\"meta.tag.punctuation.tag-close.xml\",regex:\"/?>\",onMatch:function(e,t,n){return t==n[0]&&n.shift(),e.length==2&&(n[0]==this.nextState&&n[1]--,(!n[1]||n[1]<0)&&n.splice(0,2)),this.next=n[0]||\"start\",[{type:this.token,value:e}]},nextState:\"jsx\"},n,f(\"jsxAttributes\"),{token:\"entity.other.attribute-name.xml\",regex:e},{token:\"keyword.operator.attribute-equals.xml\",regex:\"=\"},{token:\"text.tag-whitespace.xml\",regex:\"\\\\s+\"},{token:\"string.attribute-value.xml\",regex:\"'\",stateName:\"jsx_attr_q\",push:[{token:\"string.attribute-value.xml\",regex:\"'\",next:\"pop\"},{include:\"reference\"},{defaultToken:\"string.attribute-value.xml\"}]},{token:\"string.attribute-value.xml\",regex:'\"',stateName:\"jsx_attr_qq\",push:[{token:\"string.attribute-value.xml\",regex:'\"',next:\"pop\"},{include:\"reference\"},{defaultToken:\"string.attribute-value.xml\"}]},t],this.$rules.reference=[{token:\"constant.language.escape.reference.xml\",regex:\"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\\\.-]+;)\"}]}function f(e){return[{token:\"comment\",regex:/\\/\\*/,next:[i.getTagRule(),{token:\"comment\",regex:\"\\\\*\\\\/\",next:e||\"pop\"},{defaultToken:\"comment\",caseInsensitive:!0}]},{token:\"comment\",regex:\"\\\\/\\\\/\",next:[i.getTagRule(),{token:\"comment\",regex:\"$|^\",next:e||\"pop\"},{defaultToken:\"comment\",caseInsensitive:!0}]}]}var r=e(\"../lib/oop\"),i=e(\"./doc_comment_highlight_rules\").DocCommentHighlightRules,s=e(\"./text_highlight_rules\").TextHighlightRules,o=\"[a-zA-Z\\\\$_\\u00a1-\\uffff][a-zA-Z\\\\d\\\\$_\\u00a1-\\uffff]*\",u=function(e){var t=this.createKeywordMapper({\"variable.language\":\"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document\",keyword:\"const|yield|import|get|set|async|await|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static\",\"storage.type\":\"const|let|var|function\",\"constant.language\":\"null|Infinity|NaN|undefined\",\"support.function\":\"alert\",\"constant.language.boolean\":\"true|false\"},\"identifier\"),n=\"case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void\",r=\"\\\\\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|u{[0-9a-fA-F]{1,6}}|[0-2][0-7]{0,2}|3[0-7][0-7]?|[4-7][0-7]?|.)\";this.$rules={no_regex:[i.getStartRule(\"doc-start\"),f(\"no_regex\"),{token:\"string\",regex:\"'(?=.)\",next:\"qstring\"},{token:\"string\",regex:'\"(?=.)',next:\"qqstring\"},{token:\"constant.numeric\",regex:/0(?:[xX][0-9a-fA-F]+|[bB][01]+)\\b/},{token:\"constant.numeric\",regex:/[+-]?\\d[\\d_]*(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b/},{token:[\"storage.type\",\"punctuation.operator\",\"support.function\",\"punctuation.operator\",\"entity.name.function\",\"text\",\"keyword.operator\"],regex:\"(\"+o+\")(\\\\.)(prototype)(\\\\.)(\"+o+\")(\\\\s*)(=)\",next:\"function_arguments\"},{token:[\"storage.type\",\"punctuation.operator\",\"entity.name.function\",\"text\",\"keyword.operator\",\"text\",\"storage.type\",\"text\",\"paren.lparen\"],regex:\"(\"+o+\")(\\\\.)(\"+o+\")(\\\\s*)(=)(\\\\s*)(function)(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:[\"entity.name.function\",\"text\",\"keyword.operator\",\"text\",\"storage.type\",\"text\",\"paren.lparen\"],regex:\"(\"+o+\")(\\\\s*)(=)(\\\\s*)(function)(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:[\"storage.type\",\"punctuation.operator\",\"entity.name.function\",\"text\",\"keyword.operator\",\"text\",\"storage.type\",\"text\",\"entity.name.function\",\"text\",\"paren.lparen\"],regex:\"(\"+o+\")(\\\\.)(\"+o+\")(\\\\s*)(=)(\\\\s*)(function)(\\\\s+)(\\\\w+)(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:[\"storage.type\",\"text\",\"entity.name.function\",\"text\",\"paren.lparen\"],regex:\"(function)(\\\\s+)(\"+o+\")(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:[\"entity.name.function\",\"text\",\"punctuation.operator\",\"text\",\"storage.type\",\"text\",\"paren.lparen\"],regex:\"(\"+o+\")(\\\\s*)(:)(\\\\s*)(function)(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:[\"text\",\"text\",\"storage.type\",\"text\",\"paren.lparen\"],regex:\"(:)(\\\\s*)(function)(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:\"keyword\",regex:\"(?:\"+n+\")\\\\b\",next:\"start\"},{token:[\"support.constant\"],regex:/that\\b/},{token:[\"storage.type\",\"punctuation.operator\",\"support.function.firebug\"],regex:/(console)(\\.)(warn|info|log|error|time|trace|timeEnd|assert)\\b/},{token:t,regex:o},{token:\"punctuation.operator\",regex:/[.](?![.])/,next:\"property\"},{token:\"keyword.operator\",regex:/--|\\+\\+|\\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\\|\\||\\?\\:|[!$%&*+\\-~\\/^]=?/,next:\"start\"},{token:\"punctuation.operator\",regex:/[?:,;.]/,next:\"start\"},{token:\"paren.lparen\",regex:/[\\[({]/,next:\"start\"},{token:\"paren.rparen\",regex:/[\\])}]/},{token:\"comment\",regex:/^#!.*$/}],property:[{token:\"text\",regex:\"\\\\s+\"},{token:[\"storage.type\",\"punctuation.operator\",\"entity.name.function\",\"text\",\"keyword.operator\",\"text\",\"storage.type\",\"text\",\"entity.name.function\",\"text\",\"paren.lparen\"],regex:\"(\"+o+\")(\\\\.)(\"+o+\")(\\\\s*)(=)(\\\\s*)(function)(?:(\\\\s+)(\\\\w+))?(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:\"punctuation.operator\",regex:/[.](?![.])/},{token:\"support.function\",regex:/(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\\b(?=\\()/},{token:\"support.function.dom\",regex:/(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\\b(?=\\()/},{token:\"support.constant\",regex:/(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\\b/},{token:\"identifier\",regex:o},{regex:\"\",token:\"empty\",next:\"no_regex\"}],start:[i.getStartRule(\"doc-start\"),f(\"start\"),{token:\"string.regexp\",regex:\"\\\\/\",next:\"regex\"},{token:\"text\",regex:\"\\\\s+|^$\",next:\"start\"},{token:\"empty\",regex:\"\",next:\"no_regex\"}],regex:[{token:\"regexp.keyword.operator\",regex:\"\\\\\\\\(?:u[\\\\da-fA-F]{4}|x[\\\\da-fA-F]{2}|.)\"},{token:\"string.regexp\",regex:\"/[sxngimy]*\",next:\"no_regex\"},{token:\"invalid\",regex:/\\{\\d+\\b,?\\d*\\}[+*]|[+*$^?][+*]|[$^][?]|\\?{3,}/},{token:\"constant.language.escape\",regex:/\\(\\?[:=!]|\\)|\\{\\d+\\b,?\\d*\\}|[+*]\\?|[()$^+*?.]/},{token:\"constant.language.delimiter\",regex:/\\|/},{token:\"constant.language.escape\",regex:/\\[\\^?/,next:\"regex_character_class\"},{token:\"empty\",regex:\"$\",next:\"no_regex\"},{defaultToken:\"string.regexp\"}],regex_character_class:[{token:\"regexp.charclass.keyword.operator\",regex:\"\\\\\\\\(?:u[\\\\da-fA-F]{4}|x[\\\\da-fA-F]{2}|.)\"},{token:\"constant.language.escape\",regex:\"]\",next:\"regex\"},{token:\"constant.language.escape\",regex:\"-\"},{token:\"empty\",regex:\"$\",next:\"no_regex\"},{defaultToken:\"string.regexp.charachterclass\"}],function_arguments:[{token:\"variable.parameter\",regex:o},{token:\"punctuation.operator\",regex:\"[, ]+\"},{token:\"punctuation.operator\",regex:\"$\"},{token:\"empty\",regex:\"\",next:\"no_regex\"}],qqstring:[{token:\"constant.language.escape\",regex:r},{token:\"string\",regex:\"\\\\\\\\$\",next:\"qqstring\"},{token:\"string\",regex:'\"|$',next:\"no_regex\"},{defaultToken:\"string\"}],qstring:[{token:\"constant.language.escape\",regex:r},{token:\"string\",regex:\"\\\\\\\\$\",next:\"qstring\"},{token:\"string\",regex:\"'|$\",next:\"no_regex\"},{defaultToken:\"string\"}]};if(!e||!e.noES6)this.$rules.no_regex.unshift({regex:\"[{}]\",onMatch:function(e,t,n){this.next=e==\"{\"?this.nextState:\"\";if(e==\"{\"&&n.length)n.unshift(\"start\",t);else if(e==\"}\"&&n.length){n.shift(),this.next=n.shift();if(this.next.indexOf(\"string\")!=-1||this.next.indexOf(\"jsx\")!=-1)return\"paren.quasi.end\"}return e==\"{\"?\"paren.lparen\":\"paren.rparen\"},nextState:\"start\"},{token:\"string.quasi.start\",regex:/`/,push:[{token:\"constant.language.escape\",regex:r},{token:\"paren.quasi.start\",regex:/\\${/,push:\"start\"},{token:\"string.quasi.end\",regex:/`/,next:\"pop\"},{defaultToken:\"string.quasi\"}]}),(!e||!e.noJSX)&&a.call(this);this.embedRules(i,\"doc-\",[i.getEndRule(\"no_regex\")]),this.normalizeRules()};r.inherits(u,s),t.JavaScriptHighlightRules=u}),ace.define(\"ace/mode/matching_brace_outdent\",[\"require\",\"exports\",\"module\",\"ace/range\"],function(e,t,n){\"use strict\";var r=e(\"../range\").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\\s+$/.test(e)?/^\\s*\\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\\s*\\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define(\"ace/mode/behaviour/cstyle\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/behaviour\",\"ace/token_iterator\",\"ace/lib/lang\"],function(e,t,n){\"use strict\";var r=e(\"../../lib/oop\"),i=e(\"../behaviour\").Behaviour,s=e(\"../../token_iterator\").TokenIterator,o=e(\"../../lib/lang\"),u=[\"text\",\"paren.rparen\",\"punctuation.operator\"],a=[\"text\",\"paren.rparen\",\"punctuation.operator\",\"comment\"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.index,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:\"\",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:\"\",maybeInsertedLineEnd:\"\"}},h=function(e,t,n,r){var i=e.end.row-e.start.row;return{text:n+t+r,selection:[0,e.start.column+1,i,e.end.column+(i?0:1)]}},p=function(){this.add(\"braces\",\"insertion\",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i==\"{\"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==\"\"&&l!==\"{\"&&n.getWrapBehavioursEnabled())return h(a,l,\"{\",\"}\");if(p.isSaneInsertion(n,r))return/[\\]\\}\\)]/.test(u[s.column])||n.inMultiSelectMode?(p.recordAutoInsert(n,r,\"}\"),{text:\"{}\",selection:[1,1]}):(p.recordMaybeInsert(n,r,\"{\"),{text:\"{\",selection:[1,1]})}else if(i==\"}\"){c(n);var d=u.substring(s.column,s.column+1);if(d==\"}\"){var v=r.$findOpeningBracket(\"}\",{column:s.column+1,row:s.row});if(v!==null&&p.isAutoInsertedClosing(s,u,i))return p.popAutoInsertedClosing(),{text:\"\",selection:[1,1]}}}else{if(i==\"\\n\"||i==\"\\r\\n\"){c(n);var m=\"\";p.isMaybeInsertedClosing(s,u)&&(m=o.stringRepeat(\"}\",f.maybeInsertedBrackets),p.clearMaybeInsertedClosing());var d=u.substring(s.column,s.column+1);if(d===\"}\"){var g=r.findMatchingBracket({row:s.row,column:s.column+1},\"}\");if(!g)return null;var y=this.$getIndent(r.getLine(g.row))}else{if(!m){p.clearMaybeInsertedClosing();return}var y=this.$getIndent(u)}var b=y+r.getTabString();return{text:\"\\n\"+b+\"\\n\"+y+m,selection:[1,b.length,1,b.length]}}p.clearMaybeInsertedClosing()}}),this.add(\"braces\",\"deletion\",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s==\"{\"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u==\"}\")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add(\"parens\",\"insertion\",function(e,t,n,r,i){if(i==\"(\"){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==\"\"&&n.getWrapBehavioursEnabled())return h(s,o,\"(\",\")\");if(p.isSaneInsertion(n,r))return p.recordAutoInsert(n,r,\")\"),{text:\"()\",selection:[1,1]}}else if(i==\")\"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==\")\"){var l=r.$findOpeningBracket(\")\",{column:u.column+1,row:u.row});if(l!==null&&p.isAutoInsertedClosing(u,a,i))return p.popAutoInsertedClosing(),{text:\"\",selection:[1,1]}}}}),this.add(\"parens\",\"deletion\",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s==\"(\"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==\")\")return i.end.column++,i}}),this.add(\"brackets\",\"insertion\",function(e,t,n,r,i){if(i==\"[\"){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==\"\"&&n.getWrapBehavioursEnabled())return h(s,o,\"[\",\"]\");if(p.isSaneInsertion(n,r))return p.recordAutoInsert(n,r,\"]\"),{text:\"[]\",selection:[1,1]}}else if(i==\"]\"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==\"]\"){var l=r.$findOpeningBracket(\"]\",{column:u.column+1,row:u.row});if(l!==null&&p.isAutoInsertedClosing(u,a,i))return p.popAutoInsertedClosing(),{text:\"\",selection:[1,1]}}}}),this.add(\"brackets\",\"deletion\",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s==\"[\"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==\"]\")return i.end.column++,i}}),this.add(\"string_dquotes\",\"insertion\",function(e,t,n,r,i){if(i=='\"'||i==\"'\"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==\"\"&&u!==\"'\"&&u!='\"'&&n.getWrapBehavioursEnabled())return h(o,u,s,s);if(!u){var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column),p=f.substring(a.column,a.column+1),d=r.getTokenAt(a.row,a.column),v=r.getTokenAt(a.row,a.column+1);if(l==\"\\\\\"&&d&&/escape/.test(d.type))return null;var m=d&&/string|escape/.test(d.type),g=!v||/string|escape/.test(v.type),y;if(p==s)y=m!==g;else{if(m&&!g)return null;if(m&&g)return null;var b=r.$mode.tokenRe;b.lastIndex=0;var w=b.test(l);b.lastIndex=0;var E=b.test(l);if(w||E)return null;if(p&&!/[\\s;,.})\\]\\\\]/.test(p))return null;y=!0}return{text:y?s+s:\"\",selection:[1,1]}}}}),this.add(\"string_dquotes\",\"deletion\",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='\"'||s==\"'\")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};p.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||\"text\",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||\"text\",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||\"text\",a)},p.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},p.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},p.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},p.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},p.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},p.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},p.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(p,i),t.CstyleBehaviour=p}),ace.define(\"ace/mode/folding/cstyle\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/range\",\"ace/mode/folding/fold_mode\"],function(e,t,n){\"use strict\";var r=e(\"../../lib/oop\"),i=e(\"../../range\").Range,s=e(\"./fold_mode\").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\\|[^|]*?$/,\"|\"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\\|[^|]*?$/,\"|\"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\\{|\\[)[^\\}\\]]*$|^\\s*(\\/\\*)/,this.foldingStopMarker=/^[^\\[\\{]*(\\}|\\])|^[\\s\\*]*(\\*\\/)/,this.singleLineBlockCommentRe=/^\\s*(\\/\\*).*\\*\\/\\s*$/,this.tripleStarBlockCommentRe=/^\\s*(\\/\\*\\*\\*).*\\*\\/\\s*$/,this.startRegionRe=/^\\s*(\\/\\*|\\/\\/)#?region\\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);if(this.singleLineBlockCommentRe.test(r)&&!this.startRegionRe.test(r)&&!this.tripleStarBlockCommentRe.test(r))return\"\";var i=this._getFoldWidgetBase(e,t,n);return!i&&this.startRegionRe.test(r)?\"start\":i},this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n);if(this.startRegionRe.test(i))return this.getCommentRegionBlock(e,i,n);var s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!=\"all\"&&(u=null)),u}if(t===\"markbegin\")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,\"all\",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)},this.getCommentRegionBlock=function(e,t,n){var r=t.search(/\\s*$/),s=e.getLength(),o=n,u=/^\\s*(?:\\/\\*|\\/\\/|--)#?(end)?region\\b/,a=1;while(++n<s){t=e.getLine(n);var f=u.exec(t);if(!f)continue;f[1]?a--:a++;if(!a)break}var l=n;if(l>o)return new i(o,r,l,t.length)}}.call(o.prototype)}),ace.define(\"ace/mode/javascript\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/text\",\"ace/mode/javascript_highlight_rules\",\"ace/mode/matching_brace_outdent\",\"ace/range\",\"ace/worker/worker_client\",\"ace/mode/behaviour/cstyle\",\"ace/mode/folding/cstyle\"],function(e,t,n){\"use strict\";var r=e(\"../lib/oop\"),i=e(\"./text\").Mode,s=e(\"./javascript_highlight_rules\").JavaScriptHighlightRules,o=e(\"./matching_brace_outdent\").MatchingBraceOutdent,u=e(\"../range\").Range,a=e(\"../worker/worker_client\").WorkerClient,f=e(\"./behaviour/cstyle\").CstyleBehaviour,l=e(\"./folding/cstyle\").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.foldingRules=new l};r.inherits(c,i),function(){this.lineCommentStart=\"//\",this.blockComment={start:\"/*\",end:\"*/\"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type==\"comment\")return r;if(e==\"start\"||e==\"no_regex\"){var u=t.match(/^.*(?:\\bcase\\b.*\\:|[\\{\\(\\[])\\s*$/);u&&(r+=n)}else if(e==\"doc-start\"){if(o==\"start\"||o==\"no_regex\")return\"\";var u=t.match(/^\\s*(\\/?)\\*/);u&&(u[1]&&(r+=\" \"),r+=\"* \")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new a([\"ace\"],\"ace/mode/javascript_worker\",\"JavaScriptWorker\");return t.attachToDocument(e.getDocument()),t.on(\"annotate\",function(t){e.setAnnotations(t.data)}),t.on(\"terminate\",function(){e.clearAnnotations()}),t},this.$id=\"ace/mode/javascript\"}.call(c.prototype),t.Mode=c}),ace.define(\"ace/mode/java_highlight_rules\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/doc_comment_highlight_rules\",\"ace/mode/text_highlight_rules\"],function(e,t,n){\"use strict\";var r=e(\"../lib/oop\"),i=e(\"./doc_comment_highlight_rules\").DocCommentHighlightRules,s=e(\"./text_highlight_rules\").TextHighlightRules,o=function(){var e=\"abstract|continue|for|new|switch|assert|default|goto|package|synchronized|boolean|do|if|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while\",t=\"null|Infinity|NaN|undefined\",n=\"AbstractMethodError|AssertionError|ClassCircularityError|ClassFormatError|Deprecated|EnumConstantNotPresentException|ExceptionInInitializerError|IllegalAccessError|IllegalThreadStateException|InstantiationError|InternalError|NegativeArraySizeException|NoSuchFieldError|Override|Process|ProcessBuilder|SecurityManager|StringIndexOutOfBoundsException|SuppressWarnings|TypeNotPresentException|UnknownError|UnsatisfiedLinkError|UnsupportedClassVersionError|VerifyError|InstantiationException|IndexOutOfBoundsException|ArrayIndexOutOfBoundsException|CloneNotSupportedException|NoSuchFieldException|IllegalArgumentException|NumberFormatException|SecurityException|Void|InheritableThreadLocal|IllegalStateException|InterruptedException|NoSuchMethodException|IllegalAccessException|UnsupportedOperationException|Enum|StrictMath|Package|Compiler|Readable|Runtime|StringBuilder|Math|IncompatibleClassChangeError|NoSuchMethodError|ThreadLocal|RuntimePermission|ArithmeticException|NullPointerException|Long|Integer|Short|Byte|Double|Number|Float|Character|Boolean|StackTraceElement|Appendable|StringBuffer|Iterable|ThreadGroup|Runnable|Thread|IllegalMonitorStateException|StackOverflowError|OutOfMemoryError|VirtualMachineError|ArrayStoreException|ClassCastException|LinkageError|NoClassDefFoundError|ClassNotFoundException|RuntimeException|Exception|ThreadDeath|Error|Throwable|System|ClassLoader|Cloneable|Class|CharSequence|Comparable|String|Object\",r=this.createKeywordMapper({\"variable.language\":\"this\",keyword:e,\"constant.language\":t,\"support.function\":n},\"identifier\");this.$rules={start:[{token:\"comment\",regex:\"\\\\/\\\\/.*$\"},i.getStartRule(\"doc-start\"),{token:\"comment\",regex:\"\\\\/\\\\*\",next:\"comment\"},{token:\"string\",regex:'[\"](?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?[\"]'},{token:\"string\",regex:\"['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\"},{token:\"constant.numeric\",regex:/0(?:[xX][0-9a-fA-F][0-9a-fA-F_]*|[bB][01][01_]*)[LlSsDdFfYy]?\\b/},{token:\"constant.numeric\",regex:/[+-]?\\d[\\d_]*(?:(?:\\.[\\d_]*)?(?:[eE][+-]?[\\d_]+)?)?[LlSsDdFfYy]?\\b/},{token:\"constant.language.boolean\",regex:\"(?:true|false)\\\\b\"},{token:r,regex:\"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"},{token:\"keyword.operator\",regex:\"!|\\\\$|%|&|\\\\*|\\\\-\\\\-|\\\\-|\\\\+\\\\+|\\\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\\\|\\\\||\\\\?\\\\:|\\\\*=|%=|\\\\+=|\\\\-=|&=|\\\\^=|\\\\b(?:in|instanceof|new|delete|typeof|void)\"},{token:\"lparen\",regex:\"[[({]\"},{token:\"rparen\",regex:\"[\\\\])}]\"},{token:\"text\",regex:\"\\\\s+\"}],comment:[{token:\"comment\",regex:\".*?\\\\*\\\\/\",next:\"start\"},{token:\"comment\",regex:\".+\"}]},this.embedRules(i,\"doc-\",[i.getEndRule(\"start\")])};r.inherits(o,s),t.JavaHighlightRules=o}),ace.define(\"ace/mode/java\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/javascript\",\"ace/mode/java_highlight_rules\"],function(e,t,n){\"use strict\";var r=e(\"../lib/oop\"),i=e(\"./javascript\").Mode,s=e(\"./java_highlight_rules\").JavaHighlightRules,o=function(){i.call(this),this.HighlightRules=s};r.inherits(o,i),function(){this.createWorker=function(e){return null},this.$id=\"ace/mode/java\"}.call(o.prototype),t.Mode=o})"

/***/ }),
/* 49 */
/***/ (function(module, exports) {

module.exports = "ace.define(\"ace/mode/doc_comment_highlight_rules\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/text_highlight_rules\"],function(e,t,n){\"use strict\";var r=e(\"../lib/oop\"),i=e(\"./text_highlight_rules\").TextHighlightRules,s=function(){this.$rules={start:[{token:\"comment.doc.tag\",regex:\"@[\\\\w\\\\d_]+\"},s.getTagRule(),{defaultToken:\"comment.doc\",caseInsensitive:!0}]}};r.inherits(s,i),s.getTagRule=function(e){return{token:\"comment.doc.tag.storage.type\",regex:\"\\\\b(?:TODO|FIXME|XXX|HACK)\\\\b\"}},s.getStartRule=function(e){return{token:\"comment.doc\",regex:\"\\\\/\\\\*(?=\\\\*)\",next:e}},s.getEndRule=function(e){return{token:\"comment.doc\",regex:\"\\\\*\\\\/\",next:e}},t.DocCommentHighlightRules=s}),ace.define(\"ace/mode/javascript_highlight_rules\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/doc_comment_highlight_rules\",\"ace/mode/text_highlight_rules\"],function(e,t,n){\"use strict\";function a(){var e=o.replace(\"\\\\d\",\"\\\\d\\\\-\"),t={onMatch:function(e,t,n){var r=e.charAt(1)==\"/\"?2:1;if(r==1)t!=this.nextState?n.unshift(this.next,this.nextState,0):n.unshift(this.next),n[2]++;else if(r==2&&t==this.nextState){n[1]--;if(!n[1]||n[1]<0)n.shift(),n.shift()}return[{type:\"meta.tag.punctuation.\"+(r==1?\"\":\"end-\")+\"tag-open.xml\",value:e.slice(0,r)},{type:\"meta.tag.tag-name.xml\",value:e.substr(r)}]},regex:\"</?\"+e+\"\",next:\"jsxAttributes\",nextState:\"jsx\"};this.$rules.start.unshift(t);var n={regex:\"{\",token:\"paren.quasi.start\",push:\"start\"};this.$rules.jsx=[n,t,{include:\"reference\"},{defaultToken:\"string\"}],this.$rules.jsxAttributes=[{token:\"meta.tag.punctuation.tag-close.xml\",regex:\"/?>\",onMatch:function(e,t,n){return t==n[0]&&n.shift(),e.length==2&&(n[0]==this.nextState&&n[1]--,(!n[1]||n[1]<0)&&n.splice(0,2)),this.next=n[0]||\"start\",[{type:this.token,value:e}]},nextState:\"jsx\"},n,f(\"jsxAttributes\"),{token:\"entity.other.attribute-name.xml\",regex:e},{token:\"keyword.operator.attribute-equals.xml\",regex:\"=\"},{token:\"text.tag-whitespace.xml\",regex:\"\\\\s+\"},{token:\"string.attribute-value.xml\",regex:\"'\",stateName:\"jsx_attr_q\",push:[{token:\"string.attribute-value.xml\",regex:\"'\",next:\"pop\"},{include:\"reference\"},{defaultToken:\"string.attribute-value.xml\"}]},{token:\"string.attribute-value.xml\",regex:'\"',stateName:\"jsx_attr_qq\",push:[{token:\"string.attribute-value.xml\",regex:'\"',next:\"pop\"},{include:\"reference\"},{defaultToken:\"string.attribute-value.xml\"}]},t],this.$rules.reference=[{token:\"constant.language.escape.reference.xml\",regex:\"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\\\.-]+;)\"}]}function f(e){return[{token:\"comment\",regex:/\\/\\*/,next:[i.getTagRule(),{token:\"comment\",regex:\"\\\\*\\\\/\",next:e||\"pop\"},{defaultToken:\"comment\",caseInsensitive:!0}]},{token:\"comment\",regex:\"\\\\/\\\\/\",next:[i.getTagRule(),{token:\"comment\",regex:\"$|^\",next:e||\"pop\"},{defaultToken:\"comment\",caseInsensitive:!0}]}]}var r=e(\"../lib/oop\"),i=e(\"./doc_comment_highlight_rules\").DocCommentHighlightRules,s=e(\"./text_highlight_rules\").TextHighlightRules,o=\"[a-zA-Z\\\\$_\\u00a1-\\uffff][a-zA-Z\\\\d\\\\$_\\u00a1-\\uffff]*\",u=function(e){var t=this.createKeywordMapper({\"variable.language\":\"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document\",keyword:\"const|yield|import|get|set|async|await|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static\",\"storage.type\":\"const|let|var|function\",\"constant.language\":\"null|Infinity|NaN|undefined\",\"support.function\":\"alert\",\"constant.language.boolean\":\"true|false\"},\"identifier\"),n=\"case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void\",r=\"\\\\\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|u{[0-9a-fA-F]{1,6}}|[0-2][0-7]{0,2}|3[0-7][0-7]?|[4-7][0-7]?|.)\";this.$rules={no_regex:[i.getStartRule(\"doc-start\"),f(\"no_regex\"),{token:\"string\",regex:\"'(?=.)\",next:\"qstring\"},{token:\"string\",regex:'\"(?=.)',next:\"qqstring\"},{token:\"constant.numeric\",regex:/0(?:[xX][0-9a-fA-F]+|[bB][01]+)\\b/},{token:\"constant.numeric\",regex:/[+-]?\\d[\\d_]*(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b/},{token:[\"storage.type\",\"punctuation.operator\",\"support.function\",\"punctuation.operator\",\"entity.name.function\",\"text\",\"keyword.operator\"],regex:\"(\"+o+\")(\\\\.)(prototype)(\\\\.)(\"+o+\")(\\\\s*)(=)\",next:\"function_arguments\"},{token:[\"storage.type\",\"punctuation.operator\",\"entity.name.function\",\"text\",\"keyword.operator\",\"text\",\"storage.type\",\"text\",\"paren.lparen\"],regex:\"(\"+o+\")(\\\\.)(\"+o+\")(\\\\s*)(=)(\\\\s*)(function)(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:[\"entity.name.function\",\"text\",\"keyword.operator\",\"text\",\"storage.type\",\"text\",\"paren.lparen\"],regex:\"(\"+o+\")(\\\\s*)(=)(\\\\s*)(function)(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:[\"storage.type\",\"punctuation.operator\",\"entity.name.function\",\"text\",\"keyword.operator\",\"text\",\"storage.type\",\"text\",\"entity.name.function\",\"text\",\"paren.lparen\"],regex:\"(\"+o+\")(\\\\.)(\"+o+\")(\\\\s*)(=)(\\\\s*)(function)(\\\\s+)(\\\\w+)(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:[\"storage.type\",\"text\",\"entity.name.function\",\"text\",\"paren.lparen\"],regex:\"(function)(\\\\s+)(\"+o+\")(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:[\"entity.name.function\",\"text\",\"punctuation.operator\",\"text\",\"storage.type\",\"text\",\"paren.lparen\"],regex:\"(\"+o+\")(\\\\s*)(:)(\\\\s*)(function)(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:[\"text\",\"text\",\"storage.type\",\"text\",\"paren.lparen\"],regex:\"(:)(\\\\s*)(function)(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:\"keyword\",regex:\"(?:\"+n+\")\\\\b\",next:\"start\"},{token:[\"support.constant\"],regex:/that\\b/},{token:[\"storage.type\",\"punctuation.operator\",\"support.function.firebug\"],regex:/(console)(\\.)(warn|info|log|error|time|trace|timeEnd|assert)\\b/},{token:t,regex:o},{token:\"punctuation.operator\",regex:/[.](?![.])/,next:\"property\"},{token:\"keyword.operator\",regex:/--|\\+\\+|\\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\\|\\||\\?\\:|[!$%&*+\\-~\\/^]=?/,next:\"start\"},{token:\"punctuation.operator\",regex:/[?:,;.]/,next:\"start\"},{token:\"paren.lparen\",regex:/[\\[({]/,next:\"start\"},{token:\"paren.rparen\",regex:/[\\])}]/},{token:\"comment\",regex:/^#!.*$/}],property:[{token:\"text\",regex:\"\\\\s+\"},{token:[\"storage.type\",\"punctuation.operator\",\"entity.name.function\",\"text\",\"keyword.operator\",\"text\",\"storage.type\",\"text\",\"entity.name.function\",\"text\",\"paren.lparen\"],regex:\"(\"+o+\")(\\\\.)(\"+o+\")(\\\\s*)(=)(\\\\s*)(function)(?:(\\\\s+)(\\\\w+))?(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:\"punctuation.operator\",regex:/[.](?![.])/},{token:\"support.function\",regex:/(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\\b(?=\\()/},{token:\"support.function.dom\",regex:/(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\\b(?=\\()/},{token:\"support.constant\",regex:/(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\\b/},{token:\"identifier\",regex:o},{regex:\"\",token:\"empty\",next:\"no_regex\"}],start:[i.getStartRule(\"doc-start\"),f(\"start\"),{token:\"string.regexp\",regex:\"\\\\/\",next:\"regex\"},{token:\"text\",regex:\"\\\\s+|^$\",next:\"start\"},{token:\"empty\",regex:\"\",next:\"no_regex\"}],regex:[{token:\"regexp.keyword.operator\",regex:\"\\\\\\\\(?:u[\\\\da-fA-F]{4}|x[\\\\da-fA-F]{2}|.)\"},{token:\"string.regexp\",regex:\"/[sxngimy]*\",next:\"no_regex\"},{token:\"invalid\",regex:/\\{\\d+\\b,?\\d*\\}[+*]|[+*$^?][+*]|[$^][?]|\\?{3,}/},{token:\"constant.language.escape\",regex:/\\(\\?[:=!]|\\)|\\{\\d+\\b,?\\d*\\}|[+*]\\?|[()$^+*?.]/},{token:\"constant.language.delimiter\",regex:/\\|/},{token:\"constant.language.escape\",regex:/\\[\\^?/,next:\"regex_character_class\"},{token:\"empty\",regex:\"$\",next:\"no_regex\"},{defaultToken:\"string.regexp\"}],regex_character_class:[{token:\"regexp.charclass.keyword.operator\",regex:\"\\\\\\\\(?:u[\\\\da-fA-F]{4}|x[\\\\da-fA-F]{2}|.)\"},{token:\"constant.language.escape\",regex:\"]\",next:\"regex\"},{token:\"constant.language.escape\",regex:\"-\"},{token:\"empty\",regex:\"$\",next:\"no_regex\"},{defaultToken:\"string.regexp.charachterclass\"}],function_arguments:[{token:\"variable.parameter\",regex:o},{token:\"punctuation.operator\",regex:\"[, ]+\"},{token:\"punctuation.operator\",regex:\"$\"},{token:\"empty\",regex:\"\",next:\"no_regex\"}],qqstring:[{token:\"constant.language.escape\",regex:r},{token:\"string\",regex:\"\\\\\\\\$\",next:\"qqstring\"},{token:\"string\",regex:'\"|$',next:\"no_regex\"},{defaultToken:\"string\"}],qstring:[{token:\"constant.language.escape\",regex:r},{token:\"string\",regex:\"\\\\\\\\$\",next:\"qstring\"},{token:\"string\",regex:\"'|$\",next:\"no_regex\"},{defaultToken:\"string\"}]};if(!e||!e.noES6)this.$rules.no_regex.unshift({regex:\"[{}]\",onMatch:function(e,t,n){this.next=e==\"{\"?this.nextState:\"\";if(e==\"{\"&&n.length)n.unshift(\"start\",t);else if(e==\"}\"&&n.length){n.shift(),this.next=n.shift();if(this.next.indexOf(\"string\")!=-1||this.next.indexOf(\"jsx\")!=-1)return\"paren.quasi.end\"}return e==\"{\"?\"paren.lparen\":\"paren.rparen\"},nextState:\"start\"},{token:\"string.quasi.start\",regex:/`/,push:[{token:\"constant.language.escape\",regex:r},{token:\"paren.quasi.start\",regex:/\\${/,push:\"start\"},{token:\"string.quasi.end\",regex:/`/,next:\"pop\"},{defaultToken:\"string.quasi\"}]}),(!e||!e.noJSX)&&a.call(this);this.embedRules(i,\"doc-\",[i.getEndRule(\"no_regex\")]),this.normalizeRules()};r.inherits(u,s),t.JavaScriptHighlightRules=u}),ace.define(\"ace/mode/matching_brace_outdent\",[\"require\",\"exports\",\"module\",\"ace/range\"],function(e,t,n){\"use strict\";var r=e(\"../range\").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\\s+$/.test(e)?/^\\s*\\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\\s*\\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define(\"ace/mode/behaviour/cstyle\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/behaviour\",\"ace/token_iterator\",\"ace/lib/lang\"],function(e,t,n){\"use strict\";var r=e(\"../../lib/oop\"),i=e(\"../behaviour\").Behaviour,s=e(\"../../token_iterator\").TokenIterator,o=e(\"../../lib/lang\"),u=[\"text\",\"paren.rparen\",\"punctuation.operator\"],a=[\"text\",\"paren.rparen\",\"punctuation.operator\",\"comment\"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.index,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:\"\",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:\"\",maybeInsertedLineEnd:\"\"}},h=function(e,t,n,r){var i=e.end.row-e.start.row;return{text:n+t+r,selection:[0,e.start.column+1,i,e.end.column+(i?0:1)]}},p=function(){this.add(\"braces\",\"insertion\",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i==\"{\"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==\"\"&&l!==\"{\"&&n.getWrapBehavioursEnabled())return h(a,l,\"{\",\"}\");if(p.isSaneInsertion(n,r))return/[\\]\\}\\)]/.test(u[s.column])||n.inMultiSelectMode?(p.recordAutoInsert(n,r,\"}\"),{text:\"{}\",selection:[1,1]}):(p.recordMaybeInsert(n,r,\"{\"),{text:\"{\",selection:[1,1]})}else if(i==\"}\"){c(n);var d=u.substring(s.column,s.column+1);if(d==\"}\"){var v=r.$findOpeningBracket(\"}\",{column:s.column+1,row:s.row});if(v!==null&&p.isAutoInsertedClosing(s,u,i))return p.popAutoInsertedClosing(),{text:\"\",selection:[1,1]}}}else{if(i==\"\\n\"||i==\"\\r\\n\"){c(n);var m=\"\";p.isMaybeInsertedClosing(s,u)&&(m=o.stringRepeat(\"}\",f.maybeInsertedBrackets),p.clearMaybeInsertedClosing());var d=u.substring(s.column,s.column+1);if(d===\"}\"){var g=r.findMatchingBracket({row:s.row,column:s.column+1},\"}\");if(!g)return null;var y=this.$getIndent(r.getLine(g.row))}else{if(!m){p.clearMaybeInsertedClosing();return}var y=this.$getIndent(u)}var b=y+r.getTabString();return{text:\"\\n\"+b+\"\\n\"+y+m,selection:[1,b.length,1,b.length]}}p.clearMaybeInsertedClosing()}}),this.add(\"braces\",\"deletion\",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s==\"{\"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u==\"}\")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add(\"parens\",\"insertion\",function(e,t,n,r,i){if(i==\"(\"){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==\"\"&&n.getWrapBehavioursEnabled())return h(s,o,\"(\",\")\");if(p.isSaneInsertion(n,r))return p.recordAutoInsert(n,r,\")\"),{text:\"()\",selection:[1,1]}}else if(i==\")\"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==\")\"){var l=r.$findOpeningBracket(\")\",{column:u.column+1,row:u.row});if(l!==null&&p.isAutoInsertedClosing(u,a,i))return p.popAutoInsertedClosing(),{text:\"\",selection:[1,1]}}}}),this.add(\"parens\",\"deletion\",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s==\"(\"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==\")\")return i.end.column++,i}}),this.add(\"brackets\",\"insertion\",function(e,t,n,r,i){if(i==\"[\"){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==\"\"&&n.getWrapBehavioursEnabled())return h(s,o,\"[\",\"]\");if(p.isSaneInsertion(n,r))return p.recordAutoInsert(n,r,\"]\"),{text:\"[]\",selection:[1,1]}}else if(i==\"]\"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==\"]\"){var l=r.$findOpeningBracket(\"]\",{column:u.column+1,row:u.row});if(l!==null&&p.isAutoInsertedClosing(u,a,i))return p.popAutoInsertedClosing(),{text:\"\",selection:[1,1]}}}}),this.add(\"brackets\",\"deletion\",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s==\"[\"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==\"]\")return i.end.column++,i}}),this.add(\"string_dquotes\",\"insertion\",function(e,t,n,r,i){if(i=='\"'||i==\"'\"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==\"\"&&u!==\"'\"&&u!='\"'&&n.getWrapBehavioursEnabled())return h(o,u,s,s);if(!u){var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column),p=f.substring(a.column,a.column+1),d=r.getTokenAt(a.row,a.column),v=r.getTokenAt(a.row,a.column+1);if(l==\"\\\\\"&&d&&/escape/.test(d.type))return null;var m=d&&/string|escape/.test(d.type),g=!v||/string|escape/.test(v.type),y;if(p==s)y=m!==g;else{if(m&&!g)return null;if(m&&g)return null;var b=r.$mode.tokenRe;b.lastIndex=0;var w=b.test(l);b.lastIndex=0;var E=b.test(l);if(w||E)return null;if(p&&!/[\\s;,.})\\]\\\\]/.test(p))return null;y=!0}return{text:y?s+s:\"\",selection:[1,1]}}}}),this.add(\"string_dquotes\",\"deletion\",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='\"'||s==\"'\")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};p.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||\"text\",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||\"text\",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||\"text\",a)},p.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},p.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},p.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},p.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},p.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},p.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},p.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(p,i),t.CstyleBehaviour=p}),ace.define(\"ace/mode/folding/cstyle\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/range\",\"ace/mode/folding/fold_mode\"],function(e,t,n){\"use strict\";var r=e(\"../../lib/oop\"),i=e(\"../../range\").Range,s=e(\"./fold_mode\").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\\|[^|]*?$/,\"|\"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\\|[^|]*?$/,\"|\"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\\{|\\[)[^\\}\\]]*$|^\\s*(\\/\\*)/,this.foldingStopMarker=/^[^\\[\\{]*(\\}|\\])|^[\\s\\*]*(\\*\\/)/,this.singleLineBlockCommentRe=/^\\s*(\\/\\*).*\\*\\/\\s*$/,this.tripleStarBlockCommentRe=/^\\s*(\\/\\*\\*\\*).*\\*\\/\\s*$/,this.startRegionRe=/^\\s*(\\/\\*|\\/\\/)#?region\\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);if(this.singleLineBlockCommentRe.test(r)&&!this.startRegionRe.test(r)&&!this.tripleStarBlockCommentRe.test(r))return\"\";var i=this._getFoldWidgetBase(e,t,n);return!i&&this.startRegionRe.test(r)?\"start\":i},this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n);if(this.startRegionRe.test(i))return this.getCommentRegionBlock(e,i,n);var s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!=\"all\"&&(u=null)),u}if(t===\"markbegin\")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,\"all\",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)},this.getCommentRegionBlock=function(e,t,n){var r=t.search(/\\s*$/),s=e.getLength(),o=n,u=/^\\s*(?:\\/\\*|\\/\\/|--)#?(end)?region\\b/,a=1;while(++n<s){t=e.getLine(n);var f=u.exec(t);if(!f)continue;f[1]?a--:a++;if(!a)break}var l=n;if(l>o)return new i(o,r,l,t.length)}}.call(o.prototype)}),ace.define(\"ace/mode/javascript\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/text\",\"ace/mode/javascript_highlight_rules\",\"ace/mode/matching_brace_outdent\",\"ace/range\",\"ace/worker/worker_client\",\"ace/mode/behaviour/cstyle\",\"ace/mode/folding/cstyle\"],function(e,t,n){\"use strict\";var r=e(\"../lib/oop\"),i=e(\"./text\").Mode,s=e(\"./javascript_highlight_rules\").JavaScriptHighlightRules,o=e(\"./matching_brace_outdent\").MatchingBraceOutdent,u=e(\"../range\").Range,a=e(\"../worker/worker_client\").WorkerClient,f=e(\"./behaviour/cstyle\").CstyleBehaviour,l=e(\"./folding/cstyle\").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.foldingRules=new l};r.inherits(c,i),function(){this.lineCommentStart=\"//\",this.blockComment={start:\"/*\",end:\"*/\"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type==\"comment\")return r;if(e==\"start\"||e==\"no_regex\"){var u=t.match(/^.*(?:\\bcase\\b.*\\:|[\\{\\(\\[])\\s*$/);u&&(r+=n)}else if(e==\"doc-start\"){if(o==\"start\"||o==\"no_regex\")return\"\";var u=t.match(/^\\s*(\\/?)\\*/);u&&(u[1]&&(r+=\" \"),r+=\"* \")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new a([\"ace\"],\"ace/mode/javascript_worker\",\"JavaScriptWorker\");return t.attachToDocument(e.getDocument()),t.on(\"annotate\",function(t){e.setAnnotations(t.data)}),t.on(\"terminate\",function(){e.clearAnnotations()}),t},this.$id=\"ace/mode/javascript\"}.call(c.prototype),t.Mode=c})"

/***/ }),
/* 50 */
/***/ (function(module, exports) {

module.exports = "ace.define(\"ace/mode/python_highlight_rules\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/text_highlight_rules\"],function(e,t,n){\"use strict\";var r=e(\"../lib/oop\"),i=e(\"./text_highlight_rules\").TextHighlightRules,s=function(){var e=\"and|as|assert|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|not|or|pass|print|raise|return|try|while|with|yield\",t=\"True|False|None|NotImplemented|Ellipsis|__debug__\",n=\"abs|divmod|input|open|staticmethod|all|enumerate|int|ord|str|any|eval|isinstance|pow|sum|basestring|execfile|issubclass|print|super|binfile|iter|property|tuple|bool|filter|len|range|type|bytearray|float|list|raw_input|unichr|callable|format|locals|reduce|unicode|chr|frozenset|long|reload|vars|classmethod|getattr|map|repr|xrange|cmp|globals|max|reversed|zip|compile|hasattr|memoryview|round|__import__|complex|hash|min|set|apply|delattr|help|next|setattr|buffer|dict|hex|object|slice|coerce|dir|id|oct|sorted|intern\",r=this.createKeywordMapper({\"invalid.deprecated\":\"debugger\",\"support.function\":n,\"constant.language\":t,keyword:e},\"identifier\"),i=\"(?:r|u|ur|R|U|UR|Ur|uR)?\",s=\"(?:(?:[1-9]\\\\d*)|(?:0))\",o=\"(?:0[oO]?[0-7]+)\",u=\"(?:0[xX][\\\\dA-Fa-f]+)\",a=\"(?:0[bB][01]+)\",f=\"(?:\"+s+\"|\"+o+\"|\"+u+\"|\"+a+\")\",l=\"(?:[eE][+-]?\\\\d+)\",c=\"(?:\\\\.\\\\d+)\",h=\"(?:\\\\d+)\",p=\"(?:(?:\"+h+\"?\"+c+\")|(?:\"+h+\"\\\\.))\",d=\"(?:(?:\"+p+\"|\"+h+\")\"+l+\")\",v=\"(?:\"+d+\"|\"+p+\")\",m=\"\\\\\\\\(x[0-9A-Fa-f]{2}|[0-7]{3}|[\\\\\\\\abfnrtv'\\\"]|U[0-9A-Fa-f]{8}|u[0-9A-Fa-f]{4})\";this.$rules={start:[{token:\"comment\",regex:\"#.*$\"},{token:\"string\",regex:i+'\"{3}',next:\"qqstring3\"},{token:\"string\",regex:i+'\"(?=.)',next:\"qqstring\"},{token:\"string\",regex:i+\"'{3}\",next:\"qstring3\"},{token:\"string\",regex:i+\"'(?=.)\",next:\"qstring\"},{token:\"constant.numeric\",regex:\"(?:\"+v+\"|\\\\d+)[jJ]\\\\b\"},{token:\"constant.numeric\",regex:v},{token:\"constant.numeric\",regex:f+\"[lL]\\\\b\"},{token:\"constant.numeric\",regex:f+\"\\\\b\"},{token:r,regex:\"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"},{token:\"keyword.operator\",regex:\"\\\\+|\\\\-|\\\\*|\\\\*\\\\*|\\\\/|\\\\/\\\\/|%|<<|>>|&|\\\\||\\\\^|~|<|>|<=|=>|==|!=|<>|=\"},{token:\"paren.lparen\",regex:\"[\\\\[\\\\(\\\\{]\"},{token:\"paren.rparen\",regex:\"[\\\\]\\\\)\\\\}]\"},{token:\"text\",regex:\"\\\\s+\"}],qqstring3:[{token:\"constant.language.escape\",regex:m},{token:\"string\",regex:'\"{3}',next:\"start\"},{defaultToken:\"string\"}],qstring3:[{token:\"constant.language.escape\",regex:m},{token:\"string\",regex:\"'{3}\",next:\"start\"},{defaultToken:\"string\"}],qqstring:[{token:\"constant.language.escape\",regex:m},{token:\"string\",regex:\"\\\\\\\\$\",next:\"qqstring\"},{token:\"string\",regex:'\"|$',next:\"start\"},{defaultToken:\"string\"}],qstring:[{token:\"constant.language.escape\",regex:m},{token:\"string\",regex:\"\\\\\\\\$\",next:\"qstring\"},{token:\"string\",regex:\"'|$\",next:\"start\"},{defaultToken:\"string\"}]}};r.inherits(s,i),t.PythonHighlightRules=s}),ace.define(\"ace/mode/folding/pythonic\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/folding/fold_mode\"],function(e,t,n){\"use strict\";var r=e(\"../../lib/oop\"),i=e(\"./fold_mode\").FoldMode,s=t.FoldMode=function(e){this.foldingStartMarker=new RegExp(\"([\\\\[{])(?:\\\\s*)$|(\"+e+\")(?:\\\\s*)(?:#.*)?$\")};r.inherits(s,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=e.getLine(n),i=r.match(this.foldingStartMarker);if(i)return i[1]?this.openingBracketBlock(e,i[1],n,i.index):i[2]?this.indentationBlock(e,n,i.index+i[2].length):this.indentationBlock(e,n)}}.call(s.prototype)}),ace.define(\"ace/mode/python\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/text\",\"ace/mode/python_highlight_rules\",\"ace/mode/folding/pythonic\",\"ace/range\"],function(e,t,n){\"use strict\";var r=e(\"../lib/oop\"),i=e(\"./text\").Mode,s=e(\"./python_highlight_rules\").PythonHighlightRules,o=e(\"./folding/pythonic\").FoldMode,u=e(\"../range\").Range,a=function(){this.HighlightRules=s,this.foldingRules=new o(\"\\\\:\")};r.inherits(a,i),function(){this.lineCommentStart=\"#\",this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens;if(s.length&&s[s.length-1].type==\"comment\")return r;if(e==\"start\"){var o=t.match(/^.*[\\{\\(\\[\\:]\\s*$/);o&&(r+=n)}return r};var e={pass:1,\"return\":1,raise:1,\"break\":1,\"continue\":1};this.checkOutdent=function(t,n,r){if(r!==\"\\r\\n\"&&r!==\"\\r\"&&r!==\"\\n\")return!1;var i=this.getTokenizer().getLineTokens(n.trim(),t).tokens;if(!i)return!1;do var s=i.pop();while(s&&(s.type==\"comment\"||s.type==\"text\"&&s.value.match(/^\\s+$/)));return s?s.type==\"keyword\"&&e[s.value]:!1},this.autoOutdent=function(e,t,n){n+=1;var r=this.$getIndent(t.getLine(n)),i=t.getTabString();r.slice(-i.length)==i&&t.remove(new u(n,r.length-i.length,n,r.length))},this.$id=\"ace/mode/python\"}.call(a.prototype),t.Mode=a})"

/***/ }),
/* 51 */
/***/ (function(module, exports) {

module.exports = "ace.define(\"ace/mode/ruby_highlight_rules\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/text_highlight_rules\"],function(e,t,n){\"use strict\";var r=e(\"../lib/oop\"),i=e(\"./text_highlight_rules\").TextHighlightRules,s=t.constantOtherSymbol={token:\"constant.other.symbol.ruby\",regex:\"[:](?:[A-Za-z_]|[@$](?=[a-zA-Z0-9_]))[a-zA-Z0-9_]*[!=?]?\"},o=t.qString={token:\"string\",regex:\"['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\"},u=t.qqString={token:\"string\",regex:'[\"](?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?[\"]'},a=t.tString={token:\"string\",regex:\"[`](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[`]\"},f=t.constantNumericHex={token:\"constant.numeric\",regex:\"0[xX][0-9a-fA-F](?:[0-9a-fA-F]|_(?=[0-9a-fA-F]))*\\\\b\"},l=t.constantNumericFloat={token:\"constant.numeric\",regex:\"[+-]?\\\\d(?:\\\\d|_(?=\\\\d))*(?:(?:\\\\.\\\\d(?:\\\\d|_(?=\\\\d))*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"},c=function(){var e=\"abort|Array|assert|assert_equal|assert_not_equal|assert_same|assert_not_same|assert_nil|assert_not_nil|assert_match|assert_no_match|assert_in_delta|assert_throws|assert_raise|assert_nothing_raised|assert_instance_of|assert_kind_of|assert_respond_to|assert_operator|assert_send|assert_difference|assert_no_difference|assert_recognizes|assert_generates|assert_response|assert_redirected_to|assert_template|assert_select|assert_select_email|assert_select_rjs|assert_select_encoded|css_select|at_exit|attr|attr_writer|attr_reader|attr_accessor|attr_accessible|autoload|binding|block_given?|callcc|caller|catch|chomp|chomp!|chop|chop!|defined?|delete_via_redirect|eval|exec|exit|exit!|fail|Float|flunk|follow_redirect!|fork|form_for|form_tag|format|gets|global_variables|gsub|gsub!|get_via_redirect|host!|https?|https!|include|Integer|lambda|link_to|link_to_unless_current|link_to_function|link_to_remote|load|local_variables|loop|open|open_session|p|print|printf|proc|putc|puts|post_via_redirect|put_via_redirect|raise|rand|raw|readline|readlines|redirect?|request_via_redirect|require|scan|select|set_trace_func|sleep|split|sprintf|srand|String|stylesheet_link_tag|syscall|system|sub|sub!|test|throw|trace_var|trap|untrace_var|atan2|cos|exp|frexp|ldexp|log|log10|sin|sqrt|tan|render|javascript_include_tag|csrf_meta_tag|label_tag|text_field_tag|submit_tag|check_box_tag|content_tag|radio_button_tag|text_area_tag|password_field_tag|hidden_field_tag|fields_for|select_tag|options_for_select|options_from_collection_for_select|collection_select|time_zone_select|select_date|select_time|select_datetime|date_select|time_select|datetime_select|select_year|select_month|select_day|select_hour|select_minute|select_second|file_field_tag|file_field|respond_to|skip_before_filter|around_filter|after_filter|verify|protect_from_forgery|rescue_from|helper_method|redirect_to|before_filter|send_data|send_file|validates_presence_of|validates_uniqueness_of|validates_length_of|validates_format_of|validates_acceptance_of|validates_associated|validates_exclusion_of|validates_inclusion_of|validates_numericality_of|validates_with|validates_each|authenticate_or_request_with_http_basic|authenticate_or_request_with_http_digest|filter_parameter_logging|match|get|post|resources|redirect|scope|assert_routing|translate|localize|extract_locale_from_tld|caches_page|expire_page|caches_action|expire_action|cache|expire_fragment|expire_cache_for|observe|cache_sweeper|has_many|has_one|belongs_to|has_and_belongs_to_many\",t=\"alias|and|BEGIN|begin|break|case|class|def|defined|do|else|elsif|END|end|ensure|__FILE__|finally|for|gem|if|in|__LINE__|module|next|not|or|private|protected|public|redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield\",n=\"true|TRUE|false|FALSE|nil|NIL|ARGF|ARGV|DATA|ENV|RUBY_PLATFORM|RUBY_RELEASE_DATE|RUBY_VERSION|STDERR|STDIN|STDOUT|TOPLEVEL_BINDING\",r=\"$DEBUG|$defout|$FILENAME|$LOAD_PATH|$SAFE|$stdin|$stdout|$stderr|$VERBOSE|$!|root_url|flash|session|cookies|params|request|response|logger|self\",i=this.$keywords=this.createKeywordMapper({keyword:t,\"constant.language\":n,\"variable.language\":r,\"support.function\":e,\"invalid.deprecated\":\"debugger\"},\"identifier\");this.$rules={start:[{token:\"comment\",regex:\"#.*$\"},{token:\"comment\",regex:\"^=begin(?:$|\\\\s.*$)\",next:\"comment\"},{token:\"string.regexp\",regex:\"[/](?:(?:\\\\[(?:\\\\\\\\]|[^\\\\]])+\\\\])|(?:\\\\\\\\/|[^\\\\]/]))*[/]\\\\w*\\\\s*(?=[).,;]|$)\"},[{regex:\"[{}]\",onMatch:function(e,t,n){this.next=e==\"{\"?this.nextState:\"\";if(e==\"{\"&&n.length)return n.unshift(\"start\",t),\"paren.lparen\";if(e==\"}\"&&n.length){n.shift(),this.next=n.shift();if(this.next.indexOf(\"string\")!=-1)return\"paren.end\"}return e==\"{\"?\"paren.lparen\":\"paren.rparen\"},nextState:\"start\"},{token:\"string.start\",regex:/\"/,push:[{token:\"constant.language.escape\",regex:/\\\\(?:[nsrtvfbae'\"\\\\]|c.|C-.|M-.(?:\\\\C-.)?|[0-7]{3}|x[\\da-fA-F]{2}|u[\\da-fA-F]{4})/},{token:\"paren.start\",regex:/\\#{/,push:\"start\"},{token:\"string.end\",regex:/\"/,next:\"pop\"},{defaultToken:\"string\"}]},{token:\"string.start\",regex:/`/,push:[{token:\"constant.language.escape\",regex:/\\\\(?:[nsrtvfbae'\"\\\\]|c.|C-.|M-.(?:\\\\C-.)?|[0-7]{3}|x[\\da-fA-F]{2}|u[\\da-fA-F]{4})/},{token:\"paren.start\",regex:/\\#{/,push:\"start\"},{token:\"string.end\",regex:/`/,next:\"pop\"},{defaultToken:\"string\"}]},{token:\"string.start\",regex:/'/,push:[{token:\"constant.language.escape\",regex:/\\\\['\\\\]/},{token:\"string.end\",regex:/'/,next:\"pop\"},{defaultToken:\"string\"}]}],{token:\"text\",regex:\"::\"},{token:\"variable.instance\",regex:\"@{1,2}[a-zA-Z_\\\\d]+\"},{token:\"support.class\",regex:\"[A-Z][a-zA-Z_\\\\d]+\"},s,f,l,{token:\"constant.language.boolean\",regex:\"(?:true|false)\\\\b\"},{token:i,regex:\"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"},{token:\"punctuation.separator.key-value\",regex:\"=>\"},{stateName:\"heredoc\",onMatch:function(e,t,n){var r=e[2]==\"-\"?\"indentedHeredoc\":\"heredoc\",i=e.split(this.splitRegex);return n.push(r,i[3]),[{type:\"constant\",value:i[1]},{type:\"string\",value:i[2]},{type:\"support.class\",value:i[3]},{type:\"string\",value:i[4]}]},regex:\"(<<-?)(['\\\"`]?)([\\\\w]+)(['\\\"`]?)\",rules:{heredoc:[{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||\"start\",\"support.class\"):(this.next=\"\",\"string\")},regex:\".*$\",next:\"start\"}],indentedHeredoc:[{token:\"string\",regex:\"^ +\"},{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||\"start\",\"support.class\"):(this.next=\"\",\"string\")},regex:\".*$\",next:\"start\"}]}},{regex:\"$\",token:\"empty\",next:function(e,t){return t[0]===\"heredoc\"||t[0]===\"indentedHeredoc\"?t[0]:e}},{token:\"string.character\",regex:\"\\\\B\\\\?.\"},{token:\"keyword.operator\",regex:\"!|\\\\$|%|&|\\\\*|\\\\-\\\\-|\\\\-|\\\\+\\\\+|\\\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\\\|\\\\||\\\\?\\\\:|\\\\*=|%=|\\\\+=|\\\\-=|&=|\\\\^=|\\\\b(?:in|instanceof|new|delete|typeof|void)\"},{token:\"paren.lparen\",regex:\"[[({]\"},{token:\"paren.rparen\",regex:\"[\\\\])}]\"},{token:\"text\",regex:\"\\\\s+\"}],comment:[{token:\"comment\",regex:\"^=end(?:$|\\\\s.*$)\",next:\"start\"},{token:\"comment\",regex:\".+\"}]},this.normalizeRules()};r.inherits(c,i),t.RubyHighlightRules=c}),ace.define(\"ace/mode/matching_brace_outdent\",[\"require\",\"exports\",\"module\",\"ace/range\"],function(e,t,n){\"use strict\";var r=e(\"../range\").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\\s+$/.test(e)?/^\\s*\\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\\s*\\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define(\"ace/mode/behaviour/cstyle\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/behaviour\",\"ace/token_iterator\",\"ace/lib/lang\"],function(e,t,n){\"use strict\";var r=e(\"../../lib/oop\"),i=e(\"../behaviour\").Behaviour,s=e(\"../../token_iterator\").TokenIterator,o=e(\"../../lib/lang\"),u=[\"text\",\"paren.rparen\",\"punctuation.operator\"],a=[\"text\",\"paren.rparen\",\"punctuation.operator\",\"comment\"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.index,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:\"\",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:\"\",maybeInsertedLineEnd:\"\"}},h=function(e,t,n,r){var i=e.end.row-e.start.row;return{text:n+t+r,selection:[0,e.start.column+1,i,e.end.column+(i?0:1)]}},p=function(){this.add(\"braces\",\"insertion\",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i==\"{\"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==\"\"&&l!==\"{\"&&n.getWrapBehavioursEnabled())return h(a,l,\"{\",\"}\");if(p.isSaneInsertion(n,r))return/[\\]\\}\\)]/.test(u[s.column])||n.inMultiSelectMode?(p.recordAutoInsert(n,r,\"}\"),{text:\"{}\",selection:[1,1]}):(p.recordMaybeInsert(n,r,\"{\"),{text:\"{\",selection:[1,1]})}else if(i==\"}\"){c(n);var d=u.substring(s.column,s.column+1);if(d==\"}\"){var v=r.$findOpeningBracket(\"}\",{column:s.column+1,row:s.row});if(v!==null&&p.isAutoInsertedClosing(s,u,i))return p.popAutoInsertedClosing(),{text:\"\",selection:[1,1]}}}else{if(i==\"\\n\"||i==\"\\r\\n\"){c(n);var m=\"\";p.isMaybeInsertedClosing(s,u)&&(m=o.stringRepeat(\"}\",f.maybeInsertedBrackets),p.clearMaybeInsertedClosing());var d=u.substring(s.column,s.column+1);if(d===\"}\"){var g=r.findMatchingBracket({row:s.row,column:s.column+1},\"}\");if(!g)return null;var y=this.$getIndent(r.getLine(g.row))}else{if(!m){p.clearMaybeInsertedClosing();return}var y=this.$getIndent(u)}var b=y+r.getTabString();return{text:\"\\n\"+b+\"\\n\"+y+m,selection:[1,b.length,1,b.length]}}p.clearMaybeInsertedClosing()}}),this.add(\"braces\",\"deletion\",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s==\"{\"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u==\"}\")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add(\"parens\",\"insertion\",function(e,t,n,r,i){if(i==\"(\"){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==\"\"&&n.getWrapBehavioursEnabled())return h(s,o,\"(\",\")\");if(p.isSaneInsertion(n,r))return p.recordAutoInsert(n,r,\")\"),{text:\"()\",selection:[1,1]}}else if(i==\")\"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==\")\"){var l=r.$findOpeningBracket(\")\",{column:u.column+1,row:u.row});if(l!==null&&p.isAutoInsertedClosing(u,a,i))return p.popAutoInsertedClosing(),{text:\"\",selection:[1,1]}}}}),this.add(\"parens\",\"deletion\",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s==\"(\"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==\")\")return i.end.column++,i}}),this.add(\"brackets\",\"insertion\",function(e,t,n,r,i){if(i==\"[\"){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==\"\"&&n.getWrapBehavioursEnabled())return h(s,o,\"[\",\"]\");if(p.isSaneInsertion(n,r))return p.recordAutoInsert(n,r,\"]\"),{text:\"[]\",selection:[1,1]}}else if(i==\"]\"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==\"]\"){var l=r.$findOpeningBracket(\"]\",{column:u.column+1,row:u.row});if(l!==null&&p.isAutoInsertedClosing(u,a,i))return p.popAutoInsertedClosing(),{text:\"\",selection:[1,1]}}}}),this.add(\"brackets\",\"deletion\",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s==\"[\"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==\"]\")return i.end.column++,i}}),this.add(\"string_dquotes\",\"insertion\",function(e,t,n,r,i){if(i=='\"'||i==\"'\"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==\"\"&&u!==\"'\"&&u!='\"'&&n.getWrapBehavioursEnabled())return h(o,u,s,s);if(!u){var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column),p=f.substring(a.column,a.column+1),d=r.getTokenAt(a.row,a.column),v=r.getTokenAt(a.row,a.column+1);if(l==\"\\\\\"&&d&&/escape/.test(d.type))return null;var m=d&&/string|escape/.test(d.type),g=!v||/string|escape/.test(v.type),y;if(p==s)y=m!==g;else{if(m&&!g)return null;if(m&&g)return null;var b=r.$mode.tokenRe;b.lastIndex=0;var w=b.test(l);b.lastIndex=0;var E=b.test(l);if(w||E)return null;if(p&&!/[\\s;,.})\\]\\\\]/.test(p))return null;y=!0}return{text:y?s+s:\"\",selection:[1,1]}}}}),this.add(\"string_dquotes\",\"deletion\",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='\"'||s==\"'\")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};p.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||\"text\",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||\"text\",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||\"text\",a)},p.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},p.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},p.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},p.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},p.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},p.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},p.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(p,i),t.CstyleBehaviour=p}),ace.define(\"ace/mode/folding/coffee\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/folding/fold_mode\",\"ace/range\"],function(e,t,n){\"use strict\";var r=e(\"../../lib/oop\"),i=e(\"./fold_mode\").FoldMode,s=e(\"../../range\").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);if(r)return r;var i=/\\S/,o=e.getLine(n),u=o.search(i);if(u==-1||o[u]!=\"#\")return;var a=o.length,f=e.getLength(),l=n,c=n;while(++n<f){o=e.getLine(n);var h=o.search(i);if(h==-1)continue;if(o[h]!=\"#\")break;c=n}if(c>l){var p=e.getLine(c).length;return new s(l,a,c,p)}},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=r.search(/\\S/),s=e.getLine(n+1),o=e.getLine(n-1),u=o.search(/\\S/),a=s.search(/\\S/);if(i==-1)return e.foldWidgets[n-1]=u!=-1&&u<a?\"start\":\"\",\"\";if(u==-1){if(i==a&&r[i]==\"#\"&&s[i]==\"#\")return e.foldWidgets[n-1]=\"\",e.foldWidgets[n+1]=\"\",\"start\"}else if(u==i&&r[i]==\"#\"&&o[i]==\"#\"&&e.getLine(n-2).search(/\\S/)==-1)return e.foldWidgets[n-1]=\"start\",e.foldWidgets[n+1]=\"\",\"\";return u!=-1&&u<i?e.foldWidgets[n-1]=\"start\":e.foldWidgets[n-1]=\"\",i<a?\"start\":\"\"}}.call(o.prototype)}),ace.define(\"ace/mode/ruby\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/text\",\"ace/mode/ruby_highlight_rules\",\"ace/mode/matching_brace_outdent\",\"ace/range\",\"ace/mode/behaviour/cstyle\",\"ace/mode/folding/coffee\"],function(e,t,n){\"use strict\";var r=e(\"../lib/oop\"),i=e(\"./text\").Mode,s=e(\"./ruby_highlight_rules\").RubyHighlightRules,o=e(\"./matching_brace_outdent\").MatchingBraceOutdent,u=e(\"../range\").Range,a=e(\"./behaviour/cstyle\").CstyleBehaviour,f=e(\"./folding/coffee\").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.lineCommentStart=\"#\",this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens;if(s.length&&s[s.length-1].type==\"comment\")return r;if(e==\"start\"){var o=t.match(/^.*[\\{\\(\\[]\\s*$/),u=t.match(/^\\s*(class|def|module)\\s.*$/),a=t.match(/.*do(\\s*|\\s+\\|.*\\|\\s*)$/),f=t.match(/^\\s*(if|else|when)\\s*/);if(o||u||a||f)r+=n}return r},this.checkOutdent=function(e,t,n){return/^\\s+(end|else)$/.test(t+n)||this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){var r=t.getLine(n);if(/}/.test(r))return this.$outdent.autoOutdent(t,n);var i=this.$getIndent(r),s=t.getLine(n-1),o=this.$getIndent(s),a=t.getTabString();o.length<=i.length&&i.slice(-a.length)==a&&t.remove(new u(n,i.length-a.length,n,i.length))},this.$id=\"ace/mode/ruby\"}.call(l.prototype),t.Mode=l})"

/***/ }),
/* 52 */
/***/ (function(module, exports) {

module.exports = "ace.define(\"ace/mode/doc_comment_highlight_rules\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/text_highlight_rules\"],function(e,t,n){\"use strict\";var r=e(\"../lib/oop\"),i=e(\"./text_highlight_rules\").TextHighlightRules,s=function(){this.$rules={start:[{token:\"comment.doc.tag\",regex:\"@[\\\\w\\\\d_]+\"},s.getTagRule(),{defaultToken:\"comment.doc\",caseInsensitive:!0}]}};r.inherits(s,i),s.getTagRule=function(e){return{token:\"comment.doc.tag.storage.type\",regex:\"\\\\b(?:TODO|FIXME|XXX|HACK)\\\\b\"}},s.getStartRule=function(e){return{token:\"comment.doc\",regex:\"\\\\/\\\\*(?=\\\\*)\",next:e}},s.getEndRule=function(e){return{token:\"comment.doc\",regex:\"\\\\*\\\\/\",next:e}},t.DocCommentHighlightRules=s}),ace.define(\"ace/mode/javascript_highlight_rules\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/doc_comment_highlight_rules\",\"ace/mode/text_highlight_rules\"],function(e,t,n){\"use strict\";function a(){var e=o.replace(\"\\\\d\",\"\\\\d\\\\-\"),t={onMatch:function(e,t,n){var r=e.charAt(1)==\"/\"?2:1;if(r==1)t!=this.nextState?n.unshift(this.next,this.nextState,0):n.unshift(this.next),n[2]++;else if(r==2&&t==this.nextState){n[1]--;if(!n[1]||n[1]<0)n.shift(),n.shift()}return[{type:\"meta.tag.punctuation.\"+(r==1?\"\":\"end-\")+\"tag-open.xml\",value:e.slice(0,r)},{type:\"meta.tag.tag-name.xml\",value:e.substr(r)}]},regex:\"</?\"+e+\"\",next:\"jsxAttributes\",nextState:\"jsx\"};this.$rules.start.unshift(t);var n={regex:\"{\",token:\"paren.quasi.start\",push:\"start\"};this.$rules.jsx=[n,t,{include:\"reference\"},{defaultToken:\"string\"}],this.$rules.jsxAttributes=[{token:\"meta.tag.punctuation.tag-close.xml\",regex:\"/?>\",onMatch:function(e,t,n){return t==n[0]&&n.shift(),e.length==2&&(n[0]==this.nextState&&n[1]--,(!n[1]||n[1]<0)&&n.splice(0,2)),this.next=n[0]||\"start\",[{type:this.token,value:e}]},nextState:\"jsx\"},n,f(\"jsxAttributes\"),{token:\"entity.other.attribute-name.xml\",regex:e},{token:\"keyword.operator.attribute-equals.xml\",regex:\"=\"},{token:\"text.tag-whitespace.xml\",regex:\"\\\\s+\"},{token:\"string.attribute-value.xml\",regex:\"'\",stateName:\"jsx_attr_q\",push:[{token:\"string.attribute-value.xml\",regex:\"'\",next:\"pop\"},{include:\"reference\"},{defaultToken:\"string.attribute-value.xml\"}]},{token:\"string.attribute-value.xml\",regex:'\"',stateName:\"jsx_attr_qq\",push:[{token:\"string.attribute-value.xml\",regex:'\"',next:\"pop\"},{include:\"reference\"},{defaultToken:\"string.attribute-value.xml\"}]},t],this.$rules.reference=[{token:\"constant.language.escape.reference.xml\",regex:\"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\\\.-]+;)\"}]}function f(e){return[{token:\"comment\",regex:/\\/\\*/,next:[i.getTagRule(),{token:\"comment\",regex:\"\\\\*\\\\/\",next:e||\"pop\"},{defaultToken:\"comment\",caseInsensitive:!0}]},{token:\"comment\",regex:\"\\\\/\\\\/\",next:[i.getTagRule(),{token:\"comment\",regex:\"$|^\",next:e||\"pop\"},{defaultToken:\"comment\",caseInsensitive:!0}]}]}var r=e(\"../lib/oop\"),i=e(\"./doc_comment_highlight_rules\").DocCommentHighlightRules,s=e(\"./text_highlight_rules\").TextHighlightRules,o=\"[a-zA-Z\\\\$_\\u00a1-\\uffff][a-zA-Z\\\\d\\\\$_\\u00a1-\\uffff]*\",u=function(e){var t=this.createKeywordMapper({\"variable.language\":\"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document\",keyword:\"const|yield|import|get|set|async|await|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static\",\"storage.type\":\"const|let|var|function\",\"constant.language\":\"null|Infinity|NaN|undefined\",\"support.function\":\"alert\",\"constant.language.boolean\":\"true|false\"},\"identifier\"),n=\"case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void\",r=\"\\\\\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|u{[0-9a-fA-F]{1,6}}|[0-2][0-7]{0,2}|3[0-7][0-7]?|[4-7][0-7]?|.)\";this.$rules={no_regex:[i.getStartRule(\"doc-start\"),f(\"no_regex\"),{token:\"string\",regex:\"'(?=.)\",next:\"qstring\"},{token:\"string\",regex:'\"(?=.)',next:\"qqstring\"},{token:\"constant.numeric\",regex:/0(?:[xX][0-9a-fA-F]+|[bB][01]+)\\b/},{token:\"constant.numeric\",regex:/[+-]?\\d[\\d_]*(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b/},{token:[\"storage.type\",\"punctuation.operator\",\"support.function\",\"punctuation.operator\",\"entity.name.function\",\"text\",\"keyword.operator\"],regex:\"(\"+o+\")(\\\\.)(prototype)(\\\\.)(\"+o+\")(\\\\s*)(=)\",next:\"function_arguments\"},{token:[\"storage.type\",\"punctuation.operator\",\"entity.name.function\",\"text\",\"keyword.operator\",\"text\",\"storage.type\",\"text\",\"paren.lparen\"],regex:\"(\"+o+\")(\\\\.)(\"+o+\")(\\\\s*)(=)(\\\\s*)(function)(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:[\"entity.name.function\",\"text\",\"keyword.operator\",\"text\",\"storage.type\",\"text\",\"paren.lparen\"],regex:\"(\"+o+\")(\\\\s*)(=)(\\\\s*)(function)(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:[\"storage.type\",\"punctuation.operator\",\"entity.name.function\",\"text\",\"keyword.operator\",\"text\",\"storage.type\",\"text\",\"entity.name.function\",\"text\",\"paren.lparen\"],regex:\"(\"+o+\")(\\\\.)(\"+o+\")(\\\\s*)(=)(\\\\s*)(function)(\\\\s+)(\\\\w+)(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:[\"storage.type\",\"text\",\"entity.name.function\",\"text\",\"paren.lparen\"],regex:\"(function)(\\\\s+)(\"+o+\")(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:[\"entity.name.function\",\"text\",\"punctuation.operator\",\"text\",\"storage.type\",\"text\",\"paren.lparen\"],regex:\"(\"+o+\")(\\\\s*)(:)(\\\\s*)(function)(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:[\"text\",\"text\",\"storage.type\",\"text\",\"paren.lparen\"],regex:\"(:)(\\\\s*)(function)(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:\"keyword\",regex:\"(?:\"+n+\")\\\\b\",next:\"start\"},{token:[\"support.constant\"],regex:/that\\b/},{token:[\"storage.type\",\"punctuation.operator\",\"support.function.firebug\"],regex:/(console)(\\.)(warn|info|log|error|time|trace|timeEnd|assert)\\b/},{token:t,regex:o},{token:\"punctuation.operator\",regex:/[.](?![.])/,next:\"property\"},{token:\"keyword.operator\",regex:/--|\\+\\+|\\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\\|\\||\\?\\:|[!$%&*+\\-~\\/^]=?/,next:\"start\"},{token:\"punctuation.operator\",regex:/[?:,;.]/,next:\"start\"},{token:\"paren.lparen\",regex:/[\\[({]/,next:\"start\"},{token:\"paren.rparen\",regex:/[\\])}]/},{token:\"comment\",regex:/^#!.*$/}],property:[{token:\"text\",regex:\"\\\\s+\"},{token:[\"storage.type\",\"punctuation.operator\",\"entity.name.function\",\"text\",\"keyword.operator\",\"text\",\"storage.type\",\"text\",\"entity.name.function\",\"text\",\"paren.lparen\"],regex:\"(\"+o+\")(\\\\.)(\"+o+\")(\\\\s*)(=)(\\\\s*)(function)(?:(\\\\s+)(\\\\w+))?(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:\"punctuation.operator\",regex:/[.](?![.])/},{token:\"support.function\",regex:/(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\\b(?=\\()/},{token:\"support.function.dom\",regex:/(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\\b(?=\\()/},{token:\"support.constant\",regex:/(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\\b/},{token:\"identifier\",regex:o},{regex:\"\",token:\"empty\",next:\"no_regex\"}],start:[i.getStartRule(\"doc-start\"),f(\"start\"),{token:\"string.regexp\",regex:\"\\\\/\",next:\"regex\"},{token:\"text\",regex:\"\\\\s+|^$\",next:\"start\"},{token:\"empty\",regex:\"\",next:\"no_regex\"}],regex:[{token:\"regexp.keyword.operator\",regex:\"\\\\\\\\(?:u[\\\\da-fA-F]{4}|x[\\\\da-fA-F]{2}|.)\"},{token:\"string.regexp\",regex:\"/[sxngimy]*\",next:\"no_regex\"},{token:\"invalid\",regex:/\\{\\d+\\b,?\\d*\\}[+*]|[+*$^?][+*]|[$^][?]|\\?{3,}/},{token:\"constant.language.escape\",regex:/\\(\\?[:=!]|\\)|\\{\\d+\\b,?\\d*\\}|[+*]\\?|[()$^+*?.]/},{token:\"constant.language.delimiter\",regex:/\\|/},{token:\"constant.language.escape\",regex:/\\[\\^?/,next:\"regex_character_class\"},{token:\"empty\",regex:\"$\",next:\"no_regex\"},{defaultToken:\"string.regexp\"}],regex_character_class:[{token:\"regexp.charclass.keyword.operator\",regex:\"\\\\\\\\(?:u[\\\\da-fA-F]{4}|x[\\\\da-fA-F]{2}|.)\"},{token:\"constant.language.escape\",regex:\"]\",next:\"regex\"},{token:\"constant.language.escape\",regex:\"-\"},{token:\"empty\",regex:\"$\",next:\"no_regex\"},{defaultToken:\"string.regexp.charachterclass\"}],function_arguments:[{token:\"variable.parameter\",regex:o},{token:\"punctuation.operator\",regex:\"[, ]+\"},{token:\"punctuation.operator\",regex:\"$\"},{token:\"empty\",regex:\"\",next:\"no_regex\"}],qqstring:[{token:\"constant.language.escape\",regex:r},{token:\"string\",regex:\"\\\\\\\\$\",next:\"qqstring\"},{token:\"string\",regex:'\"|$',next:\"no_regex\"},{defaultToken:\"string\"}],qstring:[{token:\"constant.language.escape\",regex:r},{token:\"string\",regex:\"\\\\\\\\$\",next:\"qstring\"},{token:\"string\",regex:\"'|$\",next:\"no_regex\"},{defaultToken:\"string\"}]};if(!e||!e.noES6)this.$rules.no_regex.unshift({regex:\"[{}]\",onMatch:function(e,t,n){this.next=e==\"{\"?this.nextState:\"\";if(e==\"{\"&&n.length)n.unshift(\"start\",t);else if(e==\"}\"&&n.length){n.shift(),this.next=n.shift();if(this.next.indexOf(\"string\")!=-1||this.next.indexOf(\"jsx\")!=-1)return\"paren.quasi.end\"}return e==\"{\"?\"paren.lparen\":\"paren.rparen\"},nextState:\"start\"},{token:\"string.quasi.start\",regex:/`/,push:[{token:\"constant.language.escape\",regex:r},{token:\"paren.quasi.start\",regex:/\\${/,push:\"start\"},{token:\"string.quasi.end\",regex:/`/,next:\"pop\"},{defaultToken:\"string.quasi\"}]}),(!e||!e.noJSX)&&a.call(this);this.embedRules(i,\"doc-\",[i.getEndRule(\"no_regex\")]),this.normalizeRules()};r.inherits(u,s),t.JavaScriptHighlightRules=u}),ace.define(\"ace/mode/matching_brace_outdent\",[\"require\",\"exports\",\"module\",\"ace/range\"],function(e,t,n){\"use strict\";var r=e(\"../range\").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\\s+$/.test(e)?/^\\s*\\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\\s*\\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define(\"ace/mode/behaviour/cstyle\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/behaviour\",\"ace/token_iterator\",\"ace/lib/lang\"],function(e,t,n){\"use strict\";var r=e(\"../../lib/oop\"),i=e(\"../behaviour\").Behaviour,s=e(\"../../token_iterator\").TokenIterator,o=e(\"../../lib/lang\"),u=[\"text\",\"paren.rparen\",\"punctuation.operator\"],a=[\"text\",\"paren.rparen\",\"punctuation.operator\",\"comment\"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.index,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:\"\",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:\"\",maybeInsertedLineEnd:\"\"}},h=function(e,t,n,r){var i=e.end.row-e.start.row;return{text:n+t+r,selection:[0,e.start.column+1,i,e.end.column+(i?0:1)]}},p=function(){this.add(\"braces\",\"insertion\",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i==\"{\"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==\"\"&&l!==\"{\"&&n.getWrapBehavioursEnabled())return h(a,l,\"{\",\"}\");if(p.isSaneInsertion(n,r))return/[\\]\\}\\)]/.test(u[s.column])||n.inMultiSelectMode?(p.recordAutoInsert(n,r,\"}\"),{text:\"{}\",selection:[1,1]}):(p.recordMaybeInsert(n,r,\"{\"),{text:\"{\",selection:[1,1]})}else if(i==\"}\"){c(n);var d=u.substring(s.column,s.column+1);if(d==\"}\"){var v=r.$findOpeningBracket(\"}\",{column:s.column+1,row:s.row});if(v!==null&&p.isAutoInsertedClosing(s,u,i))return p.popAutoInsertedClosing(),{text:\"\",selection:[1,1]}}}else{if(i==\"\\n\"||i==\"\\r\\n\"){c(n);var m=\"\";p.isMaybeInsertedClosing(s,u)&&(m=o.stringRepeat(\"}\",f.maybeInsertedBrackets),p.clearMaybeInsertedClosing());var d=u.substring(s.column,s.column+1);if(d===\"}\"){var g=r.findMatchingBracket({row:s.row,column:s.column+1},\"}\");if(!g)return null;var y=this.$getIndent(r.getLine(g.row))}else{if(!m){p.clearMaybeInsertedClosing();return}var y=this.$getIndent(u)}var b=y+r.getTabString();return{text:\"\\n\"+b+\"\\n\"+y+m,selection:[1,b.length,1,b.length]}}p.clearMaybeInsertedClosing()}}),this.add(\"braces\",\"deletion\",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s==\"{\"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u==\"}\")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add(\"parens\",\"insertion\",function(e,t,n,r,i){if(i==\"(\"){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==\"\"&&n.getWrapBehavioursEnabled())return h(s,o,\"(\",\")\");if(p.isSaneInsertion(n,r))return p.recordAutoInsert(n,r,\")\"),{text:\"()\",selection:[1,1]}}else if(i==\")\"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==\")\"){var l=r.$findOpeningBracket(\")\",{column:u.column+1,row:u.row});if(l!==null&&p.isAutoInsertedClosing(u,a,i))return p.popAutoInsertedClosing(),{text:\"\",selection:[1,1]}}}}),this.add(\"parens\",\"deletion\",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s==\"(\"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==\")\")return i.end.column++,i}}),this.add(\"brackets\",\"insertion\",function(e,t,n,r,i){if(i==\"[\"){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==\"\"&&n.getWrapBehavioursEnabled())return h(s,o,\"[\",\"]\");if(p.isSaneInsertion(n,r))return p.recordAutoInsert(n,r,\"]\"),{text:\"[]\",selection:[1,1]}}else if(i==\"]\"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==\"]\"){var l=r.$findOpeningBracket(\"]\",{column:u.column+1,row:u.row});if(l!==null&&p.isAutoInsertedClosing(u,a,i))return p.popAutoInsertedClosing(),{text:\"\",selection:[1,1]}}}}),this.add(\"brackets\",\"deletion\",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s==\"[\"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==\"]\")return i.end.column++,i}}),this.add(\"string_dquotes\",\"insertion\",function(e,t,n,r,i){if(i=='\"'||i==\"'\"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==\"\"&&u!==\"'\"&&u!='\"'&&n.getWrapBehavioursEnabled())return h(o,u,s,s);if(!u){var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column),p=f.substring(a.column,a.column+1),d=r.getTokenAt(a.row,a.column),v=r.getTokenAt(a.row,a.column+1);if(l==\"\\\\\"&&d&&/escape/.test(d.type))return null;var m=d&&/string|escape/.test(d.type),g=!v||/string|escape/.test(v.type),y;if(p==s)y=m!==g;else{if(m&&!g)return null;if(m&&g)return null;var b=r.$mode.tokenRe;b.lastIndex=0;var w=b.test(l);b.lastIndex=0;var E=b.test(l);if(w||E)return null;if(p&&!/[\\s;,.})\\]\\\\]/.test(p))return null;y=!0}return{text:y?s+s:\"\",selection:[1,1]}}}}),this.add(\"string_dquotes\",\"deletion\",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='\"'||s==\"'\")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};p.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||\"text\",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||\"text\",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||\"text\",a)},p.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},p.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},p.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},p.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},p.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},p.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},p.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(p,i),t.CstyleBehaviour=p}),ace.define(\"ace/mode/folding/cstyle\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/range\",\"ace/mode/folding/fold_mode\"],function(e,t,n){\"use strict\";var r=e(\"../../lib/oop\"),i=e(\"../../range\").Range,s=e(\"./fold_mode\").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\\|[^|]*?$/,\"|\"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\\|[^|]*?$/,\"|\"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\\{|\\[)[^\\}\\]]*$|^\\s*(\\/\\*)/,this.foldingStopMarker=/^[^\\[\\{]*(\\}|\\])|^[\\s\\*]*(\\*\\/)/,this.singleLineBlockCommentRe=/^\\s*(\\/\\*).*\\*\\/\\s*$/,this.tripleStarBlockCommentRe=/^\\s*(\\/\\*\\*\\*).*\\*\\/\\s*$/,this.startRegionRe=/^\\s*(\\/\\*|\\/\\/)#?region\\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);if(this.singleLineBlockCommentRe.test(r)&&!this.startRegionRe.test(r)&&!this.tripleStarBlockCommentRe.test(r))return\"\";var i=this._getFoldWidgetBase(e,t,n);return!i&&this.startRegionRe.test(r)?\"start\":i},this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n);if(this.startRegionRe.test(i))return this.getCommentRegionBlock(e,i,n);var s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!=\"all\"&&(u=null)),u}if(t===\"markbegin\")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,\"all\",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)},this.getCommentRegionBlock=function(e,t,n){var r=t.search(/\\s*$/),s=e.getLength(),o=n,u=/^\\s*(?:\\/\\*|\\/\\/|--)#?(end)?region\\b/,a=1;while(++n<s){t=e.getLine(n);var f=u.exec(t);if(!f)continue;f[1]?a--:a++;if(!a)break}var l=n;if(l>o)return new i(o,r,l,t.length)}}.call(o.prototype)}),ace.define(\"ace/mode/javascript\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/text\",\"ace/mode/javascript_highlight_rules\",\"ace/mode/matching_brace_outdent\",\"ace/range\",\"ace/worker/worker_client\",\"ace/mode/behaviour/cstyle\",\"ace/mode/folding/cstyle\"],function(e,t,n){\"use strict\";var r=e(\"../lib/oop\"),i=e(\"./text\").Mode,s=e(\"./javascript_highlight_rules\").JavaScriptHighlightRules,o=e(\"./matching_brace_outdent\").MatchingBraceOutdent,u=e(\"../range\").Range,a=e(\"../worker/worker_client\").WorkerClient,f=e(\"./behaviour/cstyle\").CstyleBehaviour,l=e(\"./folding/cstyle\").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.foldingRules=new l};r.inherits(c,i),function(){this.lineCommentStart=\"//\",this.blockComment={start:\"/*\",end:\"*/\"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type==\"comment\")return r;if(e==\"start\"||e==\"no_regex\"){var u=t.match(/^.*(?:\\bcase\\b.*\\:|[\\{\\(\\[])\\s*$/);u&&(r+=n)}else if(e==\"doc-start\"){if(o==\"start\"||o==\"no_regex\")return\"\";var u=t.match(/^\\s*(\\/?)\\*/);u&&(u[1]&&(r+=\" \"),r+=\"* \")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new a([\"ace\"],\"ace/mode/javascript_worker\",\"JavaScriptWorker\");return t.attachToDocument(e.getDocument()),t.on(\"annotate\",function(t){e.setAnnotations(t.data)}),t.on(\"terminate\",function(){e.clearAnnotations()}),t},this.$id=\"ace/mode/javascript\"}.call(c.prototype),t.Mode=c}),ace.define(\"ace/mode/typescript_highlight_rules\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/javascript_highlight_rules\"],function(e,t,n){\"use strict\";var r=e(\"../lib/oop\"),i=e(\"./javascript_highlight_rules\").JavaScriptHighlightRules,s=function(e){var t=[{token:[\"keyword.operator.ts\",\"text\",\"variable.parameter.function.ts\",\"text\"],regex:\"\\\\b(module)(\\\\s*)([a-zA-Z0-9_?.$][\\\\w?.$]*)(\\\\s*\\\\{)\"},{token:[\"storage.type.variable.ts\",\"text\",\"keyword.other.ts\",\"text\"],regex:\"(super)(\\\\s*\\\\()([a-zA-Z0-9,_?.$\\\\s]+\\\\s*)(\\\\))\"},{token:[\"entity.name.function.ts\",\"paren.lparen\",\"paren.rparen\"],regex:\"([a-zA-Z_?.$][\\\\w?.$]*)(\\\\()(\\\\))\"},{token:[\"variable.parameter.function.ts\",\"text\",\"variable.parameter.function.ts\"],regex:\"([a-zA-Z0-9_?.$][\\\\w?.$]*)(\\\\s*:\\\\s*)([a-zA-Z0-9_?.$][\\\\w?.$]*)\"},{token:[\"keyword.operator.ts\"],regex:\"(?:\\\\b(constructor|declare|interface|as|AS|public|private|class|extends|export|super)\\\\b)\"},{token:[\"storage.type.variable.ts\"],regex:\"(?:\\\\b(this\\\\.|string\\\\b|bool\\\\b|number)\\\\b)\"},{token:[\"keyword.operator.ts\",\"storage.type.variable.ts\",\"keyword.operator.ts\",\"storage.type.variable.ts\"],regex:\"(class)(\\\\s+[a-zA-Z0-9_?.$][\\\\w?.$]*\\\\s+)(extends)(\\\\s+[a-zA-Z0-9_?.$][\\\\w?.$]*\\\\s+)?\"},{token:\"keyword\",regex:\"(?:super|export|class|extends|import)\\\\b\"}],n=(new i({jsx:e&&e.jsx})).getRules();n.start=t.concat(n.start),this.$rules=n};r.inherits(s,i),t.TypeScriptHighlightRules=s}),ace.define(\"ace/mode/typescript\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/javascript\",\"ace/mode/typescript_highlight_rules\",\"ace/mode/behaviour/cstyle\",\"ace/mode/folding/cstyle\",\"ace/mode/matching_brace_outdent\"],function(e,t,n){\"use strict\";var r=e(\"../lib/oop\"),i=e(\"./javascript\").Mode,s=e(\"./typescript_highlight_rules\").TypeScriptHighlightRules,o=e(\"./behaviour/cstyle\").CstyleBehaviour,u=e(\"./folding/cstyle\").FoldMode,a=e(\"./matching_brace_outdent\").MatchingBraceOutdent,f=function(){this.HighlightRules=s,this.$outdent=new a,this.$behaviour=new o,this.foldingRules=new u};r.inherits(f,i),function(){this.createWorker=function(e){return null},this.$id=\"ace/mode/typescript\"}.call(f.prototype),t.Mode=f})"

/***/ }),
/* 53 */
/***/ (function(module, exports) {

module.exports = "!function(e){if(\"object\"==typeof exports&&\"undefined\"!=typeof module)module.exports=e();else if(\"function\"==typeof define&&define.amd)define([],e);else{var f;\"undefined\"!=typeof window?f=window:\"undefined\"!=typeof global?f=global:\"undefined\"!=typeof self&&(f=self),f.io=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error(\"Cannot find module '\"+o+\"'\")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){\n\nmodule.exports = _dereq_('./lib/');\n\n},{\"./lib/\":2}],2:[function(_dereq_,module,exports){\n\n/**\n * Module dependencies.\n */\n\nvar url = _dereq_('./url');\nvar parser = _dereq_('socket.io-parser');\nvar Manager = _dereq_('./manager');\nvar debug = _dereq_('debug')('socket.io-client');\n\n/**\n * Module exports.\n */\n\nmodule.exports = exports = lookup;\n\n/**\n * Managers cache.\n */\n\nvar cache = exports.managers = {};\n\n/**\n * Looks up an existing `Manager` for multiplexing.\n * If the user summons:\n *\n *   `io('http://localhost/a');`\n *   `io('http://localhost/b');`\n *\n * We reuse the existing instance based on same scheme/port/host,\n * and we initialize sockets for each namespace.\n *\n * @api public\n */\n\nfunction lookup(uri, opts) {\n  if (typeof uri == 'object') {\n    opts = uri;\n    uri = undefined;\n  }\n\n  opts = opts || {};\n\n  var parsed = url(uri);\n  var source = parsed.source;\n  var id = parsed.id;\n  var io;\n\n  if (opts.forceNew || opts['force new connection'] || false === opts.multiplex) {\n    debug('ignoring socket cache for %s', source);\n    io = Manager(source, opts);\n  } else {\n    if (!cache[id]) {\n      debug('new io instance for %s', source);\n      cache[id] = Manager(source, opts);\n    }\n    io = cache[id];\n  }\n\n  return io.socket(parsed.path);\n}\n\n/**\n * Protocol version.\n *\n * @api public\n */\n\nexports.protocol = parser.protocol;\n\n/**\n * `connect`.\n *\n * @param {String} uri\n * @api public\n */\n\nexports.connect = lookup;\n\n/**\n * Expose constructors for standalone build.\n *\n * @api public\n */\n\nexports.Manager = _dereq_('./manager');\nexports.Socket = _dereq_('./socket');\n\n},{\"./manager\":3,\"./socket\":5,\"./url\":6,\"debug\":10,\"socket.io-parser\":44}],3:[function(_dereq_,module,exports){\n\n/**\n * Module dependencies.\n */\n\nvar url = _dereq_('./url');\nvar eio = _dereq_('engine.io-client');\nvar Socket = _dereq_('./socket');\nvar Emitter = _dereq_('component-emitter');\nvar parser = _dereq_('socket.io-parser');\nvar on = _dereq_('./on');\nvar bind = _dereq_('component-bind');\nvar object = _dereq_('object-component');\nvar debug = _dereq_('debug')('socket.io-client:manager');\nvar indexOf = _dereq_('indexof');\nvar Backoff = _dereq_('backo2');\n\n/**\n * Module exports\n */\n\nmodule.exports = Manager;\n\n/**\n * `Manager` constructor.\n *\n * @param {String} engine instance or engine uri/opts\n * @param {Object} options\n * @api public\n */\n\nfunction Manager(uri, opts){\n  if (!(this instanceof Manager)) return new Manager(uri, opts);\n  if (uri && ('object' == typeof uri)) {\n    opts = uri;\n    uri = undefined;\n  }\n  opts = opts || {};\n\n  opts.path = opts.path || '/socket.io';\n  this.nsps = {};\n  this.subs = [];\n  this.opts = opts;\n  this.reconnection(opts.reconnection !== false);\n  this.reconnectionAttempts(opts.reconnectionAttempts || Infinity);\n  this.reconnectionDelay(opts.reconnectionDelay || 1000);\n  this.reconnectionDelayMax(opts.reconnectionDelayMax || 5000);\n  this.randomizationFactor(opts.randomizationFactor || 0.5);\n  this.backoff = new Backoff({\n    min: this.reconnectionDelay(),\n    max: this.reconnectionDelayMax(),\n    jitter: this.randomizationFactor()\n  });\n  this.timeout(null == opts.timeout ? 20000 : opts.timeout);\n  this.readyState = 'closed';\n  this.uri = uri;\n  this.connected = [];\n  this.encoding = false;\n  this.packetBuffer = [];\n  this.encoder = new parser.Encoder();\n  this.decoder = new parser.Decoder();\n  this.autoConnect = opts.autoConnect !== false;\n  if (this.autoConnect) this.open();\n}\n\n/**\n * Propagate given event to sockets and emit on `this`\n *\n * @api private\n */\n\nManager.prototype.emitAll = function() {\n  this.emit.apply(this, arguments);\n  for (var nsp in this.nsps) {\n    this.nsps[nsp].emit.apply(this.nsps[nsp], arguments);\n  }\n};\n\n/**\n * Update `socket.id` of all sockets\n *\n * @api private\n */\n\nManager.prototype.updateSocketIds = function(){\n  for (var nsp in this.nsps) {\n    this.nsps[nsp].id = this.engine.id;\n  }\n};\n\n/**\n * Mix in `Emitter`.\n */\n\nEmitter(Manager.prototype);\n\n/**\n * Sets the `reconnection` config.\n *\n * @param {Boolean} true/false if it should automatically reconnect\n * @return {Manager} self or value\n * @api public\n */\n\nManager.prototype.reconnection = function(v){\n  if (!arguments.length) return this._reconnection;\n  this._reconnection = !!v;\n  return this;\n};\n\n/**\n * Sets the reconnection attempts config.\n *\n * @param {Number} max reconnection attempts before giving up\n * @return {Manager} self or value\n * @api public\n */\n\nManager.prototype.reconnectionAttempts = function(v){\n  if (!arguments.length) return this._reconnectionAttempts;\n  this._reconnectionAttempts = v;\n  return this;\n};\n\n/**\n * Sets the delay between reconnections.\n *\n * @param {Number} delay\n * @return {Manager} self or value\n * @api public\n */\n\nManager.prototype.reconnectionDelay = function(v){\n  if (!arguments.length) return this._reconnectionDelay;\n  this._reconnectionDelay = v;\n  this.backoff && this.backoff.setMin(v);\n  return this;\n};\n\nManager.prototype.randomizationFactor = function(v){\n  if (!arguments.length) return this._randomizationFactor;\n  this._randomizationFactor = v;\n  this.backoff && this.backoff.setJitter(v);\n  return this;\n};\n\n/**\n * Sets the maximum delay between reconnections.\n *\n * @param {Number} delay\n * @return {Manager} self or value\n * @api public\n */\n\nManager.prototype.reconnectionDelayMax = function(v){\n  if (!arguments.length) return this._reconnectionDelayMax;\n  this._reconnectionDelayMax = v;\n  this.backoff && this.backoff.setMax(v);\n  return this;\n};\n\n/**\n * Sets the connection timeout. `false` to disable\n *\n * @return {Manager} self or value\n * @api public\n */\n\nManager.prototype.timeout = function(v){\n  if (!arguments.length) return this._timeout;\n  this._timeout = v;\n  return this;\n};\n\n/**\n * Starts trying to reconnect if reconnection is enabled and we have not\n * started reconnecting yet\n *\n * @api private\n */\n\nManager.prototype.maybeReconnectOnOpen = function() {\n  // Only try to reconnect if it's the first time we're connecting\n  if (!this.reconnecting && this._reconnection && this.backoff.attempts === 0) {\n    // keeps reconnection from firing twice for the same reconnection loop\n    this.reconnect();\n  }\n};\n\n\n/**\n * Sets the current transport `socket`.\n *\n * @param {Function} optional, callback\n * @return {Manager} self\n * @api public\n */\n\nManager.prototype.open =\nManager.prototype.connect = function(fn){\n  debug('readyState %s', this.readyState);\n  if (~this.readyState.indexOf('open')) return this;\n\n  debug('opening %s', this.uri);\n  this.engine = eio(this.uri, this.opts);\n  var socket = this.engine;\n  var self = this;\n  this.readyState = 'opening';\n  this.skipReconnect = false;\n\n  // emit `open`\n  var openSub = on(socket, 'open', function() {\n    self.onopen();\n    fn && fn();\n  });\n\n  // emit `connect_error`\n  var errorSub = on(socket, 'error', function(data){\n    debug('connect_error');\n    self.cleanup();\n    self.readyState = 'closed';\n    self.emitAll('connect_error', data);\n    if (fn) {\n      var err = new Error('Connection error');\n      err.data = data;\n      fn(err);\n    } else {\n      // Only do this if there is no fn to handle the error\n      self.maybeReconnectOnOpen();\n    }\n  });\n\n  // emit `connect_timeout`\n  if (false !== this._timeout) {\n    var timeout = this._timeout;\n    debug('connect attempt will timeout after %d', timeout);\n\n    // set timer\n    var timer = setTimeout(function(){\n      debug('connect attempt timed out after %d', timeout);\n      openSub.destroy();\n      socket.close();\n      socket.emit('error', 'timeout');\n      self.emitAll('connect_timeout', timeout);\n    }, timeout);\n\n    this.subs.push({\n      destroy: function(){\n        clearTimeout(timer);\n      }\n    });\n  }\n\n  this.subs.push(openSub);\n  this.subs.push(errorSub);\n\n  return this;\n};\n\n/**\n * Called upon transport open.\n *\n * @api private\n */\n\nManager.prototype.onopen = function(){\n  debug('open');\n\n  // clear old subs\n  this.cleanup();\n\n  // mark as open\n  this.readyState = 'open';\n  this.emit('open');\n\n  // add new subs\n  var socket = this.engine;\n  this.subs.push(on(socket, 'data', bind(this, 'ondata')));\n  this.subs.push(on(this.decoder, 'decoded', bind(this, 'ondecoded')));\n  this.subs.push(on(socket, 'error', bind(this, 'onerror')));\n  this.subs.push(on(socket, 'close', bind(this, 'onclose')));\n};\n\n/**\n * Called with data.\n *\n * @api private\n */\n\nManager.prototype.ondata = function(data){\n  this.decoder.add(data);\n};\n\n/**\n * Called when parser fully decodes a packet.\n *\n * @api private\n */\n\nManager.prototype.ondecoded = function(packet) {\n  this.emit('packet', packet);\n};\n\n/**\n * Called upon socket error.\n *\n * @api private\n */\n\nManager.prototype.onerror = function(err){\n  debug('error', err);\n  this.emitAll('error', err);\n};\n\n/**\n * Creates a new socket for the given `nsp`.\n *\n * @return {Socket}\n * @api public\n */\n\nManager.prototype.socket = function(nsp){\n  var socket = this.nsps[nsp];\n  if (!socket) {\n    socket = new Socket(this, nsp);\n    this.nsps[nsp] = socket;\n    var self = this;\n    socket.on('connect', function(){\n      socket.id = self.engine.id;\n      if (!~indexOf(self.connected, socket)) {\n        self.connected.push(socket);\n      }\n    });\n  }\n  return socket;\n};\n\n/**\n * Called upon a socket close.\n *\n * @param {Socket} socket\n */\n\nManager.prototype.destroy = function(socket){\n  var index = indexOf(this.connected, socket);\n  if (~index) this.connected.splice(index, 1);\n  if (this.connected.length) return;\n\n  this.close();\n};\n\n/**\n * Writes a packet.\n *\n * @param {Object} packet\n * @api private\n */\n\nManager.prototype.packet = function(packet){\n  debug('writing packet %j', packet);\n  var self = this;\n\n  if (!self.encoding) {\n    // encode, then write to engine with result\n    self.encoding = true;\n    this.encoder.encode(packet, function(encodedPackets) {\n      for (var i = 0; i < encodedPackets.length; i++) {\n        self.engine.write(encodedPackets[i]);\n      }\n      self.encoding = false;\n      self.processPacketQueue();\n    });\n  } else { // add packet to the queue\n    self.packetBuffer.push(packet);\n  }\n};\n\n/**\n * If packet buffer is non-empty, begins encoding the\n * next packet in line.\n *\n * @api private\n */\n\nManager.prototype.processPacketQueue = function() {\n  if (this.packetBuffer.length > 0 && !this.encoding) {\n    var pack = this.packetBuffer.shift();\n    this.packet(pack);\n  }\n};\n\n/**\n * Clean up transport subscriptions and packet buffer.\n *\n * @api private\n */\n\nManager.prototype.cleanup = function(){\n  var sub;\n  while (sub = this.subs.shift()) sub.destroy();\n\n  this.packetBuffer = [];\n  this.encoding = false;\n\n  this.decoder.destroy();\n};\n\n/**\n * Close the current socket.\n *\n * @api private\n */\n\nManager.prototype.close =\nManager.prototype.disconnect = function(){\n  this.skipReconnect = true;\n  this.backoff.reset();\n  this.readyState = 'closed';\n  this.engine && this.engine.close();\n};\n\n/**\n * Called upon engine close.\n *\n * @api private\n */\n\nManager.prototype.onclose = function(reason){\n  debug('close');\n  this.cleanup();\n  this.backoff.reset();\n  this.readyState = 'closed';\n  this.emit('close', reason);\n  if (this._reconnection && !this.skipReconnect) {\n    this.reconnect();\n  }\n};\n\n/**\n * Attempt a reconnection.\n *\n * @api private\n */\n\nManager.prototype.reconnect = function(){\n  if (this.reconnecting || this.skipReconnect) return this;\n\n  var self = this;\n\n  if (this.backoff.attempts >= this._reconnectionAttempts) {\n    debug('reconnect failed');\n    this.backoff.reset();\n    this.emitAll('reconnect_failed');\n    this.reconnecting = false;\n  } else {\n    var delay = this.backoff.duration();\n    debug('will wait %dms before reconnect attempt', delay);\n\n    this.reconnecting = true;\n    var timer = setTimeout(function(){\n      if (self.skipReconnect) return;\n\n      debug('attempting reconnect');\n      self.emitAll('reconnect_attempt', self.backoff.attempts);\n      self.emitAll('reconnecting', self.backoff.attempts);\n\n      // check again for the case socket closed in above events\n      if (self.skipReconnect) return;\n\n      self.open(function(err){\n        if (err) {\n          debug('reconnect attempt error');\n          self.reconnecting = false;\n          self.reconnect();\n          self.emitAll('reconnect_error', err.data);\n        } else {\n          debug('reconnect success');\n          self.onreconnect();\n        }\n      });\n    }, delay);\n\n    this.subs.push({\n      destroy: function(){\n        clearTimeout(timer);\n      }\n    });\n  }\n};\n\n/**\n * Called upon successful reconnect.\n *\n * @api private\n */\n\nManager.prototype.onreconnect = function(){\n  var attempt = this.backoff.attempts;\n  this.reconnecting = false;\n  this.backoff.reset();\n  this.updateSocketIds();\n  this.emitAll('reconnect', attempt);\n};\n\n},{\"./on\":4,\"./socket\":5,\"./url\":6,\"backo2\":7,\"component-bind\":8,\"component-emitter\":9,\"debug\":10,\"engine.io-client\":11,\"indexof\":40,\"object-component\":41,\"socket.io-parser\":44}],4:[function(_dereq_,module,exports){\n\n/**\n * Module exports.\n */\n\nmodule.exports = on;\n\n/**\n * Helper for subscriptions.\n *\n * @param {Object|EventEmitter} obj with `Emitter` mixin or `EventEmitter`\n * @param {String} event name\n * @param {Function} callback\n * @api public\n */\n\nfunction on(obj, ev, fn) {\n  obj.on(ev, fn);\n  return {\n    destroy: function(){\n      obj.removeListener(ev, fn);\n    }\n  };\n}\n\n},{}],5:[function(_dereq_,module,exports){\n\n/**\n * Module dependencies.\n */\n\nvar parser = _dereq_('socket.io-parser');\nvar Emitter = _dereq_('component-emitter');\nvar toArray = _dereq_('to-array');\nvar on = _dereq_('./on');\nvar bind = _dereq_('component-bind');\nvar debug = _dereq_('debug')('socket.io-client:socket');\nvar hasBin = _dereq_('has-binary');\n\n/**\n * Module exports.\n */\n\nmodule.exports = exports = Socket;\n\n/**\n * Internal events (blacklisted).\n * These events can't be emitted by the user.\n *\n * @api private\n */\n\nvar events = {\n  connect: 1,\n  connect_error: 1,\n  connect_timeout: 1,\n  disconnect: 1,\n  error: 1,\n  reconnect: 1,\n  reconnect_attempt: 1,\n  reconnect_failed: 1,\n  reconnect_error: 1,\n  reconnecting: 1\n};\n\n/**\n * Shortcut to `Emitter#emit`.\n */\n\nvar emit = Emitter.prototype.emit;\n\n/**\n * `Socket` constructor.\n *\n * @api public\n */\n\nfunction Socket(io, nsp){\n  this.io = io;\n  this.nsp = nsp;\n  this.json = this; // compat\n  this.ids = 0;\n  this.acks = {};\n  if (this.io.autoConnect) this.open();\n  this.receiveBuffer = [];\n  this.sendBuffer = [];\n  this.connected = false;\n  this.disconnected = true;\n}\n\n/**\n * Mix in `Emitter`.\n */\n\nEmitter(Socket.prototype);\n\n/**\n * Subscribe to open, close and packet events\n *\n * @api private\n */\n\nSocket.prototype.subEvents = function() {\n  if (this.subs) return;\n\n  var io = this.io;\n  this.subs = [\n    on(io, 'open', bind(this, 'onopen')),\n    on(io, 'packet', bind(this, 'onpacket')),\n    on(io, 'close', bind(this, 'onclose'))\n  ];\n};\n\n/**\n * \"Opens\" the socket.\n *\n * @api public\n */\n\nSocket.prototype.open =\nSocket.prototype.connect = function(){\n  if (this.connected) return this;\n\n  this.subEvents();\n  this.io.open(); // ensure open\n  if ('open' == this.io.readyState) this.onopen();\n  return this;\n};\n\n/**\n * Sends a `message` event.\n *\n * @return {Socket} self\n * @api public\n */\n\nSocket.prototype.send = function(){\n  var args = toArray(arguments);\n  args.unshift('message');\n  this.emit.apply(this, args);\n  return this;\n};\n\n/**\n * Override `emit`.\n * If the event is in `events`, it's emitted normally.\n *\n * @param {String} event name\n * @return {Socket} self\n * @api public\n */\n\nSocket.prototype.emit = function(ev){\n  if (events.hasOwnProperty(ev)) {\n    emit.apply(this, arguments);\n    return this;\n  }\n\n  var args = toArray(arguments);\n  var parserType = parser.EVENT; // default\n  if (hasBin(args)) { parserType = parser.BINARY_EVENT; } // binary\n  var packet = { type: parserType, data: args };\n\n  // event ack callback\n  if ('function' == typeof args[args.length - 1]) {\n    debug('emitting packet with ack id %d', this.ids);\n    this.acks[this.ids] = args.pop();\n    packet.id = this.ids++;\n  }\n\n  if (this.connected) {\n    this.packet(packet);\n  } else {\n    this.sendBuffer.push(packet);\n  }\n\n  return this;\n};\n\n/**\n * Sends a packet.\n *\n * @param {Object} packet\n * @api private\n */\n\nSocket.prototype.packet = function(packet){\n  packet.nsp = this.nsp;\n  this.io.packet(packet);\n};\n\n/**\n * Called upon engine `open`.\n *\n * @api private\n */\n\nSocket.prototype.onopen = function(){\n  debug('transport is open - connecting');\n\n  // write connect packet if necessary\n  if ('/' != this.nsp) {\n    this.packet({ type: parser.CONNECT });\n  }\n};\n\n/**\n * Called upon engine `close`.\n *\n * @param {String} reason\n * @api private\n */\n\nSocket.prototype.onclose = function(reason){\n  debug('close (%s)', reason);\n  this.connected = false;\n  this.disconnected = true;\n  delete this.id;\n  this.emit('disconnect', reason);\n};\n\n/**\n * Called with socket packet.\n *\n * @param {Object} packet\n * @api private\n */\n\nSocket.prototype.onpacket = function(packet){\n  if (packet.nsp != this.nsp) return;\n\n  switch (packet.type) {\n    case parser.CONNECT:\n      this.onconnect();\n      break;\n\n    case parser.EVENT:\n      this.onevent(packet);\n      break;\n\n    case parser.BINARY_EVENT:\n      this.onevent(packet);\n      break;\n\n    case parser.ACK:\n      this.onack(packet);\n      break;\n\n    case parser.BINARY_ACK:\n      this.onack(packet);\n      break;\n\n    case parser.DISCONNECT:\n      this.ondisconnect();\n      break;\n\n    case parser.ERROR:\n      this.emit('error', packet.data);\n      break;\n  }\n};\n\n/**\n * Called upon a server event.\n *\n * @param {Object} packet\n * @api private\n */\n\nSocket.prototype.onevent = function(packet){\n  var args = packet.data || [];\n  debug('emitting event %j', args);\n\n  if (null != packet.id) {\n    debug('attaching ack callback to event');\n    args.push(this.ack(packet.id));\n  }\n\n  if (this.connected) {\n    emit.apply(this, args);\n  } else {\n    this.receiveBuffer.push(args);\n  }\n};\n\n/**\n * Produces an ack callback to emit with an event.\n *\n * @api private\n */\n\nSocket.prototype.ack = function(id){\n  var self = this;\n  var sent = false;\n  return function(){\n    // prevent double callbacks\n    if (sent) return;\n    sent = true;\n    var args = toArray(arguments);\n    debug('sending ack %j', args);\n\n    var type = hasBin(args) ? parser.BINARY_ACK : parser.ACK;\n    self.packet({\n      type: type,\n      id: id,\n      data: args\n    });\n  };\n};\n\n/**\n * Called upon a server acknowlegement.\n *\n * @param {Object} packet\n * @api private\n */\n\nSocket.prototype.onack = function(packet){\n  debug('calling ack %s with %j', packet.id, packet.data);\n  var fn = this.acks[packet.id];\n  fn.apply(this, packet.data);\n  delete this.acks[packet.id];\n};\n\n/**\n * Called upon server connect.\n *\n * @api private\n */\n\nSocket.prototype.onconnect = function(){\n  this.connected = true;\n  this.disconnected = false;\n  this.emit('connect');\n  this.emitBuffered();\n};\n\n/**\n * Emit buffered events (received and emitted).\n *\n * @api private\n */\n\nSocket.prototype.emitBuffered = function(){\n  var i;\n  for (i = 0; i < this.receiveBuffer.length; i++) {\n    emit.apply(this, this.receiveBuffer[i]);\n  }\n  this.receiveBuffer = [];\n\n  for (i = 0; i < this.sendBuffer.length; i++) {\n    this.packet(this.sendBuffer[i]);\n  }\n  this.sendBuffer = [];\n};\n\n/**\n * Called upon server disconnect.\n *\n * @api private\n */\n\nSocket.prototype.ondisconnect = function(){\n  debug('server disconnect (%s)', this.nsp);\n  this.destroy();\n  this.onclose('io server disconnect');\n};\n\n/**\n * Called upon forced client/server side disconnections,\n * this method ensures the manager stops tracking us and\n * that reconnections don't get triggered for this.\n *\n * @api private.\n */\n\nSocket.prototype.destroy = function(){\n  if (this.subs) {\n    // clean subscriptions to avoid reconnections\n    for (var i = 0; i < this.subs.length; i++) {\n      this.subs[i].destroy();\n    }\n    this.subs = null;\n  }\n\n  this.io.destroy(this);\n};\n\n/**\n * Disconnects the socket manually.\n *\n * @return {Socket} self\n * @api public\n */\n\nSocket.prototype.close =\nSocket.prototype.disconnect = function(){\n  if (this.connected) {\n    debug('performing disconnect (%s)', this.nsp);\n    this.packet({ type: parser.DISCONNECT });\n  }\n\n  // remove socket from pool\n  this.destroy();\n\n  if (this.connected) {\n    // fire events\n    this.onclose('io client disconnect');\n  }\n  return this;\n};\n\n},{\"./on\":4,\"component-bind\":8,\"component-emitter\":9,\"debug\":10,\"has-binary\":36,\"socket.io-parser\":44,\"to-array\":48}],6:[function(_dereq_,module,exports){\n(function (global){\n\n/**\n * Module dependencies.\n */\n\nvar parseuri = _dereq_('parseuri');\nvar debug = _dereq_('debug')('socket.io-client:url');\n\n/**\n * Module exports.\n */\n\nmodule.exports = url;\n\n/**\n * URL parser.\n *\n * @param {String} url\n * @param {Object} An object meant to mimic window.location.\n *                 Defaults to window.location.\n * @api public\n */\n\nfunction url(uri, loc){\n  var obj = uri;\n\n  // default to window.location\n  var loc = loc || global.location;\n  if (null == uri) uri = loc.protocol + '//' + loc.host;\n\n  // relative path support\n  if ('string' == typeof uri) {\n    if ('/' == uri.charAt(0)) {\n      if ('/' == uri.charAt(1)) {\n        uri = loc.protocol + uri;\n      } else {\n        uri = loc.hostname + uri;\n      }\n    }\n\n    if (!/^(https?|wss?):\\/\\//.test(uri)) {\n      debug('protocol-less url %s', uri);\n      if ('undefined' != typeof loc) {\n        uri = loc.protocol + '//' + uri;\n      } else {\n        uri = 'https://' + uri;\n      }\n    }\n\n    // parse\n    debug('parse %s', uri);\n    obj = parseuri(uri);\n  }\n\n  // make sure we treat `localhost:80` and `localhost` equally\n  if (!obj.port) {\n    if (/^(http|ws)$/.test(obj.protocol)) {\n      obj.port = '80';\n    }\n    else if (/^(http|ws)s$/.test(obj.protocol)) {\n      obj.port = '443';\n    }\n  }\n\n  obj.path = obj.path || '/';\n\n  // define unique id\n  obj.id = obj.protocol + '://' + obj.host + ':' + obj.port;\n  // define href\n  obj.href = obj.protocol + '://' + obj.host + (loc && loc.port == obj.port ? '' : (':' + obj.port));\n\n  return obj;\n}\n\n}).call(this,typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"debug\":10,\"parseuri\":42}],7:[function(_dereq_,module,exports){\n\n/**\n * Expose `Backoff`.\n */\n\nmodule.exports = Backoff;\n\n/**\n * Initialize backoff timer with `opts`.\n *\n * - `min` initial timeout in milliseconds [100]\n * - `max` max timeout [10000]\n * - `jitter` [0]\n * - `factor` [2]\n *\n * @param {Object} opts\n * @api public\n */\n\nfunction Backoff(opts) {\n  opts = opts || {};\n  this.ms = opts.min || 100;\n  this.max = opts.max || 10000;\n  this.factor = opts.factor || 2;\n  this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0;\n  this.attempts = 0;\n}\n\n/**\n * Return the backoff duration.\n *\n * @return {Number}\n * @api public\n */\n\nBackoff.prototype.duration = function(){\n  var ms = this.ms * Math.pow(this.factor, this.attempts++);\n  if (this.jitter) {\n    var rand =  Math.random();\n    var deviation = Math.floor(rand * this.jitter * ms);\n    ms = (Math.floor(rand * 10) & 1) == 0  ? ms - deviation : ms + deviation;\n  }\n  return Math.min(ms, this.max) | 0;\n};\n\n/**\n * Reset the number of attempts.\n *\n * @api public\n */\n\nBackoff.prototype.reset = function(){\n  this.attempts = 0;\n};\n\n/**\n * Set the minimum duration\n *\n * @api public\n */\n\nBackoff.prototype.setMin = function(min){\n  this.ms = min;\n};\n\n/**\n * Set the maximum duration\n *\n * @api public\n */\n\nBackoff.prototype.setMax = function(max){\n  this.max = max;\n};\n\n/**\n * Set the jitter\n *\n * @api public\n */\n\nBackoff.prototype.setJitter = function(jitter){\n  this.jitter = jitter;\n};\n\n\n},{}],8:[function(_dereq_,module,exports){\n/**\n * Slice reference.\n */\n\nvar slice = [].slice;\n\n/**\n * Bind `obj` to `fn`.\n *\n * @param {Object} obj\n * @param {Function|String} fn or string\n * @return {Function}\n * @api public\n */\n\nmodule.exports = function(obj, fn){\n  if ('string' == typeof fn) fn = obj[fn];\n  if ('function' != typeof fn) throw new Error('bind() requires a function');\n  var args = slice.call(arguments, 2);\n  return function(){\n    return fn.apply(obj, args.concat(slice.call(arguments)));\n  }\n};\n\n},{}],9:[function(_dereq_,module,exports){\n\n/**\n * Expose `Emitter`.\n */\n\nmodule.exports = Emitter;\n\n/**\n * Initialize a new `Emitter`.\n *\n * @api public\n */\n\nfunction Emitter(obj) {\n  if (obj) return mixin(obj);\n};\n\n/**\n * Mixin the emitter properties.\n *\n * @param {Object} obj\n * @return {Object}\n * @api private\n */\n\nfunction mixin(obj) {\n  for (var key in Emitter.prototype) {\n    obj[key] = Emitter.prototype[key];\n  }\n  return obj;\n}\n\n/**\n * Listen on the given `event` with `fn`.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\nEmitter.prototype.on =\nEmitter.prototype.addEventListener = function(event, fn){\n  this._callbacks = this._callbacks || {};\n  (this._callbacks[event] = this._callbacks[event] || [])\n    .push(fn);\n  return this;\n};\n\n/**\n * Adds an `event` listener that will be invoked a single\n * time then automatically removed.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\nEmitter.prototype.once = function(event, fn){\n  var self = this;\n  this._callbacks = this._callbacks || {};\n\n  function on() {\n    self.off(event, on);\n    fn.apply(this, arguments);\n  }\n\n  on.fn = fn;\n  this.on(event, on);\n  return this;\n};\n\n/**\n * Remove the given callback for `event` or all\n * registered callbacks.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\nEmitter.prototype.off =\nEmitter.prototype.removeListener =\nEmitter.prototype.removeAllListeners =\nEmitter.prototype.removeEventListener = function(event, fn){\n  this._callbacks = this._callbacks || {};\n\n  // all\n  if (0 == arguments.length) {\n    this._callbacks = {};\n    return this;\n  }\n\n  // specific event\n  var callbacks = this._callbacks[event];\n  if (!callbacks) return this;\n\n  // remove all handlers\n  if (1 == arguments.length) {\n    delete this._callbacks[event];\n    return this;\n  }\n\n  // remove specific handler\n  var cb;\n  for (var i = 0; i < callbacks.length; i++) {\n    cb = callbacks[i];\n    if (cb === fn || cb.fn === fn) {\n      callbacks.splice(i, 1);\n      break;\n    }\n  }\n  return this;\n};\n\n/**\n * Emit `event` with the given args.\n *\n * @param {String} event\n * @param {Mixed} ...\n * @return {Emitter}\n */\n\nEmitter.prototype.emit = function(event){\n  this._callbacks = this._callbacks || {};\n  var args = [].slice.call(arguments, 1)\n    , callbacks = this._callbacks[event];\n\n  if (callbacks) {\n    callbacks = callbacks.slice(0);\n    for (var i = 0, len = callbacks.length; i < len; ++i) {\n      callbacks[i].apply(this, args);\n    }\n  }\n\n  return this;\n};\n\n/**\n * Return array of callbacks for `event`.\n *\n * @param {String} event\n * @return {Array}\n * @api public\n */\n\nEmitter.prototype.listeners = function(event){\n  this._callbacks = this._callbacks || {};\n  return this._callbacks[event] || [];\n};\n\n/**\n * Check if this emitter has `event` handlers.\n *\n * @param {String} event\n * @return {Boolean}\n * @api public\n */\n\nEmitter.prototype.hasListeners = function(event){\n  return !! this.listeners(event).length;\n};\n\n},{}],10:[function(_dereq_,module,exports){\n\n/**\n * Expose `debug()` as the module.\n */\n\nmodule.exports = debug;\n\n/**\n * Create a debugger with the given `name`.\n *\n * @param {String} name\n * @return {Type}\n * @api public\n */\n\nfunction debug(name) {\n  if (!debug.enabled(name)) return function(){};\n\n  return function(fmt){\n    fmt = coerce(fmt);\n\n    var curr = new Date;\n    var ms = curr - (debug[name] || curr);\n    debug[name] = curr;\n\n    fmt = name\n      + ' '\n      + fmt\n      + ' +' + debug.humanize(ms);\n\n    // This hackery is required for IE8\n    // where `console.log` doesn't have 'apply'\n    window.console\n      && console.log\n      && Function.prototype.apply.call(console.log, console, arguments);\n  }\n}\n\n/**\n * The currently active debug mode names.\n */\n\ndebug.names = [];\ndebug.skips = [];\n\n/**\n * Enables a debug mode by name. This can include modes\n * separated by a colon and wildcards.\n *\n * @param {String} name\n * @api public\n */\n\ndebug.enable = function(name) {\n  try {\n    localStorage.debug = name;\n  } catch(e){}\n\n  var split = (name || '').split(/[\\s,]+/)\n    , len = split.length;\n\n  for (var i = 0; i < len; i++) {\n    name = split[i].replace('*', '.*?');\n    if (name[0] === '-') {\n      debug.skips.push(new RegExp('^' + name.substr(1) + '$'));\n    }\n    else {\n      debug.names.push(new RegExp('^' + name + '$'));\n    }\n  }\n};\n\n/**\n * Disable debug output.\n *\n * @api public\n */\n\ndebug.disable = function(){\n  debug.enable('');\n};\n\n/**\n * Humanize the given `ms`.\n *\n * @param {Number} m\n * @return {String}\n * @api private\n */\n\ndebug.humanize = function(ms) {\n  var sec = 1000\n    , min = 60 * 1000\n    , hour = 60 * min;\n\n  if (ms >= hour) return (ms / hour).toFixed(1) + 'h';\n  if (ms >= min) return (ms / min).toFixed(1) + 'm';\n  if (ms >= sec) return (ms / sec | 0) + 's';\n  return ms + 'ms';\n};\n\n/**\n * Returns true if the given mode name is enabled, false otherwise.\n *\n * @param {String} name\n * @return {Boolean}\n * @api public\n */\n\ndebug.enabled = function(name) {\n  for (var i = 0, len = debug.skips.length; i < len; i++) {\n    if (debug.skips[i].test(name)) {\n      return false;\n    }\n  }\n  for (var i = 0, len = debug.names.length; i < len; i++) {\n    if (debug.names[i].test(name)) {\n      return true;\n    }\n  }\n  return false;\n};\n\n/**\n * Coerce `val`.\n */\n\nfunction coerce(val) {\n  if (val instanceof Error) return val.stack || val.message;\n  return val;\n}\n\n// persist\n\ntry {\n  if (window.localStorage) debug.enable(localStorage.debug);\n} catch(e){}\n\n},{}],11:[function(_dereq_,module,exports){\n\nmodule.exports =  _dereq_('./lib/');\n\n},{\"./lib/\":12}],12:[function(_dereq_,module,exports){\n\nmodule.exports = _dereq_('./socket');\n\n/**\n * Exports parser\n *\n * @api public\n *\n */\nmodule.exports.parser = _dereq_('engine.io-parser');\n\n},{\"./socket\":13,\"engine.io-parser\":25}],13:[function(_dereq_,module,exports){\n(function (global){\n/**\n * Module dependencies.\n */\n\nvar transports = _dereq_('./transports');\nvar Emitter = _dereq_('component-emitter');\nvar debug = _dereq_('debug')('engine.io-client:socket');\nvar index = _dereq_('indexof');\nvar parser = _dereq_('engine.io-parser');\nvar parseuri = _dereq_('parseuri');\nvar parsejson = _dereq_('parsejson');\nvar parseqs = _dereq_('parseqs');\n\n/**\n * Module exports.\n */\n\nmodule.exports = Socket;\n\n/**\n * Noop function.\n *\n * @api private\n */\n\nfunction noop(){}\n\n/**\n * Socket constructor.\n *\n * @param {String|Object} uri or options\n * @param {Object} options\n * @api public\n */\n\nfunction Socket(uri, opts){\n  if (!(this instanceof Socket)) return new Socket(uri, opts);\n\n  opts = opts || {};\n\n  if (uri && 'object' == typeof uri) {\n    opts = uri;\n    uri = null;\n  }\n\n  if (uri) {\n    uri = parseuri(uri);\n    opts.host = uri.host;\n    opts.secure = uri.protocol == 'https' || uri.protocol == 'wss';\n    opts.port = uri.port;\n    if (uri.query) opts.query = uri.query;\n  }\n\n  this.secure = null != opts.secure ? opts.secure :\n    (global.location && 'https:' == location.protocol);\n\n  if (opts.host) {\n    var pieces = opts.host.split(':');\n    opts.hostname = pieces.shift();\n    if (pieces.length) {\n      opts.port = pieces.pop();\n    } else if (!opts.port) {\n      // if no port is specified manually, use the protocol default\n      opts.port = this.secure ? '443' : '80';\n    }\n  }\n\n  this.agent = opts.agent || false;\n  this.hostname = opts.hostname ||\n    (global.location ? location.hostname : 'localhost');\n  this.port = opts.port || (global.location && location.port ?\n       location.port :\n       (this.secure ? 443 : 80));\n  this.query = opts.query || {};\n  if ('string' == typeof this.query) this.query = parseqs.decode(this.query);\n  this.upgrade = false !== opts.upgrade;\n  this.path = (opts.path || '/engine.io').replace(/\\/$/, '') + '/';\n  this.forceJSONP = !!opts.forceJSONP;\n  this.jsonp = false !== opts.jsonp;\n  this.forceBase64 = !!opts.forceBase64;\n  this.enablesXDR = !!opts.enablesXDR;\n  this.timestampParam = opts.timestampParam || 't';\n  this.timestampRequests = opts.timestampRequests;\n  this.transports = opts.transports || ['polling', 'websocket'];\n  this.readyState = '';\n  this.writeBuffer = [];\n  this.callbackBuffer = [];\n  this.policyPort = opts.policyPort || 843;\n  this.rememberUpgrade = opts.rememberUpgrade || false;\n  this.binaryType = null;\n  this.onlyBinaryUpgrades = opts.onlyBinaryUpgrades;\n\n  // SSL options for Node.js client\n  this.pfx = opts.pfx || null;\n  this.key = opts.key || null;\n  this.passphrase = opts.passphrase || null;\n  this.cert = opts.cert || null;\n  this.ca = opts.ca || null;\n  this.ciphers = opts.ciphers || null;\n  this.rejectUnauthorized = opts.rejectUnauthorized || null;\n\n  this.open();\n}\n\nSocket.priorWebsocketSuccess = false;\n\n/**\n * Mix in `Emitter`.\n */\n\nEmitter(Socket.prototype);\n\n/**\n * Protocol version.\n *\n * @api public\n */\n\nSocket.protocol = parser.protocol; // this is an int\n\n/**\n * Expose deps for legacy compatibility\n * and standalone browser access.\n */\n\nSocket.Socket = Socket;\nSocket.Transport = _dereq_('./transport');\nSocket.transports = _dereq_('./transports');\nSocket.parser = _dereq_('engine.io-parser');\n\n/**\n * Creates transport of the given type.\n *\n * @param {String} transport name\n * @return {Transport}\n * @api private\n */\n\nSocket.prototype.createTransport = function (name) {\n  debug('creating transport \"%s\"', name);\n  var query = clone(this.query);\n\n  // append engine.io protocol identifier\n  query.EIO = parser.protocol;\n\n  // transport name\n  query.transport = name;\n\n  // session id if we already have one\n  if (this.id) query.sid = this.id;\n\n  var transport = new transports[name]({\n    agent: this.agent,\n    hostname: this.hostname,\n    port: this.port,\n    secure: this.secure,\n    path: this.path,\n    query: query,\n    forceJSONP: this.forceJSONP,\n    jsonp: this.jsonp,\n    forceBase64: this.forceBase64,\n    enablesXDR: this.enablesXDR,\n    timestampRequests: this.timestampRequests,\n    timestampParam: this.timestampParam,\n    policyPort: this.policyPort,\n    socket: this,\n    pfx: this.pfx,\n    key: this.key,\n    passphrase: this.passphrase,\n    cert: this.cert,\n    ca: this.ca,\n    ciphers: this.ciphers,\n    rejectUnauthorized: this.rejectUnauthorized\n  });\n\n  return transport;\n};\n\nfunction clone (obj) {\n  var o = {};\n  for (var i in obj) {\n    if (obj.hasOwnProperty(i)) {\n      o[i] = obj[i];\n    }\n  }\n  return o;\n}\n\n/**\n * Initializes transport to use and starts probe.\n *\n * @api private\n */\nSocket.prototype.open = function () {\n  var transport;\n  if (this.rememberUpgrade && Socket.priorWebsocketSuccess && this.transports.indexOf('websocket') != -1) {\n    transport = 'websocket';\n  } else if (0 == this.transports.length) {\n    // Emit error on next tick so it can be listened to\n    var self = this;\n    setTimeout(function() {\n      self.emit('error', 'No transports available');\n    }, 0);\n    return;\n  } else {\n    transport = this.transports[0];\n  }\n  this.readyState = 'opening';\n\n  // Retry with the next transport if the transport is disabled (jsonp: false)\n  var transport;\n  try {\n    transport = this.createTransport(transport);\n  } catch (e) {\n    this.transports.shift();\n    this.open();\n    return;\n  }\n\n  transport.open();\n  this.setTransport(transport);\n};\n\n/**\n * Sets the current transport. Disables the existing one (if any).\n *\n * @api private\n */\n\nSocket.prototype.setTransport = function(transport){\n  debug('setting transport %s', transport.name);\n  var self = this;\n\n  if (this.transport) {\n    debug('clearing existing transport %s', this.transport.name);\n    this.transport.removeAllListeners();\n  }\n\n  // set up transport\n  this.transport = transport;\n\n  // set up transport listeners\n  transport\n  .on('drain', function(){\n    self.onDrain();\n  })\n  .on('packet', function(packet){\n    self.onPacket(packet);\n  })\n  .on('error', function(e){\n    self.onError(e);\n  })\n  .on('close', function(){\n    self.onClose('transport close');\n  });\n};\n\n/**\n * Probes a transport.\n *\n * @param {String} transport name\n * @api private\n */\n\nSocket.prototype.probe = function (name) {\n  debug('probing transport \"%s\"', name);\n  var transport = this.createTransport(name, { probe: 1 })\n    , failed = false\n    , self = this;\n\n  Socket.priorWebsocketSuccess = false;\n\n  function onTransportOpen(){\n    if (self.onlyBinaryUpgrades) {\n      var upgradeLosesBinary = !this.supportsBinary && self.transport.supportsBinary;\n      failed = failed || upgradeLosesBinary;\n    }\n    if (failed) return;\n\n    debug('probe transport \"%s\" opened', name);\n    transport.send([{ type: 'ping', data: 'probe' }]);\n    transport.once('packet', function (msg) {\n      if (failed) return;\n      if ('pong' == msg.type && 'probe' == msg.data) {\n        debug('probe transport \"%s\" pong', name);\n        self.upgrading = true;\n        self.emit('upgrading', transport);\n        if (!transport) return;\n        Socket.priorWebsocketSuccess = 'websocket' == transport.name;\n\n        debug('pausing current transport \"%s\"', self.transport.name);\n        self.transport.pause(function () {\n          if (failed) return;\n          if ('closed' == self.readyState) return;\n          debug('changing transport and sending upgrade packet');\n\n          cleanup();\n\n          self.setTransport(transport);\n          transport.send([{ type: 'upgrade' }]);\n          self.emit('upgrade', transport);\n          transport = null;\n          self.upgrading = false;\n          self.flush();\n        });\n      } else {\n        debug('probe transport \"%s\" failed', name);\n        var err = new Error('probe error');\n        err.transport = transport.name;\n        self.emit('upgradeError', err);\n      }\n    });\n  }\n\n  function freezeTransport() {\n    if (failed) return;\n\n    // Any callback called by transport should be ignored since now\n    failed = true;\n\n    cleanup();\n\n    transport.close();\n    transport = null;\n  }\n\n  //Handle any error that happens while probing\n  function onerror(err) {\n    var error = new Error('probe error: ' + err);\n    error.transport = transport.name;\n\n    freezeTransport();\n\n    debug('probe transport \"%s\" failed because of error: %s', name, err);\n\n    self.emit('upgradeError', error);\n  }\n\n  function onTransportClose(){\n    onerror(\"transport closed\");\n  }\n\n  //When the socket is closed while we're probing\n  function onclose(){\n    onerror(\"socket closed\");\n  }\n\n  //When the socket is upgraded while we're probing\n  function onupgrade(to){\n    if (transport && to.name != transport.name) {\n      debug('\"%s\" works - aborting \"%s\"', to.name, transport.name);\n      freezeTransport();\n    }\n  }\n\n  //Remove all listeners on the transport and on self\n  function cleanup(){\n    transport.removeListener('open', onTransportOpen);\n    transport.removeListener('error', onerror);\n    transport.removeListener('close', onTransportClose);\n    self.removeListener('close', onclose);\n    self.removeListener('upgrading', onupgrade);\n  }\n\n  transport.once('open', onTransportOpen);\n  transport.once('error', onerror);\n  transport.once('close', onTransportClose);\n\n  this.once('close', onclose);\n  this.once('upgrading', onupgrade);\n\n  transport.open();\n\n};\n\n/**\n * Called when connection is deemed open.\n *\n * @api public\n */\n\nSocket.prototype.onOpen = function () {\n  debug('socket open');\n  this.readyState = 'open';\n  Socket.priorWebsocketSuccess = 'websocket' == this.transport.name;\n  this.emit('open');\n  this.flush();\n\n  // we check for `readyState` in case an `open`\n  // listener already closed the socket\n  if ('open' == this.readyState && this.upgrade && this.transport.pause) {\n    debug('starting upgrade probes');\n    for (var i = 0, l = this.upgrades.length; i < l; i++) {\n      this.probe(this.upgrades[i]);\n    }\n  }\n};\n\n/**\n * Handles a packet.\n *\n * @api private\n */\n\nSocket.prototype.onPacket = function (packet) {\n  if ('opening' == this.readyState || 'open' == this.readyState) {\n    debug('socket receive: type \"%s\", data \"%s\"', packet.type, packet.data);\n\n    this.emit('packet', packet);\n\n    // Socket is live - any packet counts\n    this.emit('heartbeat');\n\n    switch (packet.type) {\n      case 'open':\n        this.onHandshake(parsejson(packet.data));\n        break;\n\n      case 'pong':\n        this.setPing();\n        break;\n\n      case 'error':\n        var err = new Error('server error');\n        err.code = packet.data;\n        this.emit('error', err);\n        break;\n\n      case 'message':\n        this.emit('data', packet.data);\n        this.emit('message', packet.data);\n        break;\n    }\n  } else {\n    debug('packet received with socket readyState \"%s\"', this.readyState);\n  }\n};\n\n/**\n * Called upon handshake completion.\n *\n * @param {Object} handshake obj\n * @api private\n */\n\nSocket.prototype.onHandshake = function (data) {\n  this.emit('handshake', data);\n  this.id = data.sid;\n  this.transport.query.sid = data.sid;\n  this.upgrades = this.filterUpgrades(data.upgrades);\n  this.pingInterval = data.pingInterval;\n  this.pingTimeout = data.pingTimeout;\n  this.onOpen();\n  // In case open handler closes socket\n  if  ('closed' == this.readyState) return;\n  this.setPing();\n\n  // Prolong liveness of socket on heartbeat\n  this.removeListener('heartbeat', this.onHeartbeat);\n  this.on('heartbeat', this.onHeartbeat);\n};\n\n/**\n * Resets ping timeout.\n *\n * @api private\n */\n\nSocket.prototype.onHeartbeat = function (timeout) {\n  clearTimeout(this.pingTimeoutTimer);\n  var self = this;\n  self.pingTimeoutTimer = setTimeout(function () {\n    if ('closed' == self.readyState) return;\n    self.onClose('ping timeout');\n  }, timeout || (self.pingInterval + self.pingTimeout));\n};\n\n/**\n * Pings server every `this.pingInterval` and expects response\n * within `this.pingTimeout` or closes connection.\n *\n * @api private\n */\n\nSocket.prototype.setPing = function () {\n  var self = this;\n  clearTimeout(self.pingIntervalTimer);\n  self.pingIntervalTimer = setTimeout(function () {\n    debug('writing ping packet - expecting pong within %sms', self.pingTimeout);\n    self.ping();\n    self.onHeartbeat(self.pingTimeout);\n  }, self.pingInterval);\n};\n\n/**\n* Sends a ping packet.\n*\n* @api public\n*/\n\nSocket.prototype.ping = function () {\n  this.sendPacket('ping');\n};\n\n/**\n * Called on `drain` event\n *\n * @api private\n */\n\nSocket.prototype.onDrain = function() {\n  for (var i = 0; i < this.prevBufferLen; i++) {\n    if (this.callbackBuffer[i]) {\n      this.callbackBuffer[i]();\n    }\n  }\n\n  this.writeBuffer.splice(0, this.prevBufferLen);\n  this.callbackBuffer.splice(0, this.prevBufferLen);\n\n  // setting prevBufferLen = 0 is very important\n  // for example, when upgrading, upgrade packet is sent over,\n  // and a nonzero prevBufferLen could cause problems on `drain`\n  this.prevBufferLen = 0;\n\n  if (this.writeBuffer.length == 0) {\n    this.emit('drain');\n  } else {\n    this.flush();\n  }\n};\n\n/**\n * Flush write buffers.\n *\n * @api private\n */\n\nSocket.prototype.flush = function () {\n  if ('closed' != this.readyState && this.transport.writable &&\n    !this.upgrading && this.writeBuffer.length) {\n    debug('flushing %d packets in socket', this.writeBuffer.length);\n    this.transport.send(this.writeBuffer);\n    // keep track of current length of writeBuffer\n    // splice writeBuffer and callbackBuffer on `drain`\n    this.prevBufferLen = this.writeBuffer.length;\n    this.emit('flush');\n  }\n};\n\n/**\n * Sends a message.\n *\n * @param {String} message.\n * @param {Function} callback function.\n * @return {Socket} for chaining.\n * @api public\n */\n\nSocket.prototype.write =\nSocket.prototype.send = function (msg, fn) {\n  this.sendPacket('message', msg, fn);\n  return this;\n};\n\n/**\n * Sends a packet.\n *\n * @param {String} packet type.\n * @param {String} data.\n * @param {Function} callback function.\n * @api private\n */\n\nSocket.prototype.sendPacket = function (type, data, fn) {\n  if ('closing' == this.readyState || 'closed' == this.readyState) {\n    return;\n  }\n\n  var packet = { type: type, data: data };\n  this.emit('packetCreate', packet);\n  this.writeBuffer.push(packet);\n  this.callbackBuffer.push(fn);\n  this.flush();\n};\n\n/**\n * Closes the connection.\n *\n * @api private\n */\n\nSocket.prototype.close = function () {\n  if ('opening' == this.readyState || 'open' == this.readyState) {\n    this.readyState = 'closing';\n\n    var self = this;\n\n    function close() {\n      self.onClose('forced close');\n      debug('socket closing - telling transport to close');\n      self.transport.close();\n    }\n\n    function cleanupAndClose() {\n      self.removeListener('upgrade', cleanupAndClose);\n      self.removeListener('upgradeError', cleanupAndClose);\n      close();\n    }\n\n    function waitForUpgrade() {\n      // wait for upgrade to finish since we can't send packets while pausing a transport\n      self.once('upgrade', cleanupAndClose);\n      self.once('upgradeError', cleanupAndClose);\n    }\n\n    if (this.writeBuffer.length) {\n      this.once('drain', function() {\n        if (this.upgrading) {\n          waitForUpgrade();\n        } else {\n          close();\n        }\n      });\n    } else if (this.upgrading) {\n      waitForUpgrade();\n    } else {\n      close();\n    }\n  }\n\n  return this;\n};\n\n/**\n * Called upon transport error\n *\n * @api private\n */\n\nSocket.prototype.onError = function (err) {\n  debug('socket error %j', err);\n  Socket.priorWebsocketSuccess = false;\n  this.emit('error', err);\n  this.onClose('transport error', err);\n};\n\n/**\n * Called upon transport close.\n *\n * @api private\n */\n\nSocket.prototype.onClose = function (reason, desc) {\n  if ('opening' == this.readyState || 'open' == this.readyState || 'closing' == this.readyState) {\n    debug('socket close with reason: \"%s\"', reason);\n    var self = this;\n\n    // clear timers\n    clearTimeout(this.pingIntervalTimer);\n    clearTimeout(this.pingTimeoutTimer);\n\n    // clean buffers in next tick, so developers can still\n    // grab the buffers on `close` event\n    setTimeout(function() {\n      self.writeBuffer = [];\n      self.callbackBuffer = [];\n      self.prevBufferLen = 0;\n    }, 0);\n\n    // stop event from firing again for transport\n    this.transport.removeAllListeners('close');\n\n    // ensure transport won't stay open\n    this.transport.close();\n\n    // ignore further transport communication\n    this.transport.removeAllListeners();\n\n    // set ready state\n    this.readyState = 'closed';\n\n    // clear session id\n    this.id = null;\n\n    // emit close event\n    this.emit('close', reason, desc);\n  }\n};\n\n/**\n * Filters upgrades, returning only those matching client transports.\n *\n * @param {Array} server upgrades\n * @api private\n *\n */\n\nSocket.prototype.filterUpgrades = function (upgrades) {\n  var filteredUpgrades = [];\n  for (var i = 0, j = upgrades.length; i<j; i++) {\n    if (~index(this.transports, upgrades[i])) filteredUpgrades.push(upgrades[i]);\n  }\n  return filteredUpgrades;\n};\n\n}).call(this,typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./transport\":14,\"./transports\":15,\"component-emitter\":9,\"debug\":22,\"engine.io-parser\":25,\"indexof\":40,\"parsejson\":32,\"parseqs\":33,\"parseuri\":34}],14:[function(_dereq_,module,exports){\n/**\n * Module dependencies.\n */\n\nvar parser = _dereq_('engine.io-parser');\nvar Emitter = _dereq_('component-emitter');\n\n/**\n * Module exports.\n */\n\nmodule.exports = Transport;\n\n/**\n * Transport abstract constructor.\n *\n * @param {Object} options.\n * @api private\n */\n\nfunction Transport (opts) {\n  this.path = opts.path;\n  this.hostname = opts.hostname;\n  this.port = opts.port;\n  this.secure = opts.secure;\n  this.query = opts.query;\n  this.timestampParam = opts.timestampParam;\n  this.timestampRequests = opts.timestampRequests;\n  this.readyState = '';\n  this.agent = opts.agent || false;\n  this.socket = opts.socket;\n  this.enablesXDR = opts.enablesXDR;\n\n  // SSL options for Node.js client\n  this.pfx = opts.pfx;\n  this.key = opts.key;\n  this.passphrase = opts.passphrase;\n  this.cert = opts.cert;\n  this.ca = opts.ca;\n  this.ciphers = opts.ciphers;\n  this.rejectUnauthorized = opts.rejectUnauthorized;\n}\n\n/**\n * Mix in `Emitter`.\n */\n\nEmitter(Transport.prototype);\n\n/**\n * A counter used to prevent collisions in the timestamps used\n * for cache busting.\n */\n\nTransport.timestamps = 0;\n\n/**\n * Emits an error.\n *\n * @param {String} str\n * @return {Transport} for chaining\n * @api public\n */\n\nTransport.prototype.onError = function (msg, desc) {\n  var err = new Error(msg);\n  err.type = 'TransportError';\n  err.description = desc;\n  this.emit('error', err);\n  return this;\n};\n\n/**\n * Opens the transport.\n *\n * @api public\n */\n\nTransport.prototype.open = function () {\n  if ('closed' == this.readyState || '' == this.readyState) {\n    this.readyState = 'opening';\n    this.doOpen();\n  }\n\n  return this;\n};\n\n/**\n * Closes the transport.\n *\n * @api private\n */\n\nTransport.prototype.close = function () {\n  if ('opening' == this.readyState || 'open' == this.readyState) {\n    this.doClose();\n    this.onClose();\n  }\n\n  return this;\n};\n\n/**\n * Sends multiple packets.\n *\n * @param {Array} packets\n * @api private\n */\n\nTransport.prototype.send = function(packets){\n  if ('open' == this.readyState) {\n    this.write(packets);\n  } else {\n    throw new Error('Transport not open');\n  }\n};\n\n/**\n * Called upon open\n *\n * @api private\n */\n\nTransport.prototype.onOpen = function () {\n  this.readyState = 'open';\n  this.writable = true;\n  this.emit('open');\n};\n\n/**\n * Called with data.\n *\n * @param {String} data\n * @api private\n */\n\nTransport.prototype.onData = function(data){\n  var packet = parser.decodePacket(data, this.socket.binaryType);\n  this.onPacket(packet);\n};\n\n/**\n * Called with a decoded packet.\n */\n\nTransport.prototype.onPacket = function (packet) {\n  this.emit('packet', packet);\n};\n\n/**\n * Called upon close.\n *\n * @api private\n */\n\nTransport.prototype.onClose = function () {\n  this.readyState = 'closed';\n  this.emit('close');\n};\n\n},{\"component-emitter\":9,\"engine.io-parser\":25}],15:[function(_dereq_,module,exports){\n(function (global){\n/**\n * Module dependencies\n */\n\nvar XMLHttpRequest = _dereq_('xmlhttprequest');\nvar XHR = _dereq_('./polling-xhr');\nvar JSONP = _dereq_('./polling-jsonp');\nvar websocket = _dereq_('./websocket');\n\n/**\n * Export transports.\n */\n\nexports.polling = polling;\nexports.websocket = websocket;\n\n/**\n * Polling transport polymorphic constructor.\n * Decides on xhr vs jsonp based on feature detection.\n *\n * @api private\n */\n\nfunction polling(opts){\n  var xhr;\n  var xd = false;\n  var xs = false;\n  var jsonp = false !== opts.jsonp;\n\n  if (global.location) {\n    var isSSL = 'https:' == location.protocol;\n    var port = location.port;\n\n    // some user agents have empty `location.port`\n    if (!port) {\n      port = isSSL ? 443 : 80;\n    }\n\n    xd = opts.hostname != location.hostname || port != opts.port;\n    xs = opts.secure != isSSL;\n  }\n\n  opts.xdomain = xd;\n  opts.xscheme = xs;\n  xhr = new XMLHttpRequest(opts);\n\n  if ('open' in xhr && !opts.forceJSONP) {\n    return new XHR(opts);\n  } else {\n    if (!jsonp) throw new Error('JSONP disabled');\n    return new JSONP(opts);\n  }\n}\n\n}).call(this,typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./polling-jsonp\":16,\"./polling-xhr\":17,\"./websocket\":19,\"xmlhttprequest\":20}],16:[function(_dereq_,module,exports){\n(function (global){\n\n/**\n * Module requirements.\n */\n\nvar Polling = _dereq_('./polling');\nvar inherit = _dereq_('component-inherit');\n\n/**\n * Module exports.\n */\n\nmodule.exports = JSONPPolling;\n\n/**\n * Cached regular expressions.\n */\n\nvar rNewline = /\\n/g;\nvar rEscapedNewline = /\\\\n/g;\n\n/**\n * Global JSONP callbacks.\n */\n\nvar callbacks;\n\n/**\n * Callbacks count.\n */\n\nvar index = 0;\n\n/**\n * Noop.\n */\n\nfunction empty () { }\n\n/**\n * JSONP Polling constructor.\n *\n * @param {Object} opts.\n * @api public\n */\n\nfunction JSONPPolling (opts) {\n  Polling.call(this, opts);\n\n  this.query = this.query || {};\n\n  // define global callbacks array if not present\n  // we do this here (lazily) to avoid unneeded global pollution\n  if (!callbacks) {\n    // we need to consider multiple engines in the same page\n    if (!global.___eio) global.___eio = [];\n    callbacks = global.___eio;\n  }\n\n  // callback identifier\n  this.index = callbacks.length;\n\n  // add callback to jsonp global\n  var self = this;\n  callbacks.push(function (msg) {\n    self.onData(msg);\n  });\n\n  // append to query string\n  this.query.j = this.index;\n\n  // prevent spurious errors from being emitted when the window is unloaded\n  if (global.document && global.addEventListener) {\n    global.addEventListener('beforeunload', function () {\n      if (self.script) self.script.onerror = empty;\n    }, false);\n  }\n}\n\n/**\n * Inherits from Polling.\n */\n\ninherit(JSONPPolling, Polling);\n\n/*\n * JSONP only supports binary as base64 encoded strings\n */\n\nJSONPPolling.prototype.supportsBinary = false;\n\n/**\n * Closes the socket.\n *\n * @api private\n */\n\nJSONPPolling.prototype.doClose = function () {\n  if (this.script) {\n    this.script.parentNode.removeChild(this.script);\n    this.script = null;\n  }\n\n  if (this.form) {\n    this.form.parentNode.removeChild(this.form);\n    this.form = null;\n    this.iframe = null;\n  }\n\n  Polling.prototype.doClose.call(this);\n};\n\n/**\n * Starts a poll cycle.\n *\n * @api private\n */\n\nJSONPPolling.prototype.doPoll = function () {\n  var self = this;\n  var script = document.createElement('script');\n\n  if (this.script) {\n    this.script.parentNode.removeChild(this.script);\n    this.script = null;\n  }\n\n  script.async = true;\n  script.src = this.uri();\n  script.onerror = function(e){\n    self.onError('jsonp poll error',e);\n  };\n\n  var insertAt = document.getElementsByTagName('script')[0];\n  insertAt.parentNode.insertBefore(script, insertAt);\n  this.script = script;\n\n  var isUAgecko = 'undefined' != typeof navigator && /gecko/i.test(navigator.userAgent);\n  \n  if (isUAgecko) {\n    setTimeout(function () {\n      var iframe = document.createElement('iframe');\n      document.body.appendChild(iframe);\n      document.body.removeChild(iframe);\n    }, 100);\n  }\n};\n\n/**\n * Writes with a hidden iframe.\n *\n * @param {String} data to send\n * @param {Function} called upon flush.\n * @api private\n */\n\nJSONPPolling.prototype.doWrite = function (data, fn) {\n  var self = this;\n\n  if (!this.form) {\n    var form = document.createElement('form');\n    var area = document.createElement('textarea');\n    var id = this.iframeId = 'eio_iframe_' + this.index;\n    var iframe;\n\n    form.className = 'socketio';\n    form.style.position = 'absolute';\n    form.style.top = '-1000px';\n    form.style.left = '-1000px';\n    form.target = id;\n    form.method = 'POST';\n    form.setAttribute('accept-charset', 'utf-8');\n    area.name = 'd';\n    form.appendChild(area);\n    document.body.appendChild(form);\n\n    this.form = form;\n    this.area = area;\n  }\n\n  this.form.action = this.uri();\n\n  function complete () {\n    initIframe();\n    fn();\n  }\n\n  function initIframe () {\n    if (self.iframe) {\n      try {\n        self.form.removeChild(self.iframe);\n      } catch (e) {\n        self.onError('jsonp polling iframe removal error', e);\n      }\n    }\n\n    try {\n      // ie6 dynamic iframes with target=\"\" support (thanks Chris Lambacher)\n      var html = '<iframe src=\"javascript:0\" name=\"'+ self.iframeId +'\">';\n      iframe = document.createElement(html);\n    } catch (e) {\n      iframe = document.createElement('iframe');\n      iframe.name = self.iframeId;\n      iframe.src = 'javascript:0';\n    }\n\n    iframe.id = self.iframeId;\n\n    self.form.appendChild(iframe);\n    self.iframe = iframe;\n  }\n\n  initIframe();\n\n  // escape \\n to prevent it from being converted into \\r\\n by some UAs\n  // double escaping is required for escaped new lines because unescaping of new lines can be done safely on server-side\n  data = data.replace(rEscapedNewline, '\\\\\\n');\n  this.area.value = data.replace(rNewline, '\\\\n');\n\n  try {\n    this.form.submit();\n  } catch(e) {}\n\n  if (this.iframe.attachEvent) {\n    this.iframe.onreadystatechange = function(){\n      if (self.iframe.readyState == 'complete') {\n        complete();\n      }\n    };\n  } else {\n    this.iframe.onload = complete;\n  }\n};\n\n}).call(this,typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./polling\":18,\"component-inherit\":21}],17:[function(_dereq_,module,exports){\n(function (global){\n/**\n * Module requirements.\n */\n\nvar XMLHttpRequest = _dereq_('xmlhttprequest');\nvar Polling = _dereq_('./polling');\nvar Emitter = _dereq_('component-emitter');\nvar inherit = _dereq_('component-inherit');\nvar debug = _dereq_('debug')('engine.io-client:polling-xhr');\n\n/**\n * Module exports.\n */\n\nmodule.exports = XHR;\nmodule.exports.Request = Request;\n\n/**\n * Empty function\n */\n\nfunction empty(){}\n\n/**\n * XHR Polling constructor.\n *\n * @param {Object} opts\n * @api public\n */\n\nfunction XHR(opts){\n  Polling.call(this, opts);\n\n  if (global.location) {\n    var isSSL = 'https:' == location.protocol;\n    var port = location.port;\n\n    // some user agents have empty `location.port`\n    if (!port) {\n      port = isSSL ? 443 : 80;\n    }\n\n    this.xd = opts.hostname != global.location.hostname ||\n      port != opts.port;\n    this.xs = opts.secure != isSSL;\n  }\n}\n\n/**\n * Inherits from Polling.\n */\n\ninherit(XHR, Polling);\n\n/**\n * XHR supports binary\n */\n\nXHR.prototype.supportsBinary = true;\n\n/**\n * Creates a request.\n *\n * @param {String} method\n * @api private\n */\n\nXHR.prototype.request = function(opts){\n  opts = opts || {};\n  opts.uri = this.uri();\n  opts.xd = this.xd;\n  opts.xs = this.xs;\n  opts.agent = this.agent || false;\n  opts.supportsBinary = this.supportsBinary;\n  opts.enablesXDR = this.enablesXDR;\n\n  // SSL options for Node.js client\n  opts.pfx = this.pfx;\n  opts.key = this.key;\n  opts.passphrase = this.passphrase;\n  opts.cert = this.cert;\n  opts.ca = this.ca;\n  opts.ciphers = this.ciphers;\n  opts.rejectUnauthorized = this.rejectUnauthorized;\n\n  return new Request(opts);\n};\n\n/**\n * Sends data.\n *\n * @param {String} data to send.\n * @param {Function} called upon flush.\n * @api private\n */\n\nXHR.prototype.doWrite = function(data, fn){\n  var isBinary = typeof data !== 'string' && data !== undefined;\n  var req = this.request({ method: 'POST', data: data, isBinary: isBinary });\n  var self = this;\n  req.on('success', fn);\n  req.on('error', function(err){\n    self.onError('xhr post error', err);\n  });\n  this.sendXhr = req;\n};\n\n/**\n * Starts a poll cycle.\n *\n * @api private\n */\n\nXHR.prototype.doPoll = function(){\n  debug('xhr poll');\n  var req = this.request();\n  var self = this;\n  req.on('data', function(data){\n    self.onData(data);\n  });\n  req.on('error', function(err){\n    self.onError('xhr poll error', err);\n  });\n  this.pollXhr = req;\n};\n\n/**\n * Request constructor\n *\n * @param {Object} options\n * @api public\n */\n\nfunction Request(opts){\n  this.method = opts.method || 'GET';\n  this.uri = opts.uri;\n  this.xd = !!opts.xd;\n  this.xs = !!opts.xs;\n  this.async = false !== opts.async;\n  this.data = undefined != opts.data ? opts.data : null;\n  this.agent = opts.agent;\n  this.isBinary = opts.isBinary;\n  this.supportsBinary = opts.supportsBinary;\n  this.enablesXDR = opts.enablesXDR;\n\n  // SSL options for Node.js client\n  this.pfx = opts.pfx;\n  this.key = opts.key;\n  this.passphrase = opts.passphrase;\n  this.cert = opts.cert;\n  this.ca = opts.ca;\n  this.ciphers = opts.ciphers;\n  this.rejectUnauthorized = opts.rejectUnauthorized;\n\n  this.create();\n}\n\n/**\n * Mix in `Emitter`.\n */\n\nEmitter(Request.prototype);\n\n/**\n * Creates the XHR object and sends the request.\n *\n * @api private\n */\n\nRequest.prototype.create = function(){\n  var opts = { agent: this.agent, xdomain: this.xd, xscheme: this.xs, enablesXDR: this.enablesXDR };\n\n  // SSL options for Node.js client\n  opts.pfx = this.pfx;\n  opts.key = this.key;\n  opts.passphrase = this.passphrase;\n  opts.cert = this.cert;\n  opts.ca = this.ca;\n  opts.ciphers = this.ciphers;\n  opts.rejectUnauthorized = this.rejectUnauthorized;\n\n  var xhr = this.xhr = new XMLHttpRequest(opts);\n  var self = this;\n\n  try {\n    debug('xhr open %s: %s', this.method, this.uri);\n    xhr.open(this.method, this.uri, this.async);\n    if (this.supportsBinary) {\n      // This has to be done after open because Firefox is stupid\n      // http://stackoverflow.com/questions/13216903/get-binary-data-with-xmlhttprequest-in-a-firefox-extension\n      xhr.responseType = 'arraybuffer';\n    }\n\n    if ('POST' == this.method) {\n      try {\n        if (this.isBinary) {\n          xhr.setRequestHeader('Content-type', 'application/octet-stream');\n        } else {\n          xhr.setRequestHeader('Content-type', 'text/plain;charset=UTF-8');\n        }\n      } catch (e) {}\n    }\n\n    // ie6 check\n    if ('withCredentials' in xhr) {\n      xhr.withCredentials = true;\n    }\n\n    if (this.hasXDR()) {\n      xhr.onload = function(){\n        self.onLoad();\n      };\n      xhr.onerror = function(){\n        self.onError(xhr.responseText);\n      };\n    } else {\n      xhr.onreadystatechange = function(){\n        if (4 != xhr.readyState) return;\n        if (200 == xhr.status || 1223 == xhr.status) {\n          self.onLoad();\n        } else {\n          // make sure the `error` event handler that's user-set\n          // does not throw in the same tick and gets caught here\n          setTimeout(function(){\n            self.onError(xhr.status);\n          }, 0);\n        }\n      };\n    }\n\n    debug('xhr data %s', this.data);\n    xhr.send(this.data);\n  } catch (e) {\n    // Need to defer since .create() is called directly fhrom the constructor\n    // and thus the 'error' event can only be only bound *after* this exception\n    // occurs.  Therefore, also, we cannot throw here at all.\n    setTimeout(function() {\n      self.onError(e);\n    }, 0);\n    return;\n  }\n\n  if (global.document) {\n    this.index = Request.requestsCount++;\n    Request.requests[this.index] = this;\n  }\n};\n\n/**\n * Called upon successful response.\n *\n * @api private\n */\n\nRequest.prototype.onSuccess = function(){\n  this.emit('success');\n  this.cleanup();\n};\n\n/**\n * Called if we have data.\n *\n * @api private\n */\n\nRequest.prototype.onData = function(data){\n  this.emit('data', data);\n  this.onSuccess();\n};\n\n/**\n * Called upon error.\n *\n * @api private\n */\n\nRequest.prototype.onError = function(err){\n  this.emit('error', err);\n  this.cleanup(true);\n};\n\n/**\n * Cleans up house.\n *\n * @api private\n */\n\nRequest.prototype.cleanup = function(fromError){\n  if ('undefined' == typeof this.xhr || null === this.xhr) {\n    return;\n  }\n  // xmlhttprequest\n  if (this.hasXDR()) {\n    this.xhr.onload = this.xhr.onerror = empty;\n  } else {\n    this.xhr.onreadystatechange = empty;\n  }\n\n  if (fromError) {\n    try {\n      this.xhr.abort();\n    } catch(e) {}\n  }\n\n  if (global.document) {\n    delete Request.requests[this.index];\n  }\n\n  this.xhr = null;\n};\n\n/**\n * Called upon load.\n *\n * @api private\n */\n\nRequest.prototype.onLoad = function(){\n  var data;\n  try {\n    var contentType;\n    try {\n      contentType = this.xhr.getResponseHeader('Content-Type').split(';')[0];\n    } catch (e) {}\n    if (contentType === 'application/octet-stream') {\n      data = this.xhr.response;\n    } else {\n      if (!this.supportsBinary) {\n        data = this.xhr.responseText;\n      } else {\n        data = 'ok';\n      }\n    }\n  } catch (e) {\n    this.onError(e);\n  }\n  if (null != data) {\n    this.onData(data);\n  }\n};\n\n/**\n * Check if it has XDomainRequest.\n *\n * @api private\n */\n\nRequest.prototype.hasXDR = function(){\n  return 'undefined' !== typeof global.XDomainRequest && !this.xs && this.enablesXDR;\n};\n\n/**\n * Aborts the request.\n *\n * @api public\n */\n\nRequest.prototype.abort = function(){\n  this.cleanup();\n};\n\n/**\n * Aborts pending requests when unloading the window. This is needed to prevent\n * memory leaks (e.g. when using IE) and to ensure that no spurious error is\n * emitted.\n */\n\nif (global.document) {\n  Request.requestsCount = 0;\n  Request.requests = {};\n  if (global.attachEvent) {\n    global.attachEvent('onunload', unloadHandler);\n  } else if (global.addEventListener) {\n    global.addEventListener('beforeunload', unloadHandler, false);\n  }\n}\n\nfunction unloadHandler() {\n  for (var i in Request.requests) {\n    if (Request.requests.hasOwnProperty(i)) {\n      Request.requests[i].abort();\n    }\n  }\n}\n\n}).call(this,typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./polling\":18,\"component-emitter\":9,\"component-inherit\":21,\"debug\":22,\"xmlhttprequest\":20}],18:[function(_dereq_,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Transport = _dereq_('../transport');\nvar parseqs = _dereq_('parseqs');\nvar parser = _dereq_('engine.io-parser');\nvar inherit = _dereq_('component-inherit');\nvar debug = _dereq_('debug')('engine.io-client:polling');\n\n/**\n * Module exports.\n */\n\nmodule.exports = Polling;\n\n/**\n * Is XHR2 supported?\n */\n\nvar hasXHR2 = (function() {\n  var XMLHttpRequest = _dereq_('xmlhttprequest');\n  var xhr = new XMLHttpRequest({ xdomain: false });\n  return null != xhr.responseType;\n})();\n\n/**\n * Polling interface.\n *\n * @param {Object} opts\n * @api private\n */\n\nfunction Polling(opts){\n  var forceBase64 = (opts && opts.forceBase64);\n  if (!hasXHR2 || forceBase64) {\n    this.supportsBinary = false;\n  }\n  Transport.call(this, opts);\n}\n\n/**\n * Inherits from Transport.\n */\n\ninherit(Polling, Transport);\n\n/**\n * Transport name.\n */\n\nPolling.prototype.name = 'polling';\n\n/**\n * Opens the socket (triggers polling). We write a PING message to determine\n * when the transport is open.\n *\n * @api private\n */\n\nPolling.prototype.doOpen = function(){\n  this.poll();\n};\n\n/**\n * Pauses polling.\n *\n * @param {Function} callback upon buffers are flushed and transport is paused\n * @api private\n */\n\nPolling.prototype.pause = function(onPause){\n  var pending = 0;\n  var self = this;\n\n  this.readyState = 'pausing';\n\n  function pause(){\n    debug('paused');\n    self.readyState = 'paused';\n    onPause();\n  }\n\n  if (this.polling || !this.writable) {\n    var total = 0;\n\n    if (this.polling) {\n      debug('we are currently polling - waiting to pause');\n      total++;\n      this.once('pollComplete', function(){\n        debug('pre-pause polling complete');\n        --total || pause();\n      });\n    }\n\n    if (!this.writable) {\n      debug('we are currently writing - waiting to pause');\n      total++;\n      this.once('drain', function(){\n        debug('pre-pause writing complete');\n        --total || pause();\n      });\n    }\n  } else {\n    pause();\n  }\n};\n\n/**\n * Starts polling cycle.\n *\n * @api public\n */\n\nPolling.prototype.poll = function(){\n  debug('polling');\n  this.polling = true;\n  this.doPoll();\n  this.emit('poll');\n};\n\n/**\n * Overloads onData to detect payloads.\n *\n * @api private\n */\n\nPolling.prototype.onData = function(data){\n  var self = this;\n  debug('polling got data %s', data);\n  var callback = function(packet, index, total) {\n    // if its the first message we consider the transport open\n    if ('opening' == self.readyState) {\n      self.onOpen();\n    }\n\n    // if its a close packet, we close the ongoing requests\n    if ('close' == packet.type) {\n      self.onClose();\n      return false;\n    }\n\n    // otherwise bypass onData and handle the message\n    self.onPacket(packet);\n  };\n\n  // decode payload\n  parser.decodePayload(data, this.socket.binaryType, callback);\n\n  // if an event did not trigger closing\n  if ('closed' != this.readyState) {\n    // if we got data we're not polling\n    this.polling = false;\n    this.emit('pollComplete');\n\n    if ('open' == this.readyState) {\n      this.poll();\n    } else {\n      debug('ignoring poll - transport state \"%s\"', this.readyState);\n    }\n  }\n};\n\n/**\n * For polling, send a close packet.\n *\n * @api private\n */\n\nPolling.prototype.doClose = function(){\n  var self = this;\n\n  function close(){\n    debug('writing close packet');\n    self.write([{ type: 'close' }]);\n  }\n\n  if ('open' == this.readyState) {\n    debug('transport open - closing');\n    close();\n  } else {\n    // in case we're trying to close while\n    // handshaking is in progress (GH-164)\n    debug('transport not open - deferring close');\n    this.once('open', close);\n  }\n};\n\n/**\n * Writes a packets payload.\n *\n * @param {Array} data packets\n * @param {Function} drain callback\n * @api private\n */\n\nPolling.prototype.write = function(packets){\n  var self = this;\n  this.writable = false;\n  var callbackfn = function() {\n    self.writable = true;\n    self.emit('drain');\n  };\n\n  var self = this;\n  parser.encodePayload(packets, this.supportsBinary, function(data) {\n    self.doWrite(data, callbackfn);\n  });\n};\n\n/**\n * Generates uri for connection.\n *\n * @api private\n */\n\nPolling.prototype.uri = function(){\n  var query = this.query || {};\n  var schema = this.secure ? 'https' : 'http';\n  var port = '';\n\n  // cache busting is forced\n  if (false !== this.timestampRequests) {\n    query[this.timestampParam] = +new Date + '-' + Transport.timestamps++;\n  }\n\n  if (!this.supportsBinary && !query.sid) {\n    query.b64 = 1;\n  }\n\n  query = parseqs.encode(query);\n\n  // avoid port if default for schema\n  if (this.port && (('https' == schema && this.port != 443) ||\n     ('http' == schema && this.port != 80))) {\n    port = ':' + this.port;\n  }\n\n  // prepend ? to query\n  if (query.length) {\n    query = '?' + query;\n  }\n\n  return schema + '://' + this.hostname + port + this.path + query;\n};\n\n},{\"../transport\":14,\"component-inherit\":21,\"debug\":22,\"engine.io-parser\":25,\"parseqs\":33,\"xmlhttprequest\":20}],19:[function(_dereq_,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Transport = _dereq_('../transport');\nvar parser = _dereq_('engine.io-parser');\nvar parseqs = _dereq_('parseqs');\nvar inherit = _dereq_('component-inherit');\nvar debug = _dereq_('debug')('engine.io-client:websocket');\n\n/**\n * `ws` exposes a WebSocket-compatible interface in\n * Node, or the `WebSocket` or `MozWebSocket` globals\n * in the browser.\n */\n\nvar WebSocket = _dereq_('ws');\n\n/**\n * Module exports.\n */\n\nmodule.exports = WS;\n\n/**\n * WebSocket transport constructor.\n *\n * @api {Object} connection options\n * @api public\n */\n\nfunction WS(opts){\n  var forceBase64 = (opts && opts.forceBase64);\n  if (forceBase64) {\n    this.supportsBinary = false;\n  }\n  Transport.call(this, opts);\n}\n\n/**\n * Inherits from Transport.\n */\n\ninherit(WS, Transport);\n\n/**\n * Transport name.\n *\n * @api public\n */\n\nWS.prototype.name = 'websocket';\n\n/*\n * WebSockets support binary\n */\n\nWS.prototype.supportsBinary = true;\n\n/**\n * Opens socket.\n *\n * @api private\n */\n\nWS.prototype.doOpen = function(){\n  if (!this.check()) {\n    // let probe timeout\n    return;\n  }\n\n  var self = this;\n  var uri = this.uri();\n  var protocols = void(0);\n  var opts = { agent: this.agent };\n\n  // SSL options for Node.js client\n  opts.pfx = this.pfx;\n  opts.key = this.key;\n  opts.passphrase = this.passphrase;\n  opts.cert = this.cert;\n  opts.ca = this.ca;\n  opts.ciphers = this.ciphers;\n  opts.rejectUnauthorized = this.rejectUnauthorized;\n\n  this.ws = new WebSocket(uri, protocols, opts);\n\n  if (this.ws.binaryType === undefined) {\n    this.supportsBinary = false;\n  }\n\n  this.ws.binaryType = 'arraybuffer';\n  this.addEventListeners();\n};\n\n/**\n * Adds event listeners to the socket\n *\n * @api private\n */\n\nWS.prototype.addEventListeners = function(){\n  var self = this;\n\n  this.ws.onopen = function(){\n    self.onOpen();\n  };\n  this.ws.onclose = function(){\n    self.onClose();\n  };\n  this.ws.onmessage = function(ev){\n    self.onData(ev.data);\n  };\n  this.ws.onerror = function(e){\n    self.onError('websocket error', e);\n  };\n};\n\n/**\n * Override `onData` to use a timer on iOS.\n * See: https://gist.github.com/mloughran/2052006\n *\n * @api private\n */\n\nif ('undefined' != typeof navigator\n  && /iPad|iPhone|iPod/i.test(navigator.userAgent)) {\n  WS.prototype.onData = function(data){\n    var self = this;\n    setTimeout(function(){\n      Transport.prototype.onData.call(self, data);\n    }, 0);\n  };\n}\n\n/**\n * Writes data to socket.\n *\n * @param {Array} array of packets.\n * @api private\n */\n\nWS.prototype.write = function(packets){\n  var self = this;\n  this.writable = false;\n  // encodePacket efficient as it uses WS framing\n  // no need for encodePayload\n  for (var i = 0, l = packets.length; i < l; i++) {\n    parser.encodePacket(packets[i], this.supportsBinary, function(data) {\n      //Sometimes the websocket has already been closed but the browser didn't\n      //have a chance of informing us about it yet, in that case send will\n      //throw an error\n      try {\n        self.ws.send(data);\n      } catch (e){\n        debug('websocket closed before onclose event');\n      }\n    });\n  }\n\n  function ondrain() {\n    self.writable = true;\n    self.emit('drain');\n  }\n  // fake drain\n  // defer to next tick to allow Socket to clear writeBuffer\n  setTimeout(ondrain, 0);\n};\n\n/**\n * Called upon close\n *\n * @api private\n */\n\nWS.prototype.onClose = function(){\n  Transport.prototype.onClose.call(this);\n};\n\n/**\n * Closes socket.\n *\n * @api private\n */\n\nWS.prototype.doClose = function(){\n  if (typeof this.ws !== 'undefined') {\n    this.ws.close();\n  }\n};\n\n/**\n * Generates uri for connection.\n *\n * @api private\n */\n\nWS.prototype.uri = function(){\n  var query = this.query || {};\n  var schema = this.secure ? 'wss' : 'ws';\n  var port = '';\n\n  // avoid port if default for schema\n  if (this.port && (('wss' == schema && this.port != 443)\n    || ('ws' == schema && this.port != 80))) {\n    port = ':' + this.port;\n  }\n\n  // append timestamp to URI\n  if (this.timestampRequests) {\n    query[this.timestampParam] = +new Date;\n  }\n\n  // communicate binary support capabilities\n  if (!this.supportsBinary) {\n    query.b64 = 1;\n  }\n\n  query = parseqs.encode(query);\n\n  // prepend ? to query\n  if (query.length) {\n    query = '?' + query;\n  }\n\n  return schema + '://' + this.hostname + port + this.path + query;\n};\n\n/**\n * Feature detection for WebSocket.\n *\n * @return {Boolean} whether this transport is available.\n * @api public\n */\n\nWS.prototype.check = function(){\n  return !!WebSocket && !('__initialize' in WebSocket && this.name === WS.prototype.name);\n};\n\n},{\"../transport\":14,\"component-inherit\":21,\"debug\":22,\"engine.io-parser\":25,\"parseqs\":33,\"ws\":35}],20:[function(_dereq_,module,exports){\n// browser shim for xmlhttprequest module\nvar hasCORS = _dereq_('has-cors');\n\nmodule.exports = function(opts) {\n  var xdomain = opts.xdomain;\n\n  // scheme must be same when usign XDomainRequest\n  // http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx\n  var xscheme = opts.xscheme;\n\n  // XDomainRequest has a flow of not sending cookie, therefore it should be disabled as a default.\n  // https://github.com/Automattic/engine.io-client/pull/217\n  var enablesXDR = opts.enablesXDR;\n\n  // XMLHttpRequest can be disabled on IE\n  try {\n    if ('undefined' != typeof XMLHttpRequest && (!xdomain || hasCORS)) {\n      return new XMLHttpRequest();\n    }\n  } catch (e) { }\n\n  // Use XDomainRequest for IE8 if enablesXDR is true\n  // because loading bar keeps flashing when using jsonp-polling\n  // https://github.com/yujiosaka/socke.io-ie8-loading-example\n  try {\n    if ('undefined' != typeof XDomainRequest && !xscheme && enablesXDR) {\n      return new XDomainRequest();\n    }\n  } catch (e) { }\n\n  if (!xdomain) {\n    try {\n      return new ActiveXObject('Microsoft.XMLHTTP');\n    } catch(e) { }\n  }\n}\n\n},{\"has-cors\":38}],21:[function(_dereq_,module,exports){\n\nmodule.exports = function(a, b){\n  var fn = function(){};\n  fn.prototype = b.prototype;\n  a.prototype = new fn;\n  a.prototype.constructor = a;\n};\n},{}],22:[function(_dereq_,module,exports){\n\n/**\n * This is the web browser implementation of `debug()`.\n *\n * Expose `debug()` as the module.\n */\n\nexports = module.exports = _dereq_('./debug');\nexports.log = log;\nexports.formatArgs = formatArgs;\nexports.save = save;\nexports.load = load;\nexports.useColors = useColors;\n\n/**\n * Colors.\n */\n\nexports.colors = [\n  'lightseagreen',\n  'forestgreen',\n  'goldenrod',\n  'dodgerblue',\n  'darkorchid',\n  'crimson'\n];\n\n/**\n * Currently only WebKit-based Web Inspectors, Firefox >= v31,\n * and the Firebug extension (any Firefox version) are known\n * to support \"%c\" CSS customizations.\n *\n * TODO: add a `localStorage` variable to explicitly enable/disable colors\n */\n\nfunction useColors() {\n  // is webkit? http://stackoverflow.com/a/16459606/376773\n  return ('WebkitAppearance' in document.documentElement.style) ||\n    // is firebug? http://stackoverflow.com/a/398120/376773\n    (window.console && (console.firebug || (console.exception && console.table))) ||\n    // is firefox >= v31?\n    // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages\n    (navigator.userAgent.toLowerCase().match(/firefox\\/(\\d+)/) && parseInt(RegExp.$1, 10) >= 31);\n}\n\n/**\n * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.\n */\n\nexports.formatters.j = function(v) {\n  return JSON.stringify(v);\n};\n\n\n/**\n * Colorize log arguments if enabled.\n *\n * @api public\n */\n\nfunction formatArgs() {\n  var args = arguments;\n  var useColors = this.useColors;\n\n  args[0] = (useColors ? '%c' : '')\n    + this.namespace\n    + (useColors ? ' %c' : ' ')\n    + args[0]\n    + (useColors ? '%c ' : ' ')\n    + '+' + exports.humanize(this.diff);\n\n  if (!useColors) return args;\n\n  var c = 'color: ' + this.color;\n  args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1));\n\n  // the final \"%c\" is somewhat tricky, because there could be other\n  // arguments passed either before or after the %c, so we need to\n  // figure out the correct index to insert the CSS into\n  var index = 0;\n  var lastC = 0;\n  args[0].replace(/%[a-z%]/g, function(match) {\n    if ('%' === match) return;\n    index++;\n    if ('%c' === match) {\n      // we only are interested in the *last* %c\n      // (the user may have provided their own)\n      lastC = index;\n    }\n  });\n\n  args.splice(lastC, 0, c);\n  return args;\n}\n\n/**\n * Invokes `console.log()` when available.\n * No-op when `console.log` is not a \"function\".\n *\n * @api public\n */\n\nfunction log() {\n  // This hackery is required for IE8,\n  // where the `console.log` function doesn't have 'apply'\n  return 'object' == typeof console\n    && 'function' == typeof console.log\n    && Function.prototype.apply.call(console.log, console, arguments);\n}\n\n/**\n * Save `namespaces`.\n *\n * @param {String} namespaces\n * @api private\n */\n\nfunction save(namespaces) {\n  try {\n    if (null == namespaces) {\n      localStorage.removeItem('debug');\n    } else {\n      localStorage.debug = namespaces;\n    }\n  } catch(e) {}\n}\n\n/**\n * Load `namespaces`.\n *\n * @return {String} returns the previously persisted debug modes\n * @api private\n */\n\nfunction load() {\n  var r;\n  try {\n    r = localStorage.debug;\n  } catch(e) {}\n  return r;\n}\n\n/**\n * Enable namespaces listed in `localStorage.debug` initially.\n */\n\nexports.enable(load());\n\n},{\"./debug\":23}],23:[function(_dereq_,module,exports){\n\n/**\n * This is the common logic for both the Node.js and web browser\n * implementations of `debug()`.\n *\n * Expose `debug()` as the module.\n */\n\nexports = module.exports = debug;\nexports.coerce = coerce;\nexports.disable = disable;\nexports.enable = enable;\nexports.enabled = enabled;\nexports.humanize = _dereq_('ms');\n\n/**\n * The currently active debug mode names, and names to skip.\n */\n\nexports.names = [];\nexports.skips = [];\n\n/**\n * Map of special \"%n\" handling functions, for the debug \"format\" argument.\n *\n * Valid key names are a single, lowercased letter, i.e. \"n\".\n */\n\nexports.formatters = {};\n\n/**\n * Previously assigned color.\n */\n\nvar prevColor = 0;\n\n/**\n * Previous log timestamp.\n */\n\nvar prevTime;\n\n/**\n * Select a color.\n *\n * @return {Number}\n * @api private\n */\n\nfunction selectColor() {\n  return exports.colors[prevColor++ % exports.colors.length];\n}\n\n/**\n * Create a debugger with the given `namespace`.\n *\n * @param {String} namespace\n * @return {Function}\n * @api public\n */\n\nfunction debug(namespace) {\n\n  // define the `disabled` version\n  function disabled() {\n  }\n  disabled.enabled = false;\n\n  // define the `enabled` version\n  function enabled() {\n\n    var self = enabled;\n\n    // set `diff` timestamp\n    var curr = +new Date();\n    var ms = curr - (prevTime || curr);\n    self.diff = ms;\n    self.prev = prevTime;\n    self.curr = curr;\n    prevTime = curr;\n\n    // add the `color` if not set\n    if (null == self.useColors) self.useColors = exports.useColors();\n    if (null == self.color && self.useColors) self.color = selectColor();\n\n    var args = Array.prototype.slice.call(arguments);\n\n    args[0] = exports.coerce(args[0]);\n\n    if ('string' !== typeof args[0]) {\n      // anything else let's inspect with %o\n      args = ['%o'].concat(args);\n    }\n\n    // apply any `formatters` transformations\n    var index = 0;\n    args[0] = args[0].replace(/%([a-z%])/g, function(match, format) {\n      // if we encounter an escaped % then don't increase the array index\n      if (match === '%') return match;\n      index++;\n      var formatter = exports.formatters[format];\n      if ('function' === typeof formatter) {\n        var val = args[index];\n        match = formatter.call(self, val);\n\n        // now we need to remove `args[index]` since it's inlined in the `format`\n        args.splice(index, 1);\n        index--;\n      }\n      return match;\n    });\n\n    if ('function' === typeof exports.formatArgs) {\n      args = exports.formatArgs.apply(self, args);\n    }\n    var logFn = enabled.log || exports.log || console.log.bind(console);\n    logFn.apply(self, args);\n  }\n  enabled.enabled = true;\n\n  var fn = exports.enabled(namespace) ? enabled : disabled;\n\n  fn.namespace = namespace;\n\n  return fn;\n}\n\n/**\n * Enables a debug mode by namespaces. This can include modes\n * separated by a colon and wildcards.\n *\n * @param {String} namespaces\n * @api public\n */\n\nfunction enable(namespaces) {\n  exports.save(namespaces);\n\n  var split = (namespaces || '').split(/[\\s,]+/);\n  var len = split.length;\n\n  for (var i = 0; i < len; i++) {\n    if (!split[i]) continue; // ignore empty strings\n    namespaces = split[i].replace(/\\*/g, '.*?');\n    if (namespaces[0] === '-') {\n      exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));\n    } else {\n      exports.names.push(new RegExp('^' + namespaces + '$'));\n    }\n  }\n}\n\n/**\n * Disable debug output.\n *\n * @api public\n */\n\nfunction disable() {\n  exports.enable('');\n}\n\n/**\n * Returns true if the given mode name is enabled, false otherwise.\n *\n * @param {String} name\n * @return {Boolean}\n * @api public\n */\n\nfunction enabled(name) {\n  var i, len;\n  for (i = 0, len = exports.skips.length; i < len; i++) {\n    if (exports.skips[i].test(name)) {\n      return false;\n    }\n  }\n  for (i = 0, len = exports.names.length; i < len; i++) {\n    if (exports.names[i].test(name)) {\n      return true;\n    }\n  }\n  return false;\n}\n\n/**\n * Coerce `val`.\n *\n * @param {Mixed} val\n * @return {Mixed}\n * @api private\n */\n\nfunction coerce(val) {\n  if (val instanceof Error) return val.stack || val.message;\n  return val;\n}\n\n},{\"ms\":24}],24:[function(_dereq_,module,exports){\n/**\n * Helpers.\n */\n\nvar s = 1000;\nvar m = s * 60;\nvar h = m * 60;\nvar d = h * 24;\nvar y = d * 365.25;\n\n/**\n * Parse or format the given `val`.\n *\n * Options:\n *\n *  - `long` verbose formatting [false]\n *\n * @param {String|Number} val\n * @param {Object} options\n * @return {String|Number}\n * @api public\n */\n\nmodule.exports = function(val, options){\n  options = options || {};\n  if ('string' == typeof val) return parse(val);\n  return options.long\n    ? long(val)\n    : short(val);\n};\n\n/**\n * Parse the given `str` and return milliseconds.\n *\n * @param {String} str\n * @return {Number}\n * @api private\n */\n\nfunction parse(str) {\n  var match = /^((?:\\d+)?\\.?\\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i.exec(str);\n  if (!match) return;\n  var n = parseFloat(match[1]);\n  var type = (match[2] || 'ms').toLowerCase();\n  switch (type) {\n    case 'years':\n    case 'year':\n    case 'y':\n      return n * y;\n    case 'days':\n    case 'day':\n    case 'd':\n      return n * d;\n    case 'hours':\n    case 'hour':\n    case 'h':\n      return n * h;\n    case 'minutes':\n    case 'minute':\n    case 'm':\n      return n * m;\n    case 'seconds':\n    case 'second':\n    case 's':\n      return n * s;\n    case 'ms':\n      return n;\n  }\n}\n\n/**\n * Short format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction short(ms) {\n  if (ms >= d) return Math.round(ms / d) + 'd';\n  if (ms >= h) return Math.round(ms / h) + 'h';\n  if (ms >= m) return Math.round(ms / m) + 'm';\n  if (ms >= s) return Math.round(ms / s) + 's';\n  return ms + 'ms';\n}\n\n/**\n * Long format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction long(ms) {\n  return plural(ms, d, 'day')\n    || plural(ms, h, 'hour')\n    || plural(ms, m, 'minute')\n    || plural(ms, s, 'second')\n    || ms + ' ms';\n}\n\n/**\n * Pluralization helper.\n */\n\nfunction plural(ms, n, name) {\n  if (ms < n) return;\n  if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name;\n  return Math.ceil(ms / n) + ' ' + name + 's';\n}\n\n},{}],25:[function(_dereq_,module,exports){\n(function (global){\n/**\n * Module dependencies.\n */\n\nvar keys = _dereq_('./keys');\nvar hasBinary = _dereq_('has-binary');\nvar sliceBuffer = _dereq_('arraybuffer.slice');\nvar base64encoder = _dereq_('base64-arraybuffer');\nvar after = _dereq_('after');\nvar utf8 = _dereq_('utf8');\n\n/**\n * Check if we are running an android browser. That requires us to use\n * ArrayBuffer with polling transports...\n *\n * http://ghinda.net/jpeg-blob-ajax-android/\n */\n\nvar isAndroid = navigator.userAgent.match(/Android/i);\n\n/**\n * Check if we are running in PhantomJS.\n * Uploading a Blob with PhantomJS does not work correctly, as reported here:\n * https://github.com/ariya/phantomjs/issues/11395\n * @type boolean\n */\nvar isPhantomJS = /PhantomJS/i.test(navigator.userAgent);\n\n/**\n * When true, avoids using Blobs to encode payloads.\n * @type boolean\n */\nvar dontSendBlobs = isAndroid || isPhantomJS;\n\n/**\n * Current protocol version.\n */\n\nexports.protocol = 3;\n\n/**\n * Packet types.\n */\n\nvar packets = exports.packets = {\n    open:     0    // non-ws\n  , close:    1    // non-ws\n  , ping:     2\n  , pong:     3\n  , message:  4\n  , upgrade:  5\n  , noop:     6\n};\n\nvar packetslist = keys(packets);\n\n/**\n * Premade error packet.\n */\n\nvar err = { type: 'error', data: 'parser error' };\n\n/**\n * Create a blob api even for blob builder when vendor prefixes exist\n */\n\nvar Blob = _dereq_('blob');\n\n/**\n * Encodes a packet.\n *\n *     <packet type id> [ <data> ]\n *\n * Example:\n *\n *     5hello world\n *     3\n *     4\n *\n * Binary is encoded in an identical principle\n *\n * @api private\n */\n\nexports.encodePacket = function (packet, supportsBinary, utf8encode, callback) {\n  if ('function' == typeof supportsBinary) {\n    callback = supportsBinary;\n    supportsBinary = false;\n  }\n\n  if ('function' == typeof utf8encode) {\n    callback = utf8encode;\n    utf8encode = null;\n  }\n\n  var data = (packet.data === undefined)\n    ? undefined\n    : packet.data.buffer || packet.data;\n\n  if (global.ArrayBuffer && data instanceof ArrayBuffer) {\n    return encodeArrayBuffer(packet, supportsBinary, callback);\n  } else if (Blob && data instanceof global.Blob) {\n    return encodeBlob(packet, supportsBinary, callback);\n  }\n\n  // might be an object with { base64: true, data: dataAsBase64String }\n  if (data && data.base64) {\n    return encodeBase64Object(packet, callback);\n  }\n\n  // Sending data as a utf-8 string\n  var encoded = packets[packet.type];\n\n  // data fragment is optional\n  if (undefined !== packet.data) {\n    encoded += utf8encode ? utf8.encode(String(packet.data)) : String(packet.data);\n  }\n\n  return callback('' + encoded);\n\n};\n\nfunction encodeBase64Object(packet, callback) {\n  // packet data is an object { base64: true, data: dataAsBase64String }\n  var message = 'b' + exports.packets[packet.type] + packet.data.data;\n  return callback(message);\n}\n\n/**\n * Encode packet helpers for binary types\n */\n\nfunction encodeArrayBuffer(packet, supportsBinary, callback) {\n  if (!supportsBinary) {\n    return exports.encodeBase64Packet(packet, callback);\n  }\n\n  var data = packet.data;\n  var contentArray = new Uint8Array(data);\n  var resultBuffer = new Uint8Array(1 + data.byteLength);\n\n  resultBuffer[0] = packets[packet.type];\n  for (var i = 0; i < contentArray.length; i++) {\n    resultBuffer[i+1] = contentArray[i];\n  }\n\n  return callback(resultBuffer.buffer);\n}\n\nfunction encodeBlobAsArrayBuffer(packet, supportsBinary, callback) {\n  if (!supportsBinary) {\n    return exports.encodeBase64Packet(packet, callback);\n  }\n\n  var fr = new FileReader();\n  fr.onload = function() {\n    packet.data = fr.result;\n    exports.encodePacket(packet, supportsBinary, true, callback);\n  };\n  return fr.readAsArrayBuffer(packet.data);\n}\n\nfunction encodeBlob(packet, supportsBinary, callback) {\n  if (!supportsBinary) {\n    return exports.encodeBase64Packet(packet, callback);\n  }\n\n  if (dontSendBlobs) {\n    return encodeBlobAsArrayBuffer(packet, supportsBinary, callback);\n  }\n\n  var length = new Uint8Array(1);\n  length[0] = packets[packet.type];\n  var blob = new Blob([length.buffer, packet.data]);\n\n  return callback(blob);\n}\n\n/**\n * Encodes a packet with binary data in a base64 string\n *\n * @param {Object} packet, has `type` and `data`\n * @return {String} base64 encoded message\n */\n\nexports.encodeBase64Packet = function(packet, callback) {\n  var message = 'b' + exports.packets[packet.type];\n  if (Blob && packet.data instanceof Blob) {\n    var fr = new FileReader();\n    fr.onload = function() {\n      var b64 = fr.result.split(',')[1];\n      callback(message + b64);\n    };\n    return fr.readAsDataURL(packet.data);\n  }\n\n  var b64data;\n  try {\n    b64data = String.fromCharCode.apply(null, new Uint8Array(packet.data));\n  } catch (e) {\n    // iPhone Safari doesn't let you apply with typed arrays\n    var typed = new Uint8Array(packet.data);\n    var basic = new Array(typed.length);\n    for (var i = 0; i < typed.length; i++) {\n      basic[i] = typed[i];\n    }\n    b64data = String.fromCharCode.apply(null, basic);\n  }\n  message += global.btoa(b64data);\n  return callback(message);\n};\n\n/**\n * Decodes a packet. Changes format to Blob if requested.\n *\n * @return {Object} with `type` and `data` (if any)\n * @api private\n */\n\nexports.decodePacket = function (data, binaryType, utf8decode) {\n  // String data\n  if (typeof data == 'string' || data === undefined) {\n    if (data.charAt(0) == 'b') {\n      return exports.decodeBase64Packet(data.substr(1), binaryType);\n    }\n\n    if (utf8decode) {\n      try {\n        data = utf8.decode(data);\n      } catch (e) {\n        return err;\n      }\n    }\n    var type = data.charAt(0);\n\n    if (Number(type) != type || !packetslist[type]) {\n      return err;\n    }\n\n    if (data.length > 1) {\n      return { type: packetslist[type], data: data.substring(1) };\n    } else {\n      return { type: packetslist[type] };\n    }\n  }\n\n  var asArray = new Uint8Array(data);\n  var type = asArray[0];\n  var rest = sliceBuffer(data, 1);\n  if (Blob && binaryType === 'blob') {\n    rest = new Blob([rest]);\n  }\n  return { type: packetslist[type], data: rest };\n};\n\n/**\n * Decodes a packet encoded in a base64 string\n *\n * @param {String} base64 encoded message\n * @return {Object} with `type` and `data` (if any)\n */\n\nexports.decodeBase64Packet = function(msg, binaryType) {\n  var type = packetslist[msg.charAt(0)];\n  if (!global.ArrayBuffer) {\n    return { type: type, data: { base64: true, data: msg.substr(1) } };\n  }\n\n  var data = base64encoder.decode(msg.substr(1));\n\n  if (binaryType === 'blob' && Blob) {\n    data = new Blob([data]);\n  }\n\n  return { type: type, data: data };\n};\n\n/**\n * Encodes multiple messages (payload).\n *\n *     <length>:data\n *\n * Example:\n *\n *     11:hello world2:hi\n *\n * If any contents are binary, they will be encoded as base64 strings. Base64\n * encoded strings are marked with a b before the length specifier\n *\n * @param {Array} packets\n * @api private\n */\n\nexports.encodePayload = function (packets, supportsBinary, callback) {\n  if (typeof supportsBinary == 'function') {\n    callback = supportsBinary;\n    supportsBinary = null;\n  }\n\n  var isBinary = hasBinary(packets);\n\n  if (supportsBinary && isBinary) {\n    if (Blob && !dontSendBlobs) {\n      return exports.encodePayloadAsBlob(packets, callback);\n    }\n\n    return exports.encodePayloadAsArrayBuffer(packets, callback);\n  }\n\n  if (!packets.length) {\n    return callback('0:');\n  }\n\n  function setLengthHeader(message) {\n    return message.length + ':' + message;\n  }\n\n  function encodeOne(packet, doneCallback) {\n    exports.encodePacket(packet, !isBinary ? false : supportsBinary, true, function(message) {\n      doneCallback(null, setLengthHeader(message));\n    });\n  }\n\n  map(packets, encodeOne, function(err, results) {\n    return callback(results.join(''));\n  });\n};\n\n/**\n * Async array map using after\n */\n\nfunction map(ary, each, done) {\n  var result = new Array(ary.length);\n  var next = after(ary.length, done);\n\n  var eachWithIndex = function(i, el, cb) {\n    each(el, function(error, msg) {\n      result[i] = msg;\n      cb(error, result);\n    });\n  };\n\n  for (var i = 0; i < ary.length; i++) {\n    eachWithIndex(i, ary[i], next);\n  }\n}\n\n/*\n * Decodes data when a payload is maybe expected. Possible binary contents are\n * decoded from their base64 representation\n *\n * @param {String} data, callback method\n * @api public\n */\n\nexports.decodePayload = function (data, binaryType, callback) {\n  if (typeof data != 'string') {\n    return exports.decodePayloadAsBinary(data, binaryType, callback);\n  }\n\n  if (typeof binaryType === 'function') {\n    callback = binaryType;\n    binaryType = null;\n  }\n\n  var packet;\n  if (data == '') {\n    // parser error - ignoring payload\n    return callback(err, 0, 1);\n  }\n\n  var length = ''\n    , n, msg;\n\n  for (var i = 0, l = data.length; i < l; i++) {\n    var chr = data.charAt(i);\n\n    if (':' != chr) {\n      length += chr;\n    } else {\n      if ('' == length || (length != (n = Number(length)))) {\n        // parser error - ignoring payload\n        return callback(err, 0, 1);\n      }\n\n      msg = data.substr(i + 1, n);\n\n      if (length != msg.length) {\n        // parser error - ignoring payload\n        return callback(err, 0, 1);\n      }\n\n      if (msg.length) {\n        packet = exports.decodePacket(msg, binaryType, true);\n\n        if (err.type == packet.type && err.data == packet.data) {\n          // parser error in individual packet - ignoring payload\n          return callback(err, 0, 1);\n        }\n\n        var ret = callback(packet, i + n, l);\n        if (false === ret) return;\n      }\n\n      // advance cursor\n      i += n;\n      length = '';\n    }\n  }\n\n  if (length != '') {\n    // parser error - ignoring payload\n    return callback(err, 0, 1);\n  }\n\n};\n\n/**\n * Encodes multiple messages (payload) as binary.\n *\n * <1 = binary, 0 = string><number from 0-9><number from 0-9>[...]<number\n * 255><data>\n *\n * Example:\n * 1 3 255 1 2 3, if the binary contents are interpreted as 8 bit integers\n *\n * @param {Array} packets\n * @return {ArrayBuffer} encoded payload\n * @api private\n */\n\nexports.encodePayloadAsArrayBuffer = function(packets, callback) {\n  if (!packets.length) {\n    return callback(new ArrayBuffer(0));\n  }\n\n  function encodeOne(packet, doneCallback) {\n    exports.encodePacket(packet, true, true, function(data) {\n      return doneCallback(null, data);\n    });\n  }\n\n  map(packets, encodeOne, function(err, encodedPackets) {\n    var totalLength = encodedPackets.reduce(function(acc, p) {\n      var len;\n      if (typeof p === 'string'){\n        len = p.length;\n      } else {\n        len = p.byteLength;\n      }\n      return acc + len.toString().length + len + 2; // string/binary identifier + separator = 2\n    }, 0);\n\n    var resultArray = new Uint8Array(totalLength);\n\n    var bufferIndex = 0;\n    encodedPackets.forEach(function(p) {\n      var isString = typeof p === 'string';\n      var ab = p;\n      if (isString) {\n        var view = new Uint8Array(p.length);\n        for (var i = 0; i < p.length; i++) {\n          view[i] = p.charCodeAt(i);\n        }\n        ab = view.buffer;\n      }\n\n      if (isString) { // not true binary\n        resultArray[bufferIndex++] = 0;\n      } else { // true binary\n        resultArray[bufferIndex++] = 1;\n      }\n\n      var lenStr = ab.byteLength.toString();\n      for (var i = 0; i < lenStr.length; i++) {\n        resultArray[bufferIndex++] = parseInt(lenStr[i]);\n      }\n      resultArray[bufferIndex++] = 255;\n\n      var view = new Uint8Array(ab);\n      for (var i = 0; i < view.length; i++) {\n        resultArray[bufferIndex++] = view[i];\n      }\n    });\n\n    return callback(resultArray.buffer);\n  });\n};\n\n/**\n * Encode as Blob\n */\n\nexports.encodePayloadAsBlob = function(packets, callback) {\n  function encodeOne(packet, doneCallback) {\n    exports.encodePacket(packet, true, true, function(encoded) {\n      var binaryIdentifier = new Uint8Array(1);\n      binaryIdentifier[0] = 1;\n      if (typeof encoded === 'string') {\n        var view = new Uint8Array(encoded.length);\n        for (var i = 0; i < encoded.length; i++) {\n          view[i] = encoded.charCodeAt(i);\n        }\n        encoded = view.buffer;\n        binaryIdentifier[0] = 0;\n      }\n\n      var len = (encoded instanceof ArrayBuffer)\n        ? encoded.byteLength\n        : encoded.size;\n\n      var lenStr = len.toString();\n      var lengthAry = new Uint8Array(lenStr.length + 1);\n      for (var i = 0; i < lenStr.length; i++) {\n        lengthAry[i] = parseInt(lenStr[i]);\n      }\n      lengthAry[lenStr.length] = 255;\n\n      if (Blob) {\n        var blob = new Blob([binaryIdentifier.buffer, lengthAry.buffer, encoded]);\n        doneCallback(null, blob);\n      }\n    });\n  }\n\n  map(packets, encodeOne, function(err, results) {\n    return callback(new Blob(results));\n  });\n};\n\n/*\n * Decodes data when a payload is maybe expected. Strings are decoded by\n * interpreting each byte as a key code for entries marked to start with 0. See\n * description of encodePayloadAsBinary\n *\n * @param {ArrayBuffer} data, callback method\n * @api public\n */\n\nexports.decodePayloadAsBinary = function (data, binaryType, callback) {\n  if (typeof binaryType === 'function') {\n    callback = binaryType;\n    binaryType = null;\n  }\n\n  var bufferTail = data;\n  var buffers = [];\n\n  var numberTooLong = false;\n  while (bufferTail.byteLength > 0) {\n    var tailArray = new Uint8Array(bufferTail);\n    var isString = tailArray[0] === 0;\n    var msgLength = '';\n\n    for (var i = 1; ; i++) {\n      if (tailArray[i] == 255) break;\n\n      if (msgLength.length > 310) {\n        numberTooLong = true;\n        break;\n      }\n\n      msgLength += tailArray[i];\n    }\n\n    if(numberTooLong) return callback(err, 0, 1);\n\n    bufferTail = sliceBuffer(bufferTail, 2 + msgLength.length);\n    msgLength = parseInt(msgLength);\n\n    var msg = sliceBuffer(bufferTail, 0, msgLength);\n    if (isString) {\n      try {\n        msg = String.fromCharCode.apply(null, new Uint8Array(msg));\n      } catch (e) {\n        // iPhone Safari doesn't let you apply to typed arrays\n        var typed = new Uint8Array(msg);\n        msg = '';\n        for (var i = 0; i < typed.length; i++) {\n          msg += String.fromCharCode(typed[i]);\n        }\n      }\n    }\n\n    buffers.push(msg);\n    bufferTail = sliceBuffer(bufferTail, msgLength);\n  }\n\n  var total = buffers.length;\n  buffers.forEach(function(buffer, i) {\n    callback(exports.decodePacket(buffer, binaryType, true), i, total);\n  });\n};\n\n}).call(this,typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./keys\":26,\"after\":27,\"arraybuffer.slice\":28,\"base64-arraybuffer\":29,\"blob\":30,\"has-binary\":36,\"utf8\":31}],26:[function(_dereq_,module,exports){\n\n/**\n * Gets the keys for an object.\n *\n * @return {Array} keys\n * @api private\n */\n\nmodule.exports = Object.keys || function keys (obj){\n  var arr = [];\n  var has = Object.prototype.hasOwnProperty;\n\n  for (var i in obj) {\n    if (has.call(obj, i)) {\n      arr.push(i);\n    }\n  }\n  return arr;\n};\n\n},{}],27:[function(_dereq_,module,exports){\nmodule.exports = after\n\nfunction after(count, callback, err_cb) {\n    var bail = false\n    err_cb = err_cb || noop\n    proxy.count = count\n\n    return (count === 0) ? callback() : proxy\n\n    function proxy(err, result) {\n        if (proxy.count <= 0) {\n            throw new Error('after called too many times')\n        }\n        --proxy.count\n\n        // after first error, rest are passed to err_cb\n        if (err) {\n            bail = true\n            callback(err)\n            // future error callbacks will go to error handler\n            callback = err_cb\n        } else if (proxy.count === 0 && !bail) {\n            callback(null, result)\n        }\n    }\n}\n\nfunction noop() {}\n\n},{}],28:[function(_dereq_,module,exports){\n/**\n * An abstraction for slicing an arraybuffer even when\n * ArrayBuffer.prototype.slice is not supported\n *\n * @api public\n */\n\nmodule.exports = function(arraybuffer, start, end) {\n  var bytes = arraybuffer.byteLength;\n  start = start || 0;\n  end = end || bytes;\n\n  if (arraybuffer.slice) { return arraybuffer.slice(start, end); }\n\n  if (start < 0) { start += bytes; }\n  if (end < 0) { end += bytes; }\n  if (end > bytes) { end = bytes; }\n\n  if (start >= bytes || start >= end || bytes === 0) {\n    return new ArrayBuffer(0);\n  }\n\n  var abv = new Uint8Array(arraybuffer);\n  var result = new Uint8Array(end - start);\n  for (var i = start, ii = 0; i < end; i++, ii++) {\n    result[ii] = abv[i];\n  }\n  return result.buffer;\n};\n\n},{}],29:[function(_dereq_,module,exports){\n/*\n * base64-arraybuffer\n * https://github.com/niklasvh/base64-arraybuffer\n *\n * Copyright (c) 2012 Niklas von Hertzen\n * Licensed under the MIT license.\n */\n(function(chars){\n  \"use strict\";\n\n  exports.encode = function(arraybuffer) {\n    var bytes = new Uint8Array(arraybuffer),\n    i, len = bytes.length, base64 = \"\";\n\n    for (i = 0; i < len; i+=3) {\n      base64 += chars[bytes[i] >> 2];\n      base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];\n      base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];\n      base64 += chars[bytes[i + 2] & 63];\n    }\n\n    if ((len % 3) === 2) {\n      base64 = base64.substring(0, base64.length - 1) + \"=\";\n    } else if (len % 3 === 1) {\n      base64 = base64.substring(0, base64.length - 2) + \"==\";\n    }\n\n    return base64;\n  };\n\n  exports.decode =  function(base64) {\n    var bufferLength = base64.length * 0.75,\n    len = base64.length, i, p = 0,\n    encoded1, encoded2, encoded3, encoded4;\n\n    if (base64[base64.length - 1] === \"=\") {\n      bufferLength--;\n      if (base64[base64.length - 2] === \"=\") {\n        bufferLength--;\n      }\n    }\n\n    var arraybuffer = new ArrayBuffer(bufferLength),\n    bytes = new Uint8Array(arraybuffer);\n\n    for (i = 0; i < len; i+=4) {\n      encoded1 = chars.indexOf(base64[i]);\n      encoded2 = chars.indexOf(base64[i+1]);\n      encoded3 = chars.indexOf(base64[i+2]);\n      encoded4 = chars.indexOf(base64[i+3]);\n\n      bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);\n      bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);\n      bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);\n    }\n\n    return arraybuffer;\n  };\n})(\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\");\n\n},{}],30:[function(_dereq_,module,exports){\n(function (global){\n/**\n * Create a blob builder even when vendor prefixes exist\n */\n\nvar BlobBuilder = global.BlobBuilder\n  || global.WebKitBlobBuilder\n  || global.MSBlobBuilder\n  || global.MozBlobBuilder;\n\n/**\n * Check if Blob constructor is supported\n */\n\nvar blobSupported = (function() {\n  try {\n    var b = new Blob(['hi']);\n    return b.size == 2;\n  } catch(e) {\n    return false;\n  }\n})();\n\n/**\n * Check if BlobBuilder is supported\n */\n\nvar blobBuilderSupported = BlobBuilder\n  && BlobBuilder.prototype.append\n  && BlobBuilder.prototype.getBlob;\n\nfunction BlobBuilderConstructor(ary, options) {\n  options = options || {};\n\n  var bb = new BlobBuilder();\n  for (var i = 0; i < ary.length; i++) {\n    bb.append(ary[i]);\n  }\n  return (options.type) ? bb.getBlob(options.type) : bb.getBlob();\n};\n\nmodule.exports = (function() {\n  if (blobSupported) {\n    return global.Blob;\n  } else if (blobBuilderSupported) {\n    return BlobBuilderConstructor;\n  } else {\n    return undefined;\n  }\n})();\n\n}).call(this,typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],31:[function(_dereq_,module,exports){\n(function (global){\n/*! http://mths.be/utf8js v2.0.0 by @mathias */\n;(function(root) {\n\n\t// Detect free variables `exports`\n\tvar freeExports = typeof exports == 'object' && exports;\n\n\t// Detect free variable `module`\n\tvar freeModule = typeof module == 'object' && module &&\n\t\tmodule.exports == freeExports && module;\n\n\t// Detect free variable `global`, from Node.js or Browserified code,\n\t// and use it as `root`\n\tvar freeGlobal = typeof global == 'object' && global;\n\tif (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {\n\t\troot = freeGlobal;\n\t}\n\n\t/*--------------------------------------------------------------------------*/\n\n\tvar stringFromCharCode = String.fromCharCode;\n\n\t// Taken from http://mths.be/punycode\n\tfunction ucs2decode(string) {\n\t\tvar output = [];\n\t\tvar counter = 0;\n\t\tvar length = string.length;\n\t\tvar value;\n\t\tvar extra;\n\t\twhile (counter < length) {\n\t\t\tvalue = string.charCodeAt(counter++);\n\t\t\tif (value >= 0xD800 && value <= 0xDBFF && counter < length) {\n\t\t\t\t// high surrogate, and there is a next character\n\t\t\t\textra = string.charCodeAt(counter++);\n\t\t\t\tif ((extra & 0xFC00) == 0xDC00) { // low surrogate\n\t\t\t\t\toutput.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);\n\t\t\t\t} else {\n\t\t\t\t\t// unmatched surrogate; only append this code unit, in case the next\n\t\t\t\t\t// code unit is the high surrogate of a surrogate pair\n\t\t\t\t\toutput.push(value);\n\t\t\t\t\tcounter--;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\toutput.push(value);\n\t\t\t}\n\t\t}\n\t\treturn output;\n\t}\n\n\t// Taken from http://mths.be/punycode\n\tfunction ucs2encode(array) {\n\t\tvar length = array.length;\n\t\tvar index = -1;\n\t\tvar value;\n\t\tvar output = '';\n\t\twhile (++index < length) {\n\t\t\tvalue = array[index];\n\t\t\tif (value > 0xFFFF) {\n\t\t\t\tvalue -= 0x10000;\n\t\t\t\toutput += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);\n\t\t\t\tvalue = 0xDC00 | value & 0x3FF;\n\t\t\t}\n\t\t\toutput += stringFromCharCode(value);\n\t\t}\n\t\treturn output;\n\t}\n\n\t/*--------------------------------------------------------------------------*/\n\n\tfunction createByte(codePoint, shift) {\n\t\treturn stringFromCharCode(((codePoint >> shift) & 0x3F) | 0x80);\n\t}\n\n\tfunction encodeCodePoint(codePoint) {\n\t\tif ((codePoint & 0xFFFFFF80) == 0) { // 1-byte sequence\n\t\t\treturn stringFromCharCode(codePoint);\n\t\t}\n\t\tvar symbol = '';\n\t\tif ((codePoint & 0xFFFFF800) == 0) { // 2-byte sequence\n\t\t\tsymbol = stringFromCharCode(((codePoint >> 6) & 0x1F) | 0xC0);\n\t\t}\n\t\telse if ((codePoint & 0xFFFF0000) == 0) { // 3-byte sequence\n\t\t\tsymbol = stringFromCharCode(((codePoint >> 12) & 0x0F) | 0xE0);\n\t\t\tsymbol += createByte(codePoint, 6);\n\t\t}\n\t\telse if ((codePoint & 0xFFE00000) == 0) { // 4-byte sequence\n\t\t\tsymbol = stringFromCharCode(((codePoint >> 18) & 0x07) | 0xF0);\n\t\t\tsymbol += createByte(codePoint, 12);\n\t\t\tsymbol += createByte(codePoint, 6);\n\t\t}\n\t\tsymbol += stringFromCharCode((codePoint & 0x3F) | 0x80);\n\t\treturn symbol;\n\t}\n\n\tfunction utf8encode(string) {\n\t\tvar codePoints = ucs2decode(string);\n\n\t\t// console.log(JSON.stringify(codePoints.map(function(x) {\n\t\t// \treturn 'U+' + x.toString(16).toUpperCase();\n\t\t// })));\n\n\t\tvar length = codePoints.length;\n\t\tvar index = -1;\n\t\tvar codePoint;\n\t\tvar byteString = '';\n\t\twhile (++index < length) {\n\t\t\tcodePoint = codePoints[index];\n\t\t\tbyteString += encodeCodePoint(codePoint);\n\t\t}\n\t\treturn byteString;\n\t}\n\n\t/*--------------------------------------------------------------------------*/\n\n\tfunction readContinuationByte() {\n\t\tif (byteIndex >= byteCount) {\n\t\t\tthrow Error('Invalid byte index');\n\t\t}\n\n\t\tvar continuationByte = byteArray[byteIndex] & 0xFF;\n\t\tbyteIndex++;\n\n\t\tif ((continuationByte & 0xC0) == 0x80) {\n\t\t\treturn continuationByte & 0x3F;\n\t\t}\n\n\t\t// If we end up here, it’s not a continuation byte\n\t\tthrow Error('Invalid continuation byte');\n\t}\n\n\tfunction decodeSymbol() {\n\t\tvar byte1;\n\t\tvar byte2;\n\t\tvar byte3;\n\t\tvar byte4;\n\t\tvar codePoint;\n\n\t\tif (byteIndex > byteCount) {\n\t\t\tthrow Error('Invalid byte index');\n\t\t}\n\n\t\tif (byteIndex == byteCount) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Read first byte\n\t\tbyte1 = byteArray[byteIndex] & 0xFF;\n\t\tbyteIndex++;\n\n\t\t// 1-byte sequence (no continuation bytes)\n\t\tif ((byte1 & 0x80) == 0) {\n\t\t\treturn byte1;\n\t\t}\n\n\t\t// 2-byte sequence\n\t\tif ((byte1 & 0xE0) == 0xC0) {\n\t\t\tvar byte2 = readContinuationByte();\n\t\t\tcodePoint = ((byte1 & 0x1F) << 6) | byte2;\n\t\t\tif (codePoint >= 0x80) {\n\t\t\t\treturn codePoint;\n\t\t\t} else {\n\t\t\t\tthrow Error('Invalid continuation byte');\n\t\t\t}\n\t\t}\n\n\t\t// 3-byte sequence (may include unpaired surrogates)\n\t\tif ((byte1 & 0xF0) == 0xE0) {\n\t\t\tbyte2 = readContinuationByte();\n\t\t\tbyte3 = readContinuationByte();\n\t\t\tcodePoint = ((byte1 & 0x0F) << 12) | (byte2 << 6) | byte3;\n\t\t\tif (codePoint >= 0x0800) {\n\t\t\t\treturn codePoint;\n\t\t\t} else {\n\t\t\t\tthrow Error('Invalid continuation byte');\n\t\t\t}\n\t\t}\n\n\t\t// 4-byte sequence\n\t\tif ((byte1 & 0xF8) == 0xF0) {\n\t\t\tbyte2 = readContinuationByte();\n\t\t\tbyte3 = readContinuationByte();\n\t\t\tbyte4 = readContinuationByte();\n\t\t\tcodePoint = ((byte1 & 0x0F) << 0x12) | (byte2 << 0x0C) |\n\t\t\t\t(byte3 << 0x06) | byte4;\n\t\t\tif (codePoint >= 0x010000 && codePoint <= 0x10FFFF) {\n\t\t\t\treturn codePoint;\n\t\t\t}\n\t\t}\n\n\t\tthrow Error('Invalid UTF-8 detected');\n\t}\n\n\tvar byteArray;\n\tvar byteCount;\n\tvar byteIndex;\n\tfunction utf8decode(byteString) {\n\t\tbyteArray = ucs2decode(byteString);\n\t\tbyteCount = byteArray.length;\n\t\tbyteIndex = 0;\n\t\tvar codePoints = [];\n\t\tvar tmp;\n\t\twhile ((tmp = decodeSymbol()) !== false) {\n\t\t\tcodePoints.push(tmp);\n\t\t}\n\t\treturn ucs2encode(codePoints);\n\t}\n\n\t/*--------------------------------------------------------------------------*/\n\n\tvar utf8 = {\n\t\t'version': '2.0.0',\n\t\t'encode': utf8encode,\n\t\t'decode': utf8decode\n\t};\n\n\t// Some AMD build optimizers, like r.js, check for specific condition patterns\n\t// like the following:\n\tif (\n\t\ttypeof define == 'function' &&\n\t\ttypeof define.amd == 'object' &&\n\t\tdefine.amd\n\t) {\n\t\tdefine(function() {\n\t\t\treturn utf8;\n\t\t});\n\t}\telse if (freeExports && !freeExports.nodeType) {\n\t\tif (freeModule) { // in Node.js or RingoJS v0.8.0+\n\t\t\tfreeModule.exports = utf8;\n\t\t} else { // in Narwhal or RingoJS v0.7.0-\n\t\t\tvar object = {};\n\t\t\tvar hasOwnProperty = object.hasOwnProperty;\n\t\t\tfor (var key in utf8) {\n\t\t\t\thasOwnProperty.call(utf8, key) && (freeExports[key] = utf8[key]);\n\t\t\t}\n\t\t}\n\t} else { // in Rhino or a web browser\n\t\troot.utf8 = utf8;\n\t}\n\n}(this));\n\n}).call(this,typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],32:[function(_dereq_,module,exports){\n(function (global){\n/**\n * JSON parse.\n *\n * @see Based on jQuery#parseJSON (MIT) and JSON2\n * @api private\n */\n\nvar rvalidchars = /^[\\],:{}\\s]*$/;\nvar rvalidescape = /\\\\(?:[\"\\\\\\/bfnrt]|u[0-9a-fA-F]{4})/g;\nvar rvalidtokens = /\"[^\"\\\\\\n\\r]*\"|true|false|null|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?/g;\nvar rvalidbraces = /(?:^|:|,)(?:\\s*\\[)+/g;\nvar rtrimLeft = /^\\s+/;\nvar rtrimRight = /\\s+$/;\n\nmodule.exports = function parsejson(data) {\n  if ('string' != typeof data || !data) {\n    return null;\n  }\n\n  data = data.replace(rtrimLeft, '').replace(rtrimRight, '');\n\n  // Attempt to parse using the native JSON parser first\n  if (global.JSON && JSON.parse) {\n    return JSON.parse(data);\n  }\n\n  if (rvalidchars.test(data.replace(rvalidescape, '@')\n      .replace(rvalidtokens, ']')\n      .replace(rvalidbraces, ''))) {\n    return (new Function('return ' + data))();\n  }\n};\n}).call(this,typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],33:[function(_dereq_,module,exports){\n/**\n * Compiles a querystring\n * Returns string representation of the object\n *\n * @param {Object}\n * @api private\n */\n\nexports.encode = function (obj) {\n  var str = '';\n\n  for (var i in obj) {\n    if (obj.hasOwnProperty(i)) {\n      if (str.length) str += '&';\n      str += encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]);\n    }\n  }\n\n  return str;\n};\n\n/**\n * Parses a simple querystring into an object\n *\n * @param {String} qs\n * @api private\n */\n\nexports.decode = function(qs){\n  var qry = {};\n  var pairs = qs.split('&');\n  for (var i = 0, l = pairs.length; i < l; i++) {\n    var pair = pairs[i].split('=');\n    qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);\n  }\n  return qry;\n};\n\n},{}],34:[function(_dereq_,module,exports){\n/**\n * Parses an URI\n *\n * @author Steven Levithan <stevenlevithan.com> (MIT license)\n * @api private\n */\n\nvar re = /^(?:(?![^:@]+:[^:@\\/]*@)(http|https|ws|wss):\\/\\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\\/?#]*)(?::(\\d*))?)(((\\/(?:[^?#](?![^?#\\/]*\\.[^?#\\/.]+(?:[?#]|$)))*\\/?)?([^?#\\/]*))(?:\\?([^#]*))?(?:#(.*))?)/;\n\nvar parts = [\n    'source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'anchor'\n];\n\nmodule.exports = function parseuri(str) {\n    var src = str,\n        b = str.indexOf('['),\n        e = str.indexOf(']');\n\n    if (b != -1 && e != -1) {\n        str = str.substring(0, b) + str.substring(b, e).replace(/:/g, ';') + str.substring(e, str.length);\n    }\n\n    var m = re.exec(str || ''),\n        uri = {},\n        i = 14;\n\n    while (i--) {\n        uri[parts[i]] = m[i] || '';\n    }\n\n    if (b != -1 && e != -1) {\n        uri.source = src;\n        uri.host = uri.host.substring(1, uri.host.length - 1).replace(/;/g, ':');\n        uri.authority = uri.authority.replace('[', '').replace(']', '').replace(/;/g, ':');\n        uri.ipv6uri = true;\n    }\n\n    return uri;\n};\n\n},{}],35:[function(_dereq_,module,exports){\n\n/**\n * Module dependencies.\n */\n\nvar global = (function() { return this; })();\n\n/**\n * WebSocket constructor.\n */\n\nvar WebSocket = global.WebSocket || global.MozWebSocket;\n\n/**\n * Module exports.\n */\n\nmodule.exports = WebSocket ? ws : null;\n\n/**\n * WebSocket constructor.\n *\n * The third `opts` options object gets ignored in web browsers, since it's\n * non-standard, and throws a TypeError if passed to the constructor.\n * See: https://github.com/einaros/ws/issues/227\n *\n * @param {String} uri\n * @param {Array} protocols (optional)\n * @param {Object) opts (optional)\n * @api public\n */\n\nfunction ws(uri, protocols, opts) {\n  var instance;\n  if (protocols) {\n    instance = new WebSocket(uri, protocols);\n  } else {\n    instance = new WebSocket(uri);\n  }\n  return instance;\n}\n\nif (WebSocket) ws.prototype = WebSocket.prototype;\n\n},{}],36:[function(_dereq_,module,exports){\n(function (global){\n\n/*\n * Module requirements.\n */\n\nvar isArray = _dereq_('isarray');\n\n/**\n * Module exports.\n */\n\nmodule.exports = hasBinary;\n\n/**\n * Checks for binary data.\n *\n * Right now only Buffer and ArrayBuffer are supported..\n *\n * @param {Object} anything\n * @api public\n */\n\nfunction hasBinary(data) {\n\n  function _hasBinary(obj) {\n    if (!obj) return false;\n\n    if ( (global.Buffer && global.Buffer.isBuffer(obj)) ||\n         (global.ArrayBuffer && obj instanceof ArrayBuffer) ||\n         (global.Blob && obj instanceof Blob) ||\n         (global.File && obj instanceof File)\n        ) {\n      return true;\n    }\n\n    if (isArray(obj)) {\n      for (var i = 0; i < obj.length; i++) {\n          if (_hasBinary(obj[i])) {\n              return true;\n          }\n      }\n    } else if (obj && 'object' == typeof obj) {\n      if (obj.toJSON) {\n        obj = obj.toJSON();\n      }\n\n      for (var key in obj) {\n        if (obj.hasOwnProperty(key) && _hasBinary(obj[key])) {\n          return true;\n        }\n      }\n    }\n\n    return false;\n  }\n\n  return _hasBinary(data);\n}\n\n}).call(this,typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"isarray\":37}],37:[function(_dereq_,module,exports){\nmodule.exports = Array.isArray || function (arr) {\n  return Object.prototype.toString.call(arr) == '[object Array]';\n};\n\n},{}],38:[function(_dereq_,module,exports){\n\n/**\n * Module dependencies.\n */\n\nvar global = _dereq_('global');\n\n/**\n * Module exports.\n *\n * Logic borrowed from Modernizr:\n *\n *   - https://github.com/Modernizr/Modernizr/blob/master/feature-detects/cors.js\n */\n\ntry {\n  module.exports = 'XMLHttpRequest' in global &&\n    'withCredentials' in new global.XMLHttpRequest();\n} catch (err) {\n  // if XMLHttp support is disabled in IE then it will throw\n  // when trying to create\n  module.exports = false;\n}\n\n},{\"global\":39}],39:[function(_dereq_,module,exports){\n\n/**\n * Returns `this`. Execute this without a \"context\" (i.e. without it being\n * attached to an object of the left-hand side), and `this` points to the\n * \"global\" scope of the current JS execution.\n */\n\nmodule.exports = (function () { return this; })();\n\n},{}],40:[function(_dereq_,module,exports){\n\nvar indexOf = [].indexOf;\n\nmodule.exports = function(arr, obj){\n  if (indexOf) return arr.indexOf(obj);\n  for (var i = 0; i < arr.length; ++i) {\n    if (arr[i] === obj) return i;\n  }\n  return -1;\n};\n},{}],41:[function(_dereq_,module,exports){\n\n/**\n * HOP ref.\n */\n\nvar has = Object.prototype.hasOwnProperty;\n\n/**\n * Return own keys in `obj`.\n *\n * @param {Object} obj\n * @return {Array}\n * @api public\n */\n\nexports.keys = Object.keys || function(obj){\n  var keys = [];\n  for (var key in obj) {\n    if (has.call(obj, key)) {\n      keys.push(key);\n    }\n  }\n  return keys;\n};\n\n/**\n * Return own values in `obj`.\n *\n * @param {Object} obj\n * @return {Array}\n * @api public\n */\n\nexports.values = function(obj){\n  var vals = [];\n  for (var key in obj) {\n    if (has.call(obj, key)) {\n      vals.push(obj[key]);\n    }\n  }\n  return vals;\n};\n\n/**\n * Merge `b` into `a`.\n *\n * @param {Object} a\n * @param {Object} b\n * @return {Object} a\n * @api public\n */\n\nexports.merge = function(a, b){\n  for (var key in b) {\n    if (has.call(b, key)) {\n      a[key] = b[key];\n    }\n  }\n  return a;\n};\n\n/**\n * Return length of `obj`.\n *\n * @param {Object} obj\n * @return {Number}\n * @api public\n */\n\nexports.length = function(obj){\n  return exports.keys(obj).length;\n};\n\n/**\n * Check if `obj` is empty.\n *\n * @param {Object} obj\n * @return {Boolean}\n * @api public\n */\n\nexports.isEmpty = function(obj){\n  return 0 == exports.length(obj);\n};\n},{}],42:[function(_dereq_,module,exports){\n/**\n * Parses an URI\n *\n * @author Steven Levithan <stevenlevithan.com> (MIT license)\n * @api private\n */\n\nvar re = /^(?:(?![^:@]+:[^:@\\/]*@)(http|https|ws|wss):\\/\\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\\/?#]*)(?::(\\d*))?)(((\\/(?:[^?#](?![^?#\\/]*\\.[^?#\\/.]+(?:[?#]|$)))*\\/?)?([^?#\\/]*))(?:\\?([^#]*))?(?:#(.*))?)/;\n\nvar parts = [\n    'source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host'\n  , 'port', 'relative', 'path', 'directory', 'file', 'query', 'anchor'\n];\n\nmodule.exports = function parseuri(str) {\n  var m = re.exec(str || '')\n    , uri = {}\n    , i = 14;\n\n  while (i--) {\n    uri[parts[i]] = m[i] || '';\n  }\n\n  return uri;\n};\n\n},{}],43:[function(_dereq_,module,exports){\n(function (global){\n/*global Blob,File*/\n\n/**\n * Module requirements\n */\n\nvar isArray = _dereq_('isarray');\nvar isBuf = _dereq_('./is-buffer');\n\n/**\n * Replaces every Buffer | ArrayBuffer in packet with a numbered placeholder.\n * Anything with blobs or files should be fed through removeBlobs before coming\n * here.\n *\n * @param {Object} packet - socket.io event packet\n * @return {Object} with deconstructed packet and list of buffers\n * @api public\n */\n\nexports.deconstructPacket = function(packet){\n  var buffers = [];\n  var packetData = packet.data;\n\n  function _deconstructPacket(data) {\n    if (!data) return data;\n\n    if (isBuf(data)) {\n      var placeholder = { _placeholder: true, num: buffers.length };\n      buffers.push(data);\n      return placeholder;\n    } else if (isArray(data)) {\n      var newData = new Array(data.length);\n      for (var i = 0; i < data.length; i++) {\n        newData[i] = _deconstructPacket(data[i]);\n      }\n      return newData;\n    } else if ('object' == typeof data && !(data instanceof Date)) {\n      var newData = {};\n      for (var key in data) {\n        newData[key] = _deconstructPacket(data[key]);\n      }\n      return newData;\n    }\n    return data;\n  }\n\n  var pack = packet;\n  pack.data = _deconstructPacket(packetData);\n  pack.attachments = buffers.length; // number of binary 'attachments'\n  return {packet: pack, buffers: buffers};\n};\n\n/**\n * Reconstructs a binary packet from its placeholder packet and buffers\n *\n * @param {Object} packet - event packet with placeholders\n * @param {Array} buffers - binary buffers to put in placeholder positions\n * @return {Object} reconstructed packet\n * @api public\n */\n\nexports.reconstructPacket = function(packet, buffers) {\n  var curPlaceHolder = 0;\n\n  function _reconstructPacket(data) {\n    if (data && data._placeholder) {\n      var buf = buffers[data.num]; // appropriate buffer (should be natural order anyway)\n      return buf;\n    } else if (isArray(data)) {\n      for (var i = 0; i < data.length; i++) {\n        data[i] = _reconstructPacket(data[i]);\n      }\n      return data;\n    } else if (data && 'object' == typeof data) {\n      for (var key in data) {\n        data[key] = _reconstructPacket(data[key]);\n      }\n      return data;\n    }\n    return data;\n  }\n\n  packet.data = _reconstructPacket(packet.data);\n  packet.attachments = undefined; // no longer useful\n  return packet;\n};\n\n/**\n * Asynchronously removes Blobs or Files from data via\n * FileReader's readAsArrayBuffer method. Used before encoding\n * data as msgpack. Calls callback with the blobless data.\n *\n * @param {Object} data\n * @param {Function} callback\n * @api private\n */\n\nexports.removeBlobs = function(data, callback) {\n  function _removeBlobs(obj, curKey, containingObject) {\n    if (!obj) return obj;\n\n    // convert any blob\n    if ((global.Blob && obj instanceof Blob) ||\n        (global.File && obj instanceof File)) {\n      pendingBlobs++;\n\n      // async filereader\n      var fileReader = new FileReader();\n      fileReader.onload = function() { // this.result == arraybuffer\n        if (containingObject) {\n          containingObject[curKey] = this.result;\n        }\n        else {\n          bloblessData = this.result;\n        }\n\n        // if nothing pending its callback time\n        if(! --pendingBlobs) {\n          callback(bloblessData);\n        }\n      };\n\n      fileReader.readAsArrayBuffer(obj); // blob -> arraybuffer\n    } else if (isArray(obj)) { // handle array\n      for (var i = 0; i < obj.length; i++) {\n        _removeBlobs(obj[i], i, obj);\n      }\n    } else if (obj && 'object' == typeof obj && !isBuf(obj)) { // and object\n      for (var key in obj) {\n        _removeBlobs(obj[key], key, obj);\n      }\n    }\n  }\n\n  var pendingBlobs = 0;\n  var bloblessData = data;\n  _removeBlobs(bloblessData);\n  if (!pendingBlobs) {\n    callback(bloblessData);\n  }\n};\n\n}).call(this,typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./is-buffer\":45,\"isarray\":46}],44:[function(_dereq_,module,exports){\n\n/**\n * Module dependencies.\n */\n\nvar debug = _dereq_('debug')('socket.io-parser');\nvar json = _dereq_('json3');\nvar isArray = _dereq_('isarray');\nvar Emitter = _dereq_('component-emitter');\nvar binary = _dereq_('./binary');\nvar isBuf = _dereq_('./is-buffer');\n\n/**\n * Protocol version.\n *\n * @api public\n */\n\nexports.protocol = 4;\n\n/**\n * Packet types.\n *\n * @api public\n */\n\nexports.types = [\n  'CONNECT',\n  'DISCONNECT',\n  'EVENT',\n  'BINARY_EVENT',\n  'ACK',\n  'BINARY_ACK',\n  'ERROR'\n];\n\n/**\n * Packet type `connect`.\n *\n * @api public\n */\n\nexports.CONNECT = 0;\n\n/**\n * Packet type `disconnect`.\n *\n * @api public\n */\n\nexports.DISCONNECT = 1;\n\n/**\n * Packet type `event`.\n *\n * @api public\n */\n\nexports.EVENT = 2;\n\n/**\n * Packet type `ack`.\n *\n * @api public\n */\n\nexports.ACK = 3;\n\n/**\n * Packet type `error`.\n *\n * @api public\n */\n\nexports.ERROR = 4;\n\n/**\n * Packet type 'binary event'\n *\n * @api public\n */\n\nexports.BINARY_EVENT = 5;\n\n/**\n * Packet type `binary ack`. For acks with binary arguments.\n *\n * @api public\n */\n\nexports.BINARY_ACK = 6;\n\n/**\n * Encoder constructor.\n *\n * @api public\n */\n\nexports.Encoder = Encoder;\n\n/**\n * Decoder constructor.\n *\n * @api public\n */\n\nexports.Decoder = Decoder;\n\n/**\n * A socket.io Encoder instance\n *\n * @api public\n */\n\nfunction Encoder() {}\n\n/**\n * Encode a packet as a single string if non-binary, or as a\n * buffer sequence, depending on packet type.\n *\n * @param {Object} obj - packet object\n * @param {Function} callback - function to handle encodings (likely engine.write)\n * @return Calls callback with Array of encodings\n * @api public\n */\n\nEncoder.prototype.encode = function(obj, callback){\n  debug('encoding packet %j', obj);\n\n  if (exports.BINARY_EVENT == obj.type || exports.BINARY_ACK == obj.type) {\n    encodeAsBinary(obj, callback);\n  }\n  else {\n    var encoding = encodeAsString(obj);\n    callback([encoding]);\n  }\n};\n\n/**\n * Encode packet as string.\n *\n * @param {Object} packet\n * @return {String} encoded\n * @api private\n */\n\nfunction encodeAsString(obj) {\n  var str = '';\n  var nsp = false;\n\n  // first is type\n  str += obj.type;\n\n  // attachments if we have them\n  if (exports.BINARY_EVENT == obj.type || exports.BINARY_ACK == obj.type) {\n    str += obj.attachments;\n    str += '-';\n  }\n\n  // if we have a namespace other than `/`\n  // we append it followed by a comma `,`\n  if (obj.nsp && '/' != obj.nsp) {\n    nsp = true;\n    str += obj.nsp;\n  }\n\n  // immediately followed by the id\n  if (null != obj.id) {\n    if (nsp) {\n      str += ',';\n      nsp = false;\n    }\n    str += obj.id;\n  }\n\n  // json data\n  if (null != obj.data) {\n    if (nsp) str += ',';\n    str += json.stringify(obj.data);\n  }\n\n  debug('encoded %j as %s', obj, str);\n  return str;\n}\n\n/**\n * Encode packet as 'buffer sequence' by removing blobs, and\n * deconstructing packet into object with placeholders and\n * a list of buffers.\n *\n * @param {Object} packet\n * @return {Buffer} encoded\n * @api private\n */\n\nfunction encodeAsBinary(obj, callback) {\n\n  function writeEncoding(bloblessData) {\n    var deconstruction = binary.deconstructPacket(bloblessData);\n    var pack = encodeAsString(deconstruction.packet);\n    var buffers = deconstruction.buffers;\n\n    buffers.unshift(pack); // add packet info to beginning of data list\n    callback(buffers); // write all the buffers\n  }\n\n  binary.removeBlobs(obj, writeEncoding);\n}\n\n/**\n * A socket.io Decoder instance\n *\n * @return {Object} decoder\n * @api public\n */\n\nfunction Decoder() {\n  this.reconstructor = null;\n}\n\n/**\n * Mix in `Emitter` with Decoder.\n */\n\nEmitter(Decoder.prototype);\n\n/**\n * Decodes an ecoded packet string into packet JSON.\n *\n * @param {String} obj - encoded packet\n * @return {Object} packet\n * @api public\n */\n\nDecoder.prototype.add = function(obj) {\n  var packet;\n  if ('string' == typeof obj) {\n    packet = decodeString(obj);\n    if (exports.BINARY_EVENT == packet.type || exports.BINARY_ACK == packet.type) { // binary packet's json\n      this.reconstructor = new BinaryReconstructor(packet);\n\n      // no attachments, labeled binary but no binary data to follow\n      if (this.reconstructor.reconPack.attachments == 0) {\n        this.emit('decoded', packet);\n      }\n    } else { // non-binary full packet\n      this.emit('decoded', packet);\n    }\n  }\n  else if (isBuf(obj) || obj.base64) { // raw binary data\n    if (!this.reconstructor) {\n      throw new Error('got binary data when not reconstructing a packet');\n    } else {\n      packet = this.reconstructor.takeBinaryData(obj);\n      if (packet) { // received final buffer\n        this.reconstructor = null;\n        this.emit('decoded', packet);\n      }\n    }\n  }\n  else {\n    throw new Error('Unknown type: ' + obj);\n  }\n};\n\n/**\n * Decode a packet String (JSON data)\n *\n * @param {String} str\n * @return {Object} packet\n * @api private\n */\n\nfunction decodeString(str) {\n  var p = {};\n  var i = 0;\n\n  // look up type\n  p.type = Number(str.charAt(0));\n  if (null == exports.types[p.type]) return error();\n\n  // look up attachments if type binary\n  if (exports.BINARY_EVENT == p.type || exports.BINARY_ACK == p.type) {\n    p.attachments = '';\n    while (str.charAt(++i) != '-') {\n      p.attachments += str.charAt(i);\n    }\n    p.attachments = Number(p.attachments);\n  }\n\n  // look up namespace (if any)\n  if ('/' == str.charAt(i + 1)) {\n    p.nsp = '';\n    while (++i) {\n      var c = str.charAt(i);\n      if (',' == c) break;\n      p.nsp += c;\n      if (i + 1 == str.length) break;\n    }\n  } else {\n    p.nsp = '/';\n  }\n\n  // look up id\n  var next = str.charAt(i + 1);\n  if ('' != next && Number(next) == next) {\n    p.id = '';\n    while (++i) {\n      var c = str.charAt(i);\n      if (null == c || Number(c) != c) {\n        --i;\n        break;\n      }\n      p.id += str.charAt(i);\n      if (i + 1 == str.length) break;\n    }\n    p.id = Number(p.id);\n  }\n\n  // look up json data\n  if (str.charAt(++i)) {\n    try {\n      p.data = json.parse(str.substr(i));\n    } catch(e){\n      return error();\n    }\n  }\n\n  debug('decoded %s as %j', str, p);\n  return p;\n}\n\n/**\n * Deallocates a parser's resources\n *\n * @api public\n */\n\nDecoder.prototype.destroy = function() {\n  if (this.reconstructor) {\n    this.reconstructor.finishedReconstruction();\n  }\n};\n\n/**\n * A manager of a binary event's 'buffer sequence'. Should\n * be constructed whenever a packet of type BINARY_EVENT is\n * decoded.\n *\n * @param {Object} packet\n * @return {BinaryReconstructor} initialized reconstructor\n * @api private\n */\n\nfunction BinaryReconstructor(packet) {\n  this.reconPack = packet;\n  this.buffers = [];\n}\n\n/**\n * Method to be called when binary data received from connection\n * after a BINARY_EVENT packet.\n *\n * @param {Buffer | ArrayBuffer} binData - the raw binary data received\n * @return {null | Object} returns null if more binary data is expected or\n *   a reconstructed packet object if all buffers have been received.\n * @api private\n */\n\nBinaryReconstructor.prototype.takeBinaryData = function(binData) {\n  this.buffers.push(binData);\n  if (this.buffers.length == this.reconPack.attachments) { // done with buffer list\n    var packet = binary.reconstructPacket(this.reconPack, this.buffers);\n    this.finishedReconstruction();\n    return packet;\n  }\n  return null;\n};\n\n/**\n * Cleans up binary packet reconstruction variables.\n *\n * @api private\n */\n\nBinaryReconstructor.prototype.finishedReconstruction = function() {\n  this.reconPack = null;\n  this.buffers = [];\n};\n\nfunction error(data){\n  return {\n    type: exports.ERROR,\n    data: 'parser error'\n  };\n}\n\n},{\"./binary\":43,\"./is-buffer\":45,\"component-emitter\":9,\"debug\":10,\"isarray\":46,\"json3\":47}],45:[function(_dereq_,module,exports){\n(function (global){\n\nmodule.exports = isBuf;\n\n/**\n * Returns true if obj is a buffer or an arraybuffer.\n *\n * @api private\n */\n\nfunction isBuf(obj) {\n  return (global.Buffer && global.Buffer.isBuffer(obj)) ||\n         (global.ArrayBuffer && obj instanceof ArrayBuffer);\n}\n\n}).call(this,typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],46:[function(_dereq_,module,exports){\nmodule.exports=_dereq_(37)\n},{}],47:[function(_dereq_,module,exports){\n/*! JSON v3.2.6 | http://bestiejs.github.io/json3 | Copyright 2012-2013, Kit Cambridge | http://kit.mit-license.org */\n;(function (window) {\n  // Convenience aliases.\n  var getClass = {}.toString, isProperty, forEach, undef;\n\n  // Detect the `define` function exposed by asynchronous module loaders. The\n  // strict `define` check is necessary for compatibility with `r.js`.\n  var isLoader = typeof define === \"function\" && define.amd;\n\n  // Detect native implementations.\n  var nativeJSON = typeof JSON == \"object\" && JSON;\n\n  // Set up the JSON 3 namespace, preferring the CommonJS `exports` object if\n  // available.\n  var JSON3 = typeof exports == \"object\" && exports && !exports.nodeType && exports;\n\n  if (JSON3 && nativeJSON) {\n    // Explicitly delegate to the native `stringify` and `parse`\n    // implementations in CommonJS environments.\n    JSON3.stringify = nativeJSON.stringify;\n    JSON3.parse = nativeJSON.parse;\n  } else {\n    // Export for web browsers, JavaScript engines, and asynchronous module\n    // loaders, using the global `JSON` object if available.\n    JSON3 = window.JSON = nativeJSON || {};\n  }\n\n  // Test the `Date#getUTC*` methods. Based on work by @Yaffle.\n  var isExtended = new Date(-3509827334573292);\n  try {\n    // The `getUTCFullYear`, `Month`, and `Date` methods return nonsensical\n    // results for certain dates in Opera >= 10.53.\n    isExtended = isExtended.getUTCFullYear() == -109252 && isExtended.getUTCMonth() === 0 && isExtended.getUTCDate() === 1 &&\n      // Safari < 2.0.2 stores the internal millisecond time value correctly,\n      // but clips the values returned by the date methods to the range of\n      // signed 32-bit integers ([-2 ** 31, 2 ** 31 - 1]).\n      isExtended.getUTCHours() == 10 && isExtended.getUTCMinutes() == 37 && isExtended.getUTCSeconds() == 6 && isExtended.getUTCMilliseconds() == 708;\n  } catch (exception) {}\n\n  // Internal: Determines whether the native `JSON.stringify` and `parse`\n  // implementations are spec-compliant. Based on work by Ken Snyder.\n  function has(name) {\n    if (has[name] !== undef) {\n      // Return cached feature test result.\n      return has[name];\n    }\n\n    var isSupported;\n    if (name == \"bug-string-char-index\") {\n      // IE <= 7 doesn't support accessing string characters using square\n      // bracket notation. IE 8 only supports this for primitives.\n      isSupported = \"a\"[0] != \"a\";\n    } else if (name == \"json\") {\n      // Indicates whether both `JSON.stringify` and `JSON.parse` are\n      // supported.\n      isSupported = has(\"json-stringify\") && has(\"json-parse\");\n    } else {\n      var value, serialized = '{\"a\":[1,true,false,null,\"\\\\u0000\\\\b\\\\n\\\\f\\\\r\\\\t\"]}';\n      // Test `JSON.stringify`.\n      if (name == \"json-stringify\") {\n        var stringify = JSON3.stringify, stringifySupported = typeof stringify == \"function\" && isExtended;\n        if (stringifySupported) {\n          // A test function object with a custom `toJSON` method.\n          (value = function () {\n            return 1;\n          }).toJSON = value;\n          try {\n            stringifySupported =\n              // Firefox 3.1b1 and b2 serialize string, number, and boolean\n              // primitives as object literals.\n              stringify(0) === \"0\" &&\n              // FF 3.1b1, b2, and JSON 2 serialize wrapped primitives as object\n              // literals.\n              stringify(new Number()) === \"0\" &&\n              stringify(new String()) == '\"\"' &&\n              // FF 3.1b1, 2 throw an error if the value is `null`, `undefined`, or\n              // does not define a canonical JSON representation (this applies to\n              // objects with `toJSON` properties as well, *unless* they are nested\n              // within an object or array).\n              stringify(getClass) === undef &&\n              // IE 8 serializes `undefined` as `\"undefined\"`. Safari <= 5.1.7 and\n              // FF 3.1b3 pass this test.\n              stringify(undef) === undef &&\n              // Safari <= 5.1.7 and FF 3.1b3 throw `Error`s and `TypeError`s,\n              // respectively, if the value is omitted entirely.\n              stringify() === undef &&\n              // FF 3.1b1, 2 throw an error if the given value is not a number,\n              // string, array, object, Boolean, or `null` literal. This applies to\n              // objects with custom `toJSON` methods as well, unless they are nested\n              // inside object or array literals. YUI 3.0.0b1 ignores custom `toJSON`\n              // methods entirely.\n              stringify(value) === \"1\" &&\n              stringify([value]) == \"[1]\" &&\n              // Prototype <= 1.6.1 serializes `[undefined]` as `\"[]\"` instead of\n              // `\"[null]\"`.\n              stringify([undef]) == \"[null]\" &&\n              // YUI 3.0.0b1 fails to serialize `null` literals.\n              stringify(null) == \"null\" &&\n              // FF 3.1b1, 2 halts serialization if an array contains a function:\n              // `[1, true, getClass, 1]` serializes as \"[1,true,],\". FF 3.1b3\n              // elides non-JSON values from objects and arrays, unless they\n              // define custom `toJSON` methods.\n              stringify([undef, getClass, null]) == \"[null,null,null]\" &&\n              // Simple serialization test. FF 3.1b1 uses Unicode escape sequences\n              // where character escape codes are expected (e.g., `\\b` => `\\u0008`).\n              stringify({ \"a\": [value, true, false, null, \"\\x00\\b\\n\\f\\r\\t\"] }) == serialized &&\n              // FF 3.1b1 and b2 ignore the `filter` and `width` arguments.\n              stringify(null, value) === \"1\" &&\n              stringify([1, 2], null, 1) == \"[\\n 1,\\n 2\\n]\" &&\n              // JSON 2, Prototype <= 1.7, and older WebKit builds incorrectly\n              // serialize extended years.\n              stringify(new Date(-8.64e15)) == '\"-271821-04-20T00:00:00.000Z\"' &&\n              // The milliseconds are optional in ES 5, but required in 5.1.\n              stringify(new Date(8.64e15)) == '\"+275760-09-13T00:00:00.000Z\"' &&\n              // Firefox <= 11.0 incorrectly serializes years prior to 0 as negative\n              // four-digit years instead of six-digit years. Credits: @Yaffle.\n              stringify(new Date(-621987552e5)) == '\"-000001-01-01T00:00:00.000Z\"' &&\n              // Safari <= 5.1.5 and Opera >= 10.53 incorrectly serialize millisecond\n              // values less than 1000. Credits: @Yaffle.\n              stringify(new Date(-1)) == '\"1969-12-31T23:59:59.999Z\"';\n          } catch (exception) {\n            stringifySupported = false;\n          }\n        }\n        isSupported = stringifySupported;\n      }\n      // Test `JSON.parse`.\n      if (name == \"json-parse\") {\n        var parse = JSON3.parse;\n        if (typeof parse == \"function\") {\n          try {\n            // FF 3.1b1, b2 will throw an exception if a bare literal is provided.\n            // Conforming implementations should also coerce the initial argument to\n            // a string prior to parsing.\n            if (parse(\"0\") === 0 && !parse(false)) {\n              // Simple parsing test.\n              value = parse(serialized);\n              var parseSupported = value[\"a\"].length == 5 && value[\"a\"][0] === 1;\n              if (parseSupported) {\n                try {\n                  // Safari <= 5.1.2 and FF 3.1b1 allow unescaped tabs in strings.\n                  parseSupported = !parse('\"\\t\"');\n                } catch (exception) {}\n                if (parseSupported) {\n                  try {\n                    // FF 4.0 and 4.0.1 allow leading `+` signs and leading\n                    // decimal points. FF 4.0, 4.0.1, and IE 9-10 also allow\n                    // certain octal literals.\n                    parseSupported = parse(\"01\") !== 1;\n                  } catch (exception) {}\n                }\n                if (parseSupported) {\n                  try {\n                    // FF 4.0, 4.0.1, and Rhino 1.7R3-R4 allow trailing decimal\n                    // points. These environments, along with FF 3.1b1 and 2,\n                    // also allow trailing commas in JSON objects and arrays.\n                    parseSupported = parse(\"1.\") !== 1;\n                  } catch (exception) {}\n                }\n              }\n            }\n          } catch (exception) {\n            parseSupported = false;\n          }\n        }\n        isSupported = parseSupported;\n      }\n    }\n    return has[name] = !!isSupported;\n  }\n\n  if (!has(\"json\")) {\n    // Common `[[Class]]` name aliases.\n    var functionClass = \"[object Function]\";\n    var dateClass = \"[object Date]\";\n    var numberClass = \"[object Number]\";\n    var stringClass = \"[object String]\";\n    var arrayClass = \"[object Array]\";\n    var booleanClass = \"[object Boolean]\";\n\n    // Detect incomplete support for accessing string characters by index.\n    var charIndexBuggy = has(\"bug-string-char-index\");\n\n    // Define additional utility methods if the `Date` methods are buggy.\n    if (!isExtended) {\n      var floor = Math.floor;\n      // A mapping between the months of the year and the number of days between\n      // January 1st and the first of the respective month.\n      var Months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];\n      // Internal: Calculates the number of days between the Unix epoch and the\n      // first day of the given month.\n      var getDay = function (year, month) {\n        return Months[month] + 365 * (year - 1970) + floor((year - 1969 + (month = +(month > 1))) / 4) - floor((year - 1901 + month) / 100) + floor((year - 1601 + month) / 400);\n      };\n    }\n\n    // Internal: Determines if a property is a direct property of the given\n    // object. Delegates to the native `Object#hasOwnProperty` method.\n    if (!(isProperty = {}.hasOwnProperty)) {\n      isProperty = function (property) {\n        var members = {}, constructor;\n        if ((members.__proto__ = null, members.__proto__ = {\n          // The *proto* property cannot be set multiple times in recent\n          // versions of Firefox and SeaMonkey.\n          \"toString\": 1\n        }, members).toString != getClass) {\n          // Safari <= 2.0.3 doesn't implement `Object#hasOwnProperty`, but\n          // supports the mutable *proto* property.\n          isProperty = function (property) {\n            // Capture and break the object's prototype chain (see section 8.6.2\n            // of the ES 5.1 spec). The parenthesized expression prevents an\n            // unsafe transformation by the Closure Compiler.\n            var original = this.__proto__, result = property in (this.__proto__ = null, this);\n            // Restore the original prototype chain.\n            this.__proto__ = original;\n            return result;\n          };\n        } else {\n          // Capture a reference to the top-level `Object` constructor.\n          constructor = members.constructor;\n          // Use the `constructor` property to simulate `Object#hasOwnProperty` in\n          // other environments.\n          isProperty = function (property) {\n            var parent = (this.constructor || constructor).prototype;\n            return property in this && !(property in parent && this[property] === parent[property]);\n          };\n        }\n        members = null;\n        return isProperty.call(this, property);\n      };\n    }\n\n    // Internal: A set of primitive types used by `isHostType`.\n    var PrimitiveTypes = {\n      'boolean': 1,\n      'number': 1,\n      'string': 1,\n      'undefined': 1\n    };\n\n    // Internal: Determines if the given object `property` value is a\n    // non-primitive.\n    var isHostType = function (object, property) {\n      var type = typeof object[property];\n      return type == 'object' ? !!object[property] : !PrimitiveTypes[type];\n    };\n\n    // Internal: Normalizes the `for...in` iteration algorithm across\n    // environments. Each enumerated key is yielded to a `callback` function.\n    forEach = function (object, callback) {\n      var size = 0, Properties, members, property;\n\n      // Tests for bugs in the current environment's `for...in` algorithm. The\n      // `valueOf` property inherits the non-enumerable flag from\n      // `Object.prototype` in older versions of IE, Netscape, and Mozilla.\n      (Properties = function () {\n        this.valueOf = 0;\n      }).prototype.valueOf = 0;\n\n      // Iterate over a new instance of the `Properties` class.\n      members = new Properties();\n      for (property in members) {\n        // Ignore all properties inherited from `Object.prototype`.\n        if (isProperty.call(members, property)) {\n          size++;\n        }\n      }\n      Properties = members = null;\n\n      // Normalize the iteration algorithm.\n      if (!size) {\n        // A list of non-enumerable properties inherited from `Object.prototype`.\n        members = [\"valueOf\", \"toString\", \"toLocaleString\", \"propertyIsEnumerable\", \"isPrototypeOf\", \"hasOwnProperty\", \"constructor\"];\n        // IE <= 8, Mozilla 1.0, and Netscape 6.2 ignore shadowed non-enumerable\n        // properties.\n        forEach = function (object, callback) {\n          var isFunction = getClass.call(object) == functionClass, property, length;\n          var hasProperty = !isFunction && typeof object.constructor != 'function' && isHostType(object, 'hasOwnProperty') ? object.hasOwnProperty : isProperty;\n          for (property in object) {\n            // Gecko <= 1.0 enumerates the `prototype` property of functions under\n            // certain conditions; IE does not.\n            if (!(isFunction && property == \"prototype\") && hasProperty.call(object, property)) {\n              callback(property);\n            }\n          }\n          // Manually invoke the callback for each non-enumerable property.\n          for (length = members.length; property = members[--length]; hasProperty.call(object, property) && callback(property));\n        };\n      } else if (size == 2) {\n        // Safari <= 2.0.4 enumerates shadowed properties twice.\n        forEach = function (object, callback) {\n          // Create a set of iterated properties.\n          var members = {}, isFunction = getClass.call(object) == functionClass, property;\n          for (property in object) {\n            // Store each property name to prevent double enumeration. The\n            // `prototype` property of functions is not enumerated due to cross-\n            // environment inconsistencies.\n            if (!(isFunction && property == \"prototype\") && !isProperty.call(members, property) && (members[property] = 1) && isProperty.call(object, property)) {\n              callback(property);\n            }\n          }\n        };\n      } else {\n        // No bugs detected; use the standard `for...in` algorithm.\n        forEach = function (object, callback) {\n          var isFunction = getClass.call(object) == functionClass, property, isConstructor;\n          for (property in object) {\n            if (!(isFunction && property == \"prototype\") && isProperty.call(object, property) && !(isConstructor = property === \"constructor\")) {\n              callback(property);\n            }\n          }\n          // Manually invoke the callback for the `constructor` property due to\n          // cross-environment inconsistencies.\n          if (isConstructor || isProperty.call(object, (property = \"constructor\"))) {\n            callback(property);\n          }\n        };\n      }\n      return forEach(object, callback);\n    };\n\n    // Public: Serializes a JavaScript `value` as a JSON string. The optional\n    // `filter` argument may specify either a function that alters how object and\n    // array members are serialized, or an array of strings and numbers that\n    // indicates which properties should be serialized. The optional `width`\n    // argument may be either a string or number that specifies the indentation\n    // level of the output.\n    if (!has(\"json-stringify\")) {\n      // Internal: A map of control characters and their escaped equivalents.\n      var Escapes = {\n        92: \"\\\\\\\\\",\n        34: '\\\\\"',\n        8: \"\\\\b\",\n        12: \"\\\\f\",\n        10: \"\\\\n\",\n        13: \"\\\\r\",\n        9: \"\\\\t\"\n      };\n\n      // Internal: Converts `value` into a zero-padded string such that its\n      // length is at least equal to `width`. The `width` must be <= 6.\n      var leadingZeroes = \"000000\";\n      var toPaddedString = function (width, value) {\n        // The `|| 0` expression is necessary to work around a bug in\n        // Opera <= 7.54u2 where `0 == -0`, but `String(-0) !== \"0\"`.\n        return (leadingZeroes + (value || 0)).slice(-width);\n      };\n\n      // Internal: Double-quotes a string `value`, replacing all ASCII control\n      // characters (characters with code unit values between 0 and 31) with\n      // their escaped equivalents. This is an implementation of the\n      // `Quote(value)` operation defined in ES 5.1 section 15.12.3.\n      var unicodePrefix = \"\\\\u00\";\n      var quote = function (value) {\n        var result = '\"', index = 0, length = value.length, isLarge = length > 10 && charIndexBuggy, symbols;\n        if (isLarge) {\n          symbols = value.split(\"\");\n        }\n        for (; index < length; index++) {\n          var charCode = value.charCodeAt(index);\n          // If the character is a control character, append its Unicode or\n          // shorthand escape sequence; otherwise, append the character as-is.\n          switch (charCode) {\n            case 8: case 9: case 10: case 12: case 13: case 34: case 92:\n              result += Escapes[charCode];\n              break;\n            default:\n              if (charCode < 32) {\n                result += unicodePrefix + toPaddedString(2, charCode.toString(16));\n                break;\n              }\n              result += isLarge ? symbols[index] : charIndexBuggy ? value.charAt(index) : value[index];\n          }\n        }\n        return result + '\"';\n      };\n\n      // Internal: Recursively serializes an object. Implements the\n      // `Str(key, holder)`, `JO(value)`, and `JA(value)` operations.\n      var serialize = function (property, object, callback, properties, whitespace, indentation, stack) {\n        var value, className, year, month, date, time, hours, minutes, seconds, milliseconds, results, element, index, length, prefix, result;\n        try {\n          // Necessary for host object support.\n          value = object[property];\n        } catch (exception) {}\n        if (typeof value == \"object\" && value) {\n          className = getClass.call(value);\n          if (className == dateClass && !isProperty.call(value, \"toJSON\")) {\n            if (value > -1 / 0 && value < 1 / 0) {\n              // Dates are serialized according to the `Date#toJSON` method\n              // specified in ES 5.1 section 15.9.5.44. See section 15.9.1.15\n              // for the ISO 8601 date time string format.\n              if (getDay) {\n                // Manually compute the year, month, date, hours, minutes,\n                // seconds, and milliseconds if the `getUTC*` methods are\n                // buggy. Adapted from @Yaffle's `date-shim` project.\n                date = floor(value / 864e5);\n                for (year = floor(date / 365.2425) + 1970 - 1; getDay(year + 1, 0) <= date; year++);\n                for (month = floor((date - getDay(year, 0)) / 30.42); getDay(year, month + 1) <= date; month++);\n                date = 1 + date - getDay(year, month);\n                // The `time` value specifies the time within the day (see ES\n                // 5.1 section 15.9.1.2). The formula `(A % B + B) % B` is used\n                // to compute `A modulo B`, as the `%` operator does not\n                // correspond to the `modulo` operation for negative numbers.\n                time = (value % 864e5 + 864e5) % 864e5;\n                // The hours, minutes, seconds, and milliseconds are obtained by\n                // decomposing the time within the day. See section 15.9.1.10.\n                hours = floor(time / 36e5) % 24;\n                minutes = floor(time / 6e4) % 60;\n                seconds = floor(time / 1e3) % 60;\n                milliseconds = time % 1e3;\n              } else {\n                year = value.getUTCFullYear();\n                month = value.getUTCMonth();\n                date = value.getUTCDate();\n                hours = value.getUTCHours();\n                minutes = value.getUTCMinutes();\n                seconds = value.getUTCSeconds();\n                milliseconds = value.getUTCMilliseconds();\n              }\n              // Serialize extended years correctly.\n              value = (year <= 0 || year >= 1e4 ? (year < 0 ? \"-\" : \"+\") + toPaddedString(6, year < 0 ? -year : year) : toPaddedString(4, year)) +\n                \"-\" + toPaddedString(2, month + 1) + \"-\" + toPaddedString(2, date) +\n                // Months, dates, hours, minutes, and seconds should have two\n                // digits; milliseconds should have three.\n                \"T\" + toPaddedString(2, hours) + \":\" + toPaddedString(2, minutes) + \":\" + toPaddedString(2, seconds) +\n                // Milliseconds are optional in ES 5.0, but required in 5.1.\n                \".\" + toPaddedString(3, milliseconds) + \"Z\";\n            } else {\n              value = null;\n            }\n          } else if (typeof value.toJSON == \"function\" && ((className != numberClass && className != stringClass && className != arrayClass) || isProperty.call(value, \"toJSON\"))) {\n            // Prototype <= 1.6.1 adds non-standard `toJSON` methods to the\n            // `Number`, `String`, `Date`, and `Array` prototypes. JSON 3\n            // ignores all `toJSON` methods on these objects unless they are\n            // defined directly on an instance.\n            value = value.toJSON(property);\n          }\n        }\n        if (callback) {\n          // If a replacement function was provided, call it to obtain the value\n          // for serialization.\n          value = callback.call(object, property, value);\n        }\n        if (value === null) {\n          return \"null\";\n        }\n        className = getClass.call(value);\n        if (className == booleanClass) {\n          // Booleans are represented literally.\n          return \"\" + value;\n        } else if (className == numberClass) {\n          // JSON numbers must be finite. `Infinity` and `NaN` are serialized as\n          // `\"null\"`.\n          return value > -1 / 0 && value < 1 / 0 ? \"\" + value : \"null\";\n        } else if (className == stringClass) {\n          // Strings are double-quoted and escaped.\n          return quote(\"\" + value);\n        }\n        // Recursively serialize objects and arrays.\n        if (typeof value == \"object\") {\n          // Check for cyclic structures. This is a linear search; performance\n          // is inversely proportional to the number of unique nested objects.\n          for (length = stack.length; length--;) {\n            if (stack[length] === value) {\n              // Cyclic structures cannot be serialized by `JSON.stringify`.\n              throw TypeError();\n            }\n          }\n          // Add the object to the stack of traversed objects.\n          stack.push(value);\n          results = [];\n          // Save the current indentation level and indent one additional level.\n          prefix = indentation;\n          indentation += whitespace;\n          if (className == arrayClass) {\n            // Recursively serialize array elements.\n            for (index = 0, length = value.length; index < length; index++) {\n              element = serialize(index, value, callback, properties, whitespace, indentation, stack);\n              results.push(element === undef ? \"null\" : element);\n            }\n            result = results.length ? (whitespace ? \"[\\n\" + indentation + results.join(\",\\n\" + indentation) + \"\\n\" + prefix + \"]\" : (\"[\" + results.join(\",\") + \"]\")) : \"[]\";\n          } else {\n            // Recursively serialize object members. Members are selected from\n            // either a user-specified list of property names, or the object\n            // itself.\n            forEach(properties || value, function (property) {\n              var element = serialize(property, value, callback, properties, whitespace, indentation, stack);\n              if (element !== undef) {\n                // According to ES 5.1 section 15.12.3: \"If `gap` {whitespace}\n                // is not the empty string, let `member` {quote(property) + \":\"}\n                // be the concatenation of `member` and the `space` character.\"\n                // The \"`space` character\" refers to the literal space\n                // character, not the `space` {width} argument provided to\n                // `JSON.stringify`.\n                results.push(quote(property) + \":\" + (whitespace ? \" \" : \"\") + element);\n              }\n            });\n            result = results.length ? (whitespace ? \"{\\n\" + indentation + results.join(\",\\n\" + indentation) + \"\\n\" + prefix + \"}\" : (\"{\" + results.join(\",\") + \"}\")) : \"{}\";\n          }\n          // Remove the object from the traversed object stack.\n          stack.pop();\n          return result;\n        }\n      };\n\n      // Public: `JSON.stringify`. See ES 5.1 section 15.12.3.\n      JSON3.stringify = function (source, filter, width) {\n        var whitespace, callback, properties, className;\n        if (typeof filter == \"function\" || typeof filter == \"object\" && filter) {\n          if ((className = getClass.call(filter)) == functionClass) {\n            callback = filter;\n          } else if (className == arrayClass) {\n            // Convert the property names array into a makeshift set.\n            properties = {};\n            for (var index = 0, length = filter.length, value; index < length; value = filter[index++], ((className = getClass.call(value)), className == stringClass || className == numberClass) && (properties[value] = 1));\n          }\n        }\n        if (width) {\n          if ((className = getClass.call(width)) == numberClass) {\n            // Convert the `width` to an integer and create a string containing\n            // `width` number of space characters.\n            if ((width -= width % 1) > 0) {\n              for (whitespace = \"\", width > 10 && (width = 10); whitespace.length < width; whitespace += \" \");\n            }\n          } else if (className == stringClass) {\n            whitespace = width.length <= 10 ? width : width.slice(0, 10);\n          }\n        }\n        // Opera <= 7.54u2 discards the values associated with empty string keys\n        // (`\"\"`) only if they are used directly within an object member list\n        // (e.g., `!(\"\" in { \"\": 1})`).\n        return serialize(\"\", (value = {}, value[\"\"] = source, value), callback, properties, whitespace, \"\", []);\n      };\n    }\n\n    // Public: Parses a JSON source string.\n    if (!has(\"json-parse\")) {\n      var fromCharCode = String.fromCharCode;\n\n      // Internal: A map of escaped control characters and their unescaped\n      // equivalents.\n      var Unescapes = {\n        92: \"\\\\\",\n        34: '\"',\n        47: \"/\",\n        98: \"\\b\",\n        116: \"\\t\",\n        110: \"\\n\",\n        102: \"\\f\",\n        114: \"\\r\"\n      };\n\n      // Internal: Stores the parser state.\n      var Index, Source;\n\n      // Internal: Resets the parser state and throws a `SyntaxError`.\n      var abort = function() {\n        Index = Source = null;\n        throw SyntaxError();\n      };\n\n      // Internal: Returns the next token, or `\"$\"` if the parser has reached\n      // the end of the source string. A token may be a string, number, `null`\n      // literal, or Boolean literal.\n      var lex = function () {\n        var source = Source, length = source.length, value, begin, position, isSigned, charCode;\n        while (Index < length) {\n          charCode = source.charCodeAt(Index);\n          switch (charCode) {\n            case 9: case 10: case 13: case 32:\n              // Skip whitespace tokens, including tabs, carriage returns, line\n              // feeds, and space characters.\n              Index++;\n              break;\n            case 123: case 125: case 91: case 93: case 58: case 44:\n              // Parse a punctuator token (`{`, `}`, `[`, `]`, `:`, or `,`) at\n              // the current position.\n              value = charIndexBuggy ? source.charAt(Index) : source[Index];\n              Index++;\n              return value;\n            case 34:\n              // `\"` delimits a JSON string; advance to the next character and\n              // begin parsing the string. String tokens are prefixed with the\n              // sentinel `@` character to distinguish them from punctuators and\n              // end-of-string tokens.\n              for (value = \"@\", Index++; Index < length;) {\n                charCode = source.charCodeAt(Index);\n                if (charCode < 32) {\n                  // Unescaped ASCII control characters (those with a code unit\n                  // less than the space character) are not permitted.\n                  abort();\n                } else if (charCode == 92) {\n                  // A reverse solidus (`\\`) marks the beginning of an escaped\n                  // control character (including `\"`, `\\`, and `/`) or Unicode\n                  // escape sequence.\n                  charCode = source.charCodeAt(++Index);\n                  switch (charCode) {\n                    case 92: case 34: case 47: case 98: case 116: case 110: case 102: case 114:\n                      // Revive escaped control characters.\n                      value += Unescapes[charCode];\n                      Index++;\n                      break;\n                    case 117:\n                      // `\\u` marks the beginning of a Unicode escape sequence.\n                      // Advance to the first character and validate the\n                      // four-digit code point.\n                      begin = ++Index;\n                      for (position = Index + 4; Index < position; Index++) {\n                        charCode = source.charCodeAt(Index);\n                        // A valid sequence comprises four hexdigits (case-\n                        // insensitive) that form a single hexadecimal value.\n                        if (!(charCode >= 48 && charCode <= 57 || charCode >= 97 && charCode <= 102 || charCode >= 65 && charCode <= 70)) {\n                          // Invalid Unicode escape sequence.\n                          abort();\n                        }\n                      }\n                      // Revive the escaped character.\n                      value += fromCharCode(\"0x\" + source.slice(begin, Index));\n                      break;\n                    default:\n                      // Invalid escape sequence.\n                      abort();\n                  }\n                } else {\n                  if (charCode == 34) {\n                    // An unescaped double-quote character marks the end of the\n                    // string.\n                    break;\n                  }\n                  charCode = source.charCodeAt(Index);\n                  begin = Index;\n                  // Optimize for the common case where a string is valid.\n                  while (charCode >= 32 && charCode != 92 && charCode != 34) {\n                    charCode = source.charCodeAt(++Index);\n                  }\n                  // Append the string as-is.\n                  value += source.slice(begin, Index);\n                }\n              }\n              if (source.charCodeAt(Index) == 34) {\n                // Advance to the next character and return the revived string.\n                Index++;\n                return value;\n              }\n              // Unterminated string.\n              abort();\n            default:\n              // Parse numbers and literals.\n              begin = Index;\n              // Advance past the negative sign, if one is specified.\n              if (charCode == 45) {\n                isSigned = true;\n                charCode = source.charCodeAt(++Index);\n              }\n              // Parse an integer or floating-point value.\n              if (charCode >= 48 && charCode <= 57) {\n                // Leading zeroes are interpreted as octal literals.\n                if (charCode == 48 && ((charCode = source.charCodeAt(Index + 1)), charCode >= 48 && charCode <= 57)) {\n                  // Illegal octal literal.\n                  abort();\n                }\n                isSigned = false;\n                // Parse the integer component.\n                for (; Index < length && ((charCode = source.charCodeAt(Index)), charCode >= 48 && charCode <= 57); Index++);\n                // Floats cannot contain a leading decimal point; however, this\n                // case is already accounted for by the parser.\n                if (source.charCodeAt(Index) == 46) {\n                  position = ++Index;\n                  // Parse the decimal component.\n                  for (; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++);\n                  if (position == Index) {\n                    // Illegal trailing decimal.\n                    abort();\n                  }\n                  Index = position;\n                }\n                // Parse exponents. The `e` denoting the exponent is\n                // case-insensitive.\n                charCode = source.charCodeAt(Index);\n                if (charCode == 101 || charCode == 69) {\n                  charCode = source.charCodeAt(++Index);\n                  // Skip past the sign following the exponent, if one is\n                  // specified.\n                  if (charCode == 43 || charCode == 45) {\n                    Index++;\n                  }\n                  // Parse the exponential component.\n                  for (position = Index; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++);\n                  if (position == Index) {\n                    // Illegal empty exponent.\n                    abort();\n                  }\n                  Index = position;\n                }\n                // Coerce the parsed value to a JavaScript number.\n                return +source.slice(begin, Index);\n              }\n              // A negative sign may only precede numbers.\n              if (isSigned) {\n                abort();\n              }\n              // `true`, `false`, and `null` literals.\n              if (source.slice(Index, Index + 4) == \"true\") {\n                Index += 4;\n                return true;\n              } else if (source.slice(Index, Index + 5) == \"false\") {\n                Index += 5;\n                return false;\n              } else if (source.slice(Index, Index + 4) == \"null\") {\n                Index += 4;\n                return null;\n              }\n              // Unrecognized token.\n              abort();\n          }\n        }\n        // Return the sentinel `$` character if the parser has reached the end\n        // of the source string.\n        return \"$\";\n      };\n\n      // Internal: Parses a JSON `value` token.\n      var get = function (value) {\n        var results, hasMembers;\n        if (value == \"$\") {\n          // Unexpected end of input.\n          abort();\n        }\n        if (typeof value == \"string\") {\n          if ((charIndexBuggy ? value.charAt(0) : value[0]) == \"@\") {\n            // Remove the sentinel `@` character.\n            return value.slice(1);\n          }\n          // Parse object and array literals.\n          if (value == \"[\") {\n            // Parses a JSON array, returning a new JavaScript array.\n            results = [];\n            for (;; hasMembers || (hasMembers = true)) {\n              value = lex();\n              // A closing square bracket marks the end of the array literal.\n              if (value == \"]\") {\n                break;\n              }\n              // If the array literal contains elements, the current token\n              // should be a comma separating the previous element from the\n              // next.\n              if (hasMembers) {\n                if (value == \",\") {\n                  value = lex();\n                  if (value == \"]\") {\n                    // Unexpected trailing `,` in array literal.\n                    abort();\n                  }\n                } else {\n                  // A `,` must separate each array element.\n                  abort();\n                }\n              }\n              // Elisions and leading commas are not permitted.\n              if (value == \",\") {\n                abort();\n              }\n              results.push(get(value));\n            }\n            return results;\n          } else if (value == \"{\") {\n            // Parses a JSON object, returning a new JavaScript object.\n            results = {};\n            for (;; hasMembers || (hasMembers = true)) {\n              value = lex();\n              // A closing curly brace marks the end of the object literal.\n              if (value == \"}\") {\n                break;\n              }\n              // If the object literal contains members, the current token\n              // should be a comma separator.\n              if (hasMembers) {\n                if (value == \",\") {\n                  value = lex();\n                  if (value == \"}\") {\n                    // Unexpected trailing `,` in object literal.\n                    abort();\n                  }\n                } else {\n                  // A `,` must separate each object member.\n                  abort();\n                }\n              }\n              // Leading commas are not permitted, object property names must be\n              // double-quoted strings, and a `:` must separate each property\n              // name and value.\n              if (value == \",\" || typeof value != \"string\" || (charIndexBuggy ? value.charAt(0) : value[0]) != \"@\" || lex() != \":\") {\n                abort();\n              }\n              results[value.slice(1)] = get(lex());\n            }\n            return results;\n          }\n          // Unexpected token encountered.\n          abort();\n        }\n        return value;\n      };\n\n      // Internal: Updates a traversed object member.\n      var update = function(source, property, callback) {\n        var element = walk(source, property, callback);\n        if (element === undef) {\n          delete source[property];\n        } else {\n          source[property] = element;\n        }\n      };\n\n      // Internal: Recursively traverses a parsed JSON object, invoking the\n      // `callback` function for each value. This is an implementation of the\n      // `Walk(holder, name)` operation defined in ES 5.1 section 15.12.2.\n      var walk = function (source, property, callback) {\n        var value = source[property], length;\n        if (typeof value == \"object\" && value) {\n          // `forEach` can't be used to traverse an array in Opera <= 8.54\n          // because its `Object#hasOwnProperty` implementation returns `false`\n          // for array indices (e.g., `![1, 2, 3].hasOwnProperty(\"0\")`).\n          if (getClass.call(value) == arrayClass) {\n            for (length = value.length; length--;) {\n              update(value, length, callback);\n            }\n          } else {\n            forEach(value, function (property) {\n              update(value, property, callback);\n            });\n          }\n        }\n        return callback.call(source, property, value);\n      };\n\n      // Public: `JSON.parse`. See ES 5.1 section 15.12.2.\n      JSON3.parse = function (source, callback) {\n        var result, value;\n        Index = 0;\n        Source = \"\" + source;\n        result = get(lex());\n        // If a JSON string contains multiple tokens, it is invalid.\n        if (lex() != \"$\") {\n          abort();\n        }\n        // Reset the parser state.\n        Index = Source = null;\n        return callback && getClass.call(callback) == functionClass ? walk((value = {}, value[\"\"] = result, value), \"\", callback) : result;\n      };\n    }\n  }\n\n  // Export for asynchronous module loaders.\n  if (isLoader) {\n    define(function () {\n      return JSON3;\n    });\n  }\n}(this));\n\n},{}],48:[function(_dereq_,module,exports){\nmodule.exports = toArray\n\nfunction toArray(list, index) {\n    var array = []\n\n    index = index || 0\n\n    for (var i = index || 0; i < list.length; i++) {\n        array[i - index] = list[i]\n    }\n\n    return array\n}\n\n},{}]},{},[1])\n(1)\n});\n"

/***/ }),
/* 54 */
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(1)(__webpack_require__(53))

/***/ }),
/* 55 */
/***/ (function(module, exports, __webpack_require__) {


var content = __webpack_require__(45);

if(typeof content === 'string') content = [[module.i, content, '']];

var transform;
var insertInto;



var options = {"hmr":true}

options.transform = transform
options.insertInto = undefined;

var update = __webpack_require__(3)(content, options);

if(content.locals) module.exports = content.locals;

if(false) {
	module.hot.accept("!!../node_modules/css-loader/index.js!./opt-testcases.css", function() {
		var newContent = require("!!../node_modules/css-loader/index.js!./opt-testcases.css");

		if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];

		var locals = (function(a, b) {
			var key, idx = 0;

			for(key in a) {
				if(!b || a[key] !== b[key]) return false;
				idx++;
			}

			for(key in b) idx--;

			return idx === 0;
		}(content.locals, newContent.locals));

		if(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');

		update(newContent);
	});

	module.hot.dispose(function() { update(); });
}

/***/ }),
/* 56 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
/* WEBPACK VAR INJECTION */(function($) {
Object.defineProperty(exports, "__esModule", { value: true });
var opt_shared_sessions_1 = __webpack_require__(33);
var pytutor_1 = __webpack_require__(4);
// represents a list of TogetherJS events that can be replayed, paused, etc.
// within the context of the current app, along with audio
var OptDemoVideo = /** @class */ (function () {
    function OptDemoVideo(frontend, serializedJsonStr) {
        if (serializedJsonStr === void 0) { serializedJsonStr = null; }
        this.events = [];
        this.isFrozen = false; // set to true after you finish recording to 'freeze'
        this.fps = 30; // frames per second for setInterval-based playback
        this.currentFrame = 0; // for play/pause
        this.currentStep = 0; // a 'step' is an index into events, whereas a 'frame' is an animation frame
        this.isPaused = false; // is playback currently paused?
        this.rafTimerId = undefined;
        this.mp3AudioRecording = null; // a data URL representing the contents of the mp3 audio (if available)
        this.audioElt = null; // HTML5 Audio() object
        this.frontend = frontend;
        // initialize from an existing JSON string created with serializeToJSON()
        if (serializedJsonStr) {
            var obj = JSON.parse(serializedJsonStr);
            this.initialAppState = obj.initialAppState;
            this.events = obj.events;
            this.traceCache = obj.traceCache;
            this.mp3AudioRecording = obj.mp3AudioRecording;
            // VERY IMPORTANT -- set the traceCache entry of the frontend so
            // that it can actually be used. #tricky!
            // TODO: this is kind of a gross abstraction violation, eergh
            this.frontend.traceCache = this.traceCache;
            this.isFrozen = true; // freeze it!
            this.addFrameNumbers();
        }
    }
    // only record certain kinds of events in the recorder
    // see ../../v3/opt_togetherjs/server.js around line 460 for all
    OptDemoVideo.shouldRecordEvent = function (e) {
        // do NOT record cursor-click since that's too much noise
        return ((e.type == 'form-update') ||
            (e.type == 'cursor-update') ||
            (e.type == 'app.executeCode') ||
            (e.type == 'app.updateOutput') ||
            (e.type == 'app.startRecordingDemo') ||
            (e.type == 'app.stopRecordingDemo') ||
            (e.type == 'app.aceChangeCursor') ||
            (e.type == 'app.aceChangeSelection') ||
            (e.type == 'pyCodeOutputDivScroll') ||
            (e.type == 'app.hashchange'));
    };
    OptDemoVideo.prototype.addEvent = function (msg) {
        pytutor_1.assert(!this.isFrozen);
        msg.ts = new Date().getTime(); // augment with timestamp
        msg.peer = { color: "#8d549f" }; // fake just enough of a peer object for downstream functions to work
        msg.sameUrl = true;
        if (OptDemoVideo.shouldRecordEvent(msg)) {
            this.events.push(msg);
        }
    };
    // do this BEFORE TogetherJS gets initialized
    OptDemoVideo.prototype.startRecording = function () {
        pytutor_1.assert(!this.isFrozen);
        pytutor_1.assert(!opt_shared_sessions_1.TogetherJS.running);
        this.frontend.traceCacheClear();
        this.initialAppState = this.frontend.getAppState();
        // cache the current trace if we're in display mode
        if (this.initialAppState.mode == "display") {
            this.frontend.traceCacheAdd();
        }
        this.frontend.isRecordingDemo = true;
        opt_shared_sessions_1.TogetherJS.config('isDemoSession', true);
        opt_shared_sessions_1.TogetherJS(); // activate TogetherJS as the last step to start the recording
    };
    // this is run as soon as TogetherJS is ready in recording mode
    OptDemoVideo.prototype.recordTogetherJsReady = function () {
        pytutor_1.assert(opt_shared_sessions_1.TogetherJS.running && this.frontend.isRecordingDemo && !this.frontend.isPlayingDemo);
        // set the TogetherJS eventRecorderFunc to this.demoVideo.addEvent
        // (don't forget to bind it as 'this', ergh!)
        opt_shared_sessions_1.TogetherJS.config('eventRecorderFunc', this.addEvent.bind(this));
    };
    OptDemoVideo.prototype.stopRecording = function () {
        pytutor_1.assert(!this.isFrozen);
        this.traceCache = this.frontend.traceCache;
        this.isFrozen = true; // freeze it!
        this.addFrameNumbers();
        this.frontend.isRecordingDemo = false;
        opt_shared_sessions_1.TogetherJS.config('isDemoSession', false);
        opt_shared_sessions_1.TogetherJS.config('eventRecorderFunc', null);
    };
    OptDemoVideo.prototype.setInitialAppState = function () {
        pytutor_1.assert(this.initialAppState);
        this.frontend.pyInputSetValue(this.initialAppState.code);
        this.frontend.setToggleOptions(this.initialAppState);
        if (this.initialAppState.mode == 'display') {
            // we *should* get a cache hit in traceCache so this won't go to the server
            this.frontend.executeCode(this.initialAppState.curInstr);
        }
        else {
            pytutor_1.assert(this.initialAppState.mode == 'edit');
            this.frontend.enterEditMode();
        }
        this.currentFrame = 0;
        this.currentStep = 0;
        // OK this is super subtle but important. you want to call setInit
        // defined deep in the bowels of lib/togetherjs/togetherjs/togetherjsPackage.js
        // why are we calling it right now? because we need to clear the
        // edit history that TogetherJS captures to start us over with a
        // clean slate so that we can start replaying events from the start
        // of the trace. otherwise form-update events in the Ace editor
        // won't work. we need setInit since it's *synchronous* and executes
        // instantly rather than waiting on an async event queue.
        var setInit = opt_shared_sessions_1.TogetherJS.config.get('setInit');
        setInit();
    };
    OptDemoVideo.prototype.startPlayback = function () {
        pytutor_1.assert(this.isFrozen);
        pytutor_1.assert(!opt_shared_sessions_1.TogetherJS.running); // do this before TogetherJS is initialized
        pytutor_1.assert(this.mp3AudioRecording); // audio must be initialized before you start playing
        // save the original value of ignoreForms
        this.origIgnoreForms = opt_shared_sessions_1.TogetherJS.config.get('ignoreForms');
        // set this to true, which will have TogetherJS ignore ALL FORM
        // EVENTS, which means that it will ignore events fired on the Ace
        // editor (which are form-update events or somethin') ... if we
        // don't do that, then spurious events will get fired durin playback
        // and weird stuff will happen
        opt_shared_sessions_1.TogetherJS.config('ignoreForms', true);
        this.frontend.isPlayingDemo = true;
        opt_shared_sessions_1.TogetherJS.config('isDemoSession', true);
        opt_shared_sessions_1.TogetherJS(); // activate TogetherJS as the last step to start playback mode
    };
    // set a timer to play in real time starting at this.currentFrame
    OptDemoVideo.prototype.playFromCurrentFrame = function () {
        var _this = this;
        pytutor_1.assert(opt_shared_sessions_1.TogetherJS.running && this.frontend.isPlayingDemo);
        var totalFrames = this.getTotalNumFrames();
        // if we're at the VERY end, then loop back to the very beginning
        if (this.currentFrame >= totalFrames) {
            this.setInitialAppState();
        }
        var startingFrame = this.currentFrame;
        // play the first N steps to get up to right before this.currentFrame
        // TODO: it's kinda klunky to convert "video" frames to steps, which
        // which are actually indices into this.events
        if (startingFrame > 0) {
            var step = this.frameToStepNumber(startingFrame);
            this.playFirstNSteps(step);
        }
        // handle audio
        pytutor_1.assert(this.mp3AudioRecording);
        // always create a new element each time to avoid stale old ones
        // being stuck at weird seek positions
        this.audioElt = new Audio();
        this.audioElt.src = this.mp3AudioRecording;
        this.audioElt.currentTime = this.frameToSeconds(startingFrame);
        this.audioElt.play();
        console.log('playFromCurrentFrame', startingFrame, 'totalFrames', totalFrames, 'currentTime:', this.audioElt.currentTime, this.audioElt.ended);
        var starttime = -1;
        var rafHelper = function (timestamp) {
            pytutor_1.assert(_this.audioElt); // we will always synchronize with the audio, so if you don't have audio, it's a dealbreaker
            if (_this.isPaused) {
                return;
            }
            // keep going until your audio dies:
            if (!_this.audioElt.ended) {
                _this.rafTimerId = requestAnimationFrame(rafHelper);
                // always use the latest values of this.audioElt.currentTime to
                // calculate the current frame so that we can try to keep the
                // audio and animation in sync as much as possible:
                var frameNum = _this.secondsToFrames(_this.audioElt.currentTime);
                _this.currentFrame = frameNum;
                //console.log('audioElt.currentTime:', this.audioElt.currentTime, frameNum, totalFrames, this.audioElt.ended);
                // TODO: this is an abstraction violation since OptDemoVideo
                // shouldn't know about #timeSlider, which is part of the GUI!
                // (maybe tunnel this through a callback?)
                $("#timeSlider").slider("value", frameNum); // triggers slider 'change' event
            }
            else {
                // set currentFrame and slider to the very end for consistency
                _this.currentFrame = totalFrames;
                $("#timeSlider").slider("value", totalFrames);
                _this.frontend.setPlayPauseButton('paused');
            }
        };
        // kick it off!
        this.isPaused = false; // unpause me!
        this.rafTimerId = requestAnimationFrame(function (timestamp) {
            starttime = timestamp;
            rafHelper(timestamp);
        });
        this.frontend.pyInputAceEditor.setReadOnly(true); // don't let the user edit code when demo is playing
    };
    OptDemoVideo.prototype.pause = function () {
        pytutor_1.assert(opt_shared_sessions_1.TogetherJS.running && this.frontend.isPlayingDemo);
        this.isPaused = true;
        console.log('pause: currentFrame:', this.currentFrame);
        if (this.rafTimerId) {
            cancelAnimationFrame(this.rafTimerId);
            this.rafTimerId = undefined;
        }
        if (this.audioElt) {
            this.audioElt.pause();
            // kill it and start afresh each time to (hopefully) avoid out of sync issues
            this.audioElt.src = '';
            this.audioElt = null;
        }
        this.frontend.pyInputAceEditor.setReadOnly(false); // let the user edit code when paused
    };
    // this is run as soon as TogetherJS is ready in playback mode
    OptDemoVideo.prototype.playbackTogetherJsReady = function () {
        pytutor_1.assert(opt_shared_sessions_1.TogetherJS.running && this.frontend.isPlayingDemo && !this.frontend.isRecordingDemo);
        // initialize the session here
        this.sess = opt_shared_sessions_1.TogetherJS.require("session");
        // STENT for debugging only
        window.demoVideo = this;
        this.setInitialAppState(); // reset app state to the initial one
    };
    OptDemoVideo.prototype.playEvent = function (msg) {
        pytutor_1.assert(this.sess && this.frontend.isPlayingDemo);
        //this.frontend.pyInputAceEditor.resize(true);
        // seems weird but we need both session.hub.emit() and
        // TogetherJS._onmessage() in order to gracefully handle
        // both built-in TogetherJS events and custom OPT app events:
        // copied-pasted from lib/togetherjs/togetherjs/togetherjsPackage.js
        // around line 1870
        try {
            this.sess.hub.emit(msg.type, msg);
        }
        catch (e) {
            console.warn(e);
            // let it go! let it go!
        }
        try {
            opt_shared_sessions_1.TogetherJS._onmessage(msg);
        }
        catch (e) {
            console.warn(e);
            // let it go! let it go!
        }
        // however, TogetherJS._onmessage mangles up the type fields
        // (UGH!), so we need to restore them back to their original
        // form to ensure idempotence. copied from session.appSend()
        var type = msg.type;
        if (type.search(/^togetherjs\./) === 0) {
            type = type.substr("togetherjs.".length);
        }
        else if (type.search(/^app\./) === -1) {
            type = "app." + type;
        }
        msg.type = type;
    };
    OptDemoVideo.prototype.playStep = function (i) {
        pytutor_1.assert(i >= 0 && i < this.events.length);
        this.playEvent(this.events[i]);
        this.currentStep = i; // very important!!!
    };
    // play all steps from [lower, upper], inclusive
    OptDemoVideo.prototype.playStepRange = function (lower, upper) {
        //console.log('playStepRange', lower, upper, 'curStep:', this.currentStep);
        pytutor_1.assert(lower <= upper);
        for (var i = lower; i <= upper; i++) {
            this.playStep(i);
        }
    };
    // this method *instantaneously* plays all steps from 0 to n
    // (so everything it calls should work SYNCHRONOUSLY ...
    //  if there's async code in its callee chain, something will probably break)
    OptDemoVideo.prototype.playFirstNSteps = function (n) {
        //console.log('playFirstNSteps', n, 'curStep', this.currentStep, 'curFrame', this.currentFrame);
        pytutor_1.assert(this.isFrozen);
        pytutor_1.assert(opt_shared_sessions_1.TogetherJS.running && this.frontend.isPlayingDemo);
        pytutor_1.assert(n >= 0 && n < this.events.length);
        this.setInitialAppState(); // reset app state to the initial one
        // go up to n, inclusive!
        for (var i = 0; i <= n; i++) {
            this.playStep(i);
        }
    };
    // given a frame number, convert it to the step number (i.e., index in
    // this.events) that takes place right BEFORE that given frame.
    OptDemoVideo.prototype.frameToStepNumber = function (n) {
        pytutor_1.assert(this.isFrozen && this.events[0].frameNum);
        var foundIndex = -1;
        for (var i = 0; i < this.events.length; i++) {
            if (n < this.events[i].frameNum) {
                foundIndex = i;
                break;
            }
        }
        if (foundIndex < 0) {
            return this.events.length - 1;
        }
        else if (foundIndex == 0) {
            return 0; // TODO: kinda weird that we return 0 for foundIndex being 0 or 1
        }
        else {
            return foundIndex - 1; // subtract 1 to get the step right BEFORE the found one
        }
    };
    OptDemoVideo.prototype.jumpToFrame = function (frame) {
        pytutor_1.assert(this.currentStep >= 0);
        var step = this.frameToStepNumber(frame);
        // avoid unnecessary calls
        if (step == this.currentStep) {
            // do nothing! pass thru
        }
        else if (step > this.currentStep) {
            // as an optimization, simply play ahead from the current step
            // rather than playing all steps from 0 to step again from scratch
            this.playStepRange(this.currentStep + 1, step);
        }
        else {
            // if we're stepping backwards, then we have no choice but to
            // play everything from scratch because we can't "undo" actions
            pytutor_1.assert(step >= 0 && step < this.currentStep);
            this.playFirstNSteps(step);
        }
        this.currentFrame = frame; // do this at the VERY END after all the dust clears
    };
    OptDemoVideo.prototype.stopPlayback = function () {
        this.sess = null;
        this.frontend.isPlayingDemo = false;
        opt_shared_sessions_1.TogetherJS.config('ignoreForms', this.origIgnoreForms); // restore its original value
        opt_shared_sessions_1.TogetherJS.config('isDemoSession', false);
        opt_shared_sessions_1.TogetherJS.config('eventRecorderFunc', null);
    };
    // serialize the current state to JSON:
    OptDemoVideo.prototype.serializeToJSON = function () {
        pytutor_1.assert(this.isFrozen);
        var ret = { initialAppState: this.initialAppState,
            events: this.events,
            traceCache: this.traceCache,
            mp3AudioRecording: this.mp3AudioRecording };
        return JSON.stringify(ret);
    };
    OptDemoVideo.prototype.getFrameDiff = function (a, b) {
        pytutor_1.assert(a <= b);
        return Math.floor(((b - a) / 1000) * this.fps);
    };
    // add a frameNum field for each entry in this.events
    OptDemoVideo.prototype.addFrameNumbers = function () {
        pytutor_1.assert(this.isFrozen && this.events.length > 0);
        var firstTs = this.events[0].ts;
        for (var i = 0; i < this.events.length; i++) {
            var elt = this.events[i];
            // add 1 so that the first frameNum starts at 1 instead of 0
            elt.frameNum = this.getFrameDiff(firstTs, elt.ts) + 1;
        }
    };
    // how many frames should there be in the animation?
    OptDemoVideo.prototype.getTotalNumFrames = function () {
        pytutor_1.assert(this.isFrozen && this.events.length > 0);
        var firstTs = this.events[0].ts;
        var lastTs = this.events[this.events.length - 1].ts;
        return this.getFrameDiff(firstTs, lastTs);
        // add 1 at the end for extra padding
        // NIX THIS!!!
        //return this.getFrameDiff(firstTs, lastTs) + 1;
    };
    OptDemoVideo.prototype.secondsToFrames = function (secs) {
        return Math.floor(secs * this.fps);
    };
    OptDemoVideo.prototype.frameToSeconds = function (frame) {
        return frame / this.fps;
    };
    return OptDemoVideo;
}());
exports.OptDemoVideo = OptDemoVideo;

/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0)))

/***/ }),
/* 57 */
/***/ (function(module, exports) {

module.exports = "/*!@license Copyright 2013, Heinrich Goebl, License: MIT, see https://github.com/hgoebl/mobile-detect.js*/\n!function(a,b){a(function(){\"use strict\";function a(a,b){return null!=a&&null!=b&&a.toLowerCase()===b.toLowerCase()}function c(a,b){var c,d,e=a.length;if(!e||!b)return!1;for(c=b.toLowerCase(),d=0;d<e;++d)if(c===a[d].toLowerCase())return!0;return!1}function d(a){for(var b in a)h.call(a,b)&&(a[b]=new RegExp(a[b],\"i\"))}function e(a,b){this.ua=a||\"\",this._cache={},this.maxPhoneWidth=b||600}var f={};f.mobileDetectRules={phones:{iPhone:\"\\\\biPhone\\\\b|\\\\biPod\\\\b\",BlackBerry:\"BlackBerry|\\\\bBB10\\\\b|rim[0-9]+\",HTC:\"HTC|HTC.*(Sensation|Evo|Vision|Explorer|6800|8100|8900|A7272|S510e|C110e|Legend|Desire|T8282)|APX515CKT|Qtek9090|APA9292KT|HD_mini|Sensation.*Z710e|PG86100|Z715e|Desire.*(A8181|HD)|ADR6200|ADR6400L|ADR6425|001HT|Inspire 4G|Android.*\\\\bEVO\\\\b|T-Mobile G1|Z520m\",Nexus:\"Nexus One|Nexus S|Galaxy.*Nexus|Android.*Nexus.*Mobile|Nexus 4|Nexus 5|Nexus 6\",Dell:\"Dell.*Streak|Dell.*Aero|Dell.*Venue|DELL.*Venue Pro|Dell Flash|Dell Smoke|Dell Mini 3iX|XCD28|XCD35|\\\\b001DL\\\\b|\\\\b101DL\\\\b|\\\\bGS01\\\\b\",Motorola:\"Motorola|DROIDX|DROID BIONIC|\\\\bDroid\\\\b.*Build|Android.*Xoom|HRI39|MOT-|A1260|A1680|A555|A853|A855|A953|A955|A956|Motorola.*ELECTRIFY|Motorola.*i1|i867|i940|MB200|MB300|MB501|MB502|MB508|MB511|MB520|MB525|MB526|MB611|MB612|MB632|MB810|MB855|MB860|MB861|MB865|MB870|ME501|ME502|ME511|ME525|ME600|ME632|ME722|ME811|ME860|ME863|ME865|MT620|MT710|MT716|MT720|MT810|MT870|MT917|Motorola.*TITANIUM|WX435|WX445|XT300|XT301|XT311|XT316|XT317|XT319|XT320|XT390|XT502|XT530|XT531|XT532|XT535|XT603|XT610|XT611|XT615|XT681|XT701|XT702|XT711|XT720|XT800|XT806|XT860|XT862|XT875|XT882|XT883|XT894|XT901|XT907|XT909|XT910|XT912|XT928|XT926|XT915|XT919|XT925|XT1021|\\\\bMoto E\\\\b\",Samsung:\"\\\\bSamsung\\\\b|SM-G9250|GT-19300|SGH-I337|BGT-S5230|GT-B2100|GT-B2700|GT-B2710|GT-B3210|GT-B3310|GT-B3410|GT-B3730|GT-B3740|GT-B5510|GT-B5512|GT-B5722|GT-B6520|GT-B7300|GT-B7320|GT-B7330|GT-B7350|GT-B7510|GT-B7722|GT-B7800|GT-C3010|GT-C3011|GT-C3060|GT-C3200|GT-C3212|GT-C3212I|GT-C3262|GT-C3222|GT-C3300|GT-C3300K|GT-C3303|GT-C3303K|GT-C3310|GT-C3322|GT-C3330|GT-C3350|GT-C3500|GT-C3510|GT-C3530|GT-C3630|GT-C3780|GT-C5010|GT-C5212|GT-C6620|GT-C6625|GT-C6712|GT-E1050|GT-E1070|GT-E1075|GT-E1080|GT-E1081|GT-E1085|GT-E1087|GT-E1100|GT-E1107|GT-E1110|GT-E1120|GT-E1125|GT-E1130|GT-E1160|GT-E1170|GT-E1175|GT-E1180|GT-E1182|GT-E1200|GT-E1210|GT-E1225|GT-E1230|GT-E1390|GT-E2100|GT-E2120|GT-E2121|GT-E2152|GT-E2220|GT-E2222|GT-E2230|GT-E2232|GT-E2250|GT-E2370|GT-E2550|GT-E2652|GT-E3210|GT-E3213|GT-I5500|GT-I5503|GT-I5700|GT-I5800|GT-I5801|GT-I6410|GT-I6420|GT-I7110|GT-I7410|GT-I7500|GT-I8000|GT-I8150|GT-I8160|GT-I8190|GT-I8320|GT-I8330|GT-I8350|GT-I8530|GT-I8700|GT-I8703|GT-I8910|GT-I9000|GT-I9001|GT-I9003|GT-I9010|GT-I9020|GT-I9023|GT-I9070|GT-I9082|GT-I9100|GT-I9103|GT-I9220|GT-I9250|GT-I9300|GT-I9305|GT-I9500|GT-I9505|GT-M3510|GT-M5650|GT-M7500|GT-M7600|GT-M7603|GT-M8800|GT-M8910|GT-N7000|GT-S3110|GT-S3310|GT-S3350|GT-S3353|GT-S3370|GT-S3650|GT-S3653|GT-S3770|GT-S3850|GT-S5210|GT-S5220|GT-S5229|GT-S5230|GT-S5233|GT-S5250|GT-S5253|GT-S5260|GT-S5263|GT-S5270|GT-S5300|GT-S5330|GT-S5350|GT-S5360|GT-S5363|GT-S5369|GT-S5380|GT-S5380D|GT-S5560|GT-S5570|GT-S5600|GT-S5603|GT-S5610|GT-S5620|GT-S5660|GT-S5670|GT-S5690|GT-S5750|GT-S5780|GT-S5830|GT-S5839|GT-S6102|GT-S6500|GT-S7070|GT-S7200|GT-S7220|GT-S7230|GT-S7233|GT-S7250|GT-S7500|GT-S7530|GT-S7550|GT-S7562|GT-S7710|GT-S8000|GT-S8003|GT-S8500|GT-S8530|GT-S8600|SCH-A310|SCH-A530|SCH-A570|SCH-A610|SCH-A630|SCH-A650|SCH-A790|SCH-A795|SCH-A850|SCH-A870|SCH-A890|SCH-A930|SCH-A950|SCH-A970|SCH-A990|SCH-I100|SCH-I110|SCH-I400|SCH-I405|SCH-I500|SCH-I510|SCH-I515|SCH-I600|SCH-I730|SCH-I760|SCH-I770|SCH-I830|SCH-I910|SCH-I920|SCH-I959|SCH-LC11|SCH-N150|SCH-N300|SCH-R100|SCH-R300|SCH-R351|SCH-R400|SCH-R410|SCH-T300|SCH-U310|SCH-U320|SCH-U350|SCH-U360|SCH-U365|SCH-U370|SCH-U380|SCH-U410|SCH-U430|SCH-U450|SCH-U460|SCH-U470|SCH-U490|SCH-U540|SCH-U550|SCH-U620|SCH-U640|SCH-U650|SCH-U660|SCH-U700|SCH-U740|SCH-U750|SCH-U810|SCH-U820|SCH-U900|SCH-U940|SCH-U960|SCS-26UC|SGH-A107|SGH-A117|SGH-A127|SGH-A137|SGH-A157|SGH-A167|SGH-A177|SGH-A187|SGH-A197|SGH-A227|SGH-A237|SGH-A257|SGH-A437|SGH-A517|SGH-A597|SGH-A637|SGH-A657|SGH-A667|SGH-A687|SGH-A697|SGH-A707|SGH-A717|SGH-A727|SGH-A737|SGH-A747|SGH-A767|SGH-A777|SGH-A797|SGH-A817|SGH-A827|SGH-A837|SGH-A847|SGH-A867|SGH-A877|SGH-A887|SGH-A897|SGH-A927|SGH-B100|SGH-B130|SGH-B200|SGH-B220|SGH-C100|SGH-C110|SGH-C120|SGH-C130|SGH-C140|SGH-C160|SGH-C170|SGH-C180|SGH-C200|SGH-C207|SGH-C210|SGH-C225|SGH-C230|SGH-C417|SGH-C450|SGH-D307|SGH-D347|SGH-D357|SGH-D407|SGH-D415|SGH-D780|SGH-D807|SGH-D980|SGH-E105|SGH-E200|SGH-E315|SGH-E316|SGH-E317|SGH-E335|SGH-E590|SGH-E635|SGH-E715|SGH-E890|SGH-F300|SGH-F480|SGH-I200|SGH-I300|SGH-I320|SGH-I550|SGH-I577|SGH-I600|SGH-I607|SGH-I617|SGH-I627|SGH-I637|SGH-I677|SGH-I700|SGH-I717|SGH-I727|SGH-i747M|SGH-I777|SGH-I780|SGH-I827|SGH-I847|SGH-I857|SGH-I896|SGH-I897|SGH-I900|SGH-I907|SGH-I917|SGH-I927|SGH-I937|SGH-I997|SGH-J150|SGH-J200|SGH-L170|SGH-L700|SGH-M110|SGH-M150|SGH-M200|SGH-N105|SGH-N500|SGH-N600|SGH-N620|SGH-N625|SGH-N700|SGH-N710|SGH-P107|SGH-P207|SGH-P300|SGH-P310|SGH-P520|SGH-P735|SGH-P777|SGH-Q105|SGH-R210|SGH-R220|SGH-R225|SGH-S105|SGH-S307|SGH-T109|SGH-T119|SGH-T139|SGH-T209|SGH-T219|SGH-T229|SGH-T239|SGH-T249|SGH-T259|SGH-T309|SGH-T319|SGH-T329|SGH-T339|SGH-T349|SGH-T359|SGH-T369|SGH-T379|SGH-T409|SGH-T429|SGH-T439|SGH-T459|SGH-T469|SGH-T479|SGH-T499|SGH-T509|SGH-T519|SGH-T539|SGH-T559|SGH-T589|SGH-T609|SGH-T619|SGH-T629|SGH-T639|SGH-T659|SGH-T669|SGH-T679|SGH-T709|SGH-T719|SGH-T729|SGH-T739|SGH-T746|SGH-T749|SGH-T759|SGH-T769|SGH-T809|SGH-T819|SGH-T839|SGH-T919|SGH-T929|SGH-T939|SGH-T959|SGH-T989|SGH-U100|SGH-U200|SGH-U800|SGH-V205|SGH-V206|SGH-X100|SGH-X105|SGH-X120|SGH-X140|SGH-X426|SGH-X427|SGH-X475|SGH-X495|SGH-X497|SGH-X507|SGH-X600|SGH-X610|SGH-X620|SGH-X630|SGH-X700|SGH-X820|SGH-X890|SGH-Z130|SGH-Z150|SGH-Z170|SGH-ZX10|SGH-ZX20|SHW-M110|SPH-A120|SPH-A400|SPH-A420|SPH-A460|SPH-A500|SPH-A560|SPH-A600|SPH-A620|SPH-A660|SPH-A700|SPH-A740|SPH-A760|SPH-A790|SPH-A800|SPH-A820|SPH-A840|SPH-A880|SPH-A900|SPH-A940|SPH-A960|SPH-D600|SPH-D700|SPH-D710|SPH-D720|SPH-I300|SPH-I325|SPH-I330|SPH-I350|SPH-I500|SPH-I600|SPH-I700|SPH-L700|SPH-M100|SPH-M220|SPH-M240|SPH-M300|SPH-M305|SPH-M320|SPH-M330|SPH-M350|SPH-M360|SPH-M370|SPH-M380|SPH-M510|SPH-M540|SPH-M550|SPH-M560|SPH-M570|SPH-M580|SPH-M610|SPH-M620|SPH-M630|SPH-M800|SPH-M810|SPH-M850|SPH-M900|SPH-M910|SPH-M920|SPH-M930|SPH-N100|SPH-N200|SPH-N240|SPH-N300|SPH-N400|SPH-Z400|SWC-E100|SCH-i909|GT-N7100|GT-N7105|SCH-I535|SM-N900A|SGH-I317|SGH-T999L|GT-S5360B|GT-I8262|GT-S6802|GT-S6312|GT-S6310|GT-S5312|GT-S5310|GT-I9105|GT-I8510|GT-S6790N|SM-G7105|SM-N9005|GT-S5301|GT-I9295|GT-I9195|SM-C101|GT-S7392|GT-S7560|GT-B7610|GT-I5510|GT-S7582|GT-S7530E|GT-I8750|SM-G9006V|SM-G9008V|SM-G9009D|SM-G900A|SM-G900D|SM-G900F|SM-G900H|SM-G900I|SM-G900J|SM-G900K|SM-G900L|SM-G900M|SM-G900P|SM-G900R4|SM-G900S|SM-G900T|SM-G900V|SM-G900W8|SHV-E160K|SCH-P709|SCH-P729|SM-T2558|GT-I9205|SM-G9350|SM-J120F|SM-G920F|SM-G920V|SM-G930F|SM-N910C\",LG:\"\\\\bLG\\\\b;|LG[- ]?(C800|C900|E400|E610|E900|E-900|F160|F180K|F180L|F180S|730|855|L160|LS740|LS840|LS970|LU6200|MS690|MS695|MS770|MS840|MS870|MS910|P500|P700|P705|VM696|AS680|AS695|AX840|C729|E970|GS505|272|C395|E739BK|E960|L55C|L75C|LS696|LS860|P769BK|P350|P500|P509|P870|UN272|US730|VS840|VS950|LN272|LN510|LS670|LS855|LW690|MN270|MN510|P509|P769|P930|UN200|UN270|UN510|UN610|US670|US740|US760|UX265|UX840|VN271|VN530|VS660|VS700|VS740|VS750|VS910|VS920|VS930|VX9200|VX11000|AX840A|LW770|P506|P925|P999|E612|D955|D802|MS323)\",Sony:\"SonyST|SonyLT|SonyEricsson|SonyEricssonLT15iv|LT18i|E10i|LT28h|LT26w|SonyEricssonMT27i|C5303|C6902|C6903|C6906|C6943|D2533\",Asus:\"Asus.*Galaxy|PadFone.*Mobile\",NokiaLumia:\"Lumia [0-9]{3,4}\",Micromax:\"Micromax.*\\\\b(A210|A92|A88|A72|A111|A110Q|A115|A116|A110|A90S|A26|A51|A35|A54|A25|A27|A89|A68|A65|A57|A90)\\\\b\",Palm:\"PalmSource|Palm\",Vertu:\"Vertu|Vertu.*Ltd|Vertu.*Ascent|Vertu.*Ayxta|Vertu.*Constellation(F|Quest)?|Vertu.*Monika|Vertu.*Signature\",Pantech:\"PANTECH|IM-A850S|IM-A840S|IM-A830L|IM-A830K|IM-A830S|IM-A820L|IM-A810K|IM-A810S|IM-A800S|IM-T100K|IM-A725L|IM-A780L|IM-A775C|IM-A770K|IM-A760S|IM-A750K|IM-A740S|IM-A730S|IM-A720L|IM-A710K|IM-A690L|IM-A690S|IM-A650S|IM-A630K|IM-A600S|VEGA PTL21|PT003|P8010|ADR910L|P6030|P6020|P9070|P4100|P9060|P5000|CDM8992|TXT8045|ADR8995|IS11PT|P2030|P6010|P8000|PT002|IS06|CDM8999|P9050|PT001|TXT8040|P2020|P9020|P2000|P7040|P7000|C790\",Fly:\"IQ230|IQ444|IQ450|IQ440|IQ442|IQ441|IQ245|IQ256|IQ236|IQ255|IQ235|IQ245|IQ275|IQ240|IQ285|IQ280|IQ270|IQ260|IQ250\",Wiko:\"KITE 4G|HIGHWAY|GETAWAY|STAIRWAY|DARKSIDE|DARKFULL|DARKNIGHT|DARKMOON|SLIDE|WAX 4G|RAINBOW|BLOOM|SUNSET|GOA(?!nna)|LENNY|BARRY|IGGY|OZZY|CINK FIVE|CINK PEAX|CINK PEAX 2|CINK SLIM|CINK SLIM 2|CINK +|CINK KING|CINK PEAX|CINK SLIM|SUBLIM\",iMobile:\"i-mobile (IQ|i-STYLE|idea|ZAA|Hitz)\",SimValley:\"\\\\b(SP-80|XT-930|SX-340|XT-930|SX-310|SP-360|SP60|SPT-800|SP-120|SPT-800|SP-140|SPX-5|SPX-8|SP-100|SPX-8|SPX-12)\\\\b\",Wolfgang:\"AT-B24D|AT-AS50HD|AT-AS40W|AT-AS55HD|AT-AS45q2|AT-B26D|AT-AS50Q\",Alcatel:\"Alcatel\",Nintendo:\"Nintendo 3DS\",Amoi:\"Amoi\",INQ:\"INQ\",GenericPhone:\"Tapatalk|PDA;|SAGEM|\\\\bmmp\\\\b|pocket|\\\\bpsp\\\\b|symbian|Smartphone|smartfon|treo|up.browser|up.link|vodafone|\\\\bwap\\\\b|nokia|Series40|Series60|S60|SonyEricsson|N900|MAUI.*WAP.*Browser\"},tablets:{iPad:\"iPad|iPad.*Mobile\",NexusTablet:\"Android.*Nexus[\\\\s]+(7|9|10)\",SamsungTablet:\"SAMSUNG.*Tablet|Galaxy.*Tab|SC-01C|GT-P1000|GT-P1003|GT-P1010|GT-P3105|GT-P6210|GT-P6800|GT-P6810|GT-P7100|GT-P7300|GT-P7310|GT-P7500|GT-P7510|SCH-I800|SCH-I815|SCH-I905|SGH-I957|SGH-I987|SGH-T849|SGH-T859|SGH-T869|SPH-P100|GT-P3100|GT-P3108|GT-P3110|GT-P5100|GT-P5110|GT-P6200|GT-P7320|GT-P7511|GT-N8000|GT-P8510|SGH-I497|SPH-P500|SGH-T779|SCH-I705|SCH-I915|GT-N8013|GT-P3113|GT-P5113|GT-P8110|GT-N8010|GT-N8005|GT-N8020|GT-P1013|GT-P6201|GT-P7501|GT-N5100|GT-N5105|GT-N5110|SHV-E140K|SHV-E140L|SHV-E140S|SHV-E150S|SHV-E230K|SHV-E230L|SHV-E230S|SHW-M180K|SHW-M180L|SHW-M180S|SHW-M180W|SHW-M300W|SHW-M305W|SHW-M380K|SHW-M380S|SHW-M380W|SHW-M430W|SHW-M480K|SHW-M480S|SHW-M480W|SHW-M485W|SHW-M486W|SHW-M500W|GT-I9228|SCH-P739|SCH-I925|GT-I9200|GT-P5200|GT-P5210|GT-P5210X|SM-T311|SM-T310|SM-T310X|SM-T210|SM-T210R|SM-T211|SM-P600|SM-P601|SM-P605|SM-P900|SM-P901|SM-T217|SM-T217A|SM-T217S|SM-P6000|SM-T3100|SGH-I467|XE500|SM-T110|GT-P5220|GT-I9200X|GT-N5110X|GT-N5120|SM-P905|SM-T111|SM-T2105|SM-T315|SM-T320|SM-T320X|SM-T321|SM-T520|SM-T525|SM-T530NU|SM-T230NU|SM-T330NU|SM-T900|XE500T1C|SM-P605V|SM-P905V|SM-T337V|SM-T537V|SM-T707V|SM-T807V|SM-P600X|SM-P900X|SM-T210X|SM-T230|SM-T230X|SM-T325|GT-P7503|SM-T531|SM-T330|SM-T530|SM-T705|SM-T705C|SM-T535|SM-T331|SM-T800|SM-T700|SM-T537|SM-T807|SM-P907A|SM-T337A|SM-T537A|SM-T707A|SM-T807A|SM-T237|SM-T807P|SM-P607T|SM-T217T|SM-T337T|SM-T807T|SM-T116NQ|SM-T116BU|SM-P550|SM-T350|SM-T550|SM-T9000|SM-P9000|SM-T705Y|SM-T805|GT-P3113|SM-T710|SM-T810|SM-T815|SM-T360|SM-T533|SM-T113|SM-T335|SM-T715|SM-T560|SM-T670|SM-T677|SM-T377|SM-T567|SM-T357T|SM-T555|SM-T561|SM-T713|SM-T719|SM-T813|SM-T819|SM-T580|SM-T355Y|SM-T280|SM-T817A|SM-T820|SM-W700|SM-P580|SM-T587|SM-P350|SM-P555M|SM-P355M|SM-T113NU|SM-T815Y\",Kindle:\"Kindle|Silk.*Accelerated|Android.*\\\\b(KFOT|KFTT|KFJWI|KFJWA|KFOTE|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|WFJWAE|KFSAWA|KFSAWI|KFASWI|KFARWI|KFFOWI|KFGIWI|KFMEWI)\\\\b|Android.*Silk/[0-9.]+ like Chrome/[0-9.]+ (?!Mobile)\",SurfaceTablet:\"Windows NT [0-9.]+; ARM;.*(Tablet|ARMBJS)\",HPTablet:\"HP Slate (7|8|10)|HP ElitePad 900|hp-tablet|EliteBook.*Touch|HP 8|Slate 21|HP SlateBook 10\",AsusTablet:\"^.*PadFone((?!Mobile).)*$|Transformer|TF101|TF101G|TF300T|TF300TG|TF300TL|TF700T|TF700KL|TF701T|TF810C|ME171|ME301T|ME302C|ME371MG|ME370T|ME372MG|ME172V|ME173X|ME400C|Slider SL101|\\\\bK00F\\\\b|\\\\bK00C\\\\b|\\\\bK00E\\\\b|\\\\bK00L\\\\b|TX201LA|ME176C|ME102A|\\\\bM80TA\\\\b|ME372CL|ME560CG|ME372CG|ME302KL| K010 | K011 | K017 | K01E |ME572C|ME103K|ME170C|ME171C|\\\\bME70C\\\\b|ME581C|ME581CL|ME8510C|ME181C|P01Y|PO1MA|P01Z|\\\\bP027\\\\b\",BlackBerryTablet:\"PlayBook|RIM Tablet\",HTCtablet:\"HTC_Flyer_P512|HTC Flyer|HTC Jetstream|HTC-P715a|HTC EVO View 4G|PG41200|PG09410\",MotorolaTablet:\"xoom|sholest|MZ615|MZ605|MZ505|MZ601|MZ602|MZ603|MZ604|MZ606|MZ607|MZ608|MZ609|MZ615|MZ616|MZ617\",NookTablet:\"Android.*Nook|NookColor|nook browser|BNRV200|BNRV200A|BNTV250|BNTV250A|BNTV400|BNTV600|LogicPD Zoom2\",AcerTablet:\"Android.*; \\\\b(A100|A101|A110|A200|A210|A211|A500|A501|A510|A511|A700|A701|W500|W500P|W501|W501P|W510|W511|W700|G100|G100W|B1-A71|B1-710|B1-711|A1-810|A1-811|A1-830)\\\\b|W3-810|\\\\bA3-A10\\\\b|\\\\bA3-A11\\\\b|\\\\bA3-A20\\\\b|\\\\bA3-A30\",ToshibaTablet:\"Android.*(AT100|AT105|AT200|AT205|AT270|AT275|AT300|AT305|AT1S5|AT500|AT570|AT700|AT830)|TOSHIBA.*FOLIO\",LGTablet:\"\\\\bL-06C|LG-V909|LG-V900|LG-V700|LG-V510|LG-V500|LG-V410|LG-V400|LG-VK810\\\\b\",FujitsuTablet:\"Android.*\\\\b(F-01D|F-02F|F-05E|F-10D|M532|Q572)\\\\b\",PrestigioTablet:\"PMP3170B|PMP3270B|PMP3470B|PMP7170B|PMP3370B|PMP3570C|PMP5870C|PMP3670B|PMP5570C|PMP5770D|PMP3970B|PMP3870C|PMP5580C|PMP5880D|PMP5780D|PMP5588C|PMP7280C|PMP7280C3G|PMP7280|PMP7880D|PMP5597D|PMP5597|PMP7100D|PER3464|PER3274|PER3574|PER3884|PER5274|PER5474|PMP5097CPRO|PMP5097|PMP7380D|PMP5297C|PMP5297C_QUAD|PMP812E|PMP812E3G|PMP812F|PMP810E|PMP880TD|PMT3017|PMT3037|PMT3047|PMT3057|PMT7008|PMT5887|PMT5001|PMT5002\",LenovoTablet:\"Lenovo TAB|Idea(Tab|Pad)( A1|A10| K1|)|ThinkPad([ ]+)?Tablet|YT3-850M|YT3-X90L|YT3-X90F|YT3-X90X|Lenovo.*(S2109|S2110|S5000|S6000|K3011|A3000|A3500|A1000|A2107|A2109|A1107|A5500|A7600|B6000|B8000|B8080)(-|)(FL|F|HV|H|)\",DellTablet:\"Venue 11|Venue 8|Venue 7|Dell Streak 10|Dell Streak 7\",YarvikTablet:\"Android.*\\\\b(TAB210|TAB211|TAB224|TAB250|TAB260|TAB264|TAB310|TAB360|TAB364|TAB410|TAB411|TAB420|TAB424|TAB450|TAB460|TAB461|TAB464|TAB465|TAB467|TAB468|TAB07-100|TAB07-101|TAB07-150|TAB07-151|TAB07-152|TAB07-200|TAB07-201-3G|TAB07-210|TAB07-211|TAB07-212|TAB07-214|TAB07-220|TAB07-400|TAB07-485|TAB08-150|TAB08-200|TAB08-201-3G|TAB08-201-30|TAB09-100|TAB09-211|TAB09-410|TAB10-150|TAB10-201|TAB10-211|TAB10-400|TAB10-410|TAB13-201|TAB274EUK|TAB275EUK|TAB374EUK|TAB462EUK|TAB474EUK|TAB9-200)\\\\b\",MedionTablet:\"Android.*\\\\bOYO\\\\b|LIFE.*(P9212|P9514|P9516|S9512)|LIFETAB\",ArnovaTablet:\"97G4|AN10G2|AN7bG3|AN7fG3|AN8G3|AN8cG3|AN7G3|AN9G3|AN7dG3|AN7dG3ST|AN7dG3ChildPad|AN10bG3|AN10bG3DT|AN9G2\",IntensoTablet:\"INM8002KP|INM1010FP|INM805ND|Intenso Tab|TAB1004\",IRUTablet:\"M702pro\",MegafonTablet:\"MegaFon V9|\\\\bZTE V9\\\\b|Android.*\\\\bMT7A\\\\b\",EbodaTablet:\"E-Boda (Supreme|Impresspeed|Izzycomm|Essential)\",AllViewTablet:\"Allview.*(Viva|Alldro|City|Speed|All TV|Frenzy|Quasar|Shine|TX1|AX1|AX2)\",ArchosTablet:\"\\\\b(101G9|80G9|A101IT)\\\\b|Qilive 97R|Archos5|\\\\bARCHOS (70|79|80|90|97|101|FAMILYPAD|)(b|c|)(G10| Cobalt| TITANIUM(HD|)| Xenon| Neon|XSK| 2| XS 2| PLATINUM| CARBON|GAMEPAD)\\\\b\",AinolTablet:\"NOVO7|NOVO8|NOVO10|Novo7Aurora|Novo7Basic|NOVO7PALADIN|novo9-Spark\",NokiaLumiaTablet:\"Lumia 2520\",SonyTablet:\"Sony.*Tablet|Xperia Tablet|Sony Tablet S|SO-03E|SGPT12|SGPT13|SGPT114|SGPT121|SGPT122|SGPT123|SGPT111|SGPT112|SGPT113|SGPT131|SGPT132|SGPT133|SGPT211|SGPT212|SGPT213|SGP311|SGP312|SGP321|EBRD1101|EBRD1102|EBRD1201|SGP351|SGP341|SGP511|SGP512|SGP521|SGP541|SGP551|SGP621|SGP612|SOT31\",PhilipsTablet:\"\\\\b(PI2010|PI3000|PI3100|PI3105|PI3110|PI3205|PI3210|PI3900|PI4010|PI7000|PI7100)\\\\b\",CubeTablet:\"Android.*(K8GT|U9GT|U10GT|U16GT|U17GT|U18GT|U19GT|U20GT|U23GT|U30GT)|CUBE U8GT\",CobyTablet:\"MID1042|MID1045|MID1125|MID1126|MID7012|MID7014|MID7015|MID7034|MID7035|MID7036|MID7042|MID7048|MID7127|MID8042|MID8048|MID8127|MID9042|MID9740|MID9742|MID7022|MID7010\",MIDTablet:\"M9701|M9000|M9100|M806|M1052|M806|T703|MID701|MID713|MID710|MID727|MID760|MID830|MID728|MID933|MID125|MID810|MID732|MID120|MID930|MID800|MID731|MID900|MID100|MID820|MID735|MID980|MID130|MID833|MID737|MID960|MID135|MID860|MID736|MID140|MID930|MID835|MID733|MID4X10\",MSITablet:\"MSI \\\\b(Primo 73K|Primo 73L|Primo 81L|Primo 77|Primo 93|Primo 75|Primo 76|Primo 73|Primo 81|Primo 91|Primo 90|Enjoy 71|Enjoy 7|Enjoy 10)\\\\b\",SMiTTablet:\"Android.*(\\\\bMID\\\\b|MID-560|MTV-T1200|MTV-PND531|MTV-P1101|MTV-PND530)\",RockChipTablet:\"Android.*(RK2818|RK2808A|RK2918|RK3066)|RK2738|RK2808A\",FlyTablet:\"IQ310|Fly Vision\",bqTablet:\"Android.*(bq)?.*(Elcano|Curie|Edison|Maxwell|Kepler|Pascal|Tesla|Hypatia|Platon|Newton|Livingstone|Cervantes|Avant|Aquaris [E|M]10)|Maxwell.*Lite|Maxwell.*Plus\",HuaweiTablet:\"MediaPad|MediaPad 7 Youth|IDEOS S7|S7-201c|S7-202u|S7-101|S7-103|S7-104|S7-105|S7-106|S7-201|S7-Slim\",NecTablet:\"\\\\bN-06D|\\\\bN-08D\",PantechTablet:\"Pantech.*P4100\",BronchoTablet:\"Broncho.*(N701|N708|N802|a710)\",VersusTablet:\"TOUCHPAD.*[78910]|\\\\bTOUCHTAB\\\\b\",ZyncTablet:\"z1000|Z99 2G|z99|z930|z999|z990|z909|Z919|z900\",PositivoTablet:\"TB07STA|TB10STA|TB07FTA|TB10FTA\",NabiTablet:\"Android.*\\\\bNabi\",KoboTablet:\"Kobo Touch|\\\\bK080\\\\b|\\\\bVox\\\\b Build|\\\\bArc\\\\b Build\",DanewTablet:\"DSlide.*\\\\b(700|701R|702|703R|704|802|970|971|972|973|974|1010|1012)\\\\b\",TexetTablet:\"NaviPad|TB-772A|TM-7045|TM-7055|TM-9750|TM-7016|TM-7024|TM-7026|TM-7041|TM-7043|TM-7047|TM-8041|TM-9741|TM-9747|TM-9748|TM-9751|TM-7022|TM-7021|TM-7020|TM-7011|TM-7010|TM-7023|TM-7025|TM-7037W|TM-7038W|TM-7027W|TM-9720|TM-9725|TM-9737W|TM-1020|TM-9738W|TM-9740|TM-9743W|TB-807A|TB-771A|TB-727A|TB-725A|TB-719A|TB-823A|TB-805A|TB-723A|TB-715A|TB-707A|TB-705A|TB-709A|TB-711A|TB-890HD|TB-880HD|TB-790HD|TB-780HD|TB-770HD|TB-721HD|TB-710HD|TB-434HD|TB-860HD|TB-840HD|TB-760HD|TB-750HD|TB-740HD|TB-730HD|TB-722HD|TB-720HD|TB-700HD|TB-500HD|TB-470HD|TB-431HD|TB-430HD|TB-506|TB-504|TB-446|TB-436|TB-416|TB-146SE|TB-126SE\",PlaystationTablet:\"Playstation.*(Portable|Vita)\",TrekstorTablet:\"ST10416-1|VT10416-1|ST70408-1|ST702xx-1|ST702xx-2|ST80208|ST97216|ST70104-2|VT10416-2|ST10216-2A|SurfTab\",PyleAudioTablet:\"\\\\b(PTBL10CEU|PTBL10C|PTBL72BC|PTBL72BCEU|PTBL7CEU|PTBL7C|PTBL92BC|PTBL92BCEU|PTBL9CEU|PTBL9CUK|PTBL9C)\\\\b\",AdvanTablet:\"Android.* \\\\b(E3A|T3X|T5C|T5B|T3E|T3C|T3B|T1J|T1F|T2A|T1H|T1i|E1C|T1-E|T5-A|T4|E1-B|T2Ci|T1-B|T1-D|O1-A|E1-A|T1-A|T3A|T4i)\\\\b \",DanyTechTablet:\"Genius Tab G3|Genius Tab S2|Genius Tab Q3|Genius Tab G4|Genius Tab Q4|Genius Tab G-II|Genius TAB GII|Genius TAB GIII|Genius Tab S1\",GalapadTablet:\"Android.*\\\\bG1\\\\b\",MicromaxTablet:\"Funbook|Micromax.*\\\\b(P250|P560|P360|P362|P600|P300|P350|P500|P275)\\\\b\",KarbonnTablet:\"Android.*\\\\b(A39|A37|A34|ST8|ST10|ST7|Smart Tab3|Smart Tab2)\\\\b\",AllFineTablet:\"Fine7 Genius|Fine7 Shine|Fine7 Air|Fine8 Style|Fine9 More|Fine10 Joy|Fine11 Wide\",PROSCANTablet:\"\\\\b(PEM63|PLT1023G|PLT1041|PLT1044|PLT1044G|PLT1091|PLT4311|PLT4311PL|PLT4315|PLT7030|PLT7033|PLT7033D|PLT7035|PLT7035D|PLT7044K|PLT7045K|PLT7045KB|PLT7071KG|PLT7072|PLT7223G|PLT7225G|PLT7777G|PLT7810K|PLT7849G|PLT7851G|PLT7852G|PLT8015|PLT8031|PLT8034|PLT8036|PLT8080K|PLT8082|PLT8088|PLT8223G|PLT8234G|PLT8235G|PLT8816K|PLT9011|PLT9045K|PLT9233G|PLT9735|PLT9760G|PLT9770G)\\\\b\",YONESTablet:\"BQ1078|BC1003|BC1077|RK9702|BC9730|BC9001|IT9001|BC7008|BC7010|BC708|BC728|BC7012|BC7030|BC7027|BC7026\",ChangJiaTablet:\"TPC7102|TPC7103|TPC7105|TPC7106|TPC7107|TPC7201|TPC7203|TPC7205|TPC7210|TPC7708|TPC7709|TPC7712|TPC7110|TPC8101|TPC8103|TPC8105|TPC8106|TPC8203|TPC8205|TPC8503|TPC9106|TPC9701|TPC97101|TPC97103|TPC97105|TPC97106|TPC97111|TPC97113|TPC97203|TPC97603|TPC97809|TPC97205|TPC10101|TPC10103|TPC10106|TPC10111|TPC10203|TPC10205|TPC10503\",GUTablet:\"TX-A1301|TX-M9002|Q702|kf026\",PointOfViewTablet:\"TAB-P506|TAB-navi-7-3G-M|TAB-P517|TAB-P-527|TAB-P701|TAB-P703|TAB-P721|TAB-P731N|TAB-P741|TAB-P825|TAB-P905|TAB-P925|TAB-PR945|TAB-PL1015|TAB-P1025|TAB-PI1045|TAB-P1325|TAB-PROTAB[0-9]+|TAB-PROTAB25|TAB-PROTAB26|TAB-PROTAB27|TAB-PROTAB26XL|TAB-PROTAB2-IPS9|TAB-PROTAB30-IPS9|TAB-PROTAB25XXL|TAB-PROTAB26-IPS10|TAB-PROTAB30-IPS10\",OvermaxTablet:\"OV-(SteelCore|NewBase|Basecore|Baseone|Exellen|Quattor|EduTab|Solution|ACTION|BasicTab|TeddyTab|MagicTab|Stream|TB-08|TB-09)\",HCLTablet:\"HCL.*Tablet|Connect-3G-2.0|Connect-2G-2.0|ME Tablet U1|ME Tablet U2|ME Tablet G1|ME Tablet X1|ME Tablet Y2|ME Tablet Sync\",DPSTablet:\"DPS Dream 9|DPS Dual 7\",VistureTablet:\"V97 HD|i75 3G|Visture V4( HD)?|Visture V5( HD)?|Visture V10\",CrestaTablet:\"CTP(-)?810|CTP(-)?818|CTP(-)?828|CTP(-)?838|CTP(-)?888|CTP(-)?978|CTP(-)?980|CTP(-)?987|CTP(-)?988|CTP(-)?989\",MediatekTablet:\"\\\\bMT8125|MT8389|MT8135|MT8377\\\\b\",ConcordeTablet:\"Concorde([ ]+)?Tab|ConCorde ReadMan\",GoCleverTablet:\"GOCLEVER TAB|A7GOCLEVER|M1042|M7841|M742|R1042BK|R1041|TAB A975|TAB A7842|TAB A741|TAB A741L|TAB M723G|TAB M721|TAB A1021|TAB I921|TAB R721|TAB I720|TAB T76|TAB R70|TAB R76.2|TAB R106|TAB R83.2|TAB M813G|TAB I721|GCTA722|TAB I70|TAB I71|TAB S73|TAB R73|TAB R74|TAB R93|TAB R75|TAB R76.1|TAB A73|TAB A93|TAB A93.2|TAB T72|TAB R83|TAB R974|TAB R973|TAB A101|TAB A103|TAB A104|TAB A104.2|R105BK|M713G|A972BK|TAB A971|TAB R974.2|TAB R104|TAB R83.3|TAB A1042\",ModecomTablet:\"FreeTAB 9000|FreeTAB 7.4|FreeTAB 7004|FreeTAB 7800|FreeTAB 2096|FreeTAB 7.5|FreeTAB 1014|FreeTAB 1001 |FreeTAB 8001|FreeTAB 9706|FreeTAB 9702|FreeTAB 7003|FreeTAB 7002|FreeTAB 1002|FreeTAB 7801|FreeTAB 1331|FreeTAB 1004|FreeTAB 8002|FreeTAB 8014|FreeTAB 9704|FreeTAB 1003\",VoninoTablet:\"\\\\b(Argus[ _]?S|Diamond[ _]?79HD|Emerald[ _]?78E|Luna[ _]?70C|Onyx[ _]?S|Onyx[ _]?Z|Orin[ _]?HD|Orin[ _]?S|Otis[ _]?S|SpeedStar[ _]?S|Magnet[ _]?M9|Primus[ _]?94[ _]?3G|Primus[ _]?94HD|Primus[ _]?QS|Android.*\\\\bQ8\\\\b|Sirius[ _]?EVO[ _]?QS|Sirius[ _]?QS|Spirit[ _]?S)\\\\b\",ECSTablet:\"V07OT2|TM105A|S10OT1|TR10CS1\",StorexTablet:\"eZee[_']?(Tab|Go)[0-9]+|TabLC7|Looney Tunes Tab\",VodafoneTablet:\"SmartTab([ ]+)?[0-9]+|SmartTabII10|SmartTabII7|VF-1497\",EssentielBTablet:\"Smart[ ']?TAB[ ]+?[0-9]+|Family[ ']?TAB2\",RossMoorTablet:\"RM-790|RM-997|RMD-878G|RMD-974R|RMT-705A|RMT-701|RME-601|RMT-501|RMT-711\",iMobileTablet:\"i-mobile i-note\",TolinoTablet:\"tolino tab [0-9.]+|tolino shine\",AudioSonicTablet:\"\\\\bC-22Q|T7-QC|T-17B|T-17P\\\\b\",AMPETablet:\"Android.* A78 \",SkkTablet:\"Android.* (SKYPAD|PHOENIX|CYCLOPS)\",TecnoTablet:\"TECNO P9\",JXDTablet:\"Android.* \\\\b(F3000|A3300|JXD5000|JXD3000|JXD2000|JXD300B|JXD300|S5800|S7800|S602b|S5110b|S7300|S5300|S602|S603|S5100|S5110|S601|S7100a|P3000F|P3000s|P101|P200s|P1000m|P200m|P9100|P1000s|S6600b|S908|P1000|P300|S18|S6600|S9100)\\\\b\",iJoyTablet:\"Tablet (Spirit 7|Essentia|Galatea|Fusion|Onix 7|Landa|Titan|Scooby|Deox|Stella|Themis|Argon|Unique 7|Sygnus|Hexen|Finity 7|Cream|Cream X2|Jade|Neon 7|Neron 7|Kandy|Scape|Saphyr 7|Rebel|Biox|Rebel|Rebel 8GB|Myst|Draco 7|Myst|Tab7-004|Myst|Tadeo Jones|Tablet Boing|Arrow|Draco Dual Cam|Aurix|Mint|Amity|Revolution|Finity 9|Neon 9|T9w|Amity 4GB Dual Cam|Stone 4GB|Stone 8GB|Andromeda|Silken|X2|Andromeda II|Halley|Flame|Saphyr 9,7|Touch 8|Planet|Triton|Unique 10|Hexen 10|Memphis 4GB|Memphis 8GB|Onix 10)\",FX2Tablet:\"FX2 PAD7|FX2 PAD10\",XoroTablet:\"KidsPAD 701|PAD[ ]?712|PAD[ ]?714|PAD[ ]?716|PAD[ ]?717|PAD[ ]?718|PAD[ ]?720|PAD[ ]?721|PAD[ ]?722|PAD[ ]?790|PAD[ ]?792|PAD[ ]?900|PAD[ ]?9715D|PAD[ ]?9716DR|PAD[ ]?9718DR|PAD[ ]?9719QR|PAD[ ]?9720QR|TelePAD1030|Telepad1032|TelePAD730|TelePAD731|TelePAD732|TelePAD735Q|TelePAD830|TelePAD9730|TelePAD795|MegaPAD 1331|MegaPAD 1851|MegaPAD 2151\",ViewsonicTablet:\"ViewPad 10pi|ViewPad 10e|ViewPad 10s|ViewPad E72|ViewPad7|ViewPad E100|ViewPad 7e|ViewSonic VB733|VB100a\",OdysTablet:\"LOOX|XENO10|ODYS[ -](Space|EVO|Xpress|NOON)|\\\\bXELIO\\\\b|Xelio10Pro|XELIO7PHONETAB|XELIO10EXTREME|XELIOPT2|NEO_QUAD10\",CaptivaTablet:\"CAPTIVA PAD\",IconbitTablet:\"NetTAB|NT-3702|NT-3702S|NT-3702S|NT-3603P|NT-3603P|NT-0704S|NT-0704S|NT-3805C|NT-3805C|NT-0806C|NT-0806C|NT-0909T|NT-0909T|NT-0907S|NT-0907S|NT-0902S|NT-0902S\",TeclastTablet:\"T98 4G|\\\\bP80\\\\b|\\\\bX90HD\\\\b|X98 Air|X98 Air 3G|\\\\bX89\\\\b|P80 3G|\\\\bX80h\\\\b|P98 Air|\\\\bX89HD\\\\b|P98 3G|\\\\bP90HD\\\\b|P89 3G|X98 3G|\\\\bP70h\\\\b|P79HD 3G|G18d 3G|\\\\bP79HD\\\\b|\\\\bP89s\\\\b|\\\\bA88\\\\b|\\\\bP10HD\\\\b|\\\\bP19HD\\\\b|G18 3G|\\\\bP78HD\\\\b|\\\\bA78\\\\b|\\\\bP75\\\\b|G17s 3G|G17h 3G|\\\\bP85t\\\\b|\\\\bP90\\\\b|\\\\bP11\\\\b|\\\\bP98t\\\\b|\\\\bP98HD\\\\b|\\\\bG18d\\\\b|\\\\bP85s\\\\b|\\\\bP11HD\\\\b|\\\\bP88s\\\\b|\\\\bA80HD\\\\b|\\\\bA80se\\\\b|\\\\bA10h\\\\b|\\\\bP89\\\\b|\\\\bP78s\\\\b|\\\\bG18\\\\b|\\\\bP85\\\\b|\\\\bA70h\\\\b|\\\\bA70\\\\b|\\\\bG17\\\\b|\\\\bP18\\\\b|\\\\bA80s\\\\b|\\\\bA11s\\\\b|\\\\bP88HD\\\\b|\\\\bA80h\\\\b|\\\\bP76s\\\\b|\\\\bP76h\\\\b|\\\\bP98\\\\b|\\\\bA10HD\\\\b|\\\\bP78\\\\b|\\\\bP88\\\\b|\\\\bA11\\\\b|\\\\bA10t\\\\b|\\\\bP76a\\\\b|\\\\bP76t\\\\b|\\\\bP76e\\\\b|\\\\bP85HD\\\\b|\\\\bP85a\\\\b|\\\\bP86\\\\b|\\\\bP75HD\\\\b|\\\\bP76v\\\\b|\\\\bA12\\\\b|\\\\bP75a\\\\b|\\\\bA15\\\\b|\\\\bP76Ti\\\\b|\\\\bP81HD\\\\b|\\\\bA10\\\\b|\\\\bT760VE\\\\b|\\\\bT720HD\\\\b|\\\\bP76\\\\b|\\\\bP73\\\\b|\\\\bP71\\\\b|\\\\bP72\\\\b|\\\\bT720SE\\\\b|\\\\bC520Ti\\\\b|\\\\bT760\\\\b|\\\\bT720VE\\\\b|T720-3GE|T720-WiFi\",OndaTablet:\"\\\\b(V975i|Vi30|VX530|V701|Vi60|V701s|Vi50|V801s|V719|Vx610w|VX610W|V819i|Vi10|VX580W|Vi10|V711s|V813|V811|V820w|V820|Vi20|V711|VI30W|V712|V891w|V972|V819w|V820w|Vi60|V820w|V711|V813s|V801|V819|V975s|V801|V819|V819|V818|V811|V712|V975m|V101w|V961w|V812|V818|V971|V971s|V919|V989|V116w|V102w|V973|Vi40)\\\\b[\\\\s]+\",JaytechTablet:\"TPC-PA762\",BlaupunktTablet:\"Endeavour 800NG|Endeavour 1010\",DigmaTablet:\"\\\\b(iDx10|iDx9|iDx8|iDx7|iDxD7|iDxD8|iDsQ8|iDsQ7|iDsQ8|iDsD10|iDnD7|3TS804H|iDsQ11|iDj7|iDs10)\\\\b\",EvolioTablet:\"ARIA_Mini_wifi|Aria[ _]Mini|Evolio X10|Evolio X7|Evolio X8|\\\\bEvotab\\\\b|\\\\bNeura\\\\b\",LavaTablet:\"QPAD E704|\\\\bIvoryS\\\\b|E-TAB IVORY|\\\\bE-TAB\\\\b\",AocTablet:\"MW0811|MW0812|MW0922|MTK8382|MW1031|MW0831|MW0821|MW0931|MW0712\",MpmanTablet:\"MP11 OCTA|MP10 OCTA|MPQC1114|MPQC1004|MPQC994|MPQC974|MPQC973|MPQC804|MPQC784|MPQC780|\\\\bMPG7\\\\b|MPDCG75|MPDCG71|MPDC1006|MP101DC|MPDC9000|MPDC905|MPDC706HD|MPDC706|MPDC705|MPDC110|MPDC100|MPDC99|MPDC97|MPDC88|MPDC8|MPDC77|MP709|MID701|MID711|MID170|MPDC703|MPQC1010\",CelkonTablet:\"CT695|CT888|CT[\\\\s]?910|CT7 Tab|CT9 Tab|CT3 Tab|CT2 Tab|CT1 Tab|C820|C720|\\\\bCT-1\\\\b\",WolderTablet:\"miTab \\\\b(DIAMOND|SPACE|BROOKLYN|NEO|FLY|MANHATTAN|FUNK|EVOLUTION|SKY|GOCAR|IRON|GENIUS|POP|MINT|EPSILON|BROADWAY|JUMP|HOP|LEGEND|NEW AGE|LINE|ADVANCE|FEEL|FOLLOW|LIKE|LINK|LIVE|THINK|FREEDOM|CHICAGO|CLEVELAND|BALTIMORE-GH|IOWA|BOSTON|SEATTLE|PHOENIX|DALLAS|IN 101|MasterChef)\\\\b\",MiTablet:\"\\\\bMI PAD\\\\b|\\\\bHM NOTE 1W\\\\b\",NibiruTablet:\"Nibiru M1|Nibiru Jupiter One\",NexoTablet:\"NEXO NOVA|NEXO 10|NEXO AVIO|NEXO FREE|NEXO GO|NEXO EVO|NEXO 3G|NEXO SMART|NEXO KIDDO|NEXO MOBI\",LeaderTablet:\"TBLT10Q|TBLT10I|TBL-10WDKB|TBL-10WDKBO2013|TBL-W230V2|TBL-W450|TBL-W500|SV572|TBLT7I|TBA-AC7-8G|TBLT79|TBL-8W16|TBL-10W32|TBL-10WKB|TBL-W100\",UbislateTablet:\"UbiSlate[\\\\s]?7C\",PocketBookTablet:\"Pocketbook\",KocasoTablet:\"\\\\b(TB-1207)\\\\b\",HisenseTablet:\"\\\\b(F5281|E2371)\\\\b\",Hudl:\"Hudl HT7S3|Hudl 2\",TelstraTablet:\"T-Hub2\",GenericTablet:\"Android.*\\\\b97D\\\\b|Tablet(?!.*PC)|BNTV250A|MID-WCDMA|LogicPD Zoom2|\\\\bA7EB\\\\b|CatNova8|A1_07|CT704|CT1002|\\\\bM721\\\\b|rk30sdk|\\\\bEVOTAB\\\\b|M758A|ET904|ALUMIUM10|Smartfren Tab|Endeavour 1010|Tablet-PC-4|Tagi Tab|\\\\bM6pro\\\\b|CT1020W|arc 10HD|\\\\bTP750\\\\b|\\\\bQTAQZ3\\\\b\"},oss:{AndroidOS:\"Android\",BlackBerryOS:\"blackberry|\\\\bBB10\\\\b|rim tablet os\",PalmOS:\"PalmOS|avantgo|blazer|elaine|hiptop|palm|plucker|xiino\",SymbianOS:\"Symbian|SymbOS|Series60|Series40|SYB-[0-9]+|\\\\bS60\\\\b\",WindowsMobileOS:\"Windows CE.*(PPC|Smartphone|Mobile|[0-9]{3}x[0-9]{3})|Window Mobile|Windows Phone [0-9.]+|WCE;\",WindowsPhoneOS:\"Windows Phone 10.0|Windows Phone 8.1|Windows Phone 8.0|Windows Phone OS|XBLWP7|ZuneWP7|Windows NT 6.[23]; ARM;\",iOS:\"\\\\biPhone.*Mobile|\\\\biPod|\\\\biPad\",MeeGoOS:\"MeeGo\",MaemoOS:\"Maemo\",JavaOS:\"J2ME/|\\\\bMIDP\\\\b|\\\\bCLDC\\\\b\",webOS:\"webOS|hpwOS\",badaOS:\"\\\\bBada\\\\b\",BREWOS:\"BREW\"},uas:{Chrome:\"\\\\bCrMo\\\\b|CriOS|Android.*Chrome/[.0-9]* (Mobile)?\",Dolfin:\"\\\\bDolfin\\\\b\",Opera:\"Opera.*Mini|Opera.*Mobi|Android.*Opera|Mobile.*OPR/[0-9.]+|Coast/[0-9.]+\",Skyfire:\"Skyfire\",Edge:\"Mobile Safari/[.0-9]* Edge\",IE:\"IEMobile|MSIEMobile\",Firefox:\"fennec|firefox.*maemo|(Mobile|Tablet).*Firefox|Firefox.*Mobile|FxiOS\",Bolt:\"bolt\",TeaShark:\"teashark\",Blazer:\"Blazer\",Safari:\"Version.*Mobile.*Safari|Safari.*Mobile|MobileSafari\",UCBrowser:\"UC.*Browser|UCWEB\",baiduboxapp:\"baiduboxapp\",baidubrowser:\"baidubrowser\",DiigoBrowser:\"DiigoBrowser\",Puffin:\"Puffin\",Mercury:\"\\\\bMercury\\\\b\",ObigoBrowser:\"Obigo\",NetFront:\"NF-Browser\",GenericBrowser:\"NokiaBrowser|OviBrowser|OneBrowser|TwonkyBeamBrowser|SEMC.*Browser|FlyFlow|Minimo|NetFront|Novarra-Vision|MQQBrowser|MicroMessenger\",PaleMoon:\"Android.*PaleMoon|Mobile.*PaleMoon\"},props:{Mobile:\"Mobile/[VER]\",Build:\"Build/[VER]\",Version:\"Version/[VER]\",VendorID:\"VendorID/[VER]\",iPad:\"iPad.*CPU[a-z ]+[VER]\",iPhone:\"iPhone.*CPU[a-z ]+[VER]\",iPod:\"iPod.*CPU[a-z ]+[VER]\",Kindle:\"Kindle/[VER]\",Chrome:[\"Chrome/[VER]\",\"CriOS/[VER]\",\"CrMo/[VER]\"],Coast:[\"Coast/[VER]\"],Dolfin:\"Dolfin/[VER]\",Firefox:[\"Firefox/[VER]\",\"FxiOS/[VER]\"],Fennec:\"Fennec/[VER]\",Edge:\"Edge/[VER]\",IE:[\"IEMobile/[VER];\",\"IEMobile [VER]\",\"MSIE [VER];\",\"Trident/[0-9.]+;.*rv:[VER]\"],NetFront:\"NetFront/[VER]\",NokiaBrowser:\"NokiaBrowser/[VER]\",Opera:[\" OPR/[VER]\",\"Opera Mini/[VER]\",\"Version/[VER]\"],\"Opera Mini\":\"Opera Mini/[VER]\",\"Opera Mobi\":\"Version/[VER]\",\"UC Browser\":\"UC Browser[VER]\",MQQBrowser:\"MQQBrowser/[VER]\",MicroMessenger:\"MicroMessenger/[VER]\",baiduboxapp:\"baiduboxapp/[VER]\",baidubrowser:\"baidubrowser/[VER]\",SamsungBrowser:\"SamsungBrowser/[VER]\",Iron:\"Iron/[VER]\",Safari:[\"Version/[VER]\",\"Safari/[VER]\"],Skyfire:\"Skyfire/[VER]\",Tizen:\"Tizen/[VER]\",Webkit:\"webkit[ /][VER]\",PaleMoon:\"PaleMoon/[VER]\",Gecko:\"Gecko/[VER]\",Trident:\"Trident/[VER]\",Presto:\"Presto/[VER]\",Goanna:\"Goanna/[VER]\",iOS:\" \\\\bi?OS\\\\b [VER][ ;]{1}\",Android:\"Android [VER]\",BlackBerry:[\"BlackBerry[\\\\w]+/[VER]\",\"BlackBerry.*Version/[VER]\",\"Version/[VER]\"],BREW:\"BREW [VER]\",Java:\"Java/[VER]\",\"Windows Phone OS\":[\"Windows Phone OS [VER]\",\"Windows Phone [VER]\"],\"Windows Phone\":\"Windows Phone [VER]\",\"Windows CE\":\"Windows CE/[VER]\",\"Windows NT\":\"Windows NT [VER]\",Symbian:[\"SymbianOS/[VER]\",\"Symbian/[VER]\"],webOS:[\"webOS/[VER]\",\"hpwOS/[VER];\"]},utils:{Bot:\"Googlebot|facebookexternalhit|AdsBot-Google|Google Keyword Suggestion|Facebot|YandexBot|YandexMobileBot|bingbot|ia_archiver|AhrefsBot|Ezooms|GSLFbot|WBSearchBot|Twitterbot|TweetmemeBot|Twikle|PaperLiBot|Wotbox|UnwindFetchor|Exabot|MJ12bot|YandexImages|TurnitinBot|Pingdom\",MobileBot:\"Googlebot-Mobile|AdsBot-Google-Mobile|YahooSeeker/M1A1-R2D2\",DesktopMode:\"WPDesktop\",TV:\"SonyDTV|HbbTV\",WebKit:\"(webkit)[ /]([\\\\w.]+)\",Console:\"\\\\b(Nintendo|Nintendo WiiU|Nintendo 3DS|PLAYSTATION|Xbox)\\\\b\",Watch:\"SM-V700\"}},f.detectMobileBrowsers={fullPattern:/(android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i,shortPattern:/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\-(n|u)|c55\\/|capi|ccwa|cdm\\-|cell|chtm|cldc|cmd\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\-|_)|g1 u|g560|gene|gf\\-5|g\\-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd\\-(m|p|t)|hei\\-|hi(pt|ta)|hp( i|ip)|hs\\-c|ht(c(\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\-(20|go|ma)|i230|iac( |\\-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc\\-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|\\-[a-w])|libw|lynx|m1\\-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\-2|po(ck|rt|se)|prox|psio|pt\\-g|qa\\-a|qc(07|12|21|32|60|\\-[2-7]|i\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\-|oo|p\\-)|sdk\\/|se(c(\\-|0|1)|47|mc|nd|ri)|sgh\\-|shar|sie(\\-|m)|sk\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\-|v\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\-|tdg\\-|tel(i|m)|tim\\-|t\\-mo|to(pl|sh)|ts(70|m\\-|m3|m5)|tx\\-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\\-|your|zeto|zte\\-/i,\ntabletPattern:/android|ipad|playbook|silk/i};var g,h=Object.prototype.hasOwnProperty;return f.FALLBACK_PHONE=\"UnknownPhone\",f.FALLBACK_TABLET=\"UnknownTablet\",f.FALLBACK_MOBILE=\"UnknownMobile\",g=\"isArray\"in Array?Array.isArray:function(a){return\"[object Array]\"===Object.prototype.toString.call(a)},function(){var a,b,c,e,i,j,k=f.mobileDetectRules;for(a in k.props)if(h.call(k.props,a)){for(b=k.props[a],g(b)||(b=[b]),i=b.length,e=0;e<i;++e)c=b[e],j=c.indexOf(\"[VER]\"),j>=0&&(c=c.substring(0,j)+\"([\\\\w._\\\\+]+)\"+c.substring(j+5)),b[e]=new RegExp(c,\"i\");k.props[a]=b}d(k.oss),d(k.phones),d(k.tablets),d(k.uas),d(k.utils),k.oss0={WindowsPhoneOS:k.oss.WindowsPhoneOS,WindowsMobileOS:k.oss.WindowsMobileOS}}(),f.findMatch=function(a,b){for(var c in a)if(h.call(a,c)&&a[c].test(b))return c;return null},f.findMatches=function(a,b){var c=[];for(var d in a)h.call(a,d)&&a[d].test(b)&&c.push(d);return c},f.getVersionStr=function(a,b){var c,d,e,g,i=f.mobileDetectRules.props;if(h.call(i,a))for(c=i[a],e=c.length,d=0;d<e;++d)if(g=c[d].exec(b),null!==g)return g[1];return null},f.getVersion=function(a,b){var c=f.getVersionStr(a,b);return c?f.prepareVersionNo(c):NaN},f.prepareVersionNo=function(a){var b;return b=a.split(/[a-z._ \\/\\-]/i),1===b.length&&(a=b[0]),b.length>1&&(a=b[0]+\".\",b.shift(),a+=b.join(\"\")),Number(a)},f.isMobileFallback=function(a){return f.detectMobileBrowsers.fullPattern.test(a)||f.detectMobileBrowsers.shortPattern.test(a.substr(0,4))},f.isTabletFallback=function(a){return f.detectMobileBrowsers.tabletPattern.test(a)},f.prepareDetectionCache=function(a,c,d){if(a.mobile===b){var g,h,i;return(h=f.findMatch(f.mobileDetectRules.tablets,c))?(a.mobile=a.tablet=h,void(a.phone=null)):(g=f.findMatch(f.mobileDetectRules.phones,c))?(a.mobile=a.phone=g,void(a.tablet=null)):void(f.isMobileFallback(c)?(i=e.isPhoneSized(d),i===b?(a.mobile=f.FALLBACK_MOBILE,a.tablet=a.phone=null):i?(a.mobile=a.phone=f.FALLBACK_PHONE,a.tablet=null):(a.mobile=a.tablet=f.FALLBACK_TABLET,a.phone=null)):f.isTabletFallback(c)?(a.mobile=a.tablet=f.FALLBACK_TABLET,a.phone=null):a.mobile=a.tablet=a.phone=null)}},f.mobileGrade=function(a){var b=null!==a.mobile();return a.os(\"iOS\")&&a.version(\"iPad\")>=4.3||a.os(\"iOS\")&&a.version(\"iPhone\")>=3.1||a.os(\"iOS\")&&a.version(\"iPod\")>=3.1||a.version(\"Android\")>2.1&&a.is(\"Webkit\")||a.version(\"Windows Phone OS\")>=7||a.is(\"BlackBerry\")&&a.version(\"BlackBerry\")>=6||a.match(\"Playbook.*Tablet\")||a.version(\"webOS\")>=1.4&&a.match(\"Palm|Pre|Pixi\")||a.match(\"hp.*TouchPad\")||a.is(\"Firefox\")&&a.version(\"Firefox\")>=12||a.is(\"Chrome\")&&a.is(\"AndroidOS\")&&a.version(\"Android\")>=4||a.is(\"Skyfire\")&&a.version(\"Skyfire\")>=4.1&&a.is(\"AndroidOS\")&&a.version(\"Android\")>=2.3||a.is(\"Opera\")&&a.version(\"Opera Mobi\")>11&&a.is(\"AndroidOS\")||a.is(\"MeeGoOS\")||a.is(\"Tizen\")||a.is(\"Dolfin\")&&a.version(\"Bada\")>=2||(a.is(\"UC Browser\")||a.is(\"Dolfin\"))&&a.version(\"Android\")>=2.3||a.match(\"Kindle Fire\")||a.is(\"Kindle\")&&a.version(\"Kindle\")>=3||a.is(\"AndroidOS\")&&a.is(\"NookTablet\")||a.version(\"Chrome\")>=11&&!b||a.version(\"Safari\")>=5&&!b||a.version(\"Firefox\")>=4&&!b||a.version(\"MSIE\")>=7&&!b||a.version(\"Opera\")>=10&&!b?\"A\":a.os(\"iOS\")&&a.version(\"iPad\")<4.3||a.os(\"iOS\")&&a.version(\"iPhone\")<3.1||a.os(\"iOS\")&&a.version(\"iPod\")<3.1||a.is(\"Blackberry\")&&a.version(\"BlackBerry\")>=5&&a.version(\"BlackBerry\")<6||a.version(\"Opera Mini\")>=5&&a.version(\"Opera Mini\")<=6.5&&(a.version(\"Android\")>=2.3||a.is(\"iOS\"))||a.match(\"NokiaN8|NokiaC7|N97.*Series60|Symbian/3\")||a.version(\"Opera Mobi\")>=11&&a.is(\"SymbianOS\")?\"B\":(a.version(\"BlackBerry\")<5||a.match(\"MSIEMobile|Windows CE.*Mobile\")||a.version(\"Windows Mobile\")<=5.2,\"C\")},f.detectOS=function(a){return f.findMatch(f.mobileDetectRules.oss0,a)||f.findMatch(f.mobileDetectRules.oss,a)},f.getDeviceSmallerSide=function(){return window.screen.width<window.screen.height?window.screen.width:window.screen.height},e.prototype={constructor:e,mobile:function(){return f.prepareDetectionCache(this._cache,this.ua,this.maxPhoneWidth),this._cache.mobile},phone:function(){return f.prepareDetectionCache(this._cache,this.ua,this.maxPhoneWidth),this._cache.phone},tablet:function(){return f.prepareDetectionCache(this._cache,this.ua,this.maxPhoneWidth),this._cache.tablet},userAgent:function(){return this._cache.userAgent===b&&(this._cache.userAgent=f.findMatch(f.mobileDetectRules.uas,this.ua)),this._cache.userAgent},userAgents:function(){return this._cache.userAgents===b&&(this._cache.userAgents=f.findMatches(f.mobileDetectRules.uas,this.ua)),this._cache.userAgents},os:function(){return this._cache.os===b&&(this._cache.os=f.detectOS(this.ua)),this._cache.os},version:function(a){return f.getVersion(a,this.ua)},versionStr:function(a){return f.getVersionStr(a,this.ua)},is:function(b){return c(this.userAgents(),b)||a(b,this.os())||a(b,this.phone())||a(b,this.tablet())||c(f.findMatches(f.mobileDetectRules.utils,this.ua),b)},match:function(a){return a instanceof RegExp||(a=new RegExp(a,\"i\")),a.test(this.ua)},isPhoneSized:function(a){return e.isPhoneSized(a||this.maxPhoneWidth)},mobileGrade:function(){return this._cache.grade===b&&(this._cache.grade=f.mobileGrade(this)),this._cache.grade}},\"undefined\"!=typeof window&&window.screen?e.isPhoneSized=function(a){return a<0?b:f.getDeviceSmallerSide()<=a}:e.isPhoneSized=function(){},e._impl=f,e.version=\"1.3.7 2017-09-06\",e})}(function(a){if(\"undefined\"!=typeof module&&module.exports)return function(a){module.exports=a()};if(\"function\"==typeof define&&define.amd)return define;if(\"undefined\"!=typeof window)return function(a){window.MobileDetect=a()};throw new Error(\"unknown environment\")}());"

/***/ }),
/* 58 */
/***/ (function(module, exports) {

module.exports = "!function(e,t){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=t():\"function\"==typeof define&&define.amd?define(t):e.moment=t()}(this,function(){\"use strict\";function e(){return Yt.apply(null,arguments)}function t(e){return e instanceof Array||\"[object Array]\"===Object.prototype.toString.call(e)}function n(e){return null!=e&&\"[object Object]\"===Object.prototype.toString.call(e)}function s(e){if(Object.getOwnPropertyNames)return 0===Object.getOwnPropertyNames(e).length;var t;for(t in e)if(e.hasOwnProperty(t))return!1;return!0}function i(e){return void 0===e}function r(e){return\"number\"==typeof e||\"[object Number]\"===Object.prototype.toString.call(e)}function a(e){return e instanceof Date||\"[object Date]\"===Object.prototype.toString.call(e)}function o(e,t){var n,s=[];for(n=0;n<e.length;++n)s.push(t(e[n],n));return s}function u(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function l(e,t){for(var n in t)u(t,n)&&(e[n]=t[n]);return u(t,\"toString\")&&(e.toString=t.toString),u(t,\"valueOf\")&&(e.valueOf=t.valueOf),e}function d(e,t,n,s){return je(e,t,n,s,!0).utc()}function h(){return{empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1,parsedDateParts:[],meridiem:null,rfc2822:!1,weekdayMismatch:!1}}function c(e){return null==e._pf&&(e._pf=h()),e._pf}function f(e){if(null==e._isValid){var t=c(e),n=Ot.call(t.parsedDateParts,function(e){return null!=e}),s=!isNaN(e._d.getTime())&&t.overflow<0&&!t.empty&&!t.invalidMonth&&!t.invalidWeekday&&!t.weekdayMismatch&&!t.nullInput&&!t.invalidFormat&&!t.userInvalidated&&(!t.meridiem||t.meridiem&&n);if(e._strict&&(s=s&&0===t.charsLeftOver&&0===t.unusedTokens.length&&void 0===t.bigHour),null!=Object.isFrozen&&Object.isFrozen(e))return s;e._isValid=s}return e._isValid}function m(e){var t=d(NaN);return null!=e?l(c(t),e):c(t).userInvalidated=!0,t}function _(e,t){var n,s,r;if(i(t._isAMomentObject)||(e._isAMomentObject=t._isAMomentObject),i(t._i)||(e._i=t._i),i(t._f)||(e._f=t._f),i(t._l)||(e._l=t._l),i(t._strict)||(e._strict=t._strict),i(t._tzm)||(e._tzm=t._tzm),i(t._isUTC)||(e._isUTC=t._isUTC),i(t._offset)||(e._offset=t._offset),i(t._pf)||(e._pf=c(t)),i(t._locale)||(e._locale=t._locale),xt.length>0)for(n=0;n<xt.length;n++)i(r=t[s=xt[n]])||(e[s]=r);return e}function y(t){_(this,t),this._d=new Date(null!=t._d?t._d.getTime():NaN),this.isValid()||(this._d=new Date(NaN)),!1===Tt&&(Tt=!0,e.updateOffset(this),Tt=!1)}function g(e){return e instanceof y||null!=e&&null!=e._isAMomentObject}function p(e){return e<0?Math.ceil(e)||0:Math.floor(e)}function w(e){var t=+e,n=0;return 0!==t&&isFinite(t)&&(n=p(t)),n}function v(e,t,n){var s,i=Math.min(e.length,t.length),r=Math.abs(e.length-t.length),a=0;for(s=0;s<i;s++)(n&&e[s]!==t[s]||!n&&w(e[s])!==w(t[s]))&&a++;return a+r}function M(t){!1===e.suppressDeprecationWarnings&&\"undefined\"!=typeof console&&console.warn&&console.warn(\"Deprecation warning: \"+t)}function k(t,n){var s=!0;return l(function(){if(null!=e.deprecationHandler&&e.deprecationHandler(null,t),s){for(var i,r=[],a=0;a<arguments.length;a++){if(i=\"\",\"object\"==typeof arguments[a]){i+=\"\\n[\"+a+\"] \";for(var o in arguments[0])i+=o+\": \"+arguments[0][o]+\", \";i=i.slice(0,-2)}else i=arguments[a];r.push(i)}M(t+\"\\nArguments: \"+Array.prototype.slice.call(r).join(\"\")+\"\\n\"+(new Error).stack),s=!1}return n.apply(this,arguments)},n)}function S(t,n){null!=e.deprecationHandler&&e.deprecationHandler(t,n),bt[t]||(M(n),bt[t]=!0)}function D(e){return e instanceof Function||\"[object Function]\"===Object.prototype.toString.call(e)}function Y(e,t){var s,i=l({},e);for(s in t)u(t,s)&&(n(e[s])&&n(t[s])?(i[s]={},l(i[s],e[s]),l(i[s],t[s])):null!=t[s]?i[s]=t[s]:delete i[s]);for(s in e)u(e,s)&&!u(t,s)&&n(e[s])&&(i[s]=l({},i[s]));return i}function O(e){null!=e&&this.set(e)}function x(e,t){var n=e.toLowerCase();Ut[n]=Ut[n+\"s\"]=Ut[t]=e}function T(e){return\"string\"==typeof e?Ut[e]||Ut[e.toLowerCase()]:void 0}function b(e){var t,n,s={};for(n in e)u(e,n)&&(t=T(n))&&(s[t]=e[n]);return s}function P(e,t){Nt[e]=t}function W(e){var t=[];for(var n in e)t.push({unit:n,priority:Nt[n]});return t.sort(function(e,t){return e.priority-t.priority}),t}function R(e,t,n){var s=\"\"+Math.abs(e),i=t-s.length;return(e>=0?n?\"+\":\"\":\"-\")+Math.pow(10,Math.max(0,i)).toString().substr(1)+s}function C(e,t,n,s){var i=s;\"string\"==typeof s&&(i=function(){return this[s]()}),e&&(Vt[e]=i),t&&(Vt[t[0]]=function(){return R(i.apply(this,arguments),t[1],t[2])}),n&&(Vt[n]=function(){return this.localeData().ordinal(i.apply(this,arguments),e)})}function F(e){return e.match(/\\[[\\s\\S]/)?e.replace(/^\\[|\\]$/g,\"\"):e.replace(/\\\\/g,\"\")}function U(e){var t,n,s=e.match(Ht);for(t=0,n=s.length;t<n;t++)Vt[s[t]]?s[t]=Vt[s[t]]:s[t]=F(s[t]);return function(t){var i,r=\"\";for(i=0;i<n;i++)r+=D(s[i])?s[i].call(t,e):s[i];return r}}function N(e,t){return e.isValid()?(t=H(t,e.localeData()),Gt[t]=Gt[t]||U(t),Gt[t](e)):e.localeData().invalidDate()}function H(e,t){var n=5;for(Lt.lastIndex=0;n>=0&&Lt.test(e);)e=e.replace(Lt,function(e){return t.longDateFormat(e)||e}),Lt.lastIndex=0,n-=1;return e}function L(e,t,n){rn[e]=D(t)?t:function(e,s){return e&&n?n:t}}function G(e,t){return u(rn,e)?rn[e](t._strict,t._locale):new RegExp(V(e))}function V(e){return j(e.replace(\"\\\\\",\"\").replace(/\\\\(\\[)|\\\\(\\])|\\[([^\\]\\[]*)\\]|\\\\(.)/g,function(e,t,n,s,i){return t||n||s||i}))}function j(e){return e.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g,\"\\\\$&\")}function I(e,t){var n,s=t;for(\"string\"==typeof e&&(e=[e]),r(t)&&(s=function(e,n){n[t]=w(e)}),n=0;n<e.length;n++)an[e[n]]=s}function E(e,t){I(e,function(e,n,s,i){s._w=s._w||{},t(e,s._w,s,i)})}function A(e,t,n){null!=t&&u(an,e)&&an[e](t,n._a,n,e)}function z(e){return Z(e)?366:365}function Z(e){return e%4==0&&e%100!=0||e%400==0}function $(t,n){return function(s){return null!=s?(J(this,t,s),e.updateOffset(this,n),this):q(this,t)}}function q(e,t){return e.isValid()?e._d[\"get\"+(e._isUTC?\"UTC\":\"\")+t]():NaN}function J(e,t,n){e.isValid()&&!isNaN(n)&&(\"FullYear\"===t&&Z(e.year())?e._d[\"set\"+(e._isUTC?\"UTC\":\"\")+t](n,e.month(),Q(n,e.month())):e._d[\"set\"+(e._isUTC?\"UTC\":\"\")+t](n))}function B(e,t){return(e%t+t)%t}function Q(e,t){if(isNaN(e)||isNaN(t))return NaN;var n=B(t,12);return e+=(t-n)/12,1===n?Z(e)?29:28:31-n%7%2}function X(e,t,n){var s,i,r,a=e.toLocaleLowerCase();if(!this._monthsParse)for(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[],s=0;s<12;++s)r=d([2e3,s]),this._shortMonthsParse[s]=this.monthsShort(r,\"\").toLocaleLowerCase(),this._longMonthsParse[s]=this.months(r,\"\").toLocaleLowerCase();return n?\"MMM\"===t?-1!==(i=yn.call(this._shortMonthsParse,a))?i:null:-1!==(i=yn.call(this._longMonthsParse,a))?i:null:\"MMM\"===t?-1!==(i=yn.call(this._shortMonthsParse,a))?i:-1!==(i=yn.call(this._longMonthsParse,a))?i:null:-1!==(i=yn.call(this._longMonthsParse,a))?i:-1!==(i=yn.call(this._shortMonthsParse,a))?i:null}function K(e,t){var n;if(!e.isValid())return e;if(\"string\"==typeof t)if(/^\\d+$/.test(t))t=w(t);else if(t=e.localeData().monthsParse(t),!r(t))return e;return n=Math.min(e.date(),Q(e.year(),t)),e._d[\"set\"+(e._isUTC?\"UTC\":\"\")+\"Month\"](t,n),e}function ee(t){return null!=t?(K(this,t),e.updateOffset(this,!0),this):q(this,\"Month\")}function te(){function e(e,t){return t.length-e.length}var t,n,s=[],i=[],r=[];for(t=0;t<12;t++)n=d([2e3,t]),s.push(this.monthsShort(n,\"\")),i.push(this.months(n,\"\")),r.push(this.months(n,\"\")),r.push(this.monthsShort(n,\"\"));for(s.sort(e),i.sort(e),r.sort(e),t=0;t<12;t++)s[t]=j(s[t]),i[t]=j(i[t]);for(t=0;t<24;t++)r[t]=j(r[t]);this._monthsRegex=new RegExp(\"^(\"+r.join(\"|\")+\")\",\"i\"),this._monthsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp(\"^(\"+i.join(\"|\")+\")\",\"i\"),this._monthsShortStrictRegex=new RegExp(\"^(\"+s.join(\"|\")+\")\",\"i\")}function ne(e,t,n,s,i,r,a){var o=new Date(e,t,n,s,i,r,a);return e<100&&e>=0&&isFinite(o.getFullYear())&&o.setFullYear(e),o}function se(e){var t=new Date(Date.UTC.apply(null,arguments));return e<100&&e>=0&&isFinite(t.getUTCFullYear())&&t.setUTCFullYear(e),t}function ie(e,t,n){var s=7+t-n;return-((7+se(e,0,s).getUTCDay()-t)%7)+s-1}function re(e,t,n,s,i){var r,a,o=1+7*(t-1)+(7+n-s)%7+ie(e,s,i);return o<=0?a=z(r=e-1)+o:o>z(e)?(r=e+1,a=o-z(e)):(r=e,a=o),{year:r,dayOfYear:a}}function ae(e,t,n){var s,i,r=ie(e.year(),t,n),a=Math.floor((e.dayOfYear()-r-1)/7)+1;return a<1?s=a+oe(i=e.year()-1,t,n):a>oe(e.year(),t,n)?(s=a-oe(e.year(),t,n),i=e.year()+1):(i=e.year(),s=a),{week:s,year:i}}function oe(e,t,n){var s=ie(e,t,n),i=ie(e+1,t,n);return(z(e)-s+i)/7}function ue(e,t){return\"string\"!=typeof e?e:isNaN(e)?\"number\"==typeof(e=t.weekdaysParse(e))?e:null:parseInt(e,10)}function le(e,t){return\"string\"==typeof e?t.weekdaysParse(e)%7||7:isNaN(e)?null:e}function de(e,t,n){var s,i,r,a=e.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],s=0;s<7;++s)r=d([2e3,1]).day(s),this._minWeekdaysParse[s]=this.weekdaysMin(r,\"\").toLocaleLowerCase(),this._shortWeekdaysParse[s]=this.weekdaysShort(r,\"\").toLocaleLowerCase(),this._weekdaysParse[s]=this.weekdays(r,\"\").toLocaleLowerCase();return n?\"dddd\"===t?-1!==(i=yn.call(this._weekdaysParse,a))?i:null:\"ddd\"===t?-1!==(i=yn.call(this._shortWeekdaysParse,a))?i:null:-1!==(i=yn.call(this._minWeekdaysParse,a))?i:null:\"dddd\"===t?-1!==(i=yn.call(this._weekdaysParse,a))?i:-1!==(i=yn.call(this._shortWeekdaysParse,a))?i:-1!==(i=yn.call(this._minWeekdaysParse,a))?i:null:\"ddd\"===t?-1!==(i=yn.call(this._shortWeekdaysParse,a))?i:-1!==(i=yn.call(this._weekdaysParse,a))?i:-1!==(i=yn.call(this._minWeekdaysParse,a))?i:null:-1!==(i=yn.call(this._minWeekdaysParse,a))?i:-1!==(i=yn.call(this._weekdaysParse,a))?i:-1!==(i=yn.call(this._shortWeekdaysParse,a))?i:null}function he(){function e(e,t){return t.length-e.length}var t,n,s,i,r,a=[],o=[],u=[],l=[];for(t=0;t<7;t++)n=d([2e3,1]).day(t),s=this.weekdaysMin(n,\"\"),i=this.weekdaysShort(n,\"\"),r=this.weekdays(n,\"\"),a.push(s),o.push(i),u.push(r),l.push(s),l.push(i),l.push(r);for(a.sort(e),o.sort(e),u.sort(e),l.sort(e),t=0;t<7;t++)o[t]=j(o[t]),u[t]=j(u[t]),l[t]=j(l[t]);this._weekdaysRegex=new RegExp(\"^(\"+l.join(\"|\")+\")\",\"i\"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp(\"^(\"+u.join(\"|\")+\")\",\"i\"),this._weekdaysShortStrictRegex=new RegExp(\"^(\"+o.join(\"|\")+\")\",\"i\"),this._weekdaysMinStrictRegex=new RegExp(\"^(\"+a.join(\"|\")+\")\",\"i\")}function ce(){return this.hours()%12||12}function fe(e,t){C(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function me(e,t){return t._meridiemParse}function _e(e){return e?e.toLowerCase().replace(\"_\",\"-\"):e}function ye(e){for(var t,n,s,i,r=0;r<e.length;){for(t=(i=_e(e[r]).split(\"-\")).length,n=(n=_e(e[r+1]))?n.split(\"-\"):null;t>0;){if(s=ge(i.slice(0,t).join(\"-\")))return s;if(n&&n.length>=t&&v(i,n,!0)>=t-1)break;t--}r++}return null}function ge(e){var t=null;if(!Fn[e]&&\"undefined\"!=typeof module&&module&&module.exports)try{t=Pn._abbr,require(\"./locale/\"+e),pe(t)}catch(e){}return Fn[e]}function pe(e,t){var n;return e&&(n=i(t)?ve(e):we(e,t))&&(Pn=n),Pn._abbr}function we(e,t){if(null!==t){var n=Cn;if(t.abbr=e,null!=Fn[e])S(\"defineLocaleOverride\",\"use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info.\"),n=Fn[e]._config;else if(null!=t.parentLocale){if(null==Fn[t.parentLocale])return Un[t.parentLocale]||(Un[t.parentLocale]=[]),Un[t.parentLocale].push({name:e,config:t}),null;n=Fn[t.parentLocale]._config}return Fn[e]=new O(Y(n,t)),Un[e]&&Un[e].forEach(function(e){we(e.name,e.config)}),pe(e),Fn[e]}return delete Fn[e],null}function ve(e){var n;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return Pn;if(!t(e)){if(n=ge(e))return n;e=[e]}return ye(e)}function Me(e){var t,n=e._a;return n&&-2===c(e).overflow&&(t=n[un]<0||n[un]>11?un:n[ln]<1||n[ln]>Q(n[on],n[un])?ln:n[dn]<0||n[dn]>24||24===n[dn]&&(0!==n[hn]||0!==n[cn]||0!==n[fn])?dn:n[hn]<0||n[hn]>59?hn:n[cn]<0||n[cn]>59?cn:n[fn]<0||n[fn]>999?fn:-1,c(e)._overflowDayOfYear&&(t<on||t>ln)&&(t=ln),c(e)._overflowWeeks&&-1===t&&(t=mn),c(e)._overflowWeekday&&-1===t&&(t=_n),c(e).overflow=t),e}function ke(e,t,n){return null!=e?e:null!=t?t:n}function Se(t){var n=new Date(e.now());return t._useUTC?[n.getUTCFullYear(),n.getUTCMonth(),n.getUTCDate()]:[n.getFullYear(),n.getMonth(),n.getDate()]}function De(e){var t,n,s,i,r=[];if(!e._d){for(s=Se(e),e._w&&null==e._a[ln]&&null==e._a[un]&&Ye(e),null!=e._dayOfYear&&(i=ke(e._a[on],s[on]),(e._dayOfYear>z(i)||0===e._dayOfYear)&&(c(e)._overflowDayOfYear=!0),n=se(i,0,e._dayOfYear),e._a[un]=n.getUTCMonth(),e._a[ln]=n.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=r[t]=s[t];for(;t<7;t++)e._a[t]=r[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[dn]&&0===e._a[hn]&&0===e._a[cn]&&0===e._a[fn]&&(e._nextDay=!0,e._a[dn]=0),e._d=(e._useUTC?se:ne).apply(null,r),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[dn]=24),e._w&&void 0!==e._w.d&&e._w.d!==e._d.getDay()&&(c(e).weekdayMismatch=!0)}}function Ye(e){var t,n,s,i,r,a,o,u;if(null!=(t=e._w).GG||null!=t.W||null!=t.E)r=1,a=4,n=ke(t.GG,e._a[on],ae(Ie(),1,4).year),s=ke(t.W,1),((i=ke(t.E,1))<1||i>7)&&(u=!0);else{r=e._locale._week.dow,a=e._locale._week.doy;var l=ae(Ie(),r,a);n=ke(t.gg,e._a[on],l.year),s=ke(t.w,l.week),null!=t.d?((i=t.d)<0||i>6)&&(u=!0):null!=t.e?(i=t.e+r,(t.e<0||t.e>6)&&(u=!0)):i=r}s<1||s>oe(n,r,a)?c(e)._overflowWeeks=!0:null!=u?c(e)._overflowWeekday=!0:(o=re(n,s,i,r,a),e._a[on]=o.year,e._dayOfYear=o.dayOfYear)}function Oe(e){var t,n,s,i,r,a,o=e._i,u=Nn.exec(o)||Hn.exec(o);if(u){for(c(e).iso=!0,t=0,n=Gn.length;t<n;t++)if(Gn[t][1].exec(u[1])){i=Gn[t][0],s=!1!==Gn[t][2];break}if(null==i)return void(e._isValid=!1);if(u[3]){for(t=0,n=Vn.length;t<n;t++)if(Vn[t][1].exec(u[3])){r=(u[2]||\" \")+Vn[t][0];break}if(null==r)return void(e._isValid=!1)}if(!s&&null!=r)return void(e._isValid=!1);if(u[4]){if(!Ln.exec(u[4]))return void(e._isValid=!1);a=\"Z\"}e._f=i+(r||\"\")+(a||\"\"),Fe(e)}else e._isValid=!1}function xe(e,t,n,s,i,r){var a=[Te(e),vn.indexOf(t),parseInt(n,10),parseInt(s,10),parseInt(i,10)];return r&&a.push(parseInt(r,10)),a}function Te(e){var t=parseInt(e,10);return t<=49?2e3+t:t<=999?1900+t:t}function be(e){return e.replace(/\\([^)]*\\)|[\\n\\t]/g,\" \").replace(/(\\s\\s+)/g,\" \").trim()}function Pe(e,t,n){return!e||Yn.indexOf(e)===new Date(t[0],t[1],t[2]).getDay()||(c(n).weekdayMismatch=!0,n._isValid=!1,!1)}function We(e,t,n){if(e)return En[e];if(t)return 0;var s=parseInt(n,10),i=s%100;return 60*((s-i)/100)+i}function Re(e){var t=In.exec(be(e._i));if(t){var n=xe(t[4],t[3],t[2],t[5],t[6],t[7]);if(!Pe(t[1],n,e))return;e._a=n,e._tzm=We(t[8],t[9],t[10]),e._d=se.apply(null,e._a),e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),c(e).rfc2822=!0}else e._isValid=!1}function Ce(t){var n=jn.exec(t._i);null===n?(Oe(t),!1===t._isValid&&(delete t._isValid,Re(t),!1===t._isValid&&(delete t._isValid,e.createFromInputFallback(t)))):t._d=new Date(+n[1])}function Fe(t){if(t._f!==e.ISO_8601)if(t._f!==e.RFC_2822){t._a=[],c(t).empty=!0;var n,s,i,r,a,o=\"\"+t._i,u=o.length,l=0;for(i=H(t._f,t._locale).match(Ht)||[],n=0;n<i.length;n++)r=i[n],(s=(o.match(G(r,t))||[])[0])&&((a=o.substr(0,o.indexOf(s))).length>0&&c(t).unusedInput.push(a),o=o.slice(o.indexOf(s)+s.length),l+=s.length),Vt[r]?(s?c(t).empty=!1:c(t).unusedTokens.push(r),A(r,s,t)):t._strict&&!s&&c(t).unusedTokens.push(r);c(t).charsLeftOver=u-l,o.length>0&&c(t).unusedInput.push(o),t._a[dn]<=12&&!0===c(t).bigHour&&t._a[dn]>0&&(c(t).bigHour=void 0),c(t).parsedDateParts=t._a.slice(0),c(t).meridiem=t._meridiem,t._a[dn]=Ue(t._locale,t._a[dn],t._meridiem),De(t),Me(t)}else Re(t);else Oe(t)}function Ue(e,t,n){var s;return null==n?t:null!=e.meridiemHour?e.meridiemHour(t,n):null!=e.isPM?((s=e.isPM(n))&&t<12&&(t+=12),s||12!==t||(t=0),t):t}function Ne(e){var t,n,s,i,r;if(0===e._f.length)return c(e).invalidFormat=!0,void(e._d=new Date(NaN));for(i=0;i<e._f.length;i++)r=0,t=_({},e),null!=e._useUTC&&(t._useUTC=e._useUTC),t._f=e._f[i],Fe(t),f(t)&&(r+=c(t).charsLeftOver,r+=10*c(t).unusedTokens.length,c(t).score=r,(null==s||r<s)&&(s=r,n=t));l(e,n||t)}function He(e){if(!e._d){var t=b(e._i);e._a=o([t.year,t.month,t.day||t.date,t.hour,t.minute,t.second,t.millisecond],function(e){return e&&parseInt(e,10)}),De(e)}}function Le(e){var t=new y(Me(Ge(e)));return t._nextDay&&(t.add(1,\"d\"),t._nextDay=void 0),t}function Ge(e){var n=e._i,s=e._f;return e._locale=e._locale||ve(e._l),null===n||void 0===s&&\"\"===n?m({nullInput:!0}):(\"string\"==typeof n&&(e._i=n=e._locale.preparse(n)),g(n)?new y(Me(n)):(a(n)?e._d=n:t(s)?Ne(e):s?Fe(e):Ve(e),f(e)||(e._d=null),e))}function Ve(s){var u=s._i;i(u)?s._d=new Date(e.now()):a(u)?s._d=new Date(u.valueOf()):\"string\"==typeof u?Ce(s):t(u)?(s._a=o(u.slice(0),function(e){return parseInt(e,10)}),De(s)):n(u)?He(s):r(u)?s._d=new Date(u):e.createFromInputFallback(s)}function je(e,i,r,a,o){var u={};return!0!==r&&!1!==r||(a=r,r=void 0),(n(e)&&s(e)||t(e)&&0===e.length)&&(e=void 0),u._isAMomentObject=!0,u._useUTC=u._isUTC=o,u._l=r,u._i=e,u._f=i,u._strict=a,Le(u)}function Ie(e,t,n,s){return je(e,t,n,s,!1)}function Ee(e,n){var s,i;if(1===n.length&&t(n[0])&&(n=n[0]),!n.length)return Ie();for(s=n[0],i=1;i<n.length;++i)n[i].isValid()&&!n[i][e](s)||(s=n[i]);return s}function Ae(e){for(var t in e)if(-1===yn.call(Zn,t)||null!=e[t]&&isNaN(e[t]))return!1;for(var n=!1,s=0;s<Zn.length;++s)if(e[Zn[s]]){if(n)return!1;parseFloat(e[Zn[s]])!==w(e[Zn[s]])&&(n=!0)}return!0}function ze(e){var t=b(e),n=t.year||0,s=t.quarter||0,i=t.month||0,r=t.week||0,a=t.day||0,o=t.hour||0,u=t.minute||0,l=t.second||0,d=t.millisecond||0;this._isValid=Ae(t),this._milliseconds=+d+1e3*l+6e4*u+1e3*o*60*60,this._days=+a+7*r,this._months=+i+3*s+12*n,this._data={},this._locale=ve(),this._bubble()}function Ze(e){return e instanceof ze}function $e(e){return e<0?-1*Math.round(-1*e):Math.round(e)}function qe(e,t){C(e,0,0,function(){var e=this.utcOffset(),n=\"+\";return e<0&&(e=-e,n=\"-\"),n+R(~~(e/60),2)+t+R(~~e%60,2)})}function Je(e,t){var n=(t||\"\").match(e);if(null===n)return null;var s=((n[n.length-1]||[])+\"\").match($n)||[\"-\",0,0],i=60*s[1]+w(s[2]);return 0===i?0:\"+\"===s[0]?i:-i}function Be(t,n){var s,i;return n._isUTC?(s=n.clone(),i=(g(t)||a(t)?t.valueOf():Ie(t).valueOf())-s.valueOf(),s._d.setTime(s._d.valueOf()+i),e.updateOffset(s,!1),s):Ie(t).local()}function Qe(e){return 15*-Math.round(e._d.getTimezoneOffset()/15)}function Xe(){return!!this.isValid()&&(this._isUTC&&0===this._offset)}function Ke(e,t){var n,s,i,a=e,o=null;return Ze(e)?a={ms:e._milliseconds,d:e._days,M:e._months}:r(e)?(a={},t?a[t]=e:a.milliseconds=e):(o=qn.exec(e))?(n=\"-\"===o[1]?-1:1,a={y:0,d:w(o[ln])*n,h:w(o[dn])*n,m:w(o[hn])*n,s:w(o[cn])*n,ms:w($e(1e3*o[fn]))*n}):(o=Jn.exec(e))?(n=\"-\"===o[1]?-1:(o[1],1),a={y:et(o[2],n),M:et(o[3],n),w:et(o[4],n),d:et(o[5],n),h:et(o[6],n),m:et(o[7],n),s:et(o[8],n)}):null==a?a={}:\"object\"==typeof a&&(\"from\"in a||\"to\"in a)&&(i=nt(Ie(a.from),Ie(a.to)),(a={}).ms=i.milliseconds,a.M=i.months),s=new ze(a),Ze(e)&&u(e,\"_locale\")&&(s._locale=e._locale),s}function et(e,t){var n=e&&parseFloat(e.replace(\",\",\".\"));return(isNaN(n)?0:n)*t}function tt(e,t){var n={milliseconds:0,months:0};return n.months=t.month()-e.month()+12*(t.year()-e.year()),e.clone().add(n.months,\"M\").isAfter(t)&&--n.months,n.milliseconds=+t-+e.clone().add(n.months,\"M\"),n}function nt(e,t){var n;return e.isValid()&&t.isValid()?(t=Be(t,e),e.isBefore(t)?n=tt(e,t):((n=tt(t,e)).milliseconds=-n.milliseconds,n.months=-n.months),n):{milliseconds:0,months:0}}function st(e,t){return function(n,s){var i,r;return null===s||isNaN(+s)||(S(t,\"moment().\"+t+\"(period, number) is deprecated. Please use moment().\"+t+\"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.\"),r=n,n=s,s=r),n=\"string\"==typeof n?+n:n,i=Ke(n,s),it(this,i,e),this}}function it(t,n,s,i){var r=n._milliseconds,a=$e(n._days),o=$e(n._months);t.isValid()&&(i=null==i||i,o&&K(t,q(t,\"Month\")+o*s),a&&J(t,\"Date\",q(t,\"Date\")+a*s),r&&t._d.setTime(t._d.valueOf()+r*s),i&&e.updateOffset(t,a||o))}function rt(e,t){var n,s=12*(t.year()-e.year())+(t.month()-e.month()),i=e.clone().add(s,\"months\");return n=t-i<0?(t-i)/(i-e.clone().add(s-1,\"months\")):(t-i)/(e.clone().add(s+1,\"months\")-i),-(s+n)||0}function at(e){var t;return void 0===e?this._locale._abbr:(null!=(t=ve(e))&&(this._locale=t),this)}function ot(){return this._locale}function ut(e,t){C(0,[e,e.length],0,t)}function lt(e,t,n,s,i){var r;return null==e?ae(this,s,i).year:(r=oe(e,s,i),t>r&&(t=r),dt.call(this,e,t,n,s,i))}function dt(e,t,n,s,i){var r=re(e,t,n,s,i),a=se(r.year,0,r.dayOfYear);return this.year(a.getUTCFullYear()),this.month(a.getUTCMonth()),this.date(a.getUTCDate()),this}function ht(e){return e}function ct(e,t,n,s){var i=ve(),r=d().set(s,t);return i[n](r,e)}function ft(e,t,n){if(r(e)&&(t=e,e=void 0),e=e||\"\",null!=t)return ct(e,t,n,\"month\");var s,i=[];for(s=0;s<12;s++)i[s]=ct(e,s,n,\"month\");return i}function mt(e,t,n,s){\"boolean\"==typeof e?(r(t)&&(n=t,t=void 0),t=t||\"\"):(n=t=e,e=!1,r(t)&&(n=t,t=void 0),t=t||\"\");var i=ve(),a=e?i._week.dow:0;if(null!=n)return ct(t,(n+a)%7,s,\"day\");var o,u=[];for(o=0;o<7;o++)u[o]=ct(t,(o+a)%7,s,\"day\");return u}function _t(e,t,n,s){var i=Ke(t,n);return e._milliseconds+=s*i._milliseconds,e._days+=s*i._days,e._months+=s*i._months,e._bubble()}function yt(e){return e<0?Math.floor(e):Math.ceil(e)}function gt(e){return 4800*e/146097}function pt(e){return 146097*e/4800}function wt(e){return function(){return this.as(e)}}function vt(e){return function(){return this.isValid()?this._data[e]:NaN}}function Mt(e,t,n,s,i){return i.relativeTime(t||1,!!n,e,s)}function kt(e,t,n){var s=Ke(e).abs(),i=ks(s.as(\"s\")),r=ks(s.as(\"m\")),a=ks(s.as(\"h\")),o=ks(s.as(\"d\")),u=ks(s.as(\"M\")),l=ks(s.as(\"y\")),d=i<=Ss.ss&&[\"s\",i]||i<Ss.s&&[\"ss\",i]||r<=1&&[\"m\"]||r<Ss.m&&[\"mm\",r]||a<=1&&[\"h\"]||a<Ss.h&&[\"hh\",a]||o<=1&&[\"d\"]||o<Ss.d&&[\"dd\",o]||u<=1&&[\"M\"]||u<Ss.M&&[\"MM\",u]||l<=1&&[\"y\"]||[\"yy\",l];return d[2]=t,d[3]=+e>0,d[4]=n,Mt.apply(null,d)}function St(e){return(e>0)-(e<0)||+e}function Dt(){if(!this.isValid())return this.localeData().invalidDate();var e,t,n,s=Ds(this._milliseconds)/1e3,i=Ds(this._days),r=Ds(this._months);t=p((e=p(s/60))/60),s%=60,e%=60;var a=n=p(r/12),o=r%=12,u=i,l=t,d=e,h=s?s.toFixed(3).replace(/\\.?0+$/,\"\"):\"\",c=this.asSeconds();if(!c)return\"P0D\";var f=c<0?\"-\":\"\",m=St(this._months)!==St(c)?\"-\":\"\",_=St(this._days)!==St(c)?\"-\":\"\",y=St(this._milliseconds)!==St(c)?\"-\":\"\";return f+\"P\"+(a?m+a+\"Y\":\"\")+(o?m+o+\"M\":\"\")+(u?_+u+\"D\":\"\")+(l||d||h?\"T\":\"\")+(l?y+l+\"H\":\"\")+(d?y+d+\"M\":\"\")+(h?y+h+\"S\":\"\")}var Yt,Ot;Ot=Array.prototype.some?Array.prototype.some:function(e){for(var t=Object(this),n=t.length>>>0,s=0;s<n;s++)if(s in t&&e.call(this,t[s],s,t))return!0;return!1};var xt=e.momentProperties=[],Tt=!1,bt={};e.suppressDeprecationWarnings=!1,e.deprecationHandler=null;var Pt;Pt=Object.keys?Object.keys:function(e){var t,n=[];for(t in e)u(e,t)&&n.push(t);return n};var Wt={sameDay:\"[Today at] LT\",nextDay:\"[Tomorrow at] LT\",nextWeek:\"dddd [at] LT\",lastDay:\"[Yesterday at] LT\",lastWeek:\"[Last] dddd [at] LT\",sameElse:\"L\"},Rt={LTS:\"h:mm:ss A\",LT:\"h:mm A\",L:\"MM/DD/YYYY\",LL:\"MMMM D, YYYY\",LLL:\"MMMM D, YYYY h:mm A\",LLLL:\"dddd, MMMM D, YYYY h:mm A\"},Ct=/\\d{1,2}/,Ft={future:\"in %s\",past:\"%s ago\",s:\"a few seconds\",ss:\"%d seconds\",m:\"a minute\",mm:\"%d minutes\",h:\"an hour\",hh:\"%d hours\",d:\"a day\",dd:\"%d days\",M:\"a month\",MM:\"%d months\",y:\"a year\",yy:\"%d years\"},Ut={},Nt={},Ht=/(\\[[^\\[]*\\])|(\\\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,Lt=/(\\[[^\\[]*\\])|(\\\\)?(LTS|LT|LL?L?L?|l{1,4})/g,Gt={},Vt={},jt=/\\d/,It=/\\d\\d/,Et=/\\d{3}/,At=/\\d{4}/,zt=/[+-]?\\d{6}/,Zt=/\\d\\d?/,$t=/\\d\\d\\d\\d?/,qt=/\\d\\d\\d\\d\\d\\d?/,Jt=/\\d{1,3}/,Bt=/\\d{1,4}/,Qt=/[+-]?\\d{1,6}/,Xt=/\\d+/,Kt=/[+-]?\\d+/,en=/Z|[+-]\\d\\d:?\\d\\d/gi,tn=/Z|[+-]\\d\\d(?::?\\d\\d)?/gi,nn=/[+-]?\\d+(\\.\\d{1,3})?/,sn=/[0-9]*['a-z\\u00A0-\\u05FF\\u0700-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]+|[\\u0600-\\u06FF\\/]+(\\s*?[\\u0600-\\u06FF]+){1,2}/i,rn={},an={},on=0,un=1,ln=2,dn=3,hn=4,cn=5,fn=6,mn=7,_n=8;C(\"Y\",0,0,function(){var e=this.year();return e<=9999?\"\"+e:\"+\"+e}),C(0,[\"YY\",2],0,function(){return this.year()%100}),C(0,[\"YYYY\",4],0,\"year\"),C(0,[\"YYYYY\",5],0,\"year\"),C(0,[\"YYYYYY\",6,!0],0,\"year\"),x(\"year\",\"y\"),P(\"year\",1),L(\"Y\",Kt),L(\"YY\",Zt,It),L(\"YYYY\",Bt,At),L(\"YYYYY\",Qt,zt),L(\"YYYYYY\",Qt,zt),I([\"YYYYY\",\"YYYYYY\"],on),I(\"YYYY\",function(t,n){n[on]=2===t.length?e.parseTwoDigitYear(t):w(t)}),I(\"YY\",function(t,n){n[on]=e.parseTwoDigitYear(t)}),I(\"Y\",function(e,t){t[on]=parseInt(e,10)}),e.parseTwoDigitYear=function(e){return w(e)+(w(e)>68?1900:2e3)};var yn,gn=$(\"FullYear\",!0);yn=Array.prototype.indexOf?Array.prototype.indexOf:function(e){var t;for(t=0;t<this.length;++t)if(this[t]===e)return t;return-1},C(\"M\",[\"MM\",2],\"Mo\",function(){return this.month()+1}),C(\"MMM\",0,0,function(e){return this.localeData().monthsShort(this,e)}),C(\"MMMM\",0,0,function(e){return this.localeData().months(this,e)}),x(\"month\",\"M\"),P(\"month\",8),L(\"M\",Zt),L(\"MM\",Zt,It),L(\"MMM\",function(e,t){return t.monthsShortRegex(e)}),L(\"MMMM\",function(e,t){return t.monthsRegex(e)}),I([\"M\",\"MM\"],function(e,t){t[un]=w(e)-1}),I([\"MMM\",\"MMMM\"],function(e,t,n,s){var i=n._locale.monthsParse(e,s,n._strict);null!=i?t[un]=i:c(n).invalidMonth=e});var pn=/D[oD]?(\\[[^\\[\\]]*\\]|\\s)+MMMM?/,wn=\"January_February_March_April_May_June_July_August_September_October_November_December\".split(\"_\"),vn=\"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec\".split(\"_\"),Mn=sn,kn=sn;C(\"w\",[\"ww\",2],\"wo\",\"week\"),C(\"W\",[\"WW\",2],\"Wo\",\"isoWeek\"),x(\"week\",\"w\"),x(\"isoWeek\",\"W\"),P(\"week\",5),P(\"isoWeek\",5),L(\"w\",Zt),L(\"ww\",Zt,It),L(\"W\",Zt),L(\"WW\",Zt,It),E([\"w\",\"ww\",\"W\",\"WW\"],function(e,t,n,s){t[s.substr(0,1)]=w(e)});var Sn={dow:0,doy:6};C(\"d\",0,\"do\",\"day\"),C(\"dd\",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),C(\"ddd\",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),C(\"dddd\",0,0,function(e){return this.localeData().weekdays(this,e)}),C(\"e\",0,0,\"weekday\"),C(\"E\",0,0,\"isoWeekday\"),x(\"day\",\"d\"),x(\"weekday\",\"e\"),x(\"isoWeekday\",\"E\"),P(\"day\",11),P(\"weekday\",11),P(\"isoWeekday\",11),L(\"d\",Zt),L(\"e\",Zt),L(\"E\",Zt),L(\"dd\",function(e,t){return t.weekdaysMinRegex(e)}),L(\"ddd\",function(e,t){return t.weekdaysShortRegex(e)}),L(\"dddd\",function(e,t){return t.weekdaysRegex(e)}),E([\"dd\",\"ddd\",\"dddd\"],function(e,t,n,s){var i=n._locale.weekdaysParse(e,s,n._strict);null!=i?t.d=i:c(n).invalidWeekday=e}),E([\"d\",\"e\",\"E\"],function(e,t,n,s){t[s]=w(e)});var Dn=\"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday\".split(\"_\"),Yn=\"Sun_Mon_Tue_Wed_Thu_Fri_Sat\".split(\"_\"),On=\"Su_Mo_Tu_We_Th_Fr_Sa\".split(\"_\"),xn=sn,Tn=sn,bn=sn;C(\"H\",[\"HH\",2],0,\"hour\"),C(\"h\",[\"hh\",2],0,ce),C(\"k\",[\"kk\",2],0,function(){return this.hours()||24}),C(\"hmm\",0,0,function(){return\"\"+ce.apply(this)+R(this.minutes(),2)}),C(\"hmmss\",0,0,function(){return\"\"+ce.apply(this)+R(this.minutes(),2)+R(this.seconds(),2)}),C(\"Hmm\",0,0,function(){return\"\"+this.hours()+R(this.minutes(),2)}),C(\"Hmmss\",0,0,function(){return\"\"+this.hours()+R(this.minutes(),2)+R(this.seconds(),2)}),fe(\"a\",!0),fe(\"A\",!1),x(\"hour\",\"h\"),P(\"hour\",13),L(\"a\",me),L(\"A\",me),L(\"H\",Zt),L(\"h\",Zt),L(\"k\",Zt),L(\"HH\",Zt,It),L(\"hh\",Zt,It),L(\"kk\",Zt,It),L(\"hmm\",$t),L(\"hmmss\",qt),L(\"Hmm\",$t),L(\"Hmmss\",qt),I([\"H\",\"HH\"],dn),I([\"k\",\"kk\"],function(e,t,n){var s=w(e);t[dn]=24===s?0:s}),I([\"a\",\"A\"],function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e}),I([\"h\",\"hh\"],function(e,t,n){t[dn]=w(e),c(n).bigHour=!0}),I(\"hmm\",function(e,t,n){var s=e.length-2;t[dn]=w(e.substr(0,s)),t[hn]=w(e.substr(s)),c(n).bigHour=!0}),I(\"hmmss\",function(e,t,n){var s=e.length-4,i=e.length-2;t[dn]=w(e.substr(0,s)),t[hn]=w(e.substr(s,2)),t[cn]=w(e.substr(i)),c(n).bigHour=!0}),I(\"Hmm\",function(e,t,n){var s=e.length-2;t[dn]=w(e.substr(0,s)),t[hn]=w(e.substr(s))}),I(\"Hmmss\",function(e,t,n){var s=e.length-4,i=e.length-2;t[dn]=w(e.substr(0,s)),t[hn]=w(e.substr(s,2)),t[cn]=w(e.substr(i))});var Pn,Wn=/[ap]\\.?m?\\.?/i,Rn=$(\"Hours\",!0),Cn={calendar:Wt,longDateFormat:Rt,invalidDate:\"Invalid date\",ordinal:\"%d\",dayOfMonthOrdinalParse:Ct,relativeTime:Ft,months:wn,monthsShort:vn,week:Sn,weekdays:Dn,weekdaysMin:On,weekdaysShort:Yn,meridiemParse:Wn},Fn={},Un={},Nn=/^\\s*((?:[+-]\\d{6}|\\d{4})-(?:\\d\\d-\\d\\d|W\\d\\d-\\d|W\\d\\d|\\d\\d\\d|\\d\\d))(?:(T| )(\\d\\d(?::\\d\\d(?::\\d\\d(?:[.,]\\d+)?)?)?)([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/,Hn=/^\\s*((?:[+-]\\d{6}|\\d{4})(?:\\d\\d\\d\\d|W\\d\\d\\d|W\\d\\d|\\d\\d\\d|\\d\\d))(?:(T| )(\\d\\d(?:\\d\\d(?:\\d\\d(?:[.,]\\d+)?)?)?)([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/,Ln=/Z|[+-]\\d\\d(?::?\\d\\d)?/,Gn=[[\"YYYYYY-MM-DD\",/[+-]\\d{6}-\\d\\d-\\d\\d/],[\"YYYY-MM-DD\",/\\d{4}-\\d\\d-\\d\\d/],[\"GGGG-[W]WW-E\",/\\d{4}-W\\d\\d-\\d/],[\"GGGG-[W]WW\",/\\d{4}-W\\d\\d/,!1],[\"YYYY-DDD\",/\\d{4}-\\d{3}/],[\"YYYY-MM\",/\\d{4}-\\d\\d/,!1],[\"YYYYYYMMDD\",/[+-]\\d{10}/],[\"YYYYMMDD\",/\\d{8}/],[\"GGGG[W]WWE\",/\\d{4}W\\d{3}/],[\"GGGG[W]WW\",/\\d{4}W\\d{2}/,!1],[\"YYYYDDD\",/\\d{7}/]],Vn=[[\"HH:mm:ss.SSSS\",/\\d\\d:\\d\\d:\\d\\d\\.\\d+/],[\"HH:mm:ss,SSSS\",/\\d\\d:\\d\\d:\\d\\d,\\d+/],[\"HH:mm:ss\",/\\d\\d:\\d\\d:\\d\\d/],[\"HH:mm\",/\\d\\d:\\d\\d/],[\"HHmmss.SSSS\",/\\d\\d\\d\\d\\d\\d\\.\\d+/],[\"HHmmss,SSSS\",/\\d\\d\\d\\d\\d\\d,\\d+/],[\"HHmmss\",/\\d\\d\\d\\d\\d\\d/],[\"HHmm\",/\\d\\d\\d\\d/],[\"HH\",/\\d\\d/]],jn=/^\\/?Date\\((\\-?\\d+)/i,In=/^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\\s)?(\\d{1,2})\\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\\s(\\d{2,4})\\s(\\d\\d):(\\d\\d)(?::(\\d\\d))?\\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\\d{4}))$/,En={UT:0,GMT:0,EDT:-240,EST:-300,CDT:-300,CST:-360,MDT:-360,MST:-420,PDT:-420,PST:-480};e.createFromInputFallback=k(\"value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.\",function(e){e._d=new Date(e._i+(e._useUTC?\" UTC\":\"\"))}),e.ISO_8601=function(){},e.RFC_2822=function(){};var An=k(\"moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/\",function(){var e=Ie.apply(null,arguments);return this.isValid()&&e.isValid()?e<this?this:e:m()}),zn=k(\"moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/\",function(){var e=Ie.apply(null,arguments);return this.isValid()&&e.isValid()?e>this?this:e:m()}),Zn=[\"year\",\"quarter\",\"month\",\"week\",\"day\",\"hour\",\"minute\",\"second\",\"millisecond\"];qe(\"Z\",\":\"),qe(\"ZZ\",\"\"),L(\"Z\",tn),L(\"ZZ\",tn),I([\"Z\",\"ZZ\"],function(e,t,n){n._useUTC=!0,n._tzm=Je(tn,e)});var $n=/([\\+\\-]|\\d\\d)/gi;e.updateOffset=function(){};var qn=/^(\\-|\\+)?(?:(\\d*)[. ])?(\\d+)\\:(\\d+)(?:\\:(\\d+)(\\.\\d*)?)?$/,Jn=/^(-|\\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;Ke.fn=ze.prototype,Ke.invalid=function(){return Ke(NaN)};var Bn=st(1,\"add\"),Qn=st(-1,\"subtract\");e.defaultFormat=\"YYYY-MM-DDTHH:mm:ssZ\",e.defaultFormatUtc=\"YYYY-MM-DDTHH:mm:ss[Z]\";var Xn=k(\"moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.\",function(e){return void 0===e?this.localeData():this.locale(e)});C(0,[\"gg\",2],0,function(){return this.weekYear()%100}),C(0,[\"GG\",2],0,function(){return this.isoWeekYear()%100}),ut(\"gggg\",\"weekYear\"),ut(\"ggggg\",\"weekYear\"),ut(\"GGGG\",\"isoWeekYear\"),ut(\"GGGGG\",\"isoWeekYear\"),x(\"weekYear\",\"gg\"),x(\"isoWeekYear\",\"GG\"),P(\"weekYear\",1),P(\"isoWeekYear\",1),L(\"G\",Kt),L(\"g\",Kt),L(\"GG\",Zt,It),L(\"gg\",Zt,It),L(\"GGGG\",Bt,At),L(\"gggg\",Bt,At),L(\"GGGGG\",Qt,zt),L(\"ggggg\",Qt,zt),E([\"gggg\",\"ggggg\",\"GGGG\",\"GGGGG\"],function(e,t,n,s){t[s.substr(0,2)]=w(e)}),E([\"gg\",\"GG\"],function(t,n,s,i){n[i]=e.parseTwoDigitYear(t)}),C(\"Q\",0,\"Qo\",\"quarter\"),x(\"quarter\",\"Q\"),P(\"quarter\",7),L(\"Q\",jt),I(\"Q\",function(e,t){t[un]=3*(w(e)-1)}),C(\"D\",[\"DD\",2],\"Do\",\"date\"),x(\"date\",\"D\"),P(\"date\",9),L(\"D\",Zt),L(\"DD\",Zt,It),L(\"Do\",function(e,t){return e?t._dayOfMonthOrdinalParse||t._ordinalParse:t._dayOfMonthOrdinalParseLenient}),I([\"D\",\"DD\"],ln),I(\"Do\",function(e,t){t[ln]=w(e.match(Zt)[0],10)});var Kn=$(\"Date\",!0);C(\"DDD\",[\"DDDD\",3],\"DDDo\",\"dayOfYear\"),x(\"dayOfYear\",\"DDD\"),P(\"dayOfYear\",4),L(\"DDD\",Jt),L(\"DDDD\",Et),I([\"DDD\",\"DDDD\"],function(e,t,n){n._dayOfYear=w(e)}),C(\"m\",[\"mm\",2],0,\"minute\"),x(\"minute\",\"m\"),P(\"minute\",14),L(\"m\",Zt),L(\"mm\",Zt,It),I([\"m\",\"mm\"],hn);var es=$(\"Minutes\",!1);C(\"s\",[\"ss\",2],0,\"second\"),x(\"second\",\"s\"),P(\"second\",15),L(\"s\",Zt),L(\"ss\",Zt,It),I([\"s\",\"ss\"],cn);var ts=$(\"Seconds\",!1);C(\"S\",0,0,function(){return~~(this.millisecond()/100)}),C(0,[\"SS\",2],0,function(){return~~(this.millisecond()/10)}),C(0,[\"SSS\",3],0,\"millisecond\"),C(0,[\"SSSS\",4],0,function(){return 10*this.millisecond()}),C(0,[\"SSSSS\",5],0,function(){return 100*this.millisecond()}),C(0,[\"SSSSSS\",6],0,function(){return 1e3*this.millisecond()}),C(0,[\"SSSSSSS\",7],0,function(){return 1e4*this.millisecond()}),C(0,[\"SSSSSSSS\",8],0,function(){return 1e5*this.millisecond()}),C(0,[\"SSSSSSSSS\",9],0,function(){return 1e6*this.millisecond()}),x(\"millisecond\",\"ms\"),P(\"millisecond\",16),L(\"S\",Jt,jt),L(\"SS\",Jt,It),L(\"SSS\",Jt,Et);var ns;for(ns=\"SSSS\";ns.length<=9;ns+=\"S\")L(ns,Xt);for(ns=\"S\";ns.length<=9;ns+=\"S\")I(ns,function(e,t){t[fn]=w(1e3*(\"0.\"+e))});var ss=$(\"Milliseconds\",!1);C(\"z\",0,0,\"zoneAbbr\"),C(\"zz\",0,0,\"zoneName\");var is=y.prototype;is.add=Bn,is.calendar=function(t,n){var s=t||Ie(),i=Be(s,this).startOf(\"day\"),r=e.calendarFormat(this,i)||\"sameElse\",a=n&&(D(n[r])?n[r].call(this,s):n[r]);return this.format(a||this.localeData().calendar(r,this,Ie(s)))},is.clone=function(){return new y(this)},is.diff=function(e,t,n){var s,i,r;if(!this.isValid())return NaN;if(!(s=Be(e,this)).isValid())return NaN;switch(i=6e4*(s.utcOffset()-this.utcOffset()),t=T(t)){case\"year\":r=rt(this,s)/12;break;case\"month\":r=rt(this,s);break;case\"quarter\":r=rt(this,s)/3;break;case\"second\":r=(this-s)/1e3;break;case\"minute\":r=(this-s)/6e4;break;case\"hour\":r=(this-s)/36e5;break;case\"day\":r=(this-s-i)/864e5;break;case\"week\":r=(this-s-i)/6048e5;break;default:r=this-s}return n?r:p(r)},is.endOf=function(e){return void 0===(e=T(e))||\"millisecond\"===e?this:(\"date\"===e&&(e=\"day\"),this.startOf(e).add(1,\"isoWeek\"===e?\"week\":e).subtract(1,\"ms\"))},is.format=function(t){t||(t=this.isUtc()?e.defaultFormatUtc:e.defaultFormat);var n=N(this,t);return this.localeData().postformat(n)},is.from=function(e,t){return this.isValid()&&(g(e)&&e.isValid()||Ie(e).isValid())?Ke({to:this,from:e}).locale(this.locale()).humanize(!t):this.localeData().invalidDate()},is.fromNow=function(e){return this.from(Ie(),e)},is.to=function(e,t){return this.isValid()&&(g(e)&&e.isValid()||Ie(e).isValid())?Ke({from:this,to:e}).locale(this.locale()).humanize(!t):this.localeData().invalidDate()},is.toNow=function(e){return this.to(Ie(),e)},is.get=function(e){return e=T(e),D(this[e])?this[e]():this},is.invalidAt=function(){return c(this).overflow},is.isAfter=function(e,t){var n=g(e)?e:Ie(e);return!(!this.isValid()||!n.isValid())&&(\"millisecond\"===(t=T(i(t)?\"millisecond\":t))?this.valueOf()>n.valueOf():n.valueOf()<this.clone().startOf(t).valueOf())},is.isBefore=function(e,t){var n=g(e)?e:Ie(e);return!(!this.isValid()||!n.isValid())&&(\"millisecond\"===(t=T(i(t)?\"millisecond\":t))?this.valueOf()<n.valueOf():this.clone().endOf(t).valueOf()<n.valueOf())},is.isBetween=function(e,t,n,s){return(\"(\"===(s=s||\"()\")[0]?this.isAfter(e,n):!this.isBefore(e,n))&&(\")\"===s[1]?this.isBefore(t,n):!this.isAfter(t,n))},is.isSame=function(e,t){var n,s=g(e)?e:Ie(e);return!(!this.isValid()||!s.isValid())&&(\"millisecond\"===(t=T(t||\"millisecond\"))?this.valueOf()===s.valueOf():(n=s.valueOf(),this.clone().startOf(t).valueOf()<=n&&n<=this.clone().endOf(t).valueOf()))},is.isSameOrAfter=function(e,t){return this.isSame(e,t)||this.isAfter(e,t)},is.isSameOrBefore=function(e,t){return this.isSame(e,t)||this.isBefore(e,t)},is.isValid=function(){return f(this)},is.lang=Xn,is.locale=at,is.localeData=ot,is.max=zn,is.min=An,is.parsingFlags=function(){return l({},c(this))},is.set=function(e,t){if(\"object\"==typeof e)for(var n=W(e=b(e)),s=0;s<n.length;s++)this[n[s].unit](e[n[s].unit]);else if(e=T(e),D(this[e]))return this[e](t);return this},is.startOf=function(e){switch(e=T(e)){case\"year\":this.month(0);case\"quarter\":case\"month\":this.date(1);case\"week\":case\"isoWeek\":case\"day\":case\"date\":this.hours(0);case\"hour\":this.minutes(0);case\"minute\":this.seconds(0);case\"second\":this.milliseconds(0)}return\"week\"===e&&this.weekday(0),\"isoWeek\"===e&&this.isoWeekday(1),\"quarter\"===e&&this.month(3*Math.floor(this.month()/3)),this},is.subtract=Qn,is.toArray=function(){var e=this;return[e.year(),e.month(),e.date(),e.hour(),e.minute(),e.second(),e.millisecond()]},is.toObject=function(){var e=this;return{years:e.year(),months:e.month(),date:e.date(),hours:e.hours(),minutes:e.minutes(),seconds:e.seconds(),milliseconds:e.milliseconds()}},is.toDate=function(){return new Date(this.valueOf())},is.toISOString=function(){if(!this.isValid())return null;var e=this.clone().utc();return e.year()<0||e.year()>9999?N(e,\"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]\"):D(Date.prototype.toISOString)?this.toDate().toISOString():N(e,\"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]\")},is.inspect=function(){if(!this.isValid())return\"moment.invalid(/* \"+this._i+\" */)\";var e=\"moment\",t=\"\";this.isLocal()||(e=0===this.utcOffset()?\"moment.utc\":\"moment.parseZone\",t=\"Z\");var n=\"[\"+e+'(\"]',s=0<=this.year()&&this.year()<=9999?\"YYYY\":\"YYYYYY\",i=t+'[\")]';return this.format(n+s+\"-MM-DD[T]HH:mm:ss.SSS\"+i)},is.toJSON=function(){return this.isValid()?this.toISOString():null},is.toString=function(){return this.clone().locale(\"en\").format(\"ddd MMM DD YYYY HH:mm:ss [GMT]ZZ\")},is.unix=function(){return Math.floor(this.valueOf()/1e3)},is.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},is.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},is.year=gn,is.isLeapYear=function(){return Z(this.year())},is.weekYear=function(e){return lt.call(this,e,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)},is.isoWeekYear=function(e){return lt.call(this,e,this.isoWeek(),this.isoWeekday(),1,4)},is.quarter=is.quarters=function(e){return null==e?Math.ceil((this.month()+1)/3):this.month(3*(e-1)+this.month()%3)},is.month=ee,is.daysInMonth=function(){return Q(this.year(),this.month())},is.week=is.weeks=function(e){var t=this.localeData().week(this);return null==e?t:this.add(7*(e-t),\"d\")},is.isoWeek=is.isoWeeks=function(e){var t=ae(this,1,4).week;return null==e?t:this.add(7*(e-t),\"d\")},is.weeksInYear=function(){var e=this.localeData()._week;return oe(this.year(),e.dow,e.doy)},is.isoWeeksInYear=function(){return oe(this.year(),1,4)},is.date=Kn,is.day=is.days=function(e){if(!this.isValid())return null!=e?this:NaN;var t=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=e?(e=ue(e,this.localeData()),this.add(e-t,\"d\")):t},is.weekday=function(e){if(!this.isValid())return null!=e?this:NaN;var t=(this.day()+7-this.localeData()._week.dow)%7;return null==e?t:this.add(e-t,\"d\")},is.isoWeekday=function(e){if(!this.isValid())return null!=e?this:NaN;if(null!=e){var t=le(e,this.localeData());return this.day(this.day()%7?t:t-7)}return this.day()||7},is.dayOfYear=function(e){var t=Math.round((this.clone().startOf(\"day\")-this.clone().startOf(\"year\"))/864e5)+1;return null==e?t:this.add(e-t,\"d\")},is.hour=is.hours=Rn,is.minute=is.minutes=es,is.second=is.seconds=ts,is.millisecond=is.milliseconds=ss,is.utcOffset=function(t,n,s){var i,r=this._offset||0;if(!this.isValid())return null!=t?this:NaN;if(null!=t){if(\"string\"==typeof t){if(null===(t=Je(tn,t)))return this}else Math.abs(t)<16&&!s&&(t*=60);return!this._isUTC&&n&&(i=Qe(this)),this._offset=t,this._isUTC=!0,null!=i&&this.add(i,\"m\"),r!==t&&(!n||this._changeInProgress?it(this,Ke(t-r,\"m\"),1,!1):this._changeInProgress||(this._changeInProgress=!0,e.updateOffset(this,!0),this._changeInProgress=null)),this}return this._isUTC?r:Qe(this)},is.utc=function(e){return this.utcOffset(0,e)},is.local=function(e){return this._isUTC&&(this.utcOffset(0,e),this._isUTC=!1,e&&this.subtract(Qe(this),\"m\")),this},is.parseZone=function(){if(null!=this._tzm)this.utcOffset(this._tzm,!1,!0);else if(\"string\"==typeof this._i){var e=Je(en,this._i);null!=e?this.utcOffset(e):this.utcOffset(0,!0)}return this},is.hasAlignedHourOffset=function(e){return!!this.isValid()&&(e=e?Ie(e).utcOffset():0,(this.utcOffset()-e)%60==0)},is.isDST=function(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},is.isLocal=function(){return!!this.isValid()&&!this._isUTC},is.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},is.isUtc=Xe,is.isUTC=Xe,is.zoneAbbr=function(){return this._isUTC?\"UTC\":\"\"},is.zoneName=function(){return this._isUTC?\"Coordinated Universal Time\":\"\"},is.dates=k(\"dates accessor is deprecated. Use date instead.\",Kn),is.months=k(\"months accessor is deprecated. Use month instead\",ee),is.years=k(\"years accessor is deprecated. Use year instead\",gn),is.zone=k(\"moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/\",function(e,t){return null!=e?(\"string\"!=typeof e&&(e=-e),this.utcOffset(e,t),this):-this.utcOffset()}),is.isDSTShifted=k(\"isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information\",function(){if(!i(this._isDSTShifted))return this._isDSTShifted;var e={};if(_(e,this),(e=Ge(e))._a){var t=e._isUTC?d(e._a):Ie(e._a);this._isDSTShifted=this.isValid()&&v(e._a,t.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted});var rs=O.prototype;rs.calendar=function(e,t,n){var s=this._calendar[e]||this._calendar.sameElse;return D(s)?s.call(t,n):s},rs.longDateFormat=function(e){var t=this._longDateFormat[e],n=this._longDateFormat[e.toUpperCase()];return t||!n?t:(this._longDateFormat[e]=n.replace(/MMMM|MM|DD|dddd/g,function(e){return e.slice(1)}),this._longDateFormat[e])},rs.invalidDate=function(){return this._invalidDate},rs.ordinal=function(e){return this._ordinal.replace(\"%d\",e)},rs.preparse=ht,rs.postformat=ht,rs.relativeTime=function(e,t,n,s){var i=this._relativeTime[n];return D(i)?i(e,t,n,s):i.replace(/%d/i,e)},rs.pastFuture=function(e,t){var n=this._relativeTime[e>0?\"future\":\"past\"];return D(n)?n(t):n.replace(/%s/i,t)},rs.set=function(e){var t,n;for(n in e)D(t=e[n])?this[n]=t:this[\"_\"+n]=t;this._config=e,this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+\"|\"+/\\d{1,2}/.source)},rs.months=function(e,n){return e?t(this._months)?this._months[e.month()]:this._months[(this._months.isFormat||pn).test(n)?\"format\":\"standalone\"][e.month()]:t(this._months)?this._months:this._months.standalone},rs.monthsShort=function(e,n){return e?t(this._monthsShort)?this._monthsShort[e.month()]:this._monthsShort[pn.test(n)?\"format\":\"standalone\"][e.month()]:t(this._monthsShort)?this._monthsShort:this._monthsShort.standalone},rs.monthsParse=function(e,t,n){var s,i,r;if(this._monthsParseExact)return X.call(this,e,t,n);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),s=0;s<12;s++){if(i=d([2e3,s]),n&&!this._longMonthsParse[s]&&(this._longMonthsParse[s]=new RegExp(\"^\"+this.months(i,\"\").replace(\".\",\"\")+\"$\",\"i\"),this._shortMonthsParse[s]=new RegExp(\"^\"+this.monthsShort(i,\"\").replace(\".\",\"\")+\"$\",\"i\")),n||this._monthsParse[s]||(r=\"^\"+this.months(i,\"\")+\"|^\"+this.monthsShort(i,\"\"),this._monthsParse[s]=new RegExp(r.replace(\".\",\"\"),\"i\")),n&&\"MMMM\"===t&&this._longMonthsParse[s].test(e))return s;if(n&&\"MMM\"===t&&this._shortMonthsParse[s].test(e))return s;if(!n&&this._monthsParse[s].test(e))return s}},rs.monthsRegex=function(e){return this._monthsParseExact?(u(this,\"_monthsRegex\")||te.call(this),e?this._monthsStrictRegex:this._monthsRegex):(u(this,\"_monthsRegex\")||(this._monthsRegex=kn),this._monthsStrictRegex&&e?this._monthsStrictRegex:this._monthsRegex)},rs.monthsShortRegex=function(e){return this._monthsParseExact?(u(this,\"_monthsRegex\")||te.call(this),e?this._monthsShortStrictRegex:this._monthsShortRegex):(u(this,\"_monthsShortRegex\")||(this._monthsShortRegex=Mn),this._monthsShortStrictRegex&&e?this._monthsShortStrictRegex:this._monthsShortRegex)},rs.week=function(e){return ae(e,this._week.dow,this._week.doy).week},rs.firstDayOfYear=function(){return this._week.doy},rs.firstDayOfWeek=function(){return this._week.dow},rs.weekdays=function(e,n){return e?t(this._weekdays)?this._weekdays[e.day()]:this._weekdays[this._weekdays.isFormat.test(n)?\"format\":\"standalone\"][e.day()]:t(this._weekdays)?this._weekdays:this._weekdays.standalone},rs.weekdaysMin=function(e){return e?this._weekdaysMin[e.day()]:this._weekdaysMin},rs.weekdaysShort=function(e){return e?this._weekdaysShort[e.day()]:this._weekdaysShort},rs.weekdaysParse=function(e,t,n){var s,i,r;if(this._weekdaysParseExact)return de.call(this,e,t,n);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),s=0;s<7;s++){if(i=d([2e3,1]).day(s),n&&!this._fullWeekdaysParse[s]&&(this._fullWeekdaysParse[s]=new RegExp(\"^\"+this.weekdays(i,\"\").replace(\".\",\".?\")+\"$\",\"i\"),this._shortWeekdaysParse[s]=new RegExp(\"^\"+this.weekdaysShort(i,\"\").replace(\".\",\".?\")+\"$\",\"i\"),this._minWeekdaysParse[s]=new RegExp(\"^\"+this.weekdaysMin(i,\"\").replace(\".\",\".?\")+\"$\",\"i\")),this._weekdaysParse[s]||(r=\"^\"+this.weekdays(i,\"\")+\"|^\"+this.weekdaysShort(i,\"\")+\"|^\"+this.weekdaysMin(i,\"\"),this._weekdaysParse[s]=new RegExp(r.replace(\".\",\"\"),\"i\")),n&&\"dddd\"===t&&this._fullWeekdaysParse[s].test(e))return s;if(n&&\"ddd\"===t&&this._shortWeekdaysParse[s].test(e))return s;if(n&&\"dd\"===t&&this._minWeekdaysParse[s].test(e))return s;if(!n&&this._weekdaysParse[s].test(e))return s}},rs.weekdaysRegex=function(e){return this._weekdaysParseExact?(u(this,\"_weekdaysRegex\")||he.call(this),e?this._weekdaysStrictRegex:this._weekdaysRegex):(u(this,\"_weekdaysRegex\")||(this._weekdaysRegex=xn),this._weekdaysStrictRegex&&e?this._weekdaysStrictRegex:this._weekdaysRegex)},rs.weekdaysShortRegex=function(e){return this._weekdaysParseExact?(u(this,\"_weekdaysRegex\")||he.call(this),e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(u(this,\"_weekdaysShortRegex\")||(this._weekdaysShortRegex=Tn),this._weekdaysShortStrictRegex&&e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)},rs.weekdaysMinRegex=function(e){return this._weekdaysParseExact?(u(this,\"_weekdaysRegex\")||he.call(this),e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(u(this,\"_weekdaysMinRegex\")||(this._weekdaysMinRegex=bn),this._weekdaysMinStrictRegex&&e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)},rs.isPM=function(e){return\"p\"===(e+\"\").toLowerCase().charAt(0)},rs.meridiem=function(e,t,n){return e>11?n?\"pm\":\"PM\":n?\"am\":\"AM\"},pe(\"en\",{dayOfMonthOrdinalParse:/\\d{1,2}(th|st|nd|rd)/,ordinal:function(e){var t=e%10;return e+(1===w(e%100/10)?\"th\":1===t?\"st\":2===t?\"nd\":3===t?\"rd\":\"th\")}}),e.lang=k(\"moment.lang is deprecated. Use moment.locale instead.\",pe),e.langData=k(\"moment.langData is deprecated. Use moment.localeData instead.\",ve);var as=Math.abs,os=wt(\"ms\"),us=wt(\"s\"),ls=wt(\"m\"),ds=wt(\"h\"),hs=wt(\"d\"),cs=wt(\"w\"),fs=wt(\"M\"),ms=wt(\"y\"),_s=vt(\"milliseconds\"),ys=vt(\"seconds\"),gs=vt(\"minutes\"),ps=vt(\"hours\"),ws=vt(\"days\"),vs=vt(\"months\"),Ms=vt(\"years\"),ks=Math.round,Ss={ss:44,s:45,m:45,h:22,d:26,M:11},Ds=Math.abs,Ys=ze.prototype;return Ys.isValid=function(){return this._isValid},Ys.abs=function(){var e=this._data;return this._milliseconds=as(this._milliseconds),this._days=as(this._days),this._months=as(this._months),e.milliseconds=as(e.milliseconds),e.seconds=as(e.seconds),e.minutes=as(e.minutes),e.hours=as(e.hours),e.months=as(e.months),e.years=as(e.years),this},Ys.add=function(e,t){return _t(this,e,t,1)},Ys.subtract=function(e,t){return _t(this,e,t,-1)},Ys.as=function(e){if(!this.isValid())return NaN;var t,n,s=this._milliseconds;if(\"month\"===(e=T(e))||\"year\"===e)return t=this._days+s/864e5,n=this._months+gt(t),\"month\"===e?n:n/12;switch(t=this._days+Math.round(pt(this._months)),e){case\"week\":return t/7+s/6048e5;case\"day\":return t+s/864e5;case\"hour\":return 24*t+s/36e5;case\"minute\":return 1440*t+s/6e4;case\"second\":return 86400*t+s/1e3;case\"millisecond\":return Math.floor(864e5*t)+s;default:throw new Error(\"Unknown unit \"+e)}},Ys.asMilliseconds=os,Ys.asSeconds=us,Ys.asMinutes=ls,Ys.asHours=ds,Ys.asDays=hs,Ys.asWeeks=cs,Ys.asMonths=fs,Ys.asYears=ms,Ys.valueOf=function(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*w(this._months/12):NaN},Ys._bubble=function(){var e,t,n,s,i,r=this._milliseconds,a=this._days,o=this._months,u=this._data;return r>=0&&a>=0&&o>=0||r<=0&&a<=0&&o<=0||(r+=864e5*yt(pt(o)+a),a=0,o=0),u.milliseconds=r%1e3,e=p(r/1e3),u.seconds=e%60,t=p(e/60),u.minutes=t%60,n=p(t/60),u.hours=n%24,a+=p(n/24),i=p(gt(a)),o+=i,a-=yt(pt(i)),s=p(o/12),o%=12,u.days=a,u.months=o,u.years=s,this},Ys.clone=function(){return Ke(this)},Ys.get=function(e){return e=T(e),this.isValid()?this[e+\"s\"]():NaN},Ys.milliseconds=_s,Ys.seconds=ys,Ys.minutes=gs,Ys.hours=ps,Ys.days=ws,Ys.weeks=function(){return p(this.days()/7)},Ys.months=vs,Ys.years=Ms,Ys.humanize=function(e){if(!this.isValid())return this.localeData().invalidDate();var t=this.localeData(),n=kt(this,!e,t);return e&&(n=t.pastFuture(+this,n)),t.postformat(n)},Ys.toISOString=Dt,Ys.toString=Dt,Ys.toJSON=Dt,Ys.locale=at,Ys.localeData=ot,Ys.toIsoString=k(\"toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)\",Dt),Ys.lang=Xn,C(\"X\",0,0,\"unix\"),C(\"x\",0,0,\"valueOf\"),L(\"x\",Kt),L(\"X\",nn),I(\"X\",function(e,t,n){n._d=new Date(1e3*parseFloat(e,10))}),I(\"x\",function(e,t,n){n._d=new Date(w(e))}),e.version=\"2.19.1\",function(e){Yt=e}(Ie),e.fn=is,e.min=function(){return Ee(\"isBefore\",[].slice.call(arguments,0))},e.max=function(){return Ee(\"isAfter\",[].slice.call(arguments,0))},e.now=function(){return Date.now?Date.now():+new Date},e.utc=d,e.unix=function(e){return Ie(1e3*e)},e.months=function(e,t){return ft(e,t,\"months\")},e.isDate=a,e.locale=pe,e.invalid=m,e.duration=Ke,e.isMoment=g,e.weekdays=function(e,t,n){return mt(e,t,n,\"weekdays\")},e.parseZone=function(){return Ie.apply(null,arguments).parseZone()},e.localeData=ve,e.isDuration=Ze,e.monthsShort=function(e,t){return ft(e,t,\"monthsShort\")},e.weekdaysMin=function(e,t,n){return mt(e,t,n,\"weekdaysMin\")},e.defineLocale=we,e.updateLocale=function(e,t){if(null!=t){var n,s=Cn;null!=Fn[e]&&(s=Fn[e]._config),(n=new O(t=Y(s,t))).parentLocale=Fn[e],Fn[e]=n,pe(e)}else null!=Fn[e]&&(null!=Fn[e].parentLocale?Fn[e]=Fn[e].parentLocale:null!=Fn[e]&&delete Fn[e]);return Fn[e]},e.locales=function(){return Pt(Fn)},e.weekdaysShort=function(e,t,n){return mt(e,t,n,\"weekdaysShort\")},e.normalizeUnits=T,e.relativeTimeRounding=function(e){return void 0===e?ks:\"function\"==typeof e&&(ks=e,!0)},e.relativeTimeThreshold=function(e,t){return void 0!==Ss[e]&&(void 0===t?Ss[e]:(Ss[e]=t,\"s\"===e&&(Ss.ss=t-1),!0))},e.calendarFormat=function(e,t){var n=e.diff(t,\"days\",!0);return n<-6?\"sameElse\":n<-1?\"lastWeek\":n<0?\"lastDay\":n<1?\"sameDay\":n<2?\"nextDay\":n<7?\"nextWeek\":\"sameElse\"},e.prototype=is,e});"

/***/ }),
/* 59 */
/***/ (function(module, exports) {

module.exports = "/* This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this file,\n * You can obtain one at http://mozilla.org/MPL/2.0/. */\n\n/*jshint scripturl:true */\n(function () {\n\n  // pgbovine - modify defaultConfiguration and NOT _defaultConfiguration\n  var defaultConfiguration = {\n    // Disables clicks for a certain element.\n    // (e.g., 'canvas' would not show clicks on canvas elements.)\n    // Setting this to true will disable clicks globally.\n    dontShowClicks: true, // pgbovine: on 2017-10-14, stop logging/showing clicks since they're overly verbose\n    // Experimental feature to echo clicks to certain elements across clients:\n    cloneClicks: '.togetherjsCloneClick', // pgbovine - clone clicks ONLY in these elements\n    // Enable Mozilla or Google analytics on the page when TogetherJS is activated:\n    // FIXME: these don't seem to be working, and probably should be removed in favor\n    // of the hub analytics\n    enableAnalytics: false,\n    // The code to enable (this is defaulting to a Mozilla code):\n    analyticsCode: \"UA-35433268-28\",\n    // The base URL of the hub (gets filled in below):\n    //hubBase: \"http://localhost:30035/\",     // pgbovine - localhost testing\n    hubBase: \"http://45.79.11.225:30035/\",    // pgbovine - online deployment to new Linode (starting 2017-10-27)\n    //hubBase: \"http://104.237.139.253:30035/\", // pgbovine - online deployment to old Linode (prior to 2017-10-27)\n\n    eventRecorderFunc: null, // pgbovine - for demo recording\n\n    // A function that will return the name of the user:\n    // pgbovine - customized to use opt_uuid in localStorage if available\n    // so that each user can have a somewhat-unique N-digit username\n    getUserName: function() {\n      if ('localStorage' in window && window['localStorage'] !== null) {\n        var userUUID = localStorage.getItem('opt_uuid');\n        if (userUUID) {\n          // get last 3 digits of user uuid:\n          return 'user_' + userUUID.substring(userUUID.length - 3, userUUID.length);\n        } else {\n          return null; // let TogetherJS auto-assign an animal name\n        }\n      } else {\n        return null; // let TogetherJS auto-assign an animal name\n      }\n    },\n    // A function that will return the color of the user:\n    getUserColor: null,\n    // A function that will return the avatar of the user:\n    getUserAvatar: null,\n    // The siteName is used in the walkthrough (defaults to document.title):\n    siteName: null,\n    // Whether to use the minimized version of the code (overriding the built setting)\n    useMinimizedCode: undefined,\n    // Any events to bind to\n    on: {},\n    // Hub events to bind to\n    hub_on: {},\n    // Enables the alt-T alt-T TogetherJS shortcut; however, this setting\n    // must be enabled early as TogetherJSConfig_enableShortcut = true;\n    enableShortcut: false,\n    // The name of this tool as provided to users.  The UI is updated to use this.\n    // Because of how it is used in text it should be a proper noun, e.g.,\n    // \"MySite's Collaboration Tool\"\n    toolName: \"Python Tutor shared sessions\", // pgbovine\n    // Used to auto-start TogetherJS with a {prefix: pageName, max: participants}\n    // Also with findRoom: \"roomName\" it will connect to the given room name\n    findRoom: null,\n    // If true, starts TogetherJS automatically (of course!)\n    autoStart: false,\n    // If true, then the \"Join TogetherJS Session?\" confirmation dialog\n    // won't come up\n    suppressJoinConfirmation: true, // pgbovine\n    // If true, then the \"Invite a friend\" window won't automatically come up\n    suppressInvite: true, // pgbovine\n    // A room in which to find people to invite to this session,\n    inviteFromRoom: null,\n    // This is used to keep sessions from crossing over on the same\n    // domain, if for some reason you want sessions that are limited\n    // to only a portion of the domain:\n    storagePrefix: \"togetherjs\",\n    // When true, we treat the entire URL, including the hash, as the identifier\n    // of the page; i.e., if you one person is on `http://example.com/#view1`\n    // and another person is at `http://example.com/#view2` then these two people\n    // are considered to be at completely different URLs\n    includeHashInUrl: false,\n    // When true, the WebRTC-based mic/chat will be disabled\n    disableWebRTC: true, // pgbovine\n    // When true, youTube videos will synchronize\n    youtube: true,\n    // Ignores the following console messages, disables all messages if set to true\n    ignoreMessages: [\"cursor-update\", \"keydown\", \"scroll-update\"],\n    // Ignores the following forms (will ignore all forms if set to true):\n    ignoreForms: [\":password\", '.togetherjsIgnore'], // pgbovine\n    fallbackLang: \"en_US\"\n  };\n\n  var styleSheet = \"/togetherjs/togetherjs.css\";\n\n  var baseUrl = \"\";\n  if (baseUrl == \"__\" + \"baseUrl__\") {\n    // Reset the variable if it doesn't get substituted\n    baseUrl = \"\";\n  }\n  // True if this file should use minimized sub-resources:\n  var min = \"yes\" == \"__\" + \"min__\" ? false : \"yes\" == \"yes\";\n\n  var baseUrlOverride = localStorage.getItem(\"togetherjs.baseUrlOverride\");\n  if (baseUrlOverride) {\n    try {\n      baseUrlOverride = JSON.parse(baseUrlOverride);\n    } catch (e) {\n      baseUrlOverride = null;\n    }\n    if ((! baseUrlOverride) || baseUrlOverride.expiresAt < Date.now()) {\n      // Ignore because it has expired\n      localStorage.removeItem(\"togetherjs.baseUrlOverride\");\n    } else {\n      baseUrl = baseUrlOverride.baseUrl;\n      var logger = console.warn || console.log;\n      logger.call(console, \"Using TogetherJS baseUrlOverride:\", baseUrl);\n      logger.call(console, \"To undo run: localStorage.removeItem('togetherjs.baseUrlOverride')\");\n    }\n  }\n\n  var configOverride = localStorage.getItem(\"togetherjs.configOverride\");\n  if (configOverride) {\n    try {\n      configOverride = JSON.parse(configOverride);\n    } catch (e) {\n      configOverride = null;\n    }\n    if ((! configOverride) || configOverride.expiresAt < Date.now()) {\n      localStorage.removeItem(\"togetherjs.configOverride\");\n    } else {\n      var shownAny = false;\n      for (var attr in configOverride) {\n        if (! configOverride.hasOwnProperty(attr)) {\n          continue;\n        }\n        if (attr == \"expiresAt\" || ! configOverride.hasOwnProperty(attr)) {\n          continue;\n        }\n        if (! shownAny) {\n          console.warn(\"Using TogetherJS configOverride\");\n          console.warn(\"To undo run: localStorage.removeItem('togetherjs.configOverride')\");\n        }\n        window[\"TogetherJSConfig_\" + attr] = configOverride[attr];\n        console.log(\"Config override:\", attr, \"=\", configOverride[attr]);\n      }\n    }\n  }\n\n  var version = \"unknown\";\n  // FIXME: we could/should use a version from the checkout, at least\n  // for production\n  var cacheBust = \"\";\n  if ((! cacheBust) || cacheBust == \"\") {\n    cacheBust = Date.now() + \"\";\n  } else {\n    version = cacheBust;\n  }\n\n  // Make sure we have all of the console.* methods:\n  if (typeof console == \"undefined\") {\n    console = {};\n  }\n  if (! console.log) {\n    console.log = function () {};\n  }\n  [\"debug\", \"info\", \"warn\", \"error\"].forEach(function (method) {\n    if (! console[method]) {\n      console[method] = console.log;\n    }\n  });\n\n  if (! baseUrl) {\n    var scripts = document.getElementsByTagName(\"script\");\n    for (var i=0; i<scripts.length; i++) {\n      var src = scripts[i].src;\n      if (src && src.search(/togetherjs(-min)?.js(\\?.*)?$/) !== -1) {\n        baseUrl = src.replace(/\\/*togetherjs(-min)?.js(\\?.*)?$/, \"\");\n        //console.warn(\"Detected baseUrl as\", baseUrl); // pgbovine commented out\n        break;\n      } else if (src && src.search(/togetherjs-min.js(\\?.*)?$/) !== -1) {\n        baseUrl = src.replace(/\\/*togetherjs-min.js(\\?.*)?$/, \"\");\n        //console.warn(\"Detected baseUrl as\", baseUrl); // pgbovine commented out\n        break;\n      }\n    }\n  }\n  // pgbovine - hacked to make it work within Webpack\n  if (! baseUrl) {\n    baseUrl = window.location.protocol + '//' + window.location.host + '/js/lib/togetherjs';\n    //console.warn(\"Detected baseUrl as\", baseUrl);\n  }\n  if (! baseUrl) {\n    console.warn(\"Could not determine TogetherJS's baseUrl (looked for a <script> with togetherjs.js and togetherjs-min.js)\");\n  }\n\n  function addStyle() {\n    var existing = document.getElementById(\"togetherjs-stylesheet\");\n    if (! existing) {\n      var link = document.createElement(\"link\");\n      link.id = \"togetherjs-stylesheet\";\n      link.setAttribute(\"rel\", \"stylesheet\");\n      link.href = baseUrl + styleSheet + \"?bust=\" + cacheBust;\n      document.head.appendChild(link);\n    }\n  }\n\n  function addScript(url) {\n    var script = document.createElement(\"script\");\n    script.src = baseUrl + url + \"?bust=\" + cacheBust;\n    document.head.appendChild(script);\n  }\n\n  var TogetherJS = window.TogetherJS = function TogetherJS(event) {\n    if (TogetherJS.running) {\n      var session = TogetherJS.require(\"session\");\n      session.close();\n      return;\n    }\n    TogetherJS.startup.button = null;\n    try {\n      if (event && typeof event == \"object\") {\n        if (event.target && typeof event) {\n          TogetherJS.startup.button = event.target;\n        } else if (event.nodeType == 1) {\n          TogetherJS.startup.button = event;\n        } else if (event[0] && event[0].nodeType == 1) {\n          // Probably a jQuery element\n          TogetherJS.startup.button = event[0];\n        }\n      }\n    } catch (e) {\n      console.warn(\"Error determining starting button:\", e);\n    }\n    if (window.TowTruckConfig) {\n      console.warn(\"TowTruckConfig is deprecated; please use TogetherJSConfig\");\n      if (window.TogetherJSConfig) {\n        console.warn(\"Ignoring TowTruckConfig in favor of TogetherJSConfig\");\n      } else {\n        window.TogetherJSConfig = TowTruckConfig;\n      }\n    }\n    if (window.TogetherJSConfig && (! window.TogetherJSConfig.loaded)) {\n      TogetherJS.config(window.TogetherJSConfig);\n      window.TogetherJSConfig.loaded = true;\n    }\n\n    // This handles loading configuration from global variables.  This\n    // includes TogetherJSConfig_on_*, which are attributes folded into\n    // the \"on\" configuration value.\n    var attr;\n    var attrName;\n    var globalOns = {};\n    for (attr in window) {\n      if (attr.indexOf(\"TogetherJSConfig_on_\") === 0) {\n        attrName = attr.substr((\"TogetherJSConfig_on_\").length);\n        globalOns[attrName] = window[attr];\n      } else if (attr.indexOf(\"TogetherJSConfig_\") === 0) {\n        attrName = attr.substr((\"TogetherJSConfig_\").length);\n        TogetherJS.config(attrName, window[attr]);\n      } else if (attr.indexOf(\"TowTruckConfig_on_\") === 0) {\n        attrName = attr.substr((\"TowTruckConfig_on_\").length);\n        console.warn(\"TowTruckConfig_* is deprecated, please rename\", attr, \"to TogetherJSConfig_on_\" + attrName);\n        globalOns[attrName] = window[attr];\n      } else if (attr.indexOf(\"TowTruckConfig_\") === 0) {\n        attrName = attr.substr((\"TowTruckConfig_\").length);\n        console.warn(\"TowTruckConfig_* is deprecated, please rename\", attr, \"to TogetherJSConfig_\" + attrName);\n        TogetherJS.config(attrName, window[attr]);\n      }\n\n\n    }\n    // FIXME: copy existing config?\n    // FIXME: do this directly in TogetherJS.config() ?\n    // FIXME: close these configs?\n    var ons = TogetherJS.config.get(\"on\");\n    for (attr in globalOns) {\n      if (globalOns.hasOwnProperty(attr)) {\n        // FIXME: should we avoid overwriting?  Maybe use arrays?\n        ons[attr] = globalOns[attr];\n      }\n    }\n    TogetherJS.config(\"on\", ons);\n    for (attr in ons) {\n      TogetherJS.on(attr, ons[attr]);\n    }\n    var hubOns = TogetherJS.config.get(\"hub_on\");\n    if (hubOns) {\n      for (attr in hubOns) {\n        if (hubOns.hasOwnProperty(attr)) {\n          TogetherJS.hub.on(attr, hubOns[attr]);\n        }\n      }\n    }\n\n    if (! TogetherJS.startup.reason) {\n      // Then a call to TogetherJS() from a button must be started TogetherJS\n      TogetherJS.startup.reason = \"started\";\n    }\n\n    // FIXME: maybe I should just test for TogetherJS.require:\n    if (TogetherJS._loaded) {\n      var session = TogetherJS.require(\"session\");\n      addStyle();\n      session.start();\n      return;\n    }\n    // A sort of signal to session.js to tell it to actually\n    // start itself (i.e., put up a UI and try to activate)\n    TogetherJS.startup._launch = true;\n\n    addStyle();\n    var minSetting = TogetherJS.config.get(\"useMinimizedCode\");\n    TogetherJS.config.close(\"useMinimizedCode\");\n    if (minSetting !== undefined) {\n      min = !! minSetting;\n    }\n    var requireConfig = TogetherJS._extend(TogetherJS.requireConfig);\n    var deps = [\"session\", \"jquery\"];\n    var lang = TogetherJS.getConfig(\"lang\");\n    // [igoryen]: We should generate this value in Gruntfile.js, based on the available translations\n    var availableTranslations = {\n      \"en-US\": true,\n      \"ru\": true,\n      \"ru-RU\": true\n    };\n\n    if(lang === undefined) {\n      var navigatorLang = navigator.language.replace(/_/g, \"-\");\n      if (!availableTranslations[navigatorLang]) {\n        lang = TogetherJS.config.get(\"fallbackLang\");\n      } else {\n        lang = navigatorLang;\n      }\n     TogetherJS.config(\"lang\", lang);\n    }\n\n    TogetherJS.config(\"lang\", lang.replace(/_/g, \"-\")); // rename into TogetherJS.config.get()?\n    var localeTemplates = \"templates-\" + lang;// rename into TogetherJS.config.get()?\n    deps.splice(0, 0, localeTemplates);\n    function callback(session, jquery) {\n      TogetherJS._loaded = true;\n      if (! min) {\n        TogetherJS.require = require.config({context: \"togetherjs\"});\n        TogetherJS._requireObject = require;\n      }\n    }\n    if (! min) {\n      if (typeof require == \"function\") {\n        if (! require.config) {\n          console.warn(\"The global require (\", require, \") is not requirejs; please use togetherjs-min.js\");\n          throw new Error(\"Conflict with window.require\");\n        }\n        TogetherJS.require = require.config(requireConfig);\n      }\n    }\n    if (typeof TogetherJS.require == \"function\") {\n      // This is an already-configured version of require\n      TogetherJS.require(deps, callback);\n    } else {\n      requireConfig.deps = deps;\n      requireConfig.callback = callback;\n      if (! min) {\n        window.require = requireConfig;\n      }\n    }\n    if (min) {\n      addScript(\"/togetherjs/togetherjsPackage.js\");\n    } else {\n      addScript(\"/togetherjs/libs/require.js\");\n    }\n  };\n\n  TogetherJS.pageLoaded = Date.now();\n\n  TogetherJS._extend = function (base, extensions) {\n    if (! extensions) {\n      extensions = base;\n      base = {};\n    }\n    for (var a in extensions) {\n      if (extensions.hasOwnProperty(a)) {\n        base[a] = extensions[a];\n      }\n    }\n    return base;\n  };\n\n  TogetherJS._startupInit = {\n    // What element, if any, was used to start the session:\n    button: null,\n    // The startReason is the reason TogetherJS was started.  One of:\n    //   null: not started\n    //   started: hit the start button (first page view)\n    //   joined: joined the session (first page view)\n    reason: null,\n    // Also, the session may have started on \"this\" page, or maybe is continued\n    // from a past page.  TogetherJS.continued indicates the difference (false the\n    // first time TogetherJS is started or joined, true on later page loads).\n    continued: false,\n    // This is set to tell the session what shareId to use, if the boot\n    // code knows (mostly because the URL indicates the id).\n    _joinShareId: null,\n    // This tells session to start up immediately (otherwise it would wait\n    // for session.start() to be run)\n    _launch: false\n  };\n  TogetherJS.startup = TogetherJS._extend(TogetherJS._startupInit);\n  TogetherJS.running = false;\n\n  TogetherJS.requireConfig = {\n    context: \"togetherjs\",\n    baseUrl: baseUrl + \"/togetherjs\",\n    urlArgs: \"bust=\" + cacheBust,\n    paths: {\n      jquery: \"libs/jquery-1.8.3.min\",\n      walkabout: \"libs/walkabout/walkabout\",\n      esprima: \"libs/walkabout/lib/esprima\",\n      falafel: \"libs/walkabout/lib/falafel\",\n      tinycolor: \"libs/tinycolor\",\n      whrandom: \"libs/whrandom/random\"\n    }\n  };\n\n  TogetherJS._mixinEvents = function (proto) {\n    proto.on = function on(name, callback) {\n      if (typeof callback != \"function\") {\n        console.warn(\"Bad callback for\", this, \".once(\", name, \", \", callback, \")\");\n        throw \"Error: .once() called with non-callback\";\n      }\n      if (name.search(\" \") != -1) {\n        var names = name.split(/ +/g);\n        names.forEach(function (n) {\n          this.on(n, callback);\n        }, this);\n        return;\n      }\n      if (this._knownEvents && this._knownEvents.indexOf(name) == -1) {\n        var thisString = \"\" + this;\n        if (thisString.length > 20) {\n          thisString = thisString.substr(0, 20) + \"...\";\n        }\n        console.warn(thisString + \".on('\" + name + \"', ...): unknown event\");\n        if (console.trace) {\n          console.trace();\n        }\n      }\n      if (! this._listeners) {\n        this._listeners = {};\n      }\n      if (! this._listeners[name]) {\n        this._listeners[name] = [];\n      }\n      if (this._listeners[name].indexOf(callback) == -1) {\n        this._listeners[name].push(callback);\n      }\n    };\n    proto.once = function once(name, callback) {\n      if (typeof callback != \"function\") {\n        console.warn(\"Bad callback for\", this, \".once(\", name, \", \", callback, \")\");\n        throw \"Error: .once() called with non-callback\";\n      }\n      var attr = \"onceCallback_\" + name;\n      // FIXME: maybe I should add the event name to the .once attribute:\n      if (! callback[attr]) {\n        callback[attr] = function onceCallback() {\n          callback.apply(this, arguments);\n          this.off(name, onceCallback);\n          delete callback[attr];\n        };\n      }\n      this.on(name, callback[attr]);\n    };\n    proto.off = proto.removeListener = function off(name, callback) {\n      if (this._listenerOffs) {\n        // Defer the .off() call until the .emit() is done.\n        this._listenerOffs.push([name, callback]);\n        return;\n      }\n      if (name.search(\" \") != -1) {\n        var names = name.split(/ +/g);\n        names.forEach(function (n) {\n          this.off(n, callback);\n        }, this);\n        return;\n      }\n      if ((! this._listeners) || ! this._listeners[name]) {\n        return;\n      }\n      var l = this._listeners[name], _len = l.length;\n      for (var i=0; i<_len; i++) {\n        if (l[i] == callback) {\n          l.splice(i, 1);\n          break;\n        }\n      }\n    };\n    proto.emit = function emit(name) {\n      var offs = this._listenerOffs = [];\n      if ((! this._listeners) || ! this._listeners[name]) {\n        return;\n      }\n      var args = Array.prototype.slice.call(arguments, 1);\n      var l = this._listeners[name];\n      l.forEach(function (callback) {\n\n        callback.apply(this, args);\n      }, this);\n      delete this._listenerOffs;\n      if (offs.length) {\n        offs.forEach(function (item) {\n          this.off(item[0], item[1]);\n        }, this);\n      }\n\n    };\n    return proto;\n  };\n\n  /* This finalizes the unloading of TogetherJS, including unloading modules */\n  TogetherJS._teardown = function () {\n    var requireObject = TogetherJS._requireObject || window.require;\n    // FIXME: this doesn't clear the context for min-case\n    if (requireObject.s && requireObject.s.contexts) {\n      delete requireObject.s.contexts.togetherjs;\n    }\n    TogetherJS._loaded = false;\n    TogetherJS.startup = TogetherJS._extend(TogetherJS._startupInit);\n    TogetherJS.running = false;\n  };\n\n  TogetherJS._mixinEvents(TogetherJS);\n  TogetherJS._knownEvents = [\"ready\", \"close\"];\n  TogetherJS.toString = function () {\n    return \"TogetherJS\";\n  };\n\n  var defaultHubBase = \"https://hub.togetherjs.com\";\n  if (defaultHubBase == \"__\" + \"hubUrl\"+ \"__\") {\n    // Substitution wasn't made\n    defaultHubBase = \"https://hub.togetherjs.mozillalabs.com\";\n  }\n\n  TogetherJS._configuration = {};\n  TogetherJS._defaultConfiguration = {\n    // Disables clicks for a certain element.\n    // (e.g., 'canvas' would not show clicks on canvas elements.)\n    // Setting this to true will disable clicks globally.\n    dontShowClicks: false,\n    // Experimental feature to echo clicks to certain elements across clients:\n    cloneClicks: false,\n    // Enable Mozilla or Google analytics on the page when TogetherJS is activated:\n    // FIXME: these don't seem to be working, and probably should be removed in favor\n    // of the hub analytics\n    enableAnalytics: false,\n    // The code to enable (this is defaulting to a Mozilla code):\n    analyticsCode: \"UA-35433268-28\",\n    // The base URL of the hub\n    hubBase: defaultHubBase,\n    // A function that will return the name of the user:\n    getUserName: null,\n    // A function that will return the color of the user:\n    getUserColor: null,\n    // A function that will return the avatar of the user:\n    getUserAvatar: null,\n    // The siteName is used in the walkthrough (defaults to document.title):\n    siteName: null,\n    // Whether to use the minimized version of the code (overriding the built setting)\n    useMinimizedCode: undefined,\n    // Any events to bind to\n    on: {},\n    // Hub events to bind to\n    hub_on: {},\n    // Enables the alt-T alt-T TogetherJS shortcut; however, this setting\n    // must be enabled early as TogetherJSConfig_enableShortcut = true;\n    enableShortcut: false,\n    // The name of this tool as provided to users.  The UI is updated to use this.\n    // Because of how it is used in text it should be a proper noun, e.g.,\n    // \"MySite's Collaboration Tool\"\n    toolName: null,\n    // Used to auto-start TogetherJS with a {prefix: pageName, max: participants}\n    // Also with findRoom: \"roomName\" it will connect to the given room name\n    findRoom: null,\n    // If true, starts TogetherJS automatically (of course!)\n    autoStart: false,\n    // If true, then the \"Join TogetherJS Session?\" confirmation dialog\n    // won't come up\n    suppressJoinConfirmation: false,\n    // If true, then the \"Invite a friend\" window won't automatically come up\n    suppressInvite: false,\n    // A room in which to find people to invite to this session,\n    inviteFromRoom: null,\n    // This is used to keep sessions from crossing over on the same\n    // domain, if for some reason you want sessions that are limited\n    // to only a portion of the domain:\n    storagePrefix: \"togetherjs\",\n    // When true, we treat the entire URL, including the hash, as the identifier\n    // of the page; i.e., if you one person is on `http://example.com/#view1`\n    // and another person is at `http://example.com/#view2` then these two people\n    // are considered to be at completely different URLs\n    includeHashInUrl: false,\n    // The language to present the tool in, such as \"en-US\" or \"ru-RU\"\n    // Note this must be set as TogetherJSConfig_lang, as it effects the loader\n    // and must be set as soon as this file is included\n    lang: null\n  };\n  // FIXME: there's a point at which configuration can't be updated\n  // (e.g., hubBase after the TogetherJS has loaded).  We should keep\n  // track of these and signal an error if someone attempts to\n  // reconfigure too late\n\n  TogetherJS.getConfig = function (name) { // rename into TogetherJS.config.get()?\n    var value = TogetherJS._configuration[name];\n    if (value === undefined) {\n      if (! TogetherJS._defaultConfiguration.hasOwnProperty(name)) {\n        console.error(\"Tried to load unknown configuration value:\", name);\n      }\n      value = TogetherJS._defaultConfiguration[name];\n    }\n    return value;\n  };\n  TogetherJS._defaultConfiguration = defaultConfiguration;\n  TogetherJS._configTrackers = {};\n  TogetherJS._configClosed = {};\n\n  /* TogetherJS.config(configurationObject)\n     or: TogetherJS.config(configName, value)\n\n     Adds configuration to TogetherJS.  You may also set the global variable TogetherJSConfig\n     and when TogetherJS is started that configuration will be loaded.\n\n     Unknown configuration values will lead to console error messages.\n     */\n  TogetherJS.config = function (name, maybeValue) {\n    var settings;\n    if (arguments.length == 1) {\n      if (typeof name != \"object\") {\n        throw new Error('TogetherJS.config(value) must have an object value (not: ' + name + ')');\n      }\n      settings = name;\n    } else {\n      settings = {};\n      settings[name] = maybeValue;\n    }\n    var i;\n    var tracker;\n    for (var attr in settings) {\n      if (settings.hasOwnProperty(attr)) {\n        if (TogetherJS._configClosed[attr] && TogetherJS.running) {\n          throw new Error(\"The configuration \" + attr + \" is finalized and cannot be changed\");\n        }\n      }\n    }\n    for (var attr in settings) {\n      if (! settings.hasOwnProperty(attr)) {\n        continue;\n      }\n      if (attr == \"loaded\" || attr == \"callToStart\") {\n        continue;\n      }\n      if (! TogetherJS._defaultConfiguration.hasOwnProperty(attr)) {\n        console.warn(\"Unknown configuration value passed to TogetherJS.config():\", attr);\n      }\n      var previous = TogetherJS._configuration[attr];\n      var value = settings[attr];\n      TogetherJS._configuration[attr] = value;\n      var trackers = TogetherJS._configTrackers[name] || [];\n      var failed = false;\n      for (i=0; i<trackers.length; i++) {\n        try {\n          tracker = trackers[i];\n          tracker(value, previous);\n        } catch (e) {\n          console.warn(\"Error setting configuration\", name, \"to\", value,\n                       \":\", e, \"; reverting to\", previous);\n          failed = true;\n          break;\n        }\n      }\n      if (failed) {\n        TogetherJS._configuration[attr] = previous;\n        for (i=0; i<trackers.length; i++) {\n          try {\n            tracker = trackers[i];\n            tracker(value);\n          } catch (e) {\n            console.warn(\"Error REsetting configuration\", name, \"to\", previous,\n                         \":\", e, \"(ignoring)\");\n          }\n        }\n      }\n    }\n  };\n\n  TogetherJS.config.get = function (name) {\n    var value = TogetherJS._configuration[name];\n    if (value === undefined) {\n      if (! TogetherJS._defaultConfiguration.hasOwnProperty(name)) {\n        console.error(\"Tried to load unknown configuration value:\", name);\n      }\n      value = TogetherJS._defaultConfiguration[name];\n    }\n    return value;\n  };\n\n  TogetherJS.config.track = function (name, callback) {\n    if (! TogetherJS._defaultConfiguration.hasOwnProperty(name)) {\n      throw new Error(\"Configuration is unknown: \" + name);\n    }\n    callback(TogetherJS.config.get(name));\n    if (! TogetherJS._configTrackers[name]) {\n      TogetherJS._configTrackers[name] = [];\n    }\n    TogetherJS._configTrackers[name].push(callback);\n    return callback;\n  };\n\n  TogetherJS.config.close = function (name) {\n    if (! TogetherJS._defaultConfiguration.hasOwnProperty(name)) {\n      throw new Error(\"Configuration is unknown: \" + name);\n    }\n    TogetherJS._configClosed[name] = true;\n  };\n\n  TogetherJS.reinitialize = function () {\n    if (TogetherJS.running && typeof TogetherJS.require == \"function\") {\n      TogetherJS.require([\"session\"], function (session) {\n        session.emit(\"reinitialize\");\n      });\n    }\n    // If it's not set, TogetherJS has not been loaded, and reinitialization is not needed\n  };\n\n  TogetherJS.refreshUserData = function () {\n    if (TogetherJS.running && typeof TogetherJS.require ==  \"function\") {\n      TogetherJS.require([\"session\"], function (session) {\n        session.emit(\"refresh-user-data\");\n      });\n    }\n  };\n\n  // This should contain the output of \"git describe --always --dirty\"\n  // FIXME: substitute this on the server (and update make-static-client)\n  TogetherJS.version = version;\n  TogetherJS.baseUrl = baseUrl;\n\n  TogetherJS.hub = TogetherJS._mixinEvents({});\n\n  TogetherJS._onmessage = function (msg) {\n    var type = msg.type;\n    if (type.search(/^app\\./) === 0) {\n      type = type.substr(\"app.\".length);\n    } else {\n      type = \"togetherjs.\" + type;\n    }\n    msg.type = type;\n    TogetherJS.hub.emit(msg.type, msg);\n  };\n\n  TogetherJS.send = function (msg) {\n    if (! TogetherJS.require) {\n      throw \"You cannot use TogetherJS.send() when TogetherJS is not running\";\n    }\n    var session = TogetherJS.require(\"session\");\n    session.appSend(msg);\n  };\n\n  TogetherJS.shareUrl = function () {\n    if (! TogetherJS.require) {\n      return null;\n    }\n    var session = TogetherJS.require(\"session\");\n    return session.shareUrl();\n  };\n\n  // pgbovine - added\n  TogetherJS.shareId = function () {\n    if (! TogetherJS.require) {\n      return null;\n    }\n    var session = TogetherJS.require(\"session\");\n    return session.shareId;\n  };\n\n  // pgbovine - added\n  TogetherJS.clientId = function () {\n    if (! TogetherJS.require) {\n      return null;\n    }\n    var session = TogetherJS.require(\"session\");\n    return session.clientId;\n  };\n\n  var listener = null;\n\n  TogetherJS.listenForShortcut = function () {\n    console.warn(\"Listening for alt-T alt-T to start TogetherJS\");\n    TogetherJS.removeShortcut();\n    listener = function listener(event) {\n      if (event.which == 84 && event.altKey) {\n        if (listener.pressed) {\n          // Second hit\n          TogetherJS();\n        } else {\n          listener.pressed = true;\n        }\n      } else {\n        listener.pressed = false;\n      }\n    };\n    TogetherJS.once(\"ready\", TogetherJS.removeShortcut);\n    document.addEventListener(\"keyup\", listener, false);\n  };\n\n  TogetherJS.removeShortcut = function () {\n    if (listener) {\n      document.addEventListener(\"keyup\", listener, false);\n      listener = null;\n    }\n  };\n\n  TogetherJS.config.track(\"enableShortcut\", function (enable, previous) {\n    if (enable) {\n      TogetherJS.listenForShortcut();\n    } else if (previous) {\n      TogetherJS.removeShortcut();\n    }\n  });\n\n  TogetherJS.checkForUsersOnChannel = function (address, callback) {\n    if (address.search(/^https?:/i) === 0) {\n      address = address.replace(/^http/i, 'ws');\n    }\n    var socket = new WebSocket(address);\n    var gotAnswer = false;\n    socket.onmessage = function (event) {\n      var msg = JSON.parse(event.data);\n      if (msg.type != \"init-connection\") {\n        console.warn(\"Got unexpected first message (should be init-connection):\", msg);\n        return;\n      }\n      if (gotAnswer) {\n        console.warn(\"Somehow received two responses from channel; ignoring second\");\n        socket.close();\n        return;\n      }\n      gotAnswer = true;\n      socket.close();\n      callback(msg.peerCount);\n    };\n    socket.onclose = socket.onerror = function () {\n      if (! gotAnswer) {\n        console.warn(\"Socket was closed without receiving answer\");\n        gotAnswer = true;\n        callback(undefined);\n      }\n    };\n  };\n\n  // It's nice to replace this early, before the load event fires, so we conflict\n  // as little as possible with the app we are embedded in:\n  var hash = location.hash.replace(/^#/, \"\");\n  var m = /&?togetherjs=([^&]*)/.exec(hash);\n  if (m) {\n    TogetherJS.startup._joinShareId = m[1];\n    TogetherJS.startup.reason = \"joined\";\n    var newHash = hash.substr(0, m.index) + hash.substr(m.index + m[0].length);\n    location.hash = newHash;\n  }\n  if (window._TogetherJSShareId) {\n    // A weird hack for something the addon does, to force a shareId.\n    // FIXME: probably should remove, it's a wonky feature.\n    TogetherJS.startup._joinShareId = window._TogetherJSShareId;\n    delete window._TogetherJSShareId;\n  }\n\n  function conditionalActivate() {\n    if (window.TogetherJSConfig_noAutoStart) {\n      return;\n    }\n    // A page can define this function to defer TogetherJS from starting\n    var callToStart = window.TogetherJSConfig_callToStart;\n    if (! callToStart && window.TowTruckConfig_callToStart) {\n      callToStart = window.TowTruckConfig_callToStart;\n      console.warn(\"Please rename TowTruckConfig_callToStart to TogetherJSConfig_callToStart\");\n    }\n    if (window.TogetherJSConfig && window.TogetherJSConfig.callToStart) {\n      callToStart = window.TogetherJSConfig.callToStart;\n    }\n    if (callToStart) {\n      // FIXME: need to document this:\n      callToStart(onload);\n    } else {\n      onload();\n    }\n  }\n\n  // FIXME: can we push this up before the load event?\n  // Do we need to wait at all?\n  function onload() {\n    if (TogetherJS.startup._joinShareId) {\n      TogetherJS();\n    } else if (window._TogetherJSBookmarklet) {\n      delete window._TogetherJSBookmarklet;\n      TogetherJS();\n    } else {\n      // FIXME: this doesn't respect storagePrefix:\n      var key = \"togetherjs-session.status\";\n      var value = sessionStorage.getItem(key);\n      if (value) {\n        value = JSON.parse(value);\n        if (value && value.running) {\n          TogetherJS.startup.continued = true;\n          TogetherJS.startup.reason = value.startupReason;\n          TogetherJS();\n        }\n      } else if (window.TogetherJSConfig_autoStart ||\n                 (window.TogetherJSConfig && window.TogetherJSConfig.autoStart)) {\n        TogetherJS.startup.reason = \"joined\";\n        TogetherJS();\n      }\n    }\n  }\n\n  conditionalActivate();\n\n  // FIXME: wait until load event to double check if this gets set?\n  if (window.TogetherJSConfig_enableShortcut) {\n    TogetherJS.listenForShortcut();\n  }\n\n  // For compatibility:\n  window.TowTruck = TogetherJS;\n\n})();\n"

/***/ }),
/* 60 */
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(1)(__webpack_require__(57))

/***/ }),
/* 61 */
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(1)(__webpack_require__(58))

/***/ }),
/* 62 */
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(1)(__webpack_require__(59))

/***/ }),
/* 63 */
/***/ (function(module, exports, __webpack_require__) {

var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! qTip2 - Pretty powerful tooltips - v2.0.0 - 2012-12-21
* http://craigsworks.com/projects/qtip2/
* Copyright (c) 2012 Craig Michael Thompson; Licensed MIT, GPL */

// modified by pgbovine (using "pgbovine" comments) to get it working with jQuery 3.0.0

/*jslint browser: true, onevar: true, undef: true, nomen: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: true */
/*global window: false, jQuery: false, console: false, define: false */

/* Cache window, document, undefined */
(function( window, document, undefined ) {

// Uses AMD or browser globals to create a jQuery plugin.
(function( factory ) {
	"use strict";
	if(true) {
		!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0)], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
				(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
	}
	else if(jQuery && !jQuery.fn.qtip) {
		factory(jQuery);
	}
}
(function($) {
	/* This currently causes issues with Safari 6, so for it's disabled */
	//"use strict"; // (Dis)able ECMAScript "strict" operation for this function. See more: http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/

	// Munge the primitives - Paul Irish tip
	var TRUE = true,
		FALSE = false,
		NULL = null,

		// Side names and other stuff
		X = 'x', Y = 'y',
		WIDTH = 'width',
		HEIGHT = 'height',
		TOP = 'top',
		LEFT = 'left',
		BOTTOM = 'bottom',
		RIGHT = 'right',
		CENTER = 'center',
		FLIP = 'flip',
		FLIPINVERT = 'flipinvert',
		SHIFT = 'shift',

		// Shortcut vars
		QTIP, PLUGINS, MOUSE,
		NAMESPACE = 'qtip',
		usedIDs = {},
		widget = ['ui-widget', 'ui-tooltip'],
		selector = 'div.qtip.'+NAMESPACE,
		defaultClass = NAMESPACE + '-default',
		focusClass = NAMESPACE + '-focus',
		hoverClass = NAMESPACE + '-hover',
		replaceSuffix = '_replacedByqTip',
		oldtitle = 'oldtitle',
		trackingBound;

	// Store mouse coordinates
	function storeMouse(event)
	{
		MOUSE = {
			pageX: event.pageX,
			pageY: event.pageY,
			type: 'mousemove',
			scrollX: window.pageXOffset || document.body.scrollLeft || document.documentElement.scrollLeft,
			scrollY: window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop
		};
	}
// Option object sanitizer
function sanitizeOptions(opts)
{
	var invalid = function(a) { return a === NULL || 'object' !== typeof a; },
		invalidContent = function(c) { return !$.isFunction(c) && ((!c && !c.attr) || c.length < 1 || ('object' === typeof c && !c.jquery && !c.then)); };

	if(!opts || 'object' !== typeof opts) { return FALSE; }

	if(invalid(opts.metadata)) {
		opts.metadata = { type: opts.metadata };
	}

	if('content' in opts) {
		if(invalid(opts.content) || opts.content.jquery) {
			opts.content = { text: opts.content };
		}

		if(invalidContent(opts.content.text || FALSE)) {
			opts.content.text = FALSE;
		}

		if('title' in opts.content) {
			if(invalid(opts.content.title)) {
				opts.content.title = { text: opts.content.title };
			}

			if(invalidContent(opts.content.title.text || FALSE)) {
				opts.content.title.text = FALSE;
			}
		}
	}

	if('position' in opts && invalid(opts.position)) {
		opts.position = { my: opts.position, at: opts.position };
	}

	if('show' in opts && invalid(opts.show)) {
		opts.show = opts.show.jquery ? { target: opts.show } : { event: opts.show };
	}

	if('hide' in opts && invalid(opts.hide)) {
		opts.hide = opts.hide.jquery ? { target: opts.hide } : { event: opts.hide };
	}

	if('style' in opts && invalid(opts.style)) {
		opts.style = { classes: opts.style };
	}

	// Sanitize plugin options
	$.each(PLUGINS, function() {
		if(this.sanitize) { this.sanitize(opts); }
	});

	return opts;
}

/*
* Core plugin implementation
*/
function QTip(target, options, id, attr)
{
	// Declare this reference
	var self = this,
		docBody = document.body,
		tooltipID = NAMESPACE + '-' + id,
		isPositioning = 0,
		isDrawing = 0,
		tooltip = $(),
		namespace = '.qtip-' + id,
		disabledClass = 'qtip-disabled',
		elements, cache;

	// Setup class attributes
	self.id = id;
	self.rendered = FALSE;
	self.destroyed = FALSE;
	self.elements = elements = { target: target };
	self.timers = { img: {} };
	self.options = options;
	self.checks = {};
	self.plugins = {};
	self.cache = cache = {
		event: {},
		target: $(),
		disabled: FALSE,
		attr: attr,
		onTarget: FALSE,
		lastClass: ''
	};

	function convertNotation(notation)
	{
		var i = 0, obj, option = options,

		// Split notation into array
		levels = notation.split('.');

		// Loop through
		while( option = option[ levels[i++] ] ) {
			if(i < levels.length) { obj = option; }
		}

		return [obj || options, levels.pop()];
	}

	function createWidgetClass(cls)
	{
		return widget.concat('').join(cls ? '-'+cls+' ' : ' ');
	}

	function setWidget()
	{
		var on = options.style.widget,
			disabled = tooltip.hasClass(disabledClass);

		tooltip.removeClass(disabledClass);
		disabledClass = on ? 'ui-state-disabled' : 'qtip-disabled';
		tooltip.toggleClass(disabledClass, disabled);

		tooltip.toggleClass('ui-helper-reset '+createWidgetClass(), on).toggleClass(defaultClass, options.style.def && !on);
		
		if(elements.content) {
			elements.content.toggleClass( createWidgetClass('content'), on);
		}
		if(elements.titlebar) {
			elements.titlebar.toggleClass( createWidgetClass('header'), on);
		}
		if(elements.button) {
			elements.button.toggleClass(NAMESPACE+'-icon', !on);
		}
	}

	function removeTitle(reposition)
	{
		if(elements.title) {
			elements.titlebar.remove();
			elements.titlebar = elements.title = elements.button = NULL;

			// Reposition if enabled
			if(reposition !== FALSE) { self.reposition(); }
		}
	}

	function createButton()
	{
		var button = options.content.title.button,
			isString = typeof button === 'string',
			close = isString ? button : 'Close tooltip';

		if(elements.button) { elements.button.remove(); }

		// Use custom button if one was supplied by user, else use default
		if(button.jquery) {
			elements.button = button;
		}
		else {
			elements.button = $('<a />', {
				'class': 'qtip-close ' + (options.style.widget ? '' : NAMESPACE+'-icon'),
				'title': close,
				'aria-label': close
			})
			.prepend(
				$('<span />', {
					'class': 'ui-icon ui-icon-close',
					'html': '&times;'
				})
			);
		}

		// Create button and setup attributes
		elements.button.appendTo(elements.titlebar || tooltip)
			.attr('role', 'button')
			.click(function(event) {
				if(!tooltip.hasClass(disabledClass)) { self.hide(event); }
				return FALSE;
			});
	}

	function createTitle()
	{
		var id = tooltipID+'-title';

		// Destroy previous title element, if present
		if(elements.titlebar) { removeTitle(); }

		// Create title bar and title elements
		elements.titlebar = $('<div />', {
			'class': NAMESPACE + '-titlebar ' + (options.style.widget ? createWidgetClass('header') : '')
		})
		.append(
			elements.title = $('<div />', {
				'id': id,
				'class': NAMESPACE + '-title',
				'aria-atomic': TRUE
			})
		)
		.insertBefore(elements.content)

		// Button-specific events
		.delegate('.qtip-close', 'mousedown keydown mouseup keyup mouseout', function(event) {
			$(this).toggleClass('ui-state-active ui-state-focus', event.type.substr(-4) === 'down');
		})
		.delegate('.qtip-close', 'mouseover mouseout', function(event){
			$(this).toggleClass('ui-state-hover', event.type === 'mouseover');
		});

		// Create button if enabled
		if(options.content.title.button) { createButton(); }
	}

	function updateButton(button)
	{
		var elem = elements.button;

		// Make sure tooltip is rendered and if not, return
		if(!self.rendered) { return FALSE; }

		if(!button) {
			elem.remove();
		}
		else {
			createButton();
		}
	}

	function updateTitle(content, reposition)
	{
		var elem = elements.title;

		// Make sure tooltip is rendered and if not, return
		if(!self.rendered || !content) { return FALSE; }

		// Use function to parse content
		if($.isFunction(content)) {
			content = content.call(target, cache.event, self);
		}

		// Remove title if callback returns false or null/undefined (but not '')
		if(content === FALSE || (!content && content !== '')) { return removeTitle(FALSE); }

		// Append new content if its a DOM array and show it if hidden
		else if(content.jquery && content.length > 0) {
			elem.empty().append(content.css({ display: 'block' }));
		}

		// Content is a regular string, insert the new content
		else { elem.html(content); }

		// Reposition if rnedered
		if(reposition !== FALSE && self.rendered && tooltip[0].offsetWidth > 0) {
			self.reposition(cache.event);
		}
	}

	function deferredContent(deferred)
	{
		if(deferred && $.isFunction(deferred.done)) {
			deferred.done(function(c) {
				updateContent(c, null, FALSE);
			});
		}
	}

	function updateContent(content, reposition, checkDeferred)
	{
		var elem = elements.content;

		// Make sure tooltip is rendered and content is defined. If not return
		if(!self.rendered || !content) { return FALSE; }

		// Use function to parse content
		if($.isFunction(content)) {
			content = content.call(target, cache.event, self) || '';
		}

		// Handle deferred content
		if(checkDeferred !== FALSE) {
			deferredContent(options.content.deferred);
		}

		// Append new content if its a DOM array and show it if hidden
		if(content.jquery && content.length > 0) {
			elem.empty().append(content.css({ display: 'block' }));
		}

		// Content is a regular string, insert the new content
		else { elem.html(content); }

		// Image detection
		function detectImages(next) {
			var images, srcs = {};

			function imageLoad(image) {
				// Clear src from object and any timers and events associated with the image
				if(image) {
					delete srcs[image.src];
					clearTimeout(self.timers.img[image.src]);
					$(image).unbind(namespace);
				}

				// If queue is empty after image removal, update tooltip and continue the queue
				if($.isEmptyObject(srcs)) {
					if(reposition !== FALSE) {
						self.reposition(cache.event);
					}

					next();
				}
			}

			// Find all content images without dimensions, and if no images were found, continue
			if((images = elem.find('img[src]:not([height]):not([width])')).length === 0) { return imageLoad(); }

			// Apply timer to each image to poll for dimensions
			images.each(function(i, elem) {
				// Skip if the src is already present
				if(srcs[elem.src] !== undefined) { return; }

				// Keep track of how many times we poll for image dimensions.
				// If it doesn't return in a reasonable amount of time, it's better
				// to display the tooltip, rather than hold up the queue.
				var iterations = 0, maxIterations = 3;

				(function timer(){
					// When the dimensions are found, remove the image from the queue
					if(elem.height || elem.width || (iterations > maxIterations)) { return imageLoad(elem); }

					// Increase iterations and restart timer
					iterations += 1;
					self.timers.img[elem.src] = setTimeout(timer, 700);
				}());

				// Also apply regular load/error event handlers
				$(elem).bind('error'+namespace+' load'+namespace, function(){ imageLoad(this); });

				// Store the src and element in our object
				srcs[elem.src] = elem;
			});
		}

		/*
		* If we're still rendering... insert into 'fx' queue our image dimension
		* checker which will halt the showing of the tooltip until image dimensions
		* can be detected properly.
		*/
		if(self.rendered < 0) { tooltip.queue('fx', detectImages); }

		// We're fully rendered, so reset isDrawing flag and proceed without queue delay
		else { isDrawing = 0; detectImages($.noop); }

		return self;
	}

	function assignEvents()
	{
		var posOptions = options.position,
			targets = {
				show: options.show.target,
				hide: options.hide.target,
				viewport: $(posOptions.viewport),
				document: $(document),
				body: $(document.body),
				window: $(window)
			},
			events = {
				show: $.trim('' + options.show.event).split(' '),
				hide: $.trim('' + options.hide.event).split(' ')
			};
			//IE6 = $.browser.msie && parseInt($.browser.version, 10) === 6; // pgbovine 

		// Define show event method
		function showMethod(event)
		{
			if(tooltip.hasClass(disabledClass)) { return FALSE; }

			// Clear hide timers
			clearTimeout(self.timers.show);
			clearTimeout(self.timers.hide);

			// Start show timer
			var callback = function(){ self.toggle(TRUE, event); };
			if(options.show.delay > 0) {
				self.timers.show = setTimeout(callback, options.show.delay);
			}
			else{ callback(); }
		}

		// Define hide method
		function hideMethod(event)
		{
			if(tooltip.hasClass(disabledClass) || isPositioning || isDrawing) { return FALSE; }

			// Check if new target was actually the tooltip element
			var relatedTarget = $(event.relatedTarget || event.target),
				ontoTooltip = relatedTarget.closest(selector)[0] === tooltip[0],
				ontoTarget = relatedTarget[0] === targets.show[0];

			// Clear timers and stop animation queue
			clearTimeout(self.timers.show);
			clearTimeout(self.timers.hide);

			// Prevent hiding if tooltip is fixed and event target is the tooltip. Or if mouse positioning is enabled and cursor momentarily overlaps
			if((posOptions.target === 'mouse' && ontoTooltip) || (options.hide.fixed && ((/mouse(out|leave|move)/).test(event.type) && (ontoTooltip || ontoTarget)))) {
				try { event.preventDefault(); event.stopImmediatePropagation(); } catch(e) {} return;
			}

			// If tooltip has displayed, start hide timer
			if(options.hide.delay > 0) {
				self.timers.hide = setTimeout(function(){ self.hide(event); }, options.hide.delay);
			}
			else{ self.hide(event); }
		}

		// Define inactive method
		function inactiveMethod(event)
		{
			if(tooltip.hasClass(disabledClass)) { return FALSE; }

			// Clear timer
			clearTimeout(self.timers.inactive);
			self.timers.inactive = setTimeout(function(){ self.hide(event); }, options.hide.inactive);
		}

		function repositionMethod(event) {
			if(self.rendered && tooltip[0].offsetWidth > 0) { self.reposition(event); }
		}

		// On mouseenter/mouseleave...
		tooltip.bind('mouseenter'+namespace+' mouseleave'+namespace, function(event) {
			var state = event.type === 'mouseenter';

			// Focus the tooltip on mouseenter (z-index stacking)
			if(state) { self.focus(event); }

			// Add hover class
			tooltip.toggleClass(hoverClass, state);
		});

		// If using mouseout/mouseleave as a hide event...
		if(/mouse(out|leave)/i.test(options.hide.event)) {
			// Hide tooltips when leaving current window/frame (but not select/option elements)
			if(options.hide.leave === 'window') {
				targets.window.bind('mouseout'+namespace+' blur'+namespace, function(event) {
					if(!/select|option/.test(event.target.nodeName) && !event.relatedTarget) { self.hide(event); }
				});
			}
		}

		// Enable hide.fixed
		if(options.hide.fixed) {
			// Add tooltip as a hide target
			targets.hide = targets.hide.add(tooltip);

			// Clear hide timer on tooltip hover to prevent it from closing
			tooltip.bind('mouseover'+namespace, function() {
				if(!tooltip.hasClass(disabledClass)) { clearTimeout(self.timers.hide); }
			});
		}

		/*
		* Make sure hoverIntent functions properly by using mouseleave to clear show timer if
		* mouseenter/mouseout is used for show.event, even if it isn't in the users options.
		*/
		else if(/mouse(over|enter)/i.test(options.show.event)) {
			targets.hide.bind('mouseleave'+namespace, function(event) {
				clearTimeout(self.timers.show);
			});
		}

		// Hide tooltip on document mousedown if unfocus events are enabled
		if(('' + options.hide.event).indexOf('unfocus') > -1) {
			posOptions.container.closest('html').bind('mousedown'+namespace+' touchstart'+namespace, function(event) {
				var elem = $(event.target),
					enabled = self.rendered && !tooltip.hasClass(disabledClass) && tooltip[0].offsetWidth > 0,
					isAncestor = elem.parents(selector).filter(tooltip[0]).length > 0;

				if(elem[0] !== target[0] && elem[0] !== tooltip[0] && !isAncestor &&
					!target.has(elem[0]).length && !elem.attr('disabled')
				) {
					self.hide(event);
				}
			});
		}

		// Check if the tooltip hides when inactive
		if('number' === typeof options.hide.inactive) {
			// Bind inactive method to target as a custom event
			targets.show.bind('qtip-'+id+'-inactive', inactiveMethod);

			// Define events which reset the 'inactive' event handler
			$.each(QTIP.inactiveEvents, function(index, type){
				targets.hide.add(elements.tooltip).bind(type+namespace+'-inactive', inactiveMethod);
			});
		}

		// Apply hide events
		$.each(events.hide, function(index, type) {
			var showIndex = $.inArray(type, events.show),
					targetHide = $(targets.hide);

			// Both events and targets are identical, apply events using a toggle
			if((showIndex > -1 && targetHide.add(targets.show).length === targetHide.length) || type === 'unfocus')
			{
				targets.show.bind(type+namespace, function(event) {
					if(tooltip[0].offsetWidth > 0) { hideMethod(event); }
					else { showMethod(event); }
				});

				// Don't bind the event again
				delete events.show[ showIndex ];
			}

			// Events are not identical, bind normally
			else { targets.hide.bind(type+namespace, hideMethod); }
		});

		// Apply show events
		$.each(events.show, function(index, type) {
			targets.show.bind(type+namespace, showMethod);
		});

		// Check if the tooltip hides when mouse is moved a certain distance
		if('number' === typeof options.hide.distance) {
			// Bind mousemove to target to detect distance difference
			targets.show.add(tooltip).bind('mousemove'+namespace, function(event) {
				var origin = cache.origin || {},
					limit = options.hide.distance,
					abs = Math.abs;

				// Check if the movement has gone beyond the limit, and hide it if so
				if(abs(event.pageX - origin.pageX) >= limit || abs(event.pageY - origin.pageY) >= limit) {
					self.hide(event);
				}
			});
		}

		// Mouse positioning events
		if(posOptions.target === 'mouse') {
			// Cache mousemove coords on show targets
			targets.show.bind('mousemove'+namespace, storeMouse);

			// If mouse adjustment is on...
			if(posOptions.adjust.mouse) {
				// Apply a mouseleave event so we don't get problems with overlapping
				if(options.hide.event) {
					// Hide when we leave the tooltip and not onto the show target
					tooltip.bind('mouseleave'+namespace, function(event) {
						if((event.relatedTarget || event.target) !== targets.show[0]) { self.hide(event); }
					});

					// Track if we're on the target or not
					elements.target.bind('mouseenter'+namespace+' mouseleave'+namespace, function(event) {
						cache.onTarget = event.type === 'mouseenter';
					});
				}

				// Update tooltip position on mousemove
				targets.document.bind('mousemove'+namespace, function(event) {
					// Update the tooltip position only if the tooltip is visible and adjustment is enabled
					if(self.rendered && cache.onTarget && !tooltip.hasClass(disabledClass) && tooltip[0].offsetWidth > 0) {
						self.reposition(event || MOUSE);
					}
				});
			}
		}

		// Adjust positions of the tooltip on window resize if enabled
		if(posOptions.adjust.resize || targets.viewport.length) {
			($.event.special.resize ? targets.viewport : targets.window).bind('resize'+namespace, repositionMethod);
		}

		// Adjust tooltip position on scroll of the window or viewport element if present
		targets.window.bind('scroll'+namespace, repositionMethod);
	}

	function unassignEvents()
	{
		var targets = [
				options.show.target[0],
				options.hide.target[0],
				self.rendered && elements.tooltip[0],
				options.position.container[0],
				options.position.viewport[0],
				options.position.container.closest('html')[0], // unfocus
				window,
				document
			];

		// Check if tooltip is rendered
		if(self.rendered) {
			$([]).pushStack( $.grep(targets, function(i){ return typeof i === 'object'; }) ).unbind(namespace);
		}

		// Tooltip isn't yet rendered, remove render event
		else { options.show.target.unbind(namespace+'-create'); }
	}

	// Setup builtin .set() option checks
	self.checks.builtin = {
		// Core checks
		'^id$': function(obj, o, v) {
			var id = v === TRUE ? QTIP.nextid : v,
				tooltipID = NAMESPACE + '-' + id;

			if(id !== FALSE && id.length > 0 && !$('#'+tooltipID).length) {
				tooltip[0].id = tooltipID;
				elements.content[0].id = tooltipID + '-content';
				elements.title[0].id = tooltipID + '-title';
			}
		},

		// Content checks
		'^content.text$': function(obj, o, v) { updateContent(options.content.text); },
		'^content.deferred$': function(obj, o, v) { deferredContent(options.content.deferred); },
		'^content.title.text$': function(obj, o, v) {
			// Remove title if content is null
			if(!v) { return removeTitle(); }

			// If title isn't already created, create it now and update
			if(!elements.title && v) { createTitle(); }
			updateTitle(v);
		},
		'^content.title.button$': function(obj, o, v){ updateButton(v); },

		// Position checks
		'^position.(my|at)$': function(obj, o, v){
			// Parse new corner value into Corner objecct
			if('string' === typeof v) {
				obj[o] = new PLUGINS.Corner(v);
			}
		},
		'^position.container$': function(obj, o, v){
			if(self.rendered) { tooltip.appendTo(v); }
		},

		// Show checks
		'^show.ready$': function() {
			if(!self.rendered) { self.render(1); }
			else { self.toggle(TRUE); }
		},

		// Style checks
		'^style.classes$': function(obj, o, v) {
			tooltip.attr('class', NAMESPACE + ' qtip ' + v);
		},
		'^style.width|height': function(obj, o, v) {
			tooltip.css(o, v);
		},
		'^style.widget|content.title': setWidget,

		// Events check
		'^events.(render|show|move|hide|focus|blur)$': function(obj, o, v) {
			tooltip[($.isFunction(v) ? '' : 'un') + 'bind']('tooltip'+o, v);
		},

		// Properties which require event reassignment
		'^(show|hide|position).(event|target|fixed|inactive|leave|distance|viewport|adjust)': function() {
			var posOptions = options.position;

			// Set tracking flag
			tooltip.attr('tracking', posOptions.target === 'mouse' && posOptions.adjust.mouse);

			// Reassign events
			unassignEvents(); assignEvents();
		}
	};

	$.extend(self, {
		/*
		* Psuedo-private API methods
		*/
		_triggerEvent: function(type, args, event)
		{
			var callback = $.Event('tooltip'+type);
			callback.originalEvent = (event ? $.extend({}, event) : NULL) || cache.event || NULL;
			tooltip.trigger(callback, [self].concat(args || []));

			return !callback.isDefaultPrevented();
		},

		/*
		* Public API methods
		*/
		render: function(show)
		{
			if(self.rendered) { return self; } // If tooltip has already been rendered, exit

			var text = options.content.text,
				title = options.content.title,
				posOptions = options.position;

			// Add ARIA attributes to target
			$.attr(target[0], 'aria-describedby', tooltipID);

			// Create tooltip element
			tooltip = elements.tooltip = $('<div/>', {
					'id': tooltipID,
					'class': [ NAMESPACE, defaultClass, options.style.classes, NAMESPACE + '-pos-' + options.position.my.abbrev() ].join(' '),
					'width': options.style.width || '',
					'height': options.style.height || '',
					'tracking': posOptions.target === 'mouse' && posOptions.adjust.mouse,

					/* ARIA specific attributes */
					'role': 'alert',
					'aria-live': 'polite',
					'aria-atomic': FALSE,
					'aria-describedby': tooltipID + '-content',
					'aria-hidden': TRUE
				})
				.toggleClass(disabledClass, cache.disabled)
				.data('qtip', self)
				.appendTo(options.position.container)
				.append(
					// Create content element
					elements.content = $('<div />', {
						'class': NAMESPACE + '-content',
						'id': tooltipID + '-content',
						'aria-atomic': TRUE
					})
				);

			// Set rendered flag and prevent redundant reposition calls for now
			self.rendered = -1;
			isPositioning = 1;

			// Create title...
			if(title.text) {
				createTitle();

				// Update title only if its not a callback (called in toggle if so)
				if(!$.isFunction(title.text)) { updateTitle(title.text, FALSE); }
			}

			// Create button
			else if(title.button) { createButton(); }

			// Set proper rendered flag and update content if not a callback function (called in toggle)
			if(!$.isFunction(text) || text.then) { updateContent(text, FALSE); }
			self.rendered = TRUE;

			// Setup widget classes
			setWidget();

			// Assign passed event callbacks (before plugins!)
			$.each(options.events, function(name, callback) {
				if($.isFunction(callback)) {
					tooltip.bind(name === 'toggle' ? 'tooltipshow tooltiphide' : 'tooltip'+name, callback);
				}
			});

			// Initialize 'render' plugins
			$.each(PLUGINS, function() {
				if(this.initialize === 'render') { this(self); }
			});

			// Assign events
			assignEvents();

			/* Queue this part of the render process in our fx queue so we can
			* load images before the tooltip renders fully.
			*
			* See: updateContent method
			*/
			tooltip.queue('fx', function(next) {
				// tooltiprender event
				self._triggerEvent('render');

				// Reset flags
				isPositioning = 0;

				// Show tooltip if needed
				if(options.show.ready || show) {
					self.toggle(TRUE, cache.event, FALSE);
				}

				next(); // Move on to next method in queue
			});

			return self;
		},

		get: function(notation)
		{
			var result, o;

			switch(notation.toLowerCase())
			{
				case 'dimensions':
					result = {
						height: tooltip.outerHeight(FALSE),
						width: tooltip.outerWidth(FALSE)
					};
				break;

				case 'offset':
					result = PLUGINS.offset(tooltip, options.position.container);
				break;

				default:
					o = convertNotation(notation.toLowerCase());
					result = o[0][ o[1] ];
					result = result.precedance ? result.string() : result;
				break;
			}

			return result;
		},

		set: function(option, value)
		{
			var rmove = /^position\.(my|at|adjust|target|container)|style|content|show\.ready/i,
				rdraw = /^content\.(title|attr)|style/i,
				reposition = FALSE,
				checks = self.checks,
				name;

			function callback(notation, args) {
				var category, rule, match;

				for(category in checks) {
					for(rule in checks[category]) {
						if(match = (new RegExp(rule, 'i')).exec(notation)) {
							args.push(match);
							checks[category][rule].apply(self, args);
						}
					}
				}
			}

			// Convert singular option/value pair into object form
			if('string' === typeof option) {
				name = option; option = {}; option[name] = value;
			}
			else { option = $.extend(TRUE, {}, option); }

			// Set all of the defined options to their new values
			$.each(option, function(notation, value) {
				var obj = convertNotation( notation.toLowerCase() ), previous;

				// Set new obj value
				previous = obj[0][ obj[1] ];
				obj[0][ obj[1] ] = 'object' === typeof value && value.nodeType ? $(value) : value;

				// Set the new params for the callback
				option[notation] = [obj[0], obj[1], value, previous];

				// Also check if we need to reposition
				reposition = rmove.test(notation) || reposition;
			});

			// Re-sanitize options
			sanitizeOptions(options);

			/*
			* Execute any valid callbacks for the set options
			* Also set isPositioning/isDrawing so we don't get loads of redundant repositioning calls.
			*/
			isPositioning = 1; $.each(option, callback); isPositioning = 0;

			// Update position if needed
			if(self.rendered && tooltip[0].offsetWidth > 0 && reposition) {
				self.reposition( options.position.target === 'mouse' ? NULL : cache.event );
			}

			return self;
		},

		toggle: function(state, event)
		{
			// Try to prevent flickering when tooltip overlaps show element
			if(event) {
				if((/over|enter/).test(event.type) && (/out|leave/).test(cache.event.type) &&
					options.show.target.add(event.target).length === options.show.target.length &&
					tooltip.has(event.relatedTarget).length) {
					return self;
				}

				// Cache event
				cache.event = $.extend({}, event);
			}
	
			// Render the tooltip if showing and it isn't already
			if(!self.rendered) { return state ? self.render(1) : self; }

			var type = state ? 'show' : 'hide',
				opts = options[type],
				otherOpts = options[ !state ? 'show' : 'hide' ],
				posOptions = options.position,
				contentOptions = options.content,
				visible = tooltip[0].offsetWidth > 0,
				animate = state || opts.target.length === 1,
				sameTarget = !event || opts.target.length < 2 || cache.target[0] === event.target,
				showEvent, delay;

			// Detect state if valid one isn't provided
			if((typeof state).search('boolean|number')) { state = !visible; }

			// Return if element is already in correct state
			if(!tooltip.is(':animated') && visible === state && sameTarget) { return self; }

			// tooltipshow/tooltiphide events
			if(!self._triggerEvent(type, [90])) { return self; }

			// Set ARIA hidden status attribute
			$.attr(tooltip[0], 'aria-hidden', !!!state);

			// Execute state specific properties
			if(state) {
				// Store show origin coordinates
				cache.origin = $.extend({}, MOUSE);

				// Focus the tooltip
				self.focus(event);

				// Update tooltip content & title if it's a dynamic function
				if($.isFunction(contentOptions.text)) { updateContent(contentOptions.text, FALSE); }
				if($.isFunction(contentOptions.title.text)) { updateTitle(contentOptions.title.text, FALSE); }

				// Cache mousemove events for positioning purposes (if not already tracking)
				if(!trackingBound && posOptions.target === 'mouse' && posOptions.adjust.mouse) {
					$(document).bind('mousemove.qtip', storeMouse);
					trackingBound = TRUE;
				}

				// Update the tooltip position
				self.reposition(event, arguments[2]);

				// Hide other tooltips if tooltip is solo
				if(!!opts.solo) {
					$(selector, opts.solo).not(tooltip).qtip('hide', $.Event('tooltipsolo'));
				}
			}
			else {
				// Clear show timer if we're hiding
				clearTimeout(self.timers.show);

				// Remove cached origin on hide
				delete cache.origin;

				// Remove mouse tracking event if not needed (all tracking qTips are hidden)
				if(trackingBound && !$(selector+'[tracking="true"]:visible', opts.solo).not(tooltip).length) {
					$(document).unbind('mousemove.qtip');
					trackingBound = FALSE;
				}

				// Blur the tooltip
				self.blur(event);
			}

			// Define post-animation, state specific properties
			function after() {
				if(state) {
					// Prevent antialias from disappearing in IE by removing filter
					//if($.browser.msie) { tooltip[0].style.removeAttribute('filter'); // pgbovine }

					// Remove overflow setting to prevent tip bugs
					tooltip.css('overflow', '');

					// Autofocus elements if enabled
					if('string' === typeof opts.autofocus) {
						$(opts.autofocus, tooltip).focus();
					}

					// If set, hide tooltip when inactive for delay period
					opts.target.trigger('qtip-'+id+'-inactive');
				}
				else {
					// Reset CSS states
					tooltip.css({
						display: '',
						visibility: '',
						opacity: '',
						left: '',
						top: ''
					});
				}

				// tooltipvisible/tooltiphidden events
				self._triggerEvent(state ? 'visible' : 'hidden');
			}

			// If no effect type is supplied, use a simple toggle
			if(opts.effect === FALSE || animate === FALSE) {
				tooltip[ type ]();
				after.call(tooltip);
			}

			// Use custom function if provided
			else if($.isFunction(opts.effect)) {
				tooltip.stop(1, 1);
				opts.effect.call(tooltip, self);
				tooltip.queue('fx', function(n){ after(); n(); });
			}

			// Use basic fade function by default
			else { tooltip.fadeTo(90, state ? 1 : 0, after); }

			// If inactive hide method is set, active it
			if(state) { opts.target.trigger('qtip-'+id+'-inactive'); }

			return self;
		},

		show: function(event){ return self.toggle(TRUE, event); },

		hide: function(event){ return self.toggle(FALSE, event); },

		focus: function(event)
		{
			if(!self.rendered) { return self; }

			var qtips = $(selector),
				curIndex = parseInt(tooltip[0].style.zIndex, 10),
				newIndex = QTIP.zindex + qtips.length,
				cachedEvent = $.extend({}, event),
				focusedElem;

			// Only update the z-index if it has changed and tooltip is not already focused
			if(!tooltip.hasClass(focusClass))
			{
				// tooltipfocus event
				if(self._triggerEvent('focus', [newIndex], cachedEvent)) {
					// Only update z-index's if they've changed
					if(curIndex !== newIndex) {
						// Reduce our z-index's and keep them properly ordered
						qtips.each(function() {
							if(this.style.zIndex > curIndex) {
								this.style.zIndex = this.style.zIndex - 1;
							}
						});

						// Fire blur event for focused tooltip
						qtips.filter('.' + focusClass).qtip('blur', cachedEvent);
					}

					// Set the new z-index
					tooltip.addClass(focusClass)[0].style.zIndex = newIndex;
				}
			}

			return self;
		},

		blur: function(event) {
			// Set focused status to FALSE
			tooltip.removeClass(focusClass);

			// tooltipblur event
			self._triggerEvent('blur', [tooltip.css('zIndex')], event);

			return self;
		},

		reposition: function(event, effect)
		{
			if(!self.rendered || isPositioning) { return self; }

			// Set positioning flag
			isPositioning = 1;

			var target = options.position.target,
				posOptions = options.position,
				my = posOptions.my,
				at = posOptions.at,
				adjust = posOptions.adjust,
				method = adjust.method.split(' '),
				elemWidth = tooltip.outerWidth(FALSE),
				elemHeight = tooltip.outerHeight(FALSE),
				targetWidth = 0,
				targetHeight = 0,
				type = tooltip.css('position'),
				viewport = posOptions.viewport,
				position = { left: 0, top: 0 },
				container = posOptions.container,
				visible = tooltip[0].offsetWidth > 0,
				isScroll = event && event.type === 'scroll',
				win = $(window),
				adjusted, offset;

			// Check if absolute position was passed
			if($.isArray(target) && target.length === 2) {
				// Force left top and set position
				at = { x: LEFT, y: TOP };
				position = { left: target[0], top: target[1] };
			}

			// Check if mouse was the target
			else if(target === 'mouse' && ((event && event.pageX) || cache.event.pageX)) {
				// Force left top to allow flipping
				at = { x: LEFT, y: TOP };

				// Use cached event if one isn't available for positioning
				event = MOUSE && MOUSE.pageX && (adjust.mouse || !event || !event.pageX) ? { pageX: MOUSE.pageX, pageY: MOUSE.pageY } :
					(event && (event.type === 'resize' || event.type === 'scroll') ? cache.event :
					event && event.pageX && event.type === 'mousemove' ? event :
					!adjust.mouse && cache.origin && cache.origin.pageX && options.show.distance ? cache.origin :
					event) || event || cache.event || MOUSE || {};

				// Use event coordinates for position
				if(type !== 'static') { position = container.offset(); }
				position = { left: event.pageX - position.left, top: event.pageY - position.top };

				// Scroll events are a pain, some browsers
				if(adjust.mouse && isScroll) {
					position.left -= MOUSE.scrollX - win.scrollLeft();
					position.top -= MOUSE.scrollY - win.scrollTop();
				}
			}

			// Target wasn't mouse or absolute...
			else {
				// Check if event targetting is being used
				if(target === 'event' && event && event.target && event.type !== 'scroll' && event.type !== 'resize') {
					cache.target = $(event.target);
				}
				else if(target !== 'event'){
					cache.target = $(target.jquery ? target : elements.target);
				}
				target = cache.target;

				// Parse the target into a jQuery object and make sure there's an element present
				target = $(target).eq(0);
				if(target.length === 0) { return self; }

				// Check if window or document is the target
				else if(target[0] === document || target[0] === window) {
					targetWidth = PLUGINS.iOS ? window.innerWidth : target.width();
					targetHeight = PLUGINS.iOS ? window.innerHeight : target.height();

					if(target[0] === window) {
						position = {
							top: (viewport || target).scrollTop(),
							left: (viewport || target).scrollLeft()
						};
					}
				}

				// Use Imagemap/SVG plugins if needed
				else if(PLUGINS.imagemap && target.is('area')) {
					adjusted = PLUGINS.imagemap(self, target, at, PLUGINS.viewport ? method : FALSE);
				}
				else if(PLUGINS.svg && target[0].ownerSVGElement) {
					adjusted = PLUGINS.svg(self, target, at, PLUGINS.viewport ? method : FALSE);
				}

				else {
					targetWidth = target.outerWidth(FALSE);
					targetHeight = target.outerHeight(FALSE);

					position = PLUGINS.offset(target, container);
				}

				// Parse returned plugin values into proper variables
				if(adjusted) {
					targetWidth = adjusted.width;
					targetHeight = adjusted.height;
					offset = adjusted.offset;
					position = adjusted.position;
				}

				// Adjust for position.fixed tooltips (and also iOS scroll bug in v3.2-4.0 & v4.3-4.3.2)
				if((PLUGINS.iOS > 3.1 && PLUGINS.iOS < 4.1) || 
					(PLUGINS.iOS >= 4.3 && PLUGINS.iOS < 4.33) || 
					(!PLUGINS.iOS && type === 'fixed')
				){
					position.left -= win.scrollLeft();
					position.top -= win.scrollTop();
				}

				// Adjust position relative to target
				position.left += at.x === RIGHT ? targetWidth : at.x === CENTER ? targetWidth / 2 : 0;
				position.top += at.y === BOTTOM ? targetHeight : at.y === CENTER ? targetHeight / 2 : 0;
			}

			// Adjust position relative to tooltip
			position.left += adjust.x + (my.x === RIGHT ? -elemWidth : my.x === CENTER ? -elemWidth / 2 : 0);
			position.top += adjust.y + (my.y === BOTTOM ? -elemHeight : my.y === CENTER ? -elemHeight / 2 : 0);

			// Use viewport adjustment plugin if enabled
			if(PLUGINS.viewport) {
				position.adjusted = PLUGINS.viewport(
					self, position, posOptions, targetWidth, targetHeight, elemWidth, elemHeight
				);

				// Apply offsets supplied by positioning plugin (if used)
				if(offset && position.adjusted.left) { position.left += offset.left; }
				if(offset && position.adjusted.top) {  position.top += offset.top; }
			}

			// Viewport adjustment is disabled, set values to zero
			else { position.adjusted = { left: 0, top: 0 }; }

			// tooltipmove event
			if(!self._triggerEvent('move', [position, viewport.elem || viewport], event)) { return self; }
			delete position.adjusted;

			// If effect is disabled, target it mouse, no animation is defined or positioning gives NaN out, set CSS directly
			if(effect === FALSE || !visible || isNaN(position.left) || isNaN(position.top) || target === 'mouse' || !$.isFunction(posOptions.effect)) {
				tooltip.css(position);
			}

			// Use custom function if provided
			else if($.isFunction(posOptions.effect)) {
				posOptions.effect.call(tooltip, self, $.extend({}, position));
				tooltip.queue(function(next) {
					// Reset attributes to avoid cross-browser rendering bugs
					$(this).css({ opacity: '', height: '' });
					// if($.browser.msie) { this.style.removeAttribute('filter'); } // pgbovine 

					next();
				});
			}

			// Set positioning flagwtf
			isPositioning = 0;

			return self;
		},

		disable: function(state)
		{
			if('boolean' !== typeof state) {
				state = !(tooltip.hasClass(disabledClass) || cache.disabled);
			}

			if(self.rendered) {
				tooltip.toggleClass(disabledClass, state);
				$.attr(tooltip[0], 'aria-disabled', state);
			}
			else {
				cache.disabled = !!state;
			}

			return self;
		},

		enable: function() { return self.disable(FALSE); },

		destroy: function()
		{
			var t = target[0],
				title = $.attr(t, oldtitle),
				elemAPI = target.data('qtip');

			// Set flag the signify destroy is taking place to plugins
			self.destroyed = TRUE;

			// Destroy tooltip and  any associated plugins if rendered
			if(self.rendered) {
				tooltip.stop(1,0).remove();

				$.each(self.plugins, function() {
					if(this.destroy) { this.destroy(); }
				});
			}

			// Clear timers and remove bound events
			clearTimeout(self.timers.show);
			clearTimeout(self.timers.hide);
			unassignEvents();

			// If the API if actually this qTip API...
			if(!elemAPI || self === elemAPI) {
				// Remove api object
				$.removeData(t, 'qtip');

				// Reset old title attribute if removed
				if(options.suppress && title) {
					$.attr(t, 'title', title);
					target.removeAttr(oldtitle);
				}

				// Remove ARIA attributes
				target.removeAttr('aria-describedby');
			}

			// Remove qTip events associated with this API
			target.unbind('.qtip-'+id);

			// Remove ID from sued id object
			delete usedIDs[self.id];

			return target;
		}
	});
}

// Initialization method
function init(id, opts)
{
	var obj, posOptions, attr, config, title,

	// Setup element references
	elem = $(this),
	docBody = $(document.body),

	// Use document body instead of document element if needed
	newTarget = this === document ? docBody : elem,

	// Grab metadata from element if plugin is present
	metadata = (elem.metadata) ? elem.metadata(opts.metadata) : NULL,

	// If metadata type if HTML5, grab 'name' from the object instead, or use the regular data object otherwise
	metadata5 = opts.metadata.type === 'html5' && metadata ? metadata[opts.metadata.name] : NULL,

	// Grab data from metadata.name (or data-qtipopts as fallback) using .data() method,
	html5 = elem.data(opts.metadata.name || 'qtipopts');

	// If we don't get an object returned attempt to parse it manualyl without parseJSON
	try { html5 = typeof html5 === 'string' ? $.parseJSON(html5) : html5; } catch(e) {}

	// Merge in and sanitize metadata
	config = $.extend(TRUE, {}, QTIP.defaults, opts,
		typeof html5 === 'object' ? sanitizeOptions(html5) : NULL,
		sanitizeOptions(metadata5 || metadata));

	// Re-grab our positioning options now we've merged our metadata and set id to passed value
	posOptions = config.position;
	config.id = id;

	// Setup missing content if none is detected
	if('boolean' === typeof config.content.text) {
		attr = elem.attr(config.content.attr);

		// Grab from supplied attribute if available
		if(config.content.attr !== FALSE && attr) { config.content.text = attr; }

		// No valid content was found, abort render
		else { return FALSE; }
	}

	// Setup target options
	if(!posOptions.container.length) { posOptions.container = docBody; }
	if(posOptions.target === FALSE) { posOptions.target = newTarget; }
	if(config.show.target === FALSE) { config.show.target = newTarget; }
	if(config.show.solo === TRUE) { config.show.solo = posOptions.container.closest('body'); }
	if(config.hide.target === FALSE) { config.hide.target = newTarget; }
	if(config.position.viewport === TRUE) { config.position.viewport = posOptions.container; }

	// Ensure we only use a single container
	posOptions.container = posOptions.container.eq(0);

	// Convert position corner values into x and y strings
	posOptions.at = new PLUGINS.Corner(posOptions.at);
	posOptions.my = new PLUGINS.Corner(posOptions.my);

	// Destroy previous tooltip if overwrite is enabled, or skip element if not
	if($.data(this, 'qtip')) {
		if(config.overwrite) {
			elem.qtip('destroy');
		}
		else if(config.overwrite === FALSE) {
			return FALSE;
		}
	}

	// Remove title attribute and store it if present
	if(config.suppress && (title = $.attr(this, 'title'))) {
		// Final attr call fixes event delegatiom and IE default tooltip showing problem
		$(this).removeAttr('title').attr(oldtitle, title).attr('title', '');
	}

	// Initialize the tooltip and add API reference
	obj = new QTip(elem, config, id, !!attr);
	$.data(this, 'qtip', obj);

	// Catch remove/removeqtip events on target element to destroy redundant tooltip
	elem.bind('remove.qtip-'+id+' removeqtip.qtip-'+id, function(){ obj.destroy(); });

	return obj;
}

// jQuery $.fn extension method
QTIP = $.fn.qtip = function(options, notation, newValue)
{
	var command = ('' + options).toLowerCase(), // Parse command
		returned = NULL,
		args = $.makeArray(arguments).slice(1),
		event = args[args.length - 1],
		opts = this[0] ? $.data(this[0], 'qtip') : NULL;

	// Check for API request
	if((!arguments.length && opts) || command === 'api') {
		return opts;
	}

	// Execute API command if present
	else if('string' === typeof options)
	{
		this.each(function()
		{
			var api = $.data(this, 'qtip');
			if(!api) { return TRUE; }

			// Cache the event if possible
			if(event && event.timeStamp) { api.cache.event = event; }

			// Check for specific API commands
			if((command === 'option' || command === 'options') && notation) {
				if($.isPlainObject(notation) || newValue !== undefined) {
					api.set(notation, newValue);
				}
				else {
					returned = api.get(notation);
					return FALSE;
				}
			}

			// Execute API command
			else if(api[command]) {
				api[command].apply(api[command], args);
			}
		});

		return returned !== NULL ? returned : this;
	}

	// No API commands. validate provided options and setup qTips
	else if('object' === typeof options || !arguments.length)
	{
		opts = sanitizeOptions($.extend(TRUE, {}, options));

		// Bind the qTips
		return QTIP.bind.call(this, opts, event);
	}
};

// $.fn.qtip Bind method
QTIP.bind = function(opts, event)
{
	return this.each(function(i) {
		var options, targets, events, namespace, api, id;

		// Find next available ID, or use custom ID if provided
		id = $.isArray(opts.id) ? opts.id[i] : opts.id;
		id = !id || id === FALSE || id.length < 1 || usedIDs[id] ? QTIP.nextid++ : (usedIDs[id] = id);

		// Setup events namespace
		namespace = '.qtip-'+id+'-create';

		// Initialize the qTip and re-grab newly sanitized options
		api = init.call(this, id, opts);
		if(api === FALSE) { return TRUE; }
		options = api.options;

		// Initialize plugins
		$.each(PLUGINS, function() {
			if(this.initialize === 'initialize') { this(api); }
		});

		// Determine hide and show targets
		targets = { show: options.show.target, hide: options.hide.target };
		events = {
			show: $.trim('' + options.show.event).replace(/ /g, namespace+' ') + namespace,
			hide: $.trim('' + options.hide.event).replace(/ /g, namespace+' ') + namespace
		};

		/*
		* Make sure hoverIntent functions properly by using mouseleave as a hide event if
		* mouseenter/mouseout is used for show.event, even if it isn't in the users options.
		*/
		if(/mouse(over|enter)/i.test(events.show) && !/mouse(out|leave)/i.test(events.hide)) {
			events.hide += ' mouseleave' + namespace;
		}

		/*
		* Also make sure initial mouse targetting works correctly by caching mousemove coords
		* on show targets before the tooltip has rendered.
		*
		* Also set onTarget when triggered to keep mouse tracking working
		*/
		targets.show.bind('mousemove'+namespace, function(event) {
			storeMouse(event);
			api.cache.onTarget = TRUE;
		});

		// Define hoverIntent function
		function hoverIntent(event) {
			function render() {
				// Cache mouse coords,render and render the tooltip
				api.render(typeof event === 'object' || options.show.ready);

				// Unbind show and hide events
				targets.show.add(targets.hide).unbind(namespace);
			}

			// Only continue if tooltip isn't disabled
			if(api.cache.disabled) { return FALSE; }

			// Cache the event data
			api.cache.event = $.extend({}, event);
			api.cache.target = event ? $(event.target) : [undefined];

			// Start the event sequence
			if(options.show.delay > 0) {
				clearTimeout(api.timers.show);
				api.timers.show = setTimeout(render, options.show.delay);
				if(events.show !== events.hide) {
					targets.hide.bind(events.hide, function() { clearTimeout(api.timers.show); });
				}
			}
			else { render(); }
		}

		// Bind show events to target
		targets.show.bind(events.show, hoverIntent);

		// Prerendering is enabled, create tooltip now
		if(options.show.ready || options.prerender) { hoverIntent(event); }
	})
	.attr('data-hasqtip', TRUE);
};

// Setup base plugins
PLUGINS = QTIP.plugins = {
	// Corner object parser
	Corner: function(corner) {
		corner = ('' + corner).replace(/([A-Z])/, ' $1').replace(/middle/gi, CENTER).toLowerCase();
		this.x = (corner.match(/left|right/i) || corner.match(/center/) || ['inherit'])[0].toLowerCase();
		this.y = (corner.match(/top|bottom|center/i) || ['inherit'])[0].toLowerCase();

		var f = corner.charAt(0); this.precedance = (f === 't' || f === 'b' ? Y : X);

		this.string = function() { return this.precedance === Y ? this.y+this.x : this.x+this.y; };
		this.abbrev = function() {
			var x = this.x.substr(0,1), y = this.y.substr(0,1);
			return x === y ? x : this.precedance === Y ? y + x : x + y;
		};

		this.invertx = function(center) { this.x = this.x === LEFT ? RIGHT : this.x === RIGHT ? LEFT : center || this.x; };
		this.inverty = function(center) { this.y = this.y === TOP ? BOTTOM : this.y === BOTTOM ? TOP : center || this.y; };

		this.clone = function() {
			return {
				x: this.x, y: this.y, precedance: this.precedance,
				string: this.string, abbrev: this.abbrev, clone: this.clone,
				invertx: this.invertx, inverty: this.inverty
			};
		};
	},

	// Custom (more correct for qTip!) offset calculator
	offset: function(elem, container) {
		var pos = elem.offset(),
			docBody = elem.closest('body'),
			quirks = false, // pgbovine // $.browser.msie && document.compatMode !== 'CSS1Compat',
			parent = container, scrolled,
			coffset, overflow;

		function scroll(e, i) {
			pos.left += i * e.scrollLeft();
			pos.top += i * e.scrollTop();
		}

		if(parent) {
			// Compensate for non-static containers offset
			do {
				if(parent.css('position') !== 'static') {
					coffset = parent.position();

					// Account for element positioning, borders and margins
					pos.left -= coffset.left + (parseInt(parent.css('borderLeftWidth'), 10) || 0) + (parseInt(parent.css('marginLeft'), 10) || 0);
					pos.top -= coffset.top + (parseInt(parent.css('borderTopWidth'), 10) || 0) + (parseInt(parent.css('marginTop'), 10) || 0);

					// If this is the first parent element with an overflow of "scroll" or "auto", store it
					if(!scrolled && (overflow = parent.css('overflow')) !== 'hidden' && overflow !== 'visible') { scrolled = parent; }
				}
			}
			while((parent = $(parent[0].offsetParent)).length);

			// Compensate for containers scroll if it also has an offsetParent (or in IE quirks mode)
			if(scrolled && scrolled[0] !== docBody[0] || quirks) {
				scroll( scrolled || docBody, 1 );
			}
		}

		return pos;
	},

	/*
	* iOS version detection
	*/
	iOS: parseFloat( 
		('' + (/CPU.*OS ([0-9_]{1,5})|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent) || [0,''])[1])
		.replace('undefined', '3_2').replace('_', '.').replace('_', '')
	) || FALSE,

	/*
	* jQuery-specific $.fn overrides
	*/
	fn: {
		/* Allow other plugins to successfully retrieve the title of an element with a qTip applied */
		attr: function(attr, val) {
			if(this.length) {
				var self = this[0],
					title = 'title',
					api = $.data(self, 'qtip');

				if(attr === title && api && 'object' === typeof api && api.options.suppress) {
					if(arguments.length < 2) {
						return $.attr(self, oldtitle);
					}

					// If qTip is rendered and title was originally used as content, update it
					if(api && api.options.content.attr === title && api.cache.attr) {
						api.set('content.text', val);
					}

					// Use the regular attr method to set, then cache the result
					return this.attr(oldtitle, val);
				}
			}

			return $.fn['attr'+replaceSuffix].apply(this, arguments);
		},

		/* Allow clone to correctly retrieve cached title attributes */
		clone: function(keepData) {
			var titles = $([]), title = 'title',

			// Clone our element using the real clone method
			elems = $.fn['clone'+replaceSuffix].apply(this, arguments);

			// Grab all elements with an oldtitle set, and change it to regular title attribute, if keepData is false
			if(!keepData) {
				elems.filter('['+oldtitle+']').attr('title', function() {
					return $.attr(this, oldtitle);
				})
				.removeAttr(oldtitle);
			}

			return elems;
		}
	}
};

// Apply the fn overrides above
$.each(PLUGINS.fn, function(name, func) {
	if(!func || $.fn[name+replaceSuffix]) { return TRUE; }

	var old = $.fn[name+replaceSuffix] = $.fn[name];
	$.fn[name] = function() {
		return func.apply(this, arguments) || old.apply(this, arguments);
	};
});

/* Fire off 'removeqtip' handler in $.cleanData if jQuery UI not present (it already does similar).
 * This snippet is taken directly from jQuery UI source code found here:
 *     http://code.jquery.com/ui/jquery-ui-git.js
 */
if(!$.ui) {
	$['cleanData'+replaceSuffix] = $.cleanData;
	$.cleanData = function( elems ) {
		for(var i = 0, elem; (elem = elems[i]) !== undefined; i++) {
			try { $( elem ).triggerHandler('removeqtip'); }
			catch( e ) {}
		}
		$['cleanData'+replaceSuffix]( elems );
	};
}

// Set global qTip properties
QTIP.version = '2.0.0-nightly-15f5c6bc20';
QTIP.nextid = 0;
QTIP.inactiveEvents = 'click dblclick mousedown mouseup mousemove mouseleave mouseenter'.split(' ');
QTIP.zindex = 15000;

// Define configuration defaults
QTIP.defaults = {
	prerender: FALSE,
	id: FALSE,
	overwrite: TRUE,
	suppress: TRUE,
	content: {
		text: TRUE,
		attr: 'title',
		deferred: FALSE,
		title: {
			text: FALSE,
			button: FALSE
		}
	},
	position: {
		my: 'top left',
		at: 'bottom right',
		target: FALSE,
		container: FALSE,
		viewport: FALSE,
		adjust: {
			x: 0, y: 0,
			mouse: TRUE,
			resize: TRUE,
			method: 'flipinvert flipinvert'
		},
		effect: function(api, pos, viewport) {
			$(this).animate(pos, {
				duration: 200,
				queue: FALSE
			});
		}
	},
	show: {
		target: FALSE,
		event: 'mouseenter',
		effect: TRUE,
		delay: 90,
		solo: FALSE,
		ready: FALSE,
		autofocus: FALSE
	},
	hide: {
		target: FALSE,
		event: 'mouseleave',
		effect: TRUE,
		delay: 0,
		fixed: FALSE,
		inactive: FALSE,
		leave: 'window',
		distance: FALSE
	},
	style: {
		classes: '',
		widget: FALSE,
		width: FALSE,
		height: FALSE,
		def: TRUE
	},
	events: {
		render: NULL,
		move: NULL,
		show: NULL,
		hide: NULL,
		toggle: NULL,
		visible: NULL,
		hidden: NULL,
		focus: NULL,
		blur: NULL
	}
};


}));
}( window, document ));


/***/ }),
/* 64 */
/***/ (function(module, exports, __webpack_require__) {


var content = __webpack_require__(65);

if(typeof content === 'string') content = [[module.i, content, '']];

var transform;
var insertInto;



var options = {"hmr":true}

options.transform = transform
options.insertInto = undefined;

var update = __webpack_require__(3)(content, options);

if(content.locals) module.exports = content.locals;

if(false) {
	module.hot.accept("!!../node_modules/css-loader/index.js!./jquery.qtip.css", function() {
		var newContent = require("!!../node_modules/css-loader/index.js!./jquery.qtip.css");

		if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];

		var locals = (function(a, b) {
			var key, idx = 0;

			for(key in a) {
				if(!b || a[key] !== b[key]) return false;
				idx++;
			}

			for(key in b) idx--;

			return idx === 0;
		}(content.locals, newContent.locals));

		if(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');

		update(newContent);
	});

	module.hot.dispose(function() { update(); });
}

/***/ }),
/* 65 */
/***/ (function(module, exports, __webpack_require__) {

exports = module.exports = __webpack_require__(2)(false);
// imports


// module
exports.push([module.i, "/*! qTip2 - Pretty powerful tooltips - v2.0.0 - 2012-12-21\n* http://craigsworks.com/projects/qtip2/\n* Copyright (c) 2012 Craig Michael Thompson; Licensed MIT, GPL */\n\n/* Core qTip styles */\n.qtip, .qtip{\n\tposition: absolute;\n\tleft: -28000px;\n\ttop: -28000px;\n\tdisplay: none;\n\n\tmax-width: 280px;\n\tmin-width: 50px;\n\t\n\tfont-size: 10.5px;\n\tline-height: 12px;\n\n\tdirection: ltr;\n}\n\n\t.qtip-content{\n\t\tposition: relative;\n\t\tpadding: 5px 9px;\n\t\toverflow: hidden;\n\n\t\ttext-align: left;\n\t\tword-wrap: break-word;\n\t}\n\n\t.qtip-titlebar{\n\t\tposition: relative;\n\t\tpadding: 5px 35px 5px 10px;\n\t\toverflow: hidden;\n\n\t\tborder-width: 0 0 1px;\n\t\tfont-weight: bold;\n\t}\n\n\t.qtip-titlebar + .qtip-content{ border-top-width: 0 !important; }\n\n\t/* Default close button class */\n\t.qtip-close{\n\t\tposition: absolute;\n\t\tright: -9px; top: -9px;\n\n\t\tcursor: pointer;\n\t\toutline: medium none;\n\n\t\tborder-width: 1px;\n\t\tborder-style: solid;\n\t\tborder-color: transparent;\n\t}\n\n\t\t.qtip-titlebar .qtip-close{\n\t\t\tright: 4px; top: 50%;\n\t\t\tmargin-top: -9px;\n\t\t}\n\t\n\t\t* html .qtip-titlebar .qtip-close{ top: 16px; } /* IE fix */\n\n\t\t.qtip-titlebar .ui-icon,\n\t\t.qtip-icon .ui-icon{\n\t\t\tdisplay: block;\n\t\t\ttext-indent: -1000em;\n\t\t\tdirection: ltr;\n\t\t\tvertical-align: middle;\n\t\t}\n\n\t\t.qtip-icon, .qtip-icon .ui-icon{\n\t\t\t-moz-border-radius: 3px;\n\t\t\t-webkit-border-radius: 3px;\n\t\t\tborder-radius: 3px;\n\t\t\ttext-decoration: none;\n\t\t}\n\n\t\t\t.qtip-icon .ui-icon{\n\t\t\t\twidth: 18px;\n\t\t\t\theight: 14px;\n\n\t\t\t\ttext-align: center;\n\t\t\t\ttext-indent: 0;\n\t\t\t\tfont: normal bold 10px/13px Tahoma,sans-serif;\n\n\t\t\t\tcolor: inherit;\n\t\t\t\tbackground: transparent none no-repeat -100em -100em;\n\t\t\t}\n\n\n/* Applied to 'focused' tooltips e.g. most recently displayed/interacted with */\n.qtip-focus{}\n\n/* Applied on hover of tooltips i.e. added/removed on mouseenter/mouseleave respectively */\n.qtip-hover{}\n\n/* Default tooltip style */\n.qtip-default{\n\tborder-width: 1px;\n\tborder-style: solid;\n\tborder-color: #F1D031;\n\n\tbackground-color: #FFFFA3;\n\tcolor: #555;\n}\n\n\t.qtip-default .qtip-titlebar{\n\t\tbackground-color: #FFEF93;\n\t}\n\n\t.qtip-default .qtip-icon{\n\t\tborder-color: #CCC;\n\t\tbackground: #F1F1F1;\n\t\tcolor: #777;\n\t}\n\t\n\t.qtip-default .qtip-titlebar .qtip-close{\n\t\tborder-color: #AAA;\n\t\tcolor: #111;\n\t}\n\n\n/*! Light tooltip style */\n.qtip-light{\n\tbackground-color: white;\n\tborder-color: #E2E2E2;\n\tcolor: #454545;\n}\n\n\t.qtip-light .qtip-titlebar{\n\t\tbackground-color: #f1f1f1;\n\t}\n\n\n/*! Dark tooltip style */\n.qtip-dark{\n\tbackground-color: #505050;\n\tborder-color: #303030;\n\tcolor: #f3f3f3;\n}\n\n\t.qtip-dark .qtip-titlebar{\n\t\tbackground-color: #404040;\n\t}\n\n\t.qtip-dark .qtip-icon{\n\t\tborder-color: #444;\n\t}\n\n\t.qtip-dark .qtip-titlebar .ui-state-hover{\n\t\tborder-color: #303030;\n\t}\n\n\n/*! Cream tooltip style */\n.qtip-cream{\n\tbackground-color: #FBF7AA;\n\tborder-color: #F9E98E;\n\tcolor: #A27D35;\n}\n\n\t.qtip-cream .qtip-titlebar{\n\t\tbackground-color: #F0DE7D;\n\t}\n\n\t.qtip-cream .qtip-close .qtip-icon{\n\t\tbackground-position: -82px 0;\n\t}\n\n\n/*! Red tooltip style */\n.qtip-red{\n\tbackground-color: #F78B83;\n\tborder-color: #D95252;\n\tcolor: #912323;\n}\n\n\t.qtip-red .qtip-titlebar{\n\t\tbackground-color: #F06D65;\n\t}\n\n\t.qtip-red .qtip-close .qtip-icon{\n\t\tbackground-position: -102px 0;\n\t}\n\n\t.qtip-red .qtip-icon{\n\t\tborder-color: #D95252;\n\t}\n\n\t.qtip-red .qtip-titlebar .ui-state-hover{\n\t\tborder-color: #D95252;\n\t}\n\n\n/*! Green tooltip style */\n.qtip-green{\n\tbackground-color: #CAED9E;\n\tborder-color: #90D93F;\n\tcolor: #3F6219;\n}\n\n\t.qtip-green .qtip-titlebar{\n\t\tbackground-color: #B0DE78;\n\t}\n\n\t.qtip-green .qtip-close .qtip-icon{\n\t\tbackground-position: -42px 0;\n\t}\n\n\n/*! Blue tooltip style */\n.qtip-blue{\n\tbackground-color: #E5F6FE;\n\tborder-color: #ADD9ED;\n\tcolor: #5E99BD;\n}\n\n\t.qtip-blue .qtip-titlebar{\n\t\tbackground-color: #D0E9F5;\n\t}\n\n\t.qtip-blue .qtip-close .qtip-icon{\n\t\tbackground-position: -2px 0;\n\t}\n\n\n/* Add shadows to your tooltips in: FF3+, Chrome 2+, Opera 10.6+, IE9+, Safari 2+ */\n.qtip-shadow{\n\t-webkit-box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15);\n\t-moz-box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15);\n\tbox-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15);\n}\n\n/* Add rounded corners to your tooltips in: FF3+, Chrome 2+, Opera 10.6+, IE9+, Safari 2+ */\n.qtip-rounded,\n.qtip-tipsy,\n.qtip-bootstrap{\n\t-moz-border-radius: 5px;\n\t-webkit-border-radius: 5px;\n\tborder-radius: 5px;\n}\n\n/* Youtube tooltip style */\n.qtip-youtube{\n\t-moz-border-radius: 2px;\n\t-webkit-border-radius: 2px;\n\tborder-radius: 2px;\n\t\n\t-webkit-box-shadow: 0 0 3px #333;\n\t-moz-box-shadow: 0 0 3px #333;\n\tbox-shadow: 0 0 3px #333;\n\n\tcolor: white;\n\tborder-width: 0;\n\n\tbackground: #4A4A4A;\n\tbackground-image: -webkit-gradient(linear,left top,left bottom,color-stop(0,#4A4A4A),color-stop(100%,black));\n\tbackground-image: -webkit-linear-gradient(top,#4A4A4A 0,black 100%);\n\tbackground-image: -moz-linear-gradient(top,#4A4A4A 0,black 100%);\n\tbackground-image: -ms-linear-gradient(top,#4A4A4A 0,black 100%);\n\tbackground-image: -o-linear-gradient(top,#4A4A4A 0,black 100%);\n}\n\n\t.qtip-youtube .qtip-titlebar{\n\t\tbackground-color: #4A4A4A;\n\t\tbackground-color: rgba(0,0,0,0);\n\t}\n\t\n\t.qtip-youtube .qtip-content{\n\t\tpadding: .75em;\n\t\tfont: 12px arial,sans-serif;\n\t\t\n\t\tfilter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#4a4a4a,EndColorStr=#000000);\n\t\t-ms-filter: \"progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#4a4a4a,EndColorStr=#000000);\";\n\t}\n\n\t.qtip-youtube .qtip-icon{\n\t\tborder-color: #222;\n\t}\n\n\t.qtip-youtube .qtip-titlebar .ui-state-hover{\n\t\tborder-color: #303030;\n\t}\n\n\n/* jQuery TOOLS Tooltip style */\n.qtip-jtools{\n\tbackground: #232323;\n\tbackground: rgba(0, 0, 0, 0.7);\n\tbackground-image: -webkit-gradient(linear, left top, left bottom, from(#717171), to(#232323));\n\tbackground-image: -moz-linear-gradient(top, #717171, #232323);\n\tbackground-image: -webkit-linear-gradient(top, #717171, #232323);\n\tbackground-image: -ms-linear-gradient(top, #717171, #232323);\n\tbackground-image: -o-linear-gradient(top, #717171, #232323);\n\n\tborder: 2px solid #ddd;\n\tborder: 2px solid rgba(241,241,241,1);\n\n\t-moz-border-radius: 2px;\n\t-webkit-border-radius: 2px;\n\tborder-radius: 2px;\n\n\t-webkit-box-shadow: 0 0 12px #333;\n\t-moz-box-shadow: 0 0 12px #333;\n\tbox-shadow: 0 0 12px #333;\n}\n\n\t/* IE Specific */\n\t.qtip-jtools .qtip-titlebar{\n\t\tbackground-color: transparent;\n\t\tfilter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A);\n\t\t-ms-filter: \"progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A)\";\n\t}\n\t.qtip-jtools .qtip-content{\n\t\tfilter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323);\n\t\t-ms-filter: \"progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323)\";\n\t}\n\n\t.qtip-jtools .qtip-titlebar,\n\t.qtip-jtools .qtip-content{\n\t\tbackground: transparent;\n\t\tcolor: white;\n\t\tborder: 0 dashed transparent;\n\t}\n\n\t.qtip-jtools .qtip-icon{\n\t\tborder-color: #555;\n\t}\n\n\t.qtip-jtools .qtip-titlebar .ui-state-hover{\n\t\tborder-color: #333;\n\t}\n\n\n/* Cluetip style */\n.qtip-cluetip{\n\t-webkit-box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4);\n\t-moz-box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4);\n\tbox-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4);\n\n\tbackground-color: #D9D9C2;\n\tcolor: #111;\n\tborder: 0 dashed transparent;\n}\n\n\t.qtip-cluetip .qtip-titlebar{\n\t\tbackground-color: #87876A;\n\t\tcolor: white;\n\t\tborder: 0 dashed transparent;\n\t}\n\t\n\t.qtip-cluetip .qtip-icon{\n\t\tborder-color: #808064;\n\t}\n\t\n\t.qtip-cluetip .qtip-titlebar .ui-state-hover{\n\t\tborder-color: #696952;\n\t\tcolor: #696952;\n\t}\n\n\n/* Tipsy style */\n.qtip-tipsy{\n\tbackground: black;\n\tbackground: rgba(0, 0, 0, .87);\n\n\tcolor: white;\n\tborder: 0 solid transparent;\n\n\tfont-size: 11px;\n\tfont-family: 'Lucida Grande', sans-serif;\n\tfont-weight: bold;\n\tline-height: 16px;\n\ttext-shadow: 0 1px black;\n}\n\n\t.qtip-tipsy .qtip-titlebar{\n\t\tpadding: 6px 35px 0 10;\n\t\tbackground-color: transparent;\n\t}\n\n\t.qtip-tipsy .qtip-content{\n\t\tpadding: 6px 10;\n\t}\n\t\n\t.qtip-tipsy .qtip-icon{\n\t\tborder-color: #222;\n\t\ttext-shadow: none;\n\t}\n\n\t.qtip-tipsy .qtip-titlebar .ui-state-hover{\n\t\tborder-color: #303030;\n\t}\n\n\n/* Tipped style */\n.qtip-tipped{\n\tborder: 3px solid #959FA9;\n\n\t-moz-border-radius: 3px;\n\t-webkit-border-radius: 3px;\n\tborder-radius: 3px;\n\n\tbackground-color: #F9F9F9;\n\tcolor: #454545;\n\n\tfont-weight: normal;\n\tfont-family: serif;\n}\n\n\t.qtip-tipped .qtip-titlebar{\n\t\tborder-bottom-width: 0;\n\n\t\tcolor: white;\n\t\tbackground: #3A79B8;\n\t\tbackground-image: -webkit-gradient(linear, left top, left bottom, from(#3A79B8), to(#2E629D));\n\t\tbackground-image: -webkit-linear-gradient(top, #3A79B8, #2E629D);\n\t\tbackground-image: -moz-linear-gradient(top, #3A79B8, #2E629D);\n\t\tbackground-image: -ms-linear-gradient(top, #3A79B8, #2E629D);\n\t\tbackground-image: -o-linear-gradient(top, #3A79B8, #2E629D);\n\t\tfilter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D);\n\t\t-ms-filter: \"progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D)\";\n\t}\n\n\t.qtip-tipped .qtip-icon{\n\t\tborder: 2px solid #285589;\n\t\tbackground: #285589;\n\t}\n\n\t\t.qtip-tipped .qtip-icon .ui-icon{\n\t\t\tbackground-color: #FBFBFB;\n\t\t\tcolor: #555;\n\t\t}\n\n\n/**\n * Twitter Bootstrap style.\n *\n * Tested with IE 8, IE 9, Chrome 18, Firefox 9, Opera 11.\n * Does not work with IE 7.\n */\n.qtip-bootstrap{\n\t/** Taken from Bootstrap body */\n\tfont-size: 14px;\n\tline-height: 20px;\n\tcolor: #333333;\n\n\t/** Taken from Bootstrap .popover */\n\tpadding: 1px;\n\tbackground-color: #ffffff;\n\tborder: 1px solid #ccc;\n\tborder: 1px solid rgba(0, 0, 0, 0.2);\n\t-webkit-border-radius: 6px;\n\t-moz-border-radius: 6px;\n\tborder-radius: 6px;\n\t-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n\t-moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n\tbox-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n\t-webkit-background-clip: padding-box;\n\t-moz-background-clip: padding;\n\tbackground-clip: padding-box;\n}\n\n\t.qtip-bootstrap .qtip-titlebar{\n\t\t/** Taken from Bootstrap .popover-title */\n\t\tpadding: 8px 14px;\n\t\tmargin: 0;\n\t\tfont-size: 14px;\n\t\tfont-weight: normal;\n\t\tline-height: 18px;\n\t\tbackground-color: #f7f7f7;\n\t\tborder-bottom: 1px solid #ebebeb;\n\t\t-webkit-border-radius: 5px 5px 0 0;\n\t\t-moz-border-radius: 5px 5px 0 0;\n\t\tborder-radius: 5px 5px 0 0;\n\t}\n\n\t\t.qtip-bootstrap .qtip-titlebar .qtip-close{\n\t\t\t/**\n\t\t\t * Overrides qTip2:\n\t\t\t * .qtip-titlebar .qtip-close{\n\t\t\t *   [...]\n\t\t\t *   right: 4px;\n\t\t\t *   top: 50%;\n\t\t\t *   [...]\n\t\t\t *   border-style: solid;\n\t\t\t * }\n\t\t\t */\n\t\t\tright: 11px;\n\t\t\ttop: 45%;\n\t\t\tborder-style: none;\n\t\t}\n\n\t.qtip-bootstrap .qtip-content{\n\t\t/** Taken from Bootstrap .popover-content */\n\t\tpadding: 9px 14px;\n\t}\n\n\t.qtip-bootstrap .qtip-icon{\n\t\t/**\n\t\t * Overrides qTip2:\n\t\t * .qtip-default .qtip-icon {\n\t\t *   border-color: #CCC;\n\t\t *   background: #F1F1F1;\n\t\t *   color: #777;\n\t\t * }\n\t\t */\n\t\tbackground: transparent;\n\t}\n\n\t\t.qtip-bootstrap .qtip-icon .ui-icon{\n\t\t\t/**\n\t\t\t * Overrides qTip2:\n\t\t\t * .qtip-icon .ui-icon{\n\t\t\t *   width: 18px;\n\t\t\t *   height: 14px;\n\t\t\t * }\n\t\t\t */\n\t\t\twidth: auto;\n\t\t\theight: auto;\n\n\t\t\t/* Taken from Bootstrap .close */\n\t\t\tfloat: right;\n\t\t\tfont-size: 20px;\n\t\t\tfont-weight: bold;\n\t\t\tline-height: 18px;\n\t\t\tcolor: #000000;\n\t\t\ttext-shadow: 0 1px 0 #ffffff;\n\t\t\topacity: 0.2;\n\t\t\tfilter: alpha(opacity=20);\n\t\t}\n\n\t\t.qtip-bootstrap .qtip-icon .ui-icon:hover{\n\t\t\t/* Taken from Bootstrap .close:hover */\n\t\t\tcolor: #000000;\n\t\t\ttext-decoration: none;\n\t\t\tcursor: pointer;\n\t\t\topacity: 0.4;\n\t\t\tfilter: alpha(opacity=40);\n\t\t}\n\n\n/* IE9 fix - removes all filters */\n.qtip:not(.ie9haxors) div.qtip-content,\n.qtip:not(.ie9haxors) div.qtip-titlebar{\n\tfilter: none;\n\t-ms-filter: none;\n}\n\n\n/* Tips plugin */\n.qtip .qtip-tip{\n\tmargin: 0 auto;\n\toverflow: hidden;\n\tz-index: 10;\n}\n\n\t.qtip .qtip-tip,\n\t.qtip .qtip-tip .qtip-vml{\n\t\tposition: absolute;\n\n\t\tcolor: #123456;\n\t\tbackground: transparent;\n\t\tborder: 0 dashed transparent;\n\t}\n\t\n\t.qtip .qtip-tip canvas{ top: 0; left: 0; }\n\n\t.qtip .qtip-tip .qtip-vml{\n\t\tbehavior: url(#default#VML);\n\t\tdisplay: inline-block;\n\t\tvisibility: visible;\n\t}\n/* Modal plugin */\n#qtip-overlay{\n\tposition: fixed;\n\tleft: -10000em;\n\ttop: -10000em;\n}\n\n\t/* Applied to modals with show.modal.blur set to true */\n\t#qtip-overlay.blurs{ cursor: pointer; }\n\n\t/* Change opacity of overlay here */\n\t#qtip-overlay div{\n\t\tposition: absolute;\n\t\tleft: 0; top: 0;\n\t\twidth: 100%; height: 100%;\n\n\t\tbackground-color: black;\n\n\t\topacity: 0.7;\n\t\tfilter:alpha(opacity=70);\n\t\t-ms-filter:\"progid:DXImageTransform.Microsoft.Alpha(Opacity=70)\";\n\t}\n\n\n/* IE6 Modal plugin fix */\n.qtipmodal-ie6fix{\n\tposition: absolute !important;\n}", ""]);

// exports


/***/ }),
/* 66 */
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(1)(__webpack_require__(75))

/***/ }),
/* 67 */,
/* 68 */,
/* 69 */,
/* 70 */,
/* 71 */,
/* 72 */,
/* 73 */,
/* 74 */,
/* 75 */
/***/ (function(module, exports) {

module.exports = "// from https://github.com/Audior/Recordmp3js\n// all files in recordmp3js/ are also adapted from this projec\n(function(window){\n\n  var WORKER_PATH = 'js/lib/recordmp3js/recorderWorker.js';\n  var encoderWorker = new Worker('js/lib/recordmp3js/mp3Worker.js');\n\n  var Recorder = function(source, cfg){\n    var config = cfg || {};\n    var bufferLen = config.bufferLen || 4096;\n    var numChannels = config.numChannels || 2;\n    this.context = source.context;\n    this.node = (this.context.createScriptProcessor ||\n                 this.context.createJavaScriptNode).call(this.context,\n                 bufferLen, numChannels, numChannels);\n    var worker = new Worker(config.workerPath || WORKER_PATH);\n    worker.postMessage({\n      command: 'init',\n      config: {\n        sampleRate: this.context.sampleRate,\n        numChannels: numChannels\n      }\n    });\n    var recording = false,\n      currCallback;\n\n    this.node.onaudioprocess = function(e){\n      if (!recording) return;\n      var buffer = [];\n      for (var channel = 0; channel < numChannels; channel++){\n          buffer.push(e.inputBuffer.getChannelData(channel));\n      }\n      worker.postMessage({\n        command: 'record',\n        buffer: buffer\n      });\n    }\n\n    this.configure = function(cfg){\n      for (var prop in cfg){\n        if (cfg.hasOwnProperty(prop)){\n          config[prop] = cfg[prop];\n        }\n      }\n    }\n\n    this.record = function(){\n      recording = true;\n    }\n\n    this.stop = function(){\n      recording = false;\n    }\n\n    this.clear = function(){\n      worker.postMessage({ command: 'clear' });\n    }\n\n    this.getBuffer = function(cb) {\n      currCallback = cb || config.callback;\n      worker.postMessage({ command: 'getBuffer' })\n    }\n\n    this.exportWAV = function(cb, type){\n      currCallback = cb || config.callback;\n      type = type || config.type || 'audio/wav';\n      if (!currCallback) throw new Error('Callback not set');\n      worker.postMessage({\n        command: 'exportWAV',\n        type: type\n      });\n    }\n\n\t//Mp3 conversion\n    worker.onmessage = function(e){\n      var blob = e.data;\n\t  //console.log(\"the blob \" +  blob + \" \" + blob.size + \" \" + blob.type);\n\n\t  var arrayBuffer;\n\t  var fileReader = new FileReader();\n\n\t  fileReader.onload = function(){\n\t\tarrayBuffer = this.result;\n\t\tvar buffer = new Uint8Array(arrayBuffer),\n        data = parseWav(buffer);\n\n        console.log(data);\n\t\tconsole.log(\"Converting to Mp3\");\n\t\t//log.innerHTML += \"\\n\" + \"Converting to Mp3\";\n\n        encoderWorker.postMessage({ cmd: 'init', config:{\n            mode : 3,\n\t\t\tchannels:1,\n\t\t\tsamplerate: data.sampleRate,\n\t\t\tbitrate: data.bitsPerSample\n        }});\n\n        encoderWorker.postMessage({ cmd: 'encode', buf: Uint8ArrayToFloat32Array(data.samples) });\n        encoderWorker.postMessage({ cmd: 'finish'});\n        encoderWorker.onmessage = function(e) {\n            if (e.data.cmd == 'data') {\n              config.doneEncodingMp3Callback(e.data.buf); // pgbovine - should be set when Recorder was constructed\n            }\n        };\n\t  };\n\n\t  fileReader.readAsArrayBuffer(blob);\n\n      currCallback(blob);\n    }\n\n\n\tfunction encode64(buffer) {\n\t\tvar binary = '',\n\t\t\tbytes = new Uint8Array( buffer ),\n\t\t\tlen = bytes.byteLength;\n\n\t\tfor (var i = 0; i < len; i++) {\n\t\t\tbinary += String.fromCharCode( bytes[ i ] );\n\t\t}\n\t\treturn window.btoa( binary );\n\t}\n\n\tfunction parseWav(wav) {\n\t\tfunction readInt(i, bytes) {\n\t\t\tvar ret = 0,\n\t\t\t\tshft = 0;\n\n\t\t\twhile (bytes) {\n\t\t\t\tret += wav[i] << shft;\n\t\t\t\tshft += 8;\n\t\t\t\ti++;\n\t\t\t\tbytes--;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t\tif (readInt(20, 2) != 1) throw 'Invalid compression code, not PCM';\n\t\tif (readInt(22, 2) != 1) throw 'Invalid number of channels, not 1';\n\t\treturn {\n\t\t\tsampleRate: readInt(24, 4),\n\t\t\tbitsPerSample: readInt(34, 2),\n\t\t\tsamples: wav.subarray(44)\n\t\t};\n\t}\n\n\tfunction Uint8ArrayToFloat32Array(u8a){\n\t\tvar f32Buffer = new Float32Array(u8a.length);\n\t\tfor (var i = 0; i < u8a.length; i++) {\n\t\t\tvar value = u8a[i<<1] + (u8a[(i<<1)+1]<<8);\n\t\t\tif (value >= 0x8000) value |= ~0x7FFF;\n\t\t\tf32Buffer[i] = value / 0x8000;\n\t\t}\n\t\treturn f32Buffer;\n\t}\n\n\tfunction uploadAudio(mp3Data){\n\t\tvar reader = new FileReader();\n\t\treader.onload = function(event){\n\t\t\tvar fd = new FormData();\n\t\t\tvar mp3Name = encodeURIComponent('audio_recording_' + new Date().getTime() + '.mp3');\n\t\t\tconsole.log(\"mp3name = \" + mp3Name);\n\t\t\tfd.append('fname', mp3Name);\n\t\t\tfd.append('data', event.target.result);\n\t\t\t$.ajax({\n\t\t\t\ttype: 'POST',\n\t\t\t\turl: 'upload.php',\n\t\t\t\tdata: fd,\n\t\t\t\tprocessData: false,\n\t\t\t\tcontentType: false\n\t\t\t}).done(function(data) {\n\t\t\t\t//console.log(data);\n\t\t\t\t//log.innerHTML += \"\\n\" + data;\n\t\t\t});\n\t\t};\n\t\treader.readAsDataURL(mp3Data);\n\t}\n\n    source.connect(this.node);\n    this.node.connect(this.context.destination);    //this should not be necessary\n  };\n\n  /*Recorder.forceDownload = function(blob, filename){\n\tconsole.log(\"Force download\");\n    var url = (window.URL || window.webkitURL).createObjectURL(blob);\n    var link = window.document.createElement('a');\n    link.href = url;\n    link.download = filename || 'output.wav';\n    var click = document.createEvent(\"Event\");\n    click.initEvent(\"click\", true, true);\n    link.dispatchEvent(click);\n  }*/\n\n  window.Recorder = Recorder;\n\n})(window);\n"

/***/ }),
/* 76 */,
/* 77 */,
/* 78 */,
/* 79 */,
/* 80 */,
/* 81 */,
/* 82 */,
/* 83 */,
/* 84 */,
/* 85 */,
/* 86 */,
/* 87 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
/* WEBPACK VAR INJECTION */(function($) {
// Python Tutor: https://github.com/pgbovine/OnlinePythonTutor/
// Copyright (C) Philip Guo (philip@pgbovine.net)
// LICENSE: https://github.com/pgbovine/OnlinePythonTutor/blob/master/LICENSE.txt
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
// 'codcasts' demo recorder and player for OPT
// first started hacking on it on 2018-01-01 (happy new year!)
// ... concrete idea inception around 2017-12-29, although it's been
// stewing around in my brain for a lot longer than that
/* TODOs:

  - test by recording locally (with python/js/etc. backends running on
    localhost) and then replaying remotely on pythontutor.com, since
    that's what students will ultimately be doing.
    - also make a special entry in codechella logs for tutorial replays
      so that we can EASILY FILTER THEM OUT when we're analyzing the logs
      - maybe a 'playbackRecording' event in the logs?
    - alternatively, route these to a different instance of server.js on
      another port so that it doesn't interfere with regular codechella
      (but that's more complicated to set up logistically)

  - in the video player UI, put a time indicator in seconds

  - move cursorOrSelectionChanged up to opt-shared-sessions.ts when it
    seems ready for prime time

  - in playback mode, set a more instructive username for the tutor's
    mouse pointer - and also a better and more consistent COLOR
    - #0095DD may be good (matches chat window header background)

  - ideally don't send events to the togetherjs when you're in recording
    or playback mode, so as not to overwhelm the logs. also it seems
    kinda silly that you need to connect to a remote server for this
    to work, since we don't require anything from the server
    - maybe make a mock websockets interface to FAKE a connection to the
      server so that we don't need a server at all? this seems critical
      both for performance and for being able to ship tutorials as
      self-contained packages

  - Mike Horn recommended making this like jsfiddle so that anyone can
    record these demos (either with or without audio) and i just store it
    in a local db (i'm storing user activity logs ANYWAYS) ... and just
    create shortened URLs by indexing into that db
    - if i do that, i might as well implement my own URL shortener for
      regular code URLs as well since google's URL shortener is shutting
      down, might as well!


minor-ish:

  - add title and description fields so that codcasts can serve as
    independent mini-tutorials and WORKED EXAMPLES

  - minor: save UI adjustment preferences such as the width of the code
    pane or visualizer pane so that when the video replays, it will
    preserve those widths instead of always setting them back to the
    defaults, which is helpful for users with smaller monitors
    - this is actually kinda important because resizing is a bit
      annoying

  - refactor the code so that OptDemoVideo doesn't have to know about
    GUI elements

  - things sometimes get flaky if you *ALREADY* have code in the editor
    and then try to record a demo; sometimes it doesn't work properly.

  - to prevent weird crashes from encoding mp3's in JS itself, maybe
    simply export the raw .wav files into the JSON data file, then run a
    python script offline to compress it to mp3? that would decouple the
    tutorial recording from the compressing and also give more flexibility
    to the format
    - maybe i can just use the original record to .wav program that
      Recordmp3js forked?
      - https://github.com/mattdiamond/Recorderjs
    - i already use ffmpeg to convert my vlog/podcast audio to mp3, so i
      could adapt that into my workflow as well
    - but i do like the 100% in-browser workflow since it's nice & crisp

  - NB: this recorder won't work well in live mode since we don't have a
    notion of an explicit "execute" event, so if you play back the trace
    too "slowly", then the live mode will auto-execute the code at weird
    unintended times and cause syntax errors and such; just use it in
    REGULAR visualize.html mode for now!
    - GET IT WORKING IN LIVE MODE, since i think it's doable!!!


longer-term notes:

- use codcasts as a more interactive type of WORKED EXAMPLES
   - maybe also integrate text-based annotations like subtitles at
     certain steps for mixed-media goodness

- how can we turn this into active learning activities like "here's a
  codcast, now you try something ..." and have the learner try something

- use this codcast player to replay codechella-recorded sessions so that
  i can manually review their contents

*/
var opt_shared_sessions_1 = __webpack_require__(33);
var pytutor_1 = __webpack_require__(4);
var footer_html_1 = __webpack_require__(6);
var demovideo_1 = __webpack_require__(56);
__webpack_require__(0);
__webpack_require__(63);
__webpack_require__(64);
// using this library to record audio to mp3: https://github.com/Audior/Recordmp3js
__webpack_require__(66);
// lifted from Recordmp3js
function encode64(buffer) {
    var binary = '', bytes = new Uint8Array(buffer), len = bytes.byteLength;
    for (var i = 0; i < len; i++) {
        binary += String.fromCharCode(bytes[i]);
    }
    return window.btoa(binary);
}
// polyfill from https://gist.github.com/paulirish/1579671
//
// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
// requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel
//
// MIT license
(function () {
    var lastTime = 0;
    var vendors = ['ms', 'moz', 'webkit', 'o'];
    for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
        window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
        window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame']
            || window[vendors[x] + 'CancelRequestAnimationFrame'];
    }
    if (!window.requestAnimationFrame)
        window.requestAnimationFrame = function (callback, element) {
            var currTime = new Date().getTime();
            var timeToCall = Math.max(0, 16 - (currTime - lastTime));
            var id = window.setTimeout(function () { callback(currTime + timeToCall); }, timeToCall);
            lastTime = currTime + timeToCall;
            return id;
        };
    if (!window.cancelAnimationFrame)
        window.cancelAnimationFrame = function (id) {
            clearTimeout(id);
        };
}());
var OptDemoRecorder = /** @class */ (function (_super) {
    __extends(OptDemoRecorder, _super);
    function OptDemoRecorder(params) {
        if (params === void 0) { params = {}; }
        var _this = _super.call(this, params) || this;
        _this.originFrontendJsFile = 'recorder.ts'; // TODO: test to see if this works
        _this.isRecordingDemo = false;
        _this.audioInputStream = null;
        _this.audioRecorder = null; // Recorder object from Recordmp3js
        // disable all surveys:
        _this.activateSyntaxErrorSurvey = false;
        _this.activateRuntimeErrorSurvey = false;
        _this.activateEurekaSurvey = false;
        //window.pyInputAceEditor = this.pyInputAceEditor; // STENT for debugging
        _this.disableSharedSessions = true; // don't call getHelpQueue periodically
        // always use a localhost server for recording so that we don't
        // pollute the real server logs
        opt_shared_sessions_1.TogetherJS._defaultConfiguration.hubBase = 'http://localhost:30035/';
        var recordReplayDiv = "\n      <button id=\"recordBtn\" type=\"button\" class=\"togetherjsBtn\" style=\"font-size: 9pt;\">\n      Record demo\n      </button>\n\n      <br/>\n      <button id=\"playbackBtn\" type=\"button\" class=\"togetherjsBtn\" style=\"font-size: 9pt;\">\n      Play recording\n      </button>";
        $("td#headerTdLeft").html(recordReplayDiv); // clobber the existing contents
        $("#recordBtn").click(_this.recordButtonClicked.bind(_this));
        $("#playbackBtn").click(_this.startPlayback.bind(_this));
        // TODO: move up to opt-shared-sessions.ts when you're ready
        _this.pyInputAceEditor.selection.on("changeCursor", _this.cursorOrSelectionChanged.bind(_this));
        _this.pyInputAceEditor.selection.on("changeSelection", _this.cursorOrSelectionChanged.bind(_this));
        // BEGIN - lifted from Recordmp3js
        var audio_context;
        try {
            // webkit shim
            window.AudioContext = window.AudioContext || window.webkitAudioContext;
            navigator.getUserMedia = (navigator.getUserMedia ||
                navigator.webkitGetUserMedia ||
                navigator.mozGetUserMedia ||
                navigator.msGetUserMedia);
            window.URL = window.URL || window.webkitURL;
            audio_context = new AudioContext;
            console.warn('Audio context set up.');
            //console.warn('navigator.getUserMedia ' + (navigator.getUserMedia ? 'available.' : 'not present!'));
        }
        catch (e) {
            alert('ERROR: no web audio support in this browser!');
        }
        navigator.getUserMedia({ audio: true }, 
        // success:
        function (stream) {
            _this.audioInputStream = audio_context.createMediaStreamSource(stream);
            console.warn('Media stream created.');
            console.warn("input sample rate " + _this.audioInputStream.context.sampleRate);
            console.warn('Input connected to audio context destination.');
            _this.audioRecorder = new Recorder(_this.audioInputStream, {
                numChannels: 1,
                doneEncodingMp3Callback: _this.doneEncodingMp3.bind(_this),
            });
        }, 
        // failure:
        function (e) {
            alert('ERROR: No live audio input: ' + e);
        });
        return _this;
        // END - lifted from Recordmp3js
    }
    // lifted from Recordmp3js
    OptDemoRecorder.prototype.startRecordingAudio = function () {
        pytutor_1.assert(this.audioRecorder);
        pytutor_1.assert(this.demoVideo);
        this.demoVideo.mp3AudioRecording = null; // erase any existing audio data
        this.audioRecorder.record();
    };
    OptDemoRecorder.prototype.stopRecordingAudio = function () {
        pytutor_1.assert(this.audioRecorder);
        this.audioRecorder.stop();
        this.audioRecorder.exportWAV(function (blob) {
            console.log('calling audioRecorder.exportWAV');
        });
        this.audioRecorder.clear();
    };
    OptDemoRecorder.prototype.doneEncodingMp3 = function (mp3Data) {
        console.log('doneEncodingMp3!');
        pytutor_1.assert(this.demoVideo);
        var dataUrl = 'data:audio/mp3;base64,' + encode64(mp3Data);
        this.demoVideo.mp3AudioRecording = dataUrl;
        //(localStorage as any).demoVideo = this.demoVideo.serializeToJSON(); // serialize 'this' after audio is ready
        // create a download link
        var hf = document.createElement('a');
        // serialize 'this' into a JSON string and turn it into a data URL:
        hf.href = URL.createObjectURL(new Blob([this.demoVideo.serializeToJSON()], { type: 'application/json' }));
        // set download filename based on timestamp:
        hf.download = 'codcast_' + (new Date().toISOString()) + '.json';
        hf.innerHTML = 'Download recording';
        document.getElementById('headerTdLeft').append(hf);
        // disable auto-download, since it's kind of annoying and hidden
        //hf.click(); // automatically click to download the recording as a file
    };
    // TODO: move up to opt-shared-sessions.ts when you're ready
    OptDemoRecorder.prototype.cursorOrSelectionChanged = function (e) {
        if (opt_shared_sessions_1.TogetherJS.running && !this.isPlayingDemo) {
            if (e.type === 'changeCursor') {
                var c = this.pyInputAceEditor.selection.getCursor();
                //console.log('changeCursor', c);
                opt_shared_sessions_1.TogetherJS.send({ type: "aceChangeCursor",
                    row: c.row, column: c.column });
            }
            else if (e.type === 'changeSelection') {
                var s = this.pyInputAceEditor.selection.getRange();
                //console.log('changeSelection', s);
                opt_shared_sessions_1.TogetherJS.send({ type: "aceChangeSelection",
                    start: s.start, end: s.end });
            }
            else {
                // fail soft
                console.warn('cursorOrSelectionChanged weird type', e.type);
            }
        }
    };
    // override from superclasses to be NOPs to cancel default superclass behavior
    OptDemoRecorder.prototype.takeFullCodeSnapshot = function () { return; };
    OptDemoRecorder.prototype.recordButtonClicked = function () {
        if ($("#recordBtn").data('status') === 'recording') {
            // issue this event right before stopping the recording
            // (if you do this after calling TogetherJS(), then the event
            // won't be properly logged)
            opt_shared_sessions_1.TogetherJS.send({ type: "stopRecordingDemo" });
            opt_shared_sessions_1.TogetherJS(); // this will stop recording
            $("#recordBtn").data('status', 'stopped');
            $("#recordBtn").html("Record demo");
        }
        else {
            $("#ssDiv,#surveyHeader").hide(); // hide ASAP!
            $("#togetherjsStatus").html("Recording now ...");
            this.demoVideo = new demovideo_1.OptDemoVideo(this);
            this.demoVideo.startRecording();
            $("#recordBtn").data('status', 'recording');
            $("#recordBtn").html("Stop recording");
        }
    };
    OptDemoRecorder.prototype.finishSuccessfulExecution = function () {
        pytutor_1.assert(this.myVisualizer);
        if (this.isRecordingDemo) {
            this.traceCacheAdd(); // add to cache only if we're recording a demo
        }
        // do this last
        _super.prototype.finishSuccessfulExecution.call(this);
    };
    OptDemoRecorder.prototype.handleUncaughtException = function (trace) {
        _super.prototype.handleUncaughtException.call(this, trace); // do this first
        // do this even if execution fails
        if (this.isRecordingDemo) {
            this.traceCacheAdd(); // add to cache only if we're recording a demo
        }
    };
    OptDemoRecorder.prototype.TogetherjsReadyHandler = function () {
        if (this.isRecordingDemo) {
            pytutor_1.assert(this.demoVideo);
            this.demoVideo.recordTogetherJsReady();
            // start recording audio only after TogetherJS is ready and
            // eventRecorderFunc has been set so that it can log the event:
            this.startRecordingAudio();
            opt_shared_sessions_1.TogetherJS.send({ type: "startRecordingDemo" }); // special start marker, to coincide with when audio starts recording
        }
        else if (this.isPlayingDemo) {
            _super.prototype.TogetherjsReadyHandler.call(this); // delegate to superclass
        }
        else {
            pytutor_1.assert(false);
        }
    };
    OptDemoRecorder.prototype.TogetherjsCloseHandler = function () {
        _super.prototype.TogetherjsCloseHandler.call(this);
        // reset all recording-related stuff too!
        if (this.isRecordingDemo) {
            this.stopRecordingAudio(); // it will still take some time before the encoded mp3 data is ready and doneEncodingMp3 is called!
            pytutor_1.assert(this.demoVideo);
            this.demoVideo.stopRecording();
            pytutor_1.assert(!this.isRecordingDemo);
        }
        else {
            pytutor_1.assert(this.isPlayingDemo); // the 'super' call above should've already handled this case
        }
    };
    return OptDemoRecorder;
}(opt_shared_sessions_1.OptFrontendSharedSessions)); // END Class OptDemoRecorder
exports.OptDemoRecorder = OptDemoRecorder;
$(document).ready(function () {
    // initialize all HTML elements before creating optFrontend object
    $("#footer").append(footer_html_1.footerHtml);
    var params = {};
    var optFrontend = new OptDemoRecorder(params);
    $('#pythonVersionSelector').change(optFrontend.setAceMode.bind(optFrontend));
    optFrontend.setAceMode();
});

/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0)))

/***/ })
/******/ ]);