[
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[src/**]\nindent_size = 2\nindent_style = space\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = false\n\n[*.md]\ntrim_trailing_whitespace = false\n"
  },
  {
    "path": ".gitignore",
    "content": ".DS_Store\n.idea\n\n"
  },
  {
    "path": "README.md",
    "content": "\n<p align=\"center\">\n    <img width=\"600\" src=\"http://i.imgur.com/2EVTmo1.png\" text-align=\"center\">\n</p>\n\n> Switch between the opened tabs in the blink of an eye. [Check Demo](http://i.imgur.com/Soqu41O.gifv)\n\n## Preface\n\nWhile you are working on something, number of opened tabs can quickly grow out of hand and when that happens trying to find the relevant tab can easily waste a few seconds of your time; and without any doubt every second that harms your productivity counts. TabSwitcher tries to fix this.\n\n## Features\n\n- Apply fuzzy filter over the opened tabs \n- Swiftly switch between the tabs\n- Close any irrelevant tabs during the filter \n- Leave your mouse alone; extension has shortcut for activation, switching tabs, closing them etc\n \n## Installation\n\nNo setup required. [Install it directly from the Chrome Webstore](https://chrome.google.com/webstore/detail/dnnmaaanhggngdohooaogfcnokngjcbc)\n\n## Usage\n\nFollow the instructions below\n\n- Press **COMMAND+SHIFT+K** or **CTRL+SHIFT+K** to activate and start typing the keywords to filter tabs\n\n![Use command+shift+k or ctrl+shift+k](http://i.imgur.com/o9UBZEv.png)\n\n- Use `Enter` key or mouse click to jump to tab\n- Press `;` semicolon key to close the selected tab\n\n## Note\n\n- After installing, you will have to refresh the already opened tabs\n- Chrome doesn't allow it on the `New Tab` or `Chrome Web Store` pages\n\n## Roadmap\n\n- [x] Activation by shortcut\n- [x] Fuzzy search for tabs\n- [x] Closing tabs\n- [x] Switching tab\n- [ ] Ditch jQuery, use plain Javascript plus ES6 with babel\n- [ ] Close filtered tabs\n- [ ] Pin/Unpin selected tab using shortcut\n- [ ] Save current session/selective tabs with name e.g. type `>save Session Name` to save current session and then `>sessions` to list all the sessions and restore any sessions \n- [ ] Options page, themes and modify shortcuts\n- [ ] Tweet any tab using shortcut\n\n## Contribution\n\n- Fork, enhance, create PR\n- Lock issues with any bugs or feature requests\n- Implement something from the roadmap\n- Spread the word\n \n## License\n\nMIT © [Kamran Ahmed](http://github.com/kamranahmedse)\n"
  },
  {
    "path": "assets/css/tab-switcher.css",
    "content": ".tab-switcher ul::-webkit-scrollbar {\n  display: none;\n}\n\n.tab-switcher {\n  position: fixed;\n  top: 10vh;\n  left: 20vw;\n  width: 60vw;\n  display: block;\n  padding: 0;\n  color: #666;\n  background-color: #fafafa;\n  border: 1px solid #e5e5e5;\n  box-shadow: 0 0 30px rgba(102, 96, 91, 0.7);\n  box-sizing: border-box;\n  z-index: 9999999;\n  font-family: -apple-system, BlinkMacSystemFont, Helvetica, Arial, sans-serif;\n  text-rendering: optimizeLegibility;\n}\n\n.tab-switcher input[type=\"text\"], .tab-switcher input[type=\"text\"]:focus, .tab-switcher input[type=\"text\"]:active {\n  display: block;\n  border: 0;\n  width: 100%;\n  padding: 15px;\n  -webkit-appearance: none;\n  border: none;\n  outline: none;\n  background: #fff;\n  font-size: 17px;\n  box-sizing: border-box;\n  margin: 0;\n  color: #555459;\n  box-shadow: none;\n  height: 50px;\n  position: relative;\n  z-index: 10;\n}\n\n.tab-switcher ul.tabs-list {\n  width: 100%;\n  z-index: 9;\n  top: 0;\n  list-style-type: none;\n  margin: 0;\n  padding: 0;\n  border-right: 1px solid transparent;\n  max-height: 80vh;\n  overflow-y: scroll;\n  overflow-x: hidden;\n}\n\n.tab-switcher ul.tabs-list li.selected-tab, .tab-switcher ul.tabs-list li:hover {\n  background-color: #DFDFDF;\n}\n\n.tab-switcher ul.tabs-list li.selected-tab {\n  color: #000;\n}\n\n.tab-switcher .tabs-list li {\n  padding: 15px 20px;\n  box-sizing: border-box;\n  cursor: pointer;\n  background-color: #EFEFEF;\n  line-height: 24px;\n  display: flex;\n  align-items: center;\n  margin: 0;\n}\n\n.tab-switcher .tabs-list li:not(:last-of-type) {\n  border-bottom: 1px dashed #ccc;\n}\n\n.tab-switcher .tabs-list li span.title {\n  display: inline-block;\n  flex: 1 1 auto;\n  font-size: 14px;\n  margin-left: 10px;\n  overflow: hidden;\n  white-space: nowrap;\n  text-overflow: ellipsis;\n  vertical-align: middle;\n}\n\n.tabs-list li .favicon-img {\n  flex: 0 0 50px;\n  text-align: center;\n}\n\n.tabs-list li .favicon-img img {\n  width: 24px;\n  height: auto;\n  vertical-align: bottom;\n}\n\n@media all and (max-width: 600px) {\n  .tab-switcher {\n    left: 5vw;\n    width: 90vw;\n  }\n}\n\n@media all and (min-width: 1500px) {\n  .tab-switcher {\n    left: calc(50vw - 500px);\n    width: 1000px;\n  }\n}\n"
  },
  {
    "path": "assets/lib/jquery.js",
    "content": "/*!\n * jQuery JavaScript Library v2.1.4\n * http://jquery.com/\n *\n * Includes Sizzle.js\n * http://sizzlejs.com/\n *\n * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2015-04-28T16:01Z\n */\n\n(function (global, factory) {\n\n    if (typeof module === \"object\" && typeof module.exports === \"object\") {\n        // For CommonJS and CommonJS-like environments where a proper `window`\n        // is present, execute the factory and get jQuery.\n        // For environments that do not have a `window` with a `document`\n        // (such as Node.js), expose a factory as module.exports.\n        // This accentuates the need for the creation of a real `window`.\n        // e.g. var jQuery = require(\"jquery\")(window);\n        // See ticket #14549 for more info.\n        module.exports = global.document ?\n            factory(global, true) :\n            function (w) {\n                if (!w.document) {\n                    throw new Error(\"jQuery requires a window with a document\");\n                }\n                return factory(w);\n            };\n    } else {\n        factory(global);\n    }\n\n// Pass this if window is not defined yet\n}(typeof window !== \"undefined\" ? window : this, function (window, noGlobal) {\n\n// Support: Firefox 18+\n// Can't be in strict mode, several libs including ASP.NET trace\n// the stack via arguments.caller.callee and Firefox dies if\n// you try to trace through \"use strict\" call chains. (#13335)\n//\n\n    var arr = [];\n\n    var slice = arr.slice;\n\n    var concat = arr.concat;\n\n    var push = arr.push;\n\n    var indexOf = arr.indexOf;\n\n    var class2type = {};\n\n    var toString = class2type.toString;\n\n    var hasOwn = class2type.hasOwnProperty;\n\n    var support = {};\n\n\n    var\n    // Use the correct document accordingly with window argument (sandbox)\n        document = window.document,\n\n        version = \"2.1.4\",\n\n    // Define a local copy of jQuery\n        jQuery = function (selector, context) {\n            // The jQuery object is actually just the init constructor 'enhanced'\n            // Need init if jQuery is called (just allow error to be thrown if not included)\n            return new jQuery.fn.init(selector, context);\n        },\n\n    // Support: Android<4.1\n    // Make sure we trim BOM and NBSP\n        rtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,\n\n    // Matches dashed string for camelizing\n        rmsPrefix = /^-ms-/,\n        rdashAlpha = /-([\\da-z])/gi,\n\n    // Used by jQuery.camelCase as callback to replace()\n        fcamelCase = function (all, letter) {\n            return letter.toUpperCase();\n        };\n\n    jQuery.fn = jQuery.prototype = {\n        // The current version of jQuery being used\n        jquery: version,\n\n        constructor: jQuery,\n\n        // Start with an empty selector\n        selector: \"\",\n\n        // The default length of a jQuery object is 0\n        length: 0,\n\n        toArray: function () {\n            return slice.call(this);\n        },\n\n        // Get the Nth element in the matched element set OR\n        // Get the whole matched element set as a clean array\n        get: function (num) {\n            return num != null ?\n\n                // Return just the one element from the set\n                ( num < 0 ? this[num + this.length] : this[num] ) :\n\n                // Return all the elements in a clean array\n                slice.call(this);\n        },\n\n        // Take an array of elements and push it onto the stack\n        // (returning the new matched element set)\n        pushStack: function (elems) {\n\n            // Build a new jQuery matched element set\n            var ret = jQuery.merge(this.constructor(), elems);\n\n            // Add the old object onto the stack (as a reference)\n            ret.prevObject = this;\n            ret.context = this.context;\n\n            // Return the newly-formed element set\n            return ret;\n        },\n\n        // Execute a callback for every element in the matched set.\n        // (You can seed the arguments with an array of args, but this is\n        // only used internally.)\n        each: function (callback, args) {\n            return jQuery.each(this, callback, args);\n        },\n\n        map: function (callback) {\n            return this.pushStack(jQuery.map(this, function (elem, i) {\n                return callback.call(elem, i, elem);\n            }));\n        },\n\n        slice: function () {\n            return this.pushStack(slice.apply(this, arguments));\n        },\n\n        first: function () {\n            return this.eq(0);\n        },\n\n        last: function () {\n            return this.eq(-1);\n        },\n\n        eq: function (i) {\n            var len = this.length,\n                j = +i + ( i < 0 ? len : 0 );\n            return this.pushStack(j >= 0 && j < len ? [this[j]] : []);\n        },\n\n        end: function () {\n            return this.prevObject || this.constructor(null);\n        },\n\n        // For internal use only.\n        // Behaves like an Array's method, not like a jQuery method.\n        push: push,\n        sort: arr.sort,\n        splice: arr.splice\n    };\n\n    jQuery.extend = jQuery.fn.extend = function () {\n        var options, name, src, copy, copyIsArray, clone,\n            target = arguments[0] || {},\n            i = 1,\n            length = arguments.length,\n            deep = false;\n\n        // Handle a deep copy situation\n        if (typeof target === \"boolean\") {\n            deep = target;\n\n            // Skip the boolean and the target\n            target = arguments[i] || {};\n            i++;\n        }\n\n        // Handle case when target is a string or something (possible in deep copy)\n        if (typeof target !== \"object\" && !jQuery.isFunction(target)) {\n            target = {};\n        }\n\n        // Extend jQuery itself if only one argument is passed\n        if (i === length) {\n            target = this;\n            i--;\n        }\n\n        for (; i < length; i++) {\n            // Only deal with non-null/undefined values\n            if ((options = arguments[i]) != null) {\n                // Extend the base object\n                for (name in options) {\n                    src = target[name];\n                    copy = options[name];\n\n                    // Prevent never-ending loop\n                    if (target === copy) {\n                        continue;\n                    }\n\n                    // Recurse if we're merging plain objects or arrays\n                    if (deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) )) {\n                        if (copyIsArray) {\n                            copyIsArray = false;\n                            clone = src && jQuery.isArray(src) ? src : [];\n\n                        } else {\n                            clone = src && jQuery.isPlainObject(src) ? src : {};\n                        }\n\n                        // Never move original objects, clone them\n                        target[name] = jQuery.extend(deep, clone, copy);\n\n                        // Don't bring in undefined values\n                    } else if (copy !== undefined) {\n                        target[name] = copy;\n                    }\n                }\n            }\n        }\n\n        // Return the modified object\n        return target;\n    };\n\n    jQuery.extend({\n        // Unique for each copy of jQuery on the page\n        expando: \"jQuery\" + ( version + Math.random() ).replace(/\\D/g, \"\"),\n\n        // Assume jQuery is ready without the ready module\n        isReady: true,\n\n        error: function (msg) {\n            throw new Error(msg);\n        },\n\n        noop: function () {\n        },\n\n        isFunction: function (obj) {\n            return jQuery.type(obj) === \"function\";\n        },\n\n        isArray: Array.isArray,\n\n        isWindow: function (obj) {\n            return obj != null && obj === obj.window;\n        },\n\n        isNumeric: function (obj) {\n            // parseFloat NaNs numeric-cast false positives (null|true|false|\"\")\n            // ...but misinterprets leading-number strings, particularly hex literals (\"0x...\")\n            // subtraction forces infinities to NaN\n            // adding 1 corrects loss of precision from parseFloat (#15100)\n            return !jQuery.isArray(obj) && (obj - parseFloat(obj) + 1) >= 0;\n        },\n\n        isPlainObject: function (obj) {\n            // Not plain objects:\n            // - Any object or value whose internal [[Class]] property is not \"[object Object]\"\n            // - DOM nodes\n            // - window\n            if (jQuery.type(obj) !== \"object\" || obj.nodeType || jQuery.isWindow(obj)) {\n                return false;\n            }\n\n            if (obj.constructor && !hasOwn.call(obj.constructor.prototype, \"isPrototypeOf\")) {\n                return false;\n            }\n\n            // If the function hasn't returned already, we're confident that\n            // |obj| is a plain object, created by {} or constructed with new Object\n            return true;\n        },\n\n        isEmptyObject: function (obj) {\n            var name;\n            for (name in obj) {\n                return false;\n            }\n            return true;\n        },\n\n        type: function (obj) {\n            if (obj == null) {\n                return obj + \"\";\n            }\n            // Support: Android<4.0, iOS<6 (functionish RegExp)\n            return typeof obj === \"object\" || typeof obj === \"function\" ?\n            class2type[toString.call(obj)] || \"object\" :\n                typeof obj;\n        },\n\n        // Evaluates a script in a global context\n        globalEval: function (code) {\n            var script,\n                indirect = eval;\n\n            code = jQuery.trim(code);\n\n            if (code) {\n                // If the code includes a valid, prologue position\n                // strict mode pragma, execute code by injecting a\n                // script tag into the document.\n                if (code.indexOf(\"use strict\") === 1) {\n                    script = document.createElement(\"script\");\n                    script.text = code;\n                    document.head.appendChild(script).parentNode.removeChild(script);\n                } else {\n                    // Otherwise, avoid the DOM node creation, insertion\n                    // and removal by using an indirect global eval\n                    indirect(code);\n                }\n            }\n        },\n\n        // Convert dashed to camelCase; used by the css and data modules\n        // Support: IE9-11+\n        // Microsoft forgot to hump their vendor prefix (#9572)\n        camelCase: function (string) {\n            return string.replace(rmsPrefix, \"ms-\").replace(rdashAlpha, fcamelCase);\n        },\n\n        nodeName: function (elem, name) {\n            return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n        },\n\n        // args is for internal usage only\n        each: function (obj, callback, args) {\n            var value,\n                i = 0,\n                length = obj.length,\n                isArray = isArraylike(obj);\n\n            if (args) {\n                if (isArray) {\n                    for (; i < length; i++) {\n                        value = callback.apply(obj[i], args);\n\n                        if (value === false) {\n                            break;\n                        }\n                    }\n                } else {\n                    for (i in obj) {\n                        value = callback.apply(obj[i], args);\n\n                        if (value === false) {\n                            break;\n                        }\n                    }\n                }\n\n                // A special, fast, case for the most common use of each\n            } else {\n                if (isArray) {\n                    for (; i < length; i++) {\n                        value = callback.call(obj[i], i, obj[i]);\n\n                        if (value === false) {\n                            break;\n                        }\n                    }\n                } else {\n                    for (i in obj) {\n                        value = callback.call(obj[i], i, obj[i]);\n\n                        if (value === false) {\n                            break;\n                        }\n                    }\n                }\n            }\n\n            return obj;\n        },\n\n        // Support: Android<4.1\n        trim: function (text) {\n            return text == null ?\n                \"\" :\n                ( text + \"\" ).replace(rtrim, \"\");\n        },\n\n        // results is for internal usage only\n        makeArray: function (arr, results) {\n            var ret = results || [];\n\n            if (arr != null) {\n                if (isArraylike(Object(arr))) {\n                    jQuery.merge(ret,\n                        typeof arr === \"string\" ?\n                            [arr] : arr\n                    );\n                } else {\n                    push.call(ret, arr);\n                }\n            }\n\n            return ret;\n        },\n\n        inArray: function (elem, arr, i) {\n            return arr == null ? -1 : indexOf.call(arr, elem, i);\n        },\n\n        merge: function (first, second) {\n            var len = +second.length,\n                j = 0,\n                i = first.length;\n\n            for (; j < len; j++) {\n                first[i++] = second[j];\n            }\n\n            first.length = i;\n\n            return first;\n        },\n\n        grep: function (elems, callback, invert) {\n            var callbackInverse,\n                matches = [],\n                i = 0,\n                length = elems.length,\n                callbackExpect = !invert;\n\n            // Go through the array, only saving the items\n            // that pass the validator function\n            for (; i < length; i++) {\n                callbackInverse = !callback(elems[i], i);\n                if (callbackInverse !== callbackExpect) {\n                    matches.push(elems[i]);\n                }\n            }\n\n            return matches;\n        },\n\n        // arg is for internal usage only\n        map: function (elems, callback, arg) {\n            var value,\n                i = 0,\n                length = elems.length,\n                isArray = isArraylike(elems),\n                ret = [];\n\n            // Go through the array, translating each of the items to their new values\n            if (isArray) {\n                for (; i < length; i++) {\n                    value = callback(elems[i], i, arg);\n\n                    if (value != null) {\n                        ret.push(value);\n                    }\n                }\n\n                // Go through every key on the object,\n            } else {\n                for (i in elems) {\n                    value = callback(elems[i], i, arg);\n\n                    if (value != null) {\n                        ret.push(value);\n                    }\n                }\n            }\n\n            // Flatten any nested arrays\n            return concat.apply([], ret);\n        },\n\n        // A global GUID counter for objects\n        guid: 1,\n\n        // Bind a function to a context, optionally partially applying any\n        // arguments.\n        proxy: function (fn, context) {\n            var tmp, args, proxy;\n\n            if (typeof context === \"string\") {\n                tmp = fn[context];\n                context = fn;\n                fn = tmp;\n            }\n\n            // Quick check to determine if target is callable, in the spec\n            // this throws a TypeError, but we will just return undefined.\n            if (!jQuery.isFunction(fn)) {\n                return undefined;\n            }\n\n            // Simulated bind\n            args = slice.call(arguments, 2);\n            proxy = function () {\n                return fn.apply(context || this, args.concat(slice.call(arguments)));\n            };\n\n            // Set the guid of unique handler to the same of original handler, so it can be removed\n            proxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n            return proxy;\n        },\n\n        now: Date.now,\n\n        // jQuery.support is not used in Core but other projects attach their\n        // properties to it so it needs to exist.\n        support: support\n    });\n\n// Populate the class2type map\n    jQuery.each(\"Boolean Number String Function Array Date RegExp Object Error\".split(\" \"), function (i, name) {\n        class2type[\"[object \" + name + \"]\"] = name.toLowerCase();\n    });\n\n    function isArraylike(obj) {\n\n        // Support: iOS 8.2 (not reproducible in simulator)\n        // `in` check used to prevent JIT error (gh-2145)\n        // hasOwn isn't used here due to false negatives\n        // regarding Nodelist length in IE\n        var length = \"length\" in obj && obj.length,\n            type = jQuery.type(obj);\n\n        if (type === \"function\" || jQuery.isWindow(obj)) {\n            return false;\n        }\n\n        if (obj.nodeType === 1 && length) {\n            return true;\n        }\n\n        return type === \"array\" || length === 0 ||\n            typeof length === \"number\" && length > 0 && ( length - 1 ) in obj;\n    }\n\n    var Sizzle =\n        /*!\n         * Sizzle CSS Selector Engine v2.2.0-pre\n         * http://sizzlejs.com/\n         *\n         * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors\n         * Released under the MIT license\n         * http://jquery.org/license\n         *\n         * Date: 2014-12-16\n         */\n        (function (window) {\n\n            var i,\n                support,\n                Expr,\n                getText,\n                isXML,\n                tokenize,\n                compile,\n                select,\n                outermostContext,\n                sortInput,\n                hasDuplicate,\n\n            // Local document vars\n                setDocument,\n                document,\n                docElem,\n                documentIsHTML,\n                rbuggyQSA,\n                rbuggyMatches,\n                matches,\n                contains,\n\n            // Instance-specific data\n                expando = \"sizzle\" + 1 * new Date(),\n                preferredDoc = window.document,\n                dirruns = 0,\n                done = 0,\n                classCache = createCache(),\n                tokenCache = createCache(),\n                compilerCache = createCache(),\n                sortOrder = function (a, b) {\n                    if (a === b) {\n                        hasDuplicate = true;\n                    }\n                    return 0;\n                },\n\n            // General-purpose constants\n                MAX_NEGATIVE = 1 << 31,\n\n            // Instance methods\n                hasOwn = ({}).hasOwnProperty,\n                arr = [],\n                pop = arr.pop,\n                push_native = arr.push,\n                push = arr.push,\n                slice = arr.slice,\n            // Use a stripped-down indexOf as it's faster than native\n            // http://jsperf.com/thor-indexof-vs-for/5\n                indexOf = function (list, elem) {\n                    var i = 0,\n                        len = list.length;\n                    for (; i < len; i++) {\n                        if (list[i] === elem) {\n                            return i;\n                        }\n                    }\n                    return -1;\n                },\n\n                booleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",\n\n            // Regular expressions\n\n            // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace\n                whitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n            // http://www.w3.org/TR/css3-syntax/#characters\n                characterEncoding = \"(?:\\\\\\\\.|[\\\\w-]|[^\\\\x00-\\\\xa0])+\",\n\n            // Loosely modeled on CSS identifier characters\n            // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors\n            // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\n                identifier = characterEncoding.replace(\"w\", \"w#\"),\n\n            // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors\n                attributes = \"\\\\[\" + whitespace + \"*(\" + characterEncoding + \")(?:\" + whitespace +\n                    // Operator (capture 2)\n                    \"*([*^$|!~]?=)\" + whitespace +\n                    // \"Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]\"\n                    \"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + identifier + \"))|)\" + whitespace +\n                    \"*\\\\]\",\n\n                pseudos = \":(\" + characterEncoding + \")(?:\\\\((\" +\n                    // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n                    // 1. quoted (capture 3; capture 4 or capture 5)\n                    \"('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|\" +\n                    // 2. simple (capture 6)\n                    \"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes + \")*)|\" +\n                    // 3. anything else (capture 2)\n                    \".*\" +\n                    \")\\\\)|)\",\n\n            // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n                rwhitespace = new RegExp(whitespace + \"+\", \"g\"),\n                rtrim = new RegExp(\"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\"),\n\n                rcomma = new RegExp(\"^\" + whitespace + \"*,\" + whitespace + \"*\"),\n                rcombinators = new RegExp(\"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace + \"*\"),\n\n                rattributeQuotes = new RegExp(\"=\" + whitespace + \"*([^\\\\]'\\\"]*?)\" + whitespace + \"*\\\\]\", \"g\"),\n\n                rpseudo = new RegExp(pseudos),\n                ridentifier = new RegExp(\"^\" + identifier + \"$\"),\n\n                matchExpr = {\n                    \"ID\": new RegExp(\"^#(\" + characterEncoding + \")\"),\n                    \"CLASS\": new RegExp(\"^\\\\.(\" + characterEncoding + \")\"),\n                    \"TAG\": new RegExp(\"^(\" + characterEncoding.replace(\"w\", \"w*\") + \")\"),\n                    \"ATTR\": new RegExp(\"^\" + attributes),\n                    \"PSEUDO\": new RegExp(\"^\" + pseudos),\n                    \"CHILD\": new RegExp(\"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" + whitespace +\n                        \"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\n                        \"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\"),\n                    \"bool\": new RegExp(\"^(?:\" + booleans + \")$\", \"i\"),\n                    // For use in libraries implementing .is()\n                    // We use this for POS matching in `select`\n                    \"needsContext\": new RegExp(\"^\" + whitespace + \"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" +\n                        whitespace + \"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\")\n                },\n\n                rinputs = /^(?:input|select|textarea|button)$/i,\n                rheader = /^h\\d$/i,\n\n                rnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n            // Easily-parseable/retrievable ID or TAG or CLASS selectors\n                rquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n                rsibling = /[+~]/,\n                rescape = /'|\\\\/g,\n\n            // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n                runescape = new RegExp(\"\\\\\\\\([\\\\da-f]{1,6}\" + whitespace + \"?|(\" + whitespace + \")|.)\", \"ig\"),\n                funescape = function (_, escaped, escapedWhitespace) {\n                    var high = \"0x\" + escaped - 0x10000;\n                    // NaN means non-codepoint\n                    // Support: Firefox<24\n                    // Workaround erroneous numeric interpretation of +\"0x\"\n                    return high !== high || escapedWhitespace ?\n                        escaped :\n                        high < 0 ?\n                            // BMP codepoint\n                            String.fromCharCode(high + 0x10000) :\n                            // Supplemental Plane codepoint (surrogate pair)\n                            String.fromCharCode(high >> 10 | 0xD800, high & 0x3FF | 0xDC00);\n                },\n\n            // Used for iframes\n            // See setDocument()\n            // Removing the function wrapper causes a \"Permission Denied\"\n            // error in IE\n                unloadHandler = function () {\n                    setDocument();\n                };\n\n// Optimize for push.apply( _, NodeList )\n            try {\n                push.apply(\n                    (arr = slice.call(preferredDoc.childNodes)),\n                    preferredDoc.childNodes\n                );\n                // Support: Android<4.0\n                // Detect silently failing push.apply\n                arr[preferredDoc.childNodes.length].nodeType;\n            } catch (e) {\n                push = {\n                    apply: arr.length ?\n\n                        // Leverage slice if possible\n                        function (target, els) {\n                            push_native.apply(target, slice.call(els));\n                        } :\n\n                        // Support: IE<9\n                        // Otherwise append directly\n                        function (target, els) {\n                            var j = target.length,\n                                i = 0;\n                            // Can't trust NodeList.length\n                            while ((target[j++] = els[i++])) {\n                            }\n                            target.length = j - 1;\n                        }\n                };\n            }\n\n            function Sizzle(selector, context, results, seed) {\n                var match, elem, m, nodeType,\n                // QSA vars\n                    i, groups, old, nid, newContext, newSelector;\n\n                if (( context ? context.ownerDocument || context : preferredDoc ) !== document) {\n                    setDocument(context);\n                }\n\n                context = context || document;\n                results = results || [];\n                nodeType = context.nodeType;\n\n                if (typeof selector !== \"string\" || !selector ||\n                    nodeType !== 1 && nodeType !== 9 && nodeType !== 11) {\n\n                    return results;\n                }\n\n                if (!seed && documentIsHTML) {\n\n                    // Try to shortcut find operations when possible (e.g., not under DocumentFragment)\n                    if (nodeType !== 11 && (match = rquickExpr.exec(selector))) {\n                        // Speed-up: Sizzle(\"#ID\")\n                        if ((m = match[1])) {\n                            if (nodeType === 9) {\n                                elem = context.getElementById(m);\n                                // Check parentNode to catch when Blackberry 4.6 returns\n                                // nodes that are no longer in the document (jQuery #6963)\n                                if (elem && elem.parentNode) {\n                                    // Handle the case where IE, Opera, and Webkit return items\n                                    // by name instead of ID\n                                    if (elem.id === m) {\n                                        results.push(elem);\n                                        return results;\n                                    }\n                                } else {\n                                    return results;\n                                }\n                            } else {\n                                // Context is not a document\n                                if (context.ownerDocument && (elem = context.ownerDocument.getElementById(m)) &&\n                                    contains(context, elem) && elem.id === m) {\n                                    results.push(elem);\n                                    return results;\n                                }\n                            }\n\n                            // Speed-up: Sizzle(\"TAG\")\n                        } else if (match[2]) {\n                            push.apply(results, context.getElementsByTagName(selector));\n                            return results;\n\n                            // Speed-up: Sizzle(\".CLASS\")\n                        } else if ((m = match[3]) && support.getElementsByClassName) {\n                            push.apply(results, context.getElementsByClassName(m));\n                            return results;\n                        }\n                    }\n\n                    // QSA path\n                    if (support.qsa && (!rbuggyQSA || !rbuggyQSA.test(selector))) {\n                        nid = old = expando;\n                        newContext = context;\n                        newSelector = nodeType !== 1 && selector;\n\n                        // qSA works strangely on Element-rooted queries\n                        // We can work around this by specifying an extra ID on the root\n                        // and working up from there (Thanks to Andrew Dupont for the technique)\n                        // IE 8 doesn't work on object elements\n                        if (nodeType === 1 && context.nodeName.toLowerCase() !== \"object\") {\n                            groups = tokenize(selector);\n\n                            if ((old = context.getAttribute(\"id\"))) {\n                                nid = old.replace(rescape, \"\\\\$&\");\n                            } else {\n                                context.setAttribute(\"id\", nid);\n                            }\n                            nid = \"[id='\" + nid + \"'] \";\n\n                            i = groups.length;\n                            while (i--) {\n                                groups[i] = nid + toSelector(groups[i]);\n                            }\n                            newContext = rsibling.test(selector) && testContext(context.parentNode) || context;\n                            newSelector = groups.join(\",\");\n                        }\n\n                        if (newSelector) {\n                            try {\n                                push.apply(results,\n                                    newContext.querySelectorAll(newSelector)\n                                );\n                                return results;\n                            } catch (qsaError) {\n                            } finally {\n                                if (!old) {\n                                    context.removeAttribute(\"id\");\n                                }\n                            }\n                        }\n                    }\n                }\n\n                // All others\n                return select(selector.replace(rtrim, \"$1\"), context, results, seed);\n            }\n\n            /**\n             * Create key-value caches of limited size\n             * @returns {Function(string, Object)} Returns the Object data after storing it on itself with\n             *    property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n             *    deleting the oldest entry\n             */\n            function createCache() {\n                var keys = [];\n\n                function cache(key, value) {\n                    // Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n                    if (keys.push(key + \" \") > Expr.cacheLength) {\n                        // Only keep the most recent entries\n                        delete cache[keys.shift()];\n                    }\n                    return (cache[key + \" \"] = value);\n                }\n\n                return cache;\n            }\n\n            /**\n             * Mark a function for special use by Sizzle\n             * @param {Function} fn The function to mark\n             */\n            function markFunction(fn) {\n                fn[expando] = true;\n                return fn;\n            }\n\n            /**\n             * Support testing using an element\n             * @param {Function} fn Passed the created div and expects a boolean result\n             */\n            function assert(fn) {\n                var div = document.createElement(\"div\");\n\n                try {\n                    return !!fn(div);\n                } catch (e) {\n                    return false;\n                } finally {\n                    // Remove from its parent by default\n                    if (div.parentNode) {\n                        div.parentNode.removeChild(div);\n                    }\n                    // release memory in IE\n                    div = null;\n                }\n            }\n\n            /**\n             * Adds the same handler for all of the specified attrs\n             * @param {String} attrs Pipe-separated list of attributes\n             * @param {Function} handler The method that will be applied\n             */\n            function addHandle(attrs, handler) {\n                var arr = attrs.split(\"|\"),\n                    i = attrs.length;\n\n                while (i--) {\n                    Expr.attrHandle[arr[i]] = handler;\n                }\n            }\n\n            /**\n             * Checks document order of two siblings\n             * @param {Element} a\n             * @param {Element} b\n             * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n             */\n            function siblingCheck(a, b) {\n                var cur = b && a,\n                    diff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n                        ( ~b.sourceIndex || MAX_NEGATIVE ) -\n                        ( ~a.sourceIndex || MAX_NEGATIVE );\n\n                // Use IE sourceIndex if available on both nodes\n                if (diff) {\n                    return diff;\n                }\n\n                // Check if b follows a\n                if (cur) {\n                    while ((cur = cur.nextSibling)) {\n                        if (cur === b) {\n                            return -1;\n                        }\n                    }\n                }\n\n                return a ? 1 : -1;\n            }\n\n            /**\n             * Returns a function to use in pseudos for input types\n             * @param {String} type\n             */\n            function createInputPseudo(type) {\n                return function (elem) {\n                    var name = elem.nodeName.toLowerCase();\n                    return name === \"input\" && elem.type === type;\n                };\n            }\n\n            /**\n             * Returns a function to use in pseudos for buttons\n             * @param {String} type\n             */\n            function createButtonPseudo(type) {\n                return function (elem) {\n                    var name = elem.nodeName.toLowerCase();\n                    return (name === \"input\" || name === \"button\") && elem.type === type;\n                };\n            }\n\n            /**\n             * Returns a function to use in pseudos for positionals\n             * @param {Function} fn\n             */\n            function createPositionalPseudo(fn) {\n                return markFunction(function (argument) {\n                    argument = +argument;\n                    return markFunction(function (seed, matches) {\n                        var j,\n                            matchIndexes = fn([], seed.length, argument),\n                            i = matchIndexes.length;\n\n                        // Match elements found at the specified indexes\n                        while (i--) {\n                            if (seed[(j = matchIndexes[i])]) {\n                                seed[j] = !(matches[j] = seed[j]);\n                            }\n                        }\n                    });\n                });\n            }\n\n            /**\n             * Checks a node for validity as a Sizzle context\n             * @param {Element|Object=} context\n             * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n             */\n            function testContext(context) {\n                return context && typeof context.getElementsByTagName !== \"undefined\" && context;\n            }\n\n// Expose support vars for convenience\n            support = Sizzle.support = {};\n\n            /**\n             * Detects XML nodes\n             * @param {Element|Object} elem An element or a document\n             * @returns {Boolean} True iff elem is a non-HTML XML node\n             */\n            isXML = Sizzle.isXML = function (elem) {\n                // documentElement is verified for cases where it doesn't yet exist\n                // (such as loading iframes in IE - #4833)\n                var documentElement = elem && (elem.ownerDocument || elem).documentElement;\n                return documentElement ? documentElement.nodeName !== \"HTML\" : false;\n            };\n\n            /**\n             * Sets document-related variables once based on the current document\n             * @param {Element|Object} [doc] An element or document object to use to set the document\n             * @returns {Object} Returns the current document\n             */\n            setDocument = Sizzle.setDocument = function (node) {\n                var hasCompare, parent,\n                    doc = node ? node.ownerDocument || node : preferredDoc;\n\n                // If no document and documentElement is available, return\n                if (doc === document || doc.nodeType !== 9 || !doc.documentElement) {\n                    return document;\n                }\n\n                // Set our document\n                document = doc;\n                docElem = doc.documentElement;\n                parent = doc.defaultView;\n\n                // Support: IE>8\n                // If iframe document is assigned to \"document\" variable and if iframe has been reloaded,\n                // IE will throw \"permission denied\" error when accessing \"document\" variable, see jQuery #13936\n                // IE6-8 do not support the defaultView property so parent will be undefined\n                if (parent && parent !== parent.top) {\n                    // IE11 does not have attachEvent, so all must suffer\n                    if (parent.addEventListener) {\n                        parent.addEventListener(\"unload\", unloadHandler, false);\n                    } else if (parent.attachEvent) {\n                        parent.attachEvent(\"onunload\", unloadHandler);\n                    }\n                }\n\n                /* Support tests\n                 ---------------------------------------------------------------------- */\n                documentIsHTML = !isXML(doc);\n\n                /* Attributes\n                 ---------------------------------------------------------------------- */\n\n                // Support: IE<8\n                // Verify that getAttribute really returns attributes and not properties\n                // (excepting IE8 booleans)\n                support.attributes = assert(function (div) {\n                    div.className = \"i\";\n                    return !div.getAttribute(\"className\");\n                });\n\n                /* getElement(s)By*\n                 ---------------------------------------------------------------------- */\n\n                // Check if getElementsByTagName(\"*\") returns only elements\n                support.getElementsByTagName = assert(function (div) {\n                    div.appendChild(doc.createComment(\"\"));\n                    return !div.getElementsByTagName(\"*\").length;\n                });\n\n                // Support: IE<9\n                support.getElementsByClassName = rnative.test(doc.getElementsByClassName);\n\n                // Support: IE<10\n                // Check if getElementById returns elements by name\n                // The broken getElementById methods don't pick up programatically-set names,\n                // so use a roundabout getElementsByName test\n                support.getById = assert(function (div) {\n                    docElem.appendChild(div).id = expando;\n                    return !doc.getElementsByName || !doc.getElementsByName(expando).length;\n                });\n\n                // ID find and filter\n                if (support.getById) {\n                    Expr.find[\"ID\"] = function (id, context) {\n                        if (typeof context.getElementById !== \"undefined\" && documentIsHTML) {\n                            var m = context.getElementById(id);\n                            // Check parentNode to catch when Blackberry 4.6 returns\n                            // nodes that are no longer in the document #6963\n                            return m && m.parentNode ? [m] : [];\n                        }\n                    };\n                    Expr.filter[\"ID\"] = function (id) {\n                        var attrId = id.replace(runescape, funescape);\n                        return function (elem) {\n                            return elem.getAttribute(\"id\") === attrId;\n                        };\n                    };\n                } else {\n                    // Support: IE6/7\n                    // getElementById is not reliable as a find shortcut\n                    delete Expr.find[\"ID\"];\n\n                    Expr.filter[\"ID\"] = function (id) {\n                        var attrId = id.replace(runescape, funescape);\n                        return function (elem) {\n                            var node = typeof elem.getAttributeNode !== \"undefined\" && elem.getAttributeNode(\"id\");\n                            return node && node.value === attrId;\n                        };\n                    };\n                }\n\n                // Tag\n                Expr.find[\"TAG\"] = support.getElementsByTagName ?\n                    function (tag, context) {\n                        if (typeof context.getElementsByTagName !== \"undefined\") {\n                            return context.getElementsByTagName(tag);\n\n                            // DocumentFragment nodes don't have gEBTN\n                        } else if (support.qsa) {\n                            return context.querySelectorAll(tag);\n                        }\n                    } :\n\n                    function (tag, context) {\n                        var elem,\n                            tmp = [],\n                            i = 0,\n                        // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too\n                            results = context.getElementsByTagName(tag);\n\n                        // Filter out possible comments\n                        if (tag === \"*\") {\n                            while ((elem = results[i++])) {\n                                if (elem.nodeType === 1) {\n                                    tmp.push(elem);\n                                }\n                            }\n\n                            return tmp;\n                        }\n                        return results;\n                    };\n\n                // Class\n                Expr.find[\"CLASS\"] = support.getElementsByClassName && function (className, context) {\n                        if (documentIsHTML) {\n                            return context.getElementsByClassName(className);\n                        }\n                    };\n\n                /* QSA/matchesSelector\n                 ---------------------------------------------------------------------- */\n\n                // QSA and matchesSelector support\n\n                // matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n                rbuggyMatches = [];\n\n                // qSa(:focus) reports false when true (Chrome 21)\n                // We allow this because of a bug in IE8/9 that throws an error\n                // whenever `document.activeElement` is accessed on an iframe\n                // So, we allow :focus to pass through QSA all the time to avoid the IE error\n                // See http://bugs.jquery.com/ticket/13378\n                rbuggyQSA = [];\n\n                if ((support.qsa = rnative.test(doc.querySelectorAll))) {\n                    // Build QSA regex\n                    // Regex strategy adopted from Diego Perini\n                    assert(function (div) {\n                        // Select is set to empty string on purpose\n                        // This is to test IE's treatment of not explicitly\n                        // setting a boolean content attribute,\n                        // since its presence should be enough\n                        // http://bugs.jquery.com/ticket/12359\n                        docElem.appendChild(div).innerHTML = \"<a id='\" + expando + \"'></a>\" +\n                            \"<select id='\" + expando + \"-\\f]' msallowcapture=''>\" +\n                            \"<option selected=''></option></select>\";\n\n                        // Support: IE8, Opera 11-12.16\n                        // Nothing should be selected when empty strings follow ^= or $= or *=\n                        // The test attribute must be unknown in Opera but \"safe\" for WinRT\n                        // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section\n                        if (div.querySelectorAll(\"[msallowcapture^='']\").length) {\n                            rbuggyQSA.push(\"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\");\n                        }\n\n                        // Support: IE8\n                        // Boolean attributes and \"value\" are not treated correctly\n                        if (!div.querySelectorAll(\"[selected]\").length) {\n                            rbuggyQSA.push(\"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\");\n                        }\n\n                        // Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+\n                        if (!div.querySelectorAll(\"[id~=\" + expando + \"-]\").length) {\n                            rbuggyQSA.push(\"~=\");\n                        }\n\n                        // Webkit/Opera - :checked should return selected option elements\n                        // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n                        // IE8 throws error here and will not see later tests\n                        if (!div.querySelectorAll(\":checked\").length) {\n                            rbuggyQSA.push(\":checked\");\n                        }\n\n                        // Support: Safari 8+, iOS 8+\n                        // https://bugs.webkit.org/show_bug.cgi?id=136851\n                        // In-page `selector#id sibing-combinator selector` fails\n                        if (!div.querySelectorAll(\"a#\" + expando + \"+*\").length) {\n                            rbuggyQSA.push(\".#.+[+~]\");\n                        }\n                    });\n\n                    assert(function (div) {\n                        // Support: Windows 8 Native Apps\n                        // The type and name attributes are restricted during .innerHTML assignment\n                        var input = doc.createElement(\"input\");\n                        input.setAttribute(\"type\", \"hidden\");\n                        div.appendChild(input).setAttribute(\"name\", \"D\");\n\n                        // Support: IE8\n                        // Enforce case-sensitivity of name attribute\n                        if (div.querySelectorAll(\"[name=d]\").length) {\n                            rbuggyQSA.push(\"name\" + whitespace + \"*[*^$|!~]?=\");\n                        }\n\n                        // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n                        // IE8 throws error here and will not see later tests\n                        if (!div.querySelectorAll(\":enabled\").length) {\n                            rbuggyQSA.push(\":enabled\", \":disabled\");\n                        }\n\n                        // Opera 10-11 does not throw on post-comma invalid pseudos\n                        div.querySelectorAll(\"*,:x\");\n                        rbuggyQSA.push(\",.*:\");\n                    });\n                }\n\n                if ((support.matchesSelector = rnative.test((matches = docElem.matches ||\n                        docElem.webkitMatchesSelector ||\n                        docElem.mozMatchesSelector ||\n                        docElem.oMatchesSelector ||\n                        docElem.msMatchesSelector)))) {\n\n                    assert(function (div) {\n                        // Check to see if it's possible to do matchesSelector\n                        // on a disconnected node (IE 9)\n                        support.disconnectedMatch = matches.call(div, \"div\");\n\n                        // This should fail with an exception\n                        // Gecko does not error, returns false instead\n                        matches.call(div, \"[s!='']:x\");\n                        rbuggyMatches.push(\"!=\", pseudos);\n                    });\n                }\n\n                rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join(\"|\"));\n                rbuggyMatches = rbuggyMatches.length && new RegExp(rbuggyMatches.join(\"|\"));\n\n                /* Contains\n                 ---------------------------------------------------------------------- */\n                hasCompare = rnative.test(docElem.compareDocumentPosition);\n\n                // Element contains another\n                // Purposefully does not implement inclusive descendent\n                // As in, an element does not contain itself\n                contains = hasCompare || rnative.test(docElem.contains) ?\n                    function (a, b) {\n                        var adown = a.nodeType === 9 ? a.documentElement : a,\n                            bup = b && b.parentNode;\n                        return a === bup || !!( bup && bup.nodeType === 1 && (\n                                adown.contains ?\n                                    adown.contains(bup) :\n                                a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16\n                            ));\n                    } :\n                    function (a, b) {\n                        if (b) {\n                            while ((b = b.parentNode)) {\n                                if (b === a) {\n                                    return true;\n                                }\n                            }\n                        }\n                        return false;\n                    };\n\n                /* Sorting\n                 ---------------------------------------------------------------------- */\n\n                // Document order sorting\n                sortOrder = hasCompare ?\n                    function (a, b) {\n\n                        // Flag for duplicate removal\n                        if (a === b) {\n                            hasDuplicate = true;\n                            return 0;\n                        }\n\n                        // Sort on method existence if only one input has compareDocumentPosition\n                        var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n                        if (compare) {\n                            return compare;\n                        }\n\n                        // Calculate position if both inputs belong to the same document\n                        compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?\n                            a.compareDocumentPosition(b) :\n\n                            // Otherwise we know they are disconnected\n                            1;\n\n                        // Disconnected nodes\n                        if (compare & 1 ||\n                            (!support.sortDetached && b.compareDocumentPosition(a) === compare)) {\n\n                            // Choose the first element that is related to our preferred document\n                            if (a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a)) {\n                                return -1;\n                            }\n                            if (b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b)) {\n                                return 1;\n                            }\n\n                            // Maintain original order\n                            return sortInput ?\n                                ( indexOf(sortInput, a) - indexOf(sortInput, b) ) :\n                                0;\n                        }\n\n                        return compare & 4 ? -1 : 1;\n                    } :\n                    function (a, b) {\n                        // Exit early if the nodes are identical\n                        if (a === b) {\n                            hasDuplicate = true;\n                            return 0;\n                        }\n\n                        var cur,\n                            i = 0,\n                            aup = a.parentNode,\n                            bup = b.parentNode,\n                            ap = [a],\n                            bp = [b];\n\n                        // Parentless nodes are either documents or disconnected\n                        if (!aup || !bup) {\n                            return a === doc ? -1 :\n                                b === doc ? 1 :\n                                    aup ? -1 :\n                                        bup ? 1 :\n                                            sortInput ?\n                                                ( indexOf(sortInput, a) - indexOf(sortInput, b) ) :\n                                                0;\n\n                            // If the nodes are siblings, we can do a quick check\n                        } else if (aup === bup) {\n                            return siblingCheck(a, b);\n                        }\n\n                        // Otherwise we need full lists of their ancestors for comparison\n                        cur = a;\n                        while ((cur = cur.parentNode)) {\n                            ap.unshift(cur);\n                        }\n                        cur = b;\n                        while ((cur = cur.parentNode)) {\n                            bp.unshift(cur);\n                        }\n\n                        // Walk down the tree looking for a discrepancy\n                        while (ap[i] === bp[i]) {\n                            i++;\n                        }\n\n                        return i ?\n                            // Do a sibling check if the nodes have a common ancestor\n                            siblingCheck(ap[i], bp[i]) :\n\n                            // Otherwise nodes in our document sort first\n                            ap[i] === preferredDoc ? -1 :\n                                bp[i] === preferredDoc ? 1 :\n                                    0;\n                    };\n\n                return doc;\n            };\n\n            Sizzle.matches = function (expr, elements) {\n                return Sizzle(expr, null, null, elements);\n            };\n\n            Sizzle.matchesSelector = function (elem, expr) {\n                // Set document vars if needed\n                if (( elem.ownerDocument || elem ) !== document) {\n                    setDocument(elem);\n                }\n\n                // Make sure that attribute selectors are quoted\n                expr = expr.replace(rattributeQuotes, \"='$1']\");\n\n                if (support.matchesSelector && documentIsHTML &&\n                    ( !rbuggyMatches || !rbuggyMatches.test(expr) ) &&\n                    ( !rbuggyQSA || !rbuggyQSA.test(expr) )) {\n\n                    try {\n                        var ret = matches.call(elem, expr);\n\n                        // IE 9's matchesSelector returns false on disconnected nodes\n                        if (ret || support.disconnectedMatch ||\n                            // As well, disconnected nodes are said to be in a document\n                            // fragment in IE 9\n                            elem.document && elem.document.nodeType !== 11) {\n                            return ret;\n                        }\n                    } catch (e) {\n                    }\n                }\n\n                return Sizzle(expr, document, null, [elem]).length > 0;\n            };\n\n            Sizzle.contains = function (context, elem) {\n                // Set document vars if needed\n                if (( context.ownerDocument || context ) !== document) {\n                    setDocument(context);\n                }\n                return contains(context, elem);\n            };\n\n            Sizzle.attr = function (elem, name) {\n                // Set document vars if needed\n                if (( elem.ownerDocument || elem ) !== document) {\n                    setDocument(elem);\n                }\n\n                var fn = Expr.attrHandle[name.toLowerCase()],\n                // Don't get fooled by Object.prototype properties (jQuery #13807)\n                    val = fn && hasOwn.call(Expr.attrHandle, name.toLowerCase()) ?\n                        fn(elem, name, !documentIsHTML) :\n                        undefined;\n\n                return val !== undefined ?\n                    val :\n                    support.attributes || !documentIsHTML ?\n                        elem.getAttribute(name) :\n                        (val = elem.getAttributeNode(name)) && val.specified ?\n                            val.value :\n                            null;\n            };\n\n            Sizzle.error = function (msg) {\n                throw new Error(\"Syntax error, unrecognized expression: \" + msg);\n            };\n\n            /**\n             * Document sorting and removing duplicates\n             * @param {ArrayLike} results\n             */\n            Sizzle.uniqueSort = function (results) {\n                var elem,\n                    duplicates = [],\n                    j = 0,\n                    i = 0;\n\n                // Unless we *know* we can detect duplicates, assume their presence\n                hasDuplicate = !support.detectDuplicates;\n                sortInput = !support.sortStable && results.slice(0);\n                results.sort(sortOrder);\n\n                if (hasDuplicate) {\n                    while ((elem = results[i++])) {\n                        if (elem === results[i]) {\n                            j = duplicates.push(i);\n                        }\n                    }\n                    while (j--) {\n                        results.splice(duplicates[j], 1);\n                    }\n                }\n\n                // Clear input after sorting to release objects\n                // See https://github.com/jquery/sizzle/pull/225\n                sortInput = null;\n\n                return results;\n            };\n\n            /**\n             * Utility function for retrieving the text value of an array of DOM nodes\n             * @param {Array|Element} elem\n             */\n            getText = Sizzle.getText = function (elem) {\n                var node,\n                    ret = \"\",\n                    i = 0,\n                    nodeType = elem.nodeType;\n\n                if (!nodeType) {\n                    // If no nodeType, this is expected to be an array\n                    while ((node = elem[i++])) {\n                        // Do not traverse comment nodes\n                        ret += getText(node);\n                    }\n                } else if (nodeType === 1 || nodeType === 9 || nodeType === 11) {\n                    // Use textContent for elements\n                    // innerText usage removed for consistency of new lines (jQuery #11153)\n                    if (typeof elem.textContent === \"string\") {\n                        return elem.textContent;\n                    } else {\n                        // Traverse its children\n                        for (elem = elem.firstChild; elem; elem = elem.nextSibling) {\n                            ret += getText(elem);\n                        }\n                    }\n                } else if (nodeType === 3 || nodeType === 4) {\n                    return elem.nodeValue;\n                }\n                // Do not include comment or processing instruction nodes\n\n                return ret;\n            };\n\n            Expr = Sizzle.selectors = {\n\n                // Can be adjusted by the user\n                cacheLength: 50,\n\n                createPseudo: markFunction,\n\n                match: matchExpr,\n\n                attrHandle: {},\n\n                find: {},\n\n                relative: {\n                    \">\": {dir: \"parentNode\", first: true},\n                    \" \": {dir: \"parentNode\"},\n                    \"+\": {dir: \"previousSibling\", first: true},\n                    \"~\": {dir: \"previousSibling\"}\n                },\n\n                preFilter: {\n                    \"ATTR\": function (match) {\n                        match[1] = match[1].replace(runescape, funescape);\n\n                        // Move the given value to match[3] whether quoted or unquoted\n                        match[3] = ( match[3] || match[4] || match[5] || \"\" ).replace(runescape, funescape);\n\n                        if (match[2] === \"~=\") {\n                            match[3] = \" \" + match[3] + \" \";\n                        }\n\n                        return match.slice(0, 4);\n                    },\n\n                    \"CHILD\": function (match) {\n                        /* matches from matchExpr[\"CHILD\"]\n                         1 type (only|nth|...)\n                         2 what (child|of-type)\n                         3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n                         4 xn-component of xn+y argument ([+-]?\\d*n|)\n                         5 sign of xn-component\n                         6 x of xn-component\n                         7 sign of y-component\n                         8 y of y-component\n                         */\n                        match[1] = match[1].toLowerCase();\n\n                        if (match[1].slice(0, 3) === \"nth\") {\n                            // nth-* requires argument\n                            if (!match[3]) {\n                                Sizzle.error(match[0]);\n                            }\n\n                            // numeric x and y parameters for Expr.filter.CHILD\n                            // remember that false/true cast respectively to 0/1\n                            match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === \"even\" || match[3] === \"odd\" ) );\n                            match[5] = +( ( match[7] + match[8] ) || match[3] === \"odd\" );\n\n                            // other types prohibit arguments\n                        } else if (match[3]) {\n                            Sizzle.error(match[0]);\n                        }\n\n                        return match;\n                    },\n\n                    \"PSEUDO\": function (match) {\n                        var excess,\n                            unquoted = !match[6] && match[2];\n\n                        if (matchExpr[\"CHILD\"].test(match[0])) {\n                            return null;\n                        }\n\n                        // Accept quoted arguments as-is\n                        if (match[3]) {\n                            match[2] = match[4] || match[5] || \"\";\n\n                            // Strip excess characters from unquoted arguments\n                        } else if (unquoted && rpseudo.test(unquoted) &&\n                            // Get excess from tokenize (recursively)\n                            (excess = tokenize(unquoted, true)) &&\n                            // advance to the next closing parenthesis\n                            (excess = unquoted.indexOf(\")\", unquoted.length - excess) - unquoted.length)) {\n\n                            // excess is a negative index\n                            match[0] = match[0].slice(0, excess);\n                            match[2] = unquoted.slice(0, excess);\n                        }\n\n                        // Return only captures needed by the pseudo filter method (type and argument)\n                        return match.slice(0, 3);\n                    }\n                },\n\n                filter: {\n\n                    \"TAG\": function (nodeNameSelector) {\n                        var nodeName = nodeNameSelector.replace(runescape, funescape).toLowerCase();\n                        return nodeNameSelector === \"*\" ?\n                            function () {\n                                return true;\n                            } :\n                            function (elem) {\n                                return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n                            };\n                    },\n\n                    \"CLASS\": function (className) {\n                        var pattern = classCache[className + \" \"];\n\n                        return pattern ||\n                            (pattern = new RegExp(\"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\")) &&\n                            classCache(className, function (elem) {\n                                return pattern.test(typeof elem.className === \"string\" && elem.className || typeof elem.getAttribute !== \"undefined\" && elem.getAttribute(\"class\") || \"\");\n                            });\n                    },\n\n                    \"ATTR\": function (name, operator, check) {\n                        return function (elem) {\n                            var result = Sizzle.attr(elem, name);\n\n                            if (result == null) {\n                                return operator === \"!=\";\n                            }\n                            if (!operator) {\n                                return true;\n                            }\n\n                            result += \"\";\n\n                            return operator === \"=\" ? result === check :\n                                operator === \"!=\" ? result !== check :\n                                    operator === \"^=\" ? check && result.indexOf(check) === 0 :\n                                        operator === \"*=\" ? check && result.indexOf(check) > -1 :\n                                            operator === \"$=\" ? check && result.slice(-check.length) === check :\n                                                operator === \"~=\" ? ( \" \" + result.replace(rwhitespace, \" \") + \" \" ).indexOf(check) > -1 :\n                                                    operator === \"|=\" ? result === check || result.slice(0, check.length + 1) === check + \"-\" :\n                                                        false;\n                        };\n                    },\n\n                    \"CHILD\": function (type, what, argument, first, last) {\n                        var simple = type.slice(0, 3) !== \"nth\",\n                            forward = type.slice(-4) !== \"last\",\n                            ofType = what === \"of-type\";\n\n                        return first === 1 && last === 0 ?\n\n                            // Shortcut for :nth-*(n)\n                            function (elem) {\n                                return !!elem.parentNode;\n                            } :\n\n                            function (elem, context, xml) {\n                                var cache, outerCache, node, diff, nodeIndex, start,\n                                    dir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n                                    parent = elem.parentNode,\n                                    name = ofType && elem.nodeName.toLowerCase(),\n                                    useCache = !xml && !ofType;\n\n                                if (parent) {\n\n                                    // :(first|last|only)-(child|of-type)\n                                    if (simple) {\n                                        while (dir) {\n                                            node = elem;\n                                            while ((node = node[dir])) {\n                                                if (ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) {\n                                                    return false;\n                                                }\n                                            }\n                                            // Reverse direction for :only-* (if we haven't yet done so)\n                                            start = dir = type === \"only\" && !start && \"nextSibling\";\n                                        }\n                                        return true;\n                                    }\n\n                                    start = [forward ? parent.firstChild : parent.lastChild];\n\n                                    // non-xml :nth-child(...) stores cache data on `parent`\n                                    if (forward && useCache) {\n                                        // Seek `elem` from a previously-cached index\n                                        outerCache = parent[expando] || (parent[expando] = {});\n                                        cache = outerCache[type] || [];\n                                        nodeIndex = cache[0] === dirruns && cache[1];\n                                        diff = cache[0] === dirruns && cache[2];\n                                        node = nodeIndex && parent.childNodes[nodeIndex];\n\n                                        while ((node = ++nodeIndex && node && node[dir] ||\n\n                                            // Fallback to seeking `elem` from the start\n                                            (diff = nodeIndex = 0) || start.pop())) {\n\n                                            // When found, cache indexes on `parent` and break\n                                            if (node.nodeType === 1 && ++diff && node === elem) {\n                                                outerCache[type] = [dirruns, nodeIndex, diff];\n                                                break;\n                                            }\n                                        }\n\n                                        // Use previously-cached element index if available\n                                    } else if (useCache && (cache = (elem[expando] || (elem[expando] = {}))[type]) && cache[0] === dirruns) {\n                                        diff = cache[1];\n\n                                        // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)\n                                    } else {\n                                        // Use the same loop as above to seek `elem` from the start\n                                        while ((node = ++nodeIndex && node && node[dir] ||\n                                            (diff = nodeIndex = 0) || start.pop())) {\n\n                                            if (( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff) {\n                                                // Cache the index of each encountered element\n                                                if (useCache) {\n                                                    (node[expando] || (node[expando] = {}))[type] = [dirruns, diff];\n                                                }\n\n                                                if (node === elem) {\n                                                    break;\n                                                }\n                                            }\n                                        }\n                                    }\n\n                                    // Incorporate the offset, then check against cycle size\n                                    diff -= last;\n                                    return diff === first || ( diff % first === 0 && diff / first >= 0 );\n                                }\n                            };\n                    },\n\n                    \"PSEUDO\": function (pseudo, argument) {\n                        // pseudo-class names are case-insensitive\n                        // http://www.w3.org/TR/selectors/#pseudo-classes\n                        // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n                        // Remember that setFilters inherits from pseudos\n                        var args,\n                            fn = Expr.pseudos[pseudo] || Expr.setFilters[pseudo.toLowerCase()] ||\n                                Sizzle.error(\"unsupported pseudo: \" + pseudo);\n\n                        // The user may use createPseudo to indicate that\n                        // arguments are needed to create the filter function\n                        // just as Sizzle does\n                        if (fn[expando]) {\n                            return fn(argument);\n                        }\n\n                        // But maintain support for old signatures\n                        if (fn.length > 1) {\n                            args = [pseudo, pseudo, \"\", argument];\n                            return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase()) ?\n                                markFunction(function (seed, matches) {\n                                    var idx,\n                                        matched = fn(seed, argument),\n                                        i = matched.length;\n                                    while (i--) {\n                                        idx = indexOf(seed, matched[i]);\n                                        seed[idx] = !( matches[idx] = matched[i] );\n                                    }\n                                }) :\n                                function (elem) {\n                                    return fn(elem, 0, args);\n                                };\n                        }\n\n                        return fn;\n                    }\n                },\n\n                pseudos: {\n                    // Potentially complex pseudos\n                    \"not\": markFunction(function (selector) {\n                        // Trim the selector passed to compile\n                        // to avoid treating leading and trailing\n                        // spaces as combinators\n                        var input = [],\n                            results = [],\n                            matcher = compile(selector.replace(rtrim, \"$1\"));\n\n                        return matcher[expando] ?\n                            markFunction(function (seed, matches, context, xml) {\n                                var elem,\n                                    unmatched = matcher(seed, null, xml, []),\n                                    i = seed.length;\n\n                                // Match elements unmatched by `matcher`\n                                while (i--) {\n                                    if ((elem = unmatched[i])) {\n                                        seed[i] = !(matches[i] = elem);\n                                    }\n                                }\n                            }) :\n                            function (elem, context, xml) {\n                                input[0] = elem;\n                                matcher(input, null, xml, results);\n                                // Don't keep the element (issue #299)\n                                input[0] = null;\n                                return !results.pop();\n                            };\n                    }),\n\n                    \"has\": markFunction(function (selector) {\n                        return function (elem) {\n                            return Sizzle(selector, elem).length > 0;\n                        };\n                    }),\n\n                    \"contains\": markFunction(function (text) {\n                        text = text.replace(runescape, funescape);\n                        return function (elem) {\n                            return ( elem.textContent || elem.innerText || getText(elem) ).indexOf(text) > -1;\n                        };\n                    }),\n\n                    // \"Whether an element is represented by a :lang() selector\n                    // is based solely on the element's language value\n                    // being equal to the identifier C,\n                    // or beginning with the identifier C immediately followed by \"-\".\n                    // The matching of C against the element's language value is performed case-insensitively.\n                    // The identifier C does not have to be a valid language name.\"\n                    // http://www.w3.org/TR/selectors/#lang-pseudo\n                    \"lang\": markFunction(function (lang) {\n                        // lang value must be a valid identifier\n                        if (!ridentifier.test(lang || \"\")) {\n                            Sizzle.error(\"unsupported lang: \" + lang);\n                        }\n                        lang = lang.replace(runescape, funescape).toLowerCase();\n                        return function (elem) {\n                            var elemLang;\n                            do {\n                                if ((elemLang = documentIsHTML ?\n                                        elem.lang :\n                                    elem.getAttribute(\"xml:lang\") || elem.getAttribute(\"lang\"))) {\n\n                                    elemLang = elemLang.toLowerCase();\n                                    return elemLang === lang || elemLang.indexOf(lang + \"-\") === 0;\n                                }\n                            } while ((elem = elem.parentNode) && elem.nodeType === 1);\n                            return false;\n                        };\n                    }),\n\n                    // Miscellaneous\n                    \"target\": function (elem) {\n                        var hash = window.location && window.location.hash;\n                        return hash && hash.slice(1) === elem.id;\n                    },\n\n                    \"root\": function (elem) {\n                        return elem === docElem;\n                    },\n\n                    \"focus\": function (elem) {\n                        return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n                    },\n\n                    // Boolean properties\n                    \"enabled\": function (elem) {\n                        return elem.disabled === false;\n                    },\n\n                    \"disabled\": function (elem) {\n                        return elem.disabled === true;\n                    },\n\n                    \"checked\": function (elem) {\n                        // In CSS3, :checked should return both checked and selected elements\n                        // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n                        var nodeName = elem.nodeName.toLowerCase();\n                        return (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\n                    },\n\n                    \"selected\": function (elem) {\n                        // Accessing this property makes selected-by-default\n                        // options in Safari work properly\n                        if (elem.parentNode) {\n                            elem.parentNode.selectedIndex;\n                        }\n\n                        return elem.selected === true;\n                    },\n\n                    // Contents\n                    \"empty\": function (elem) {\n                        // http://www.w3.org/TR/selectors/#empty-pseudo\n                        // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n                        //   but not by others (comment: 8; processing instruction: 7; etc.)\n                        // nodeType < 6 works because attributes (2) do not appear as children\n                        for (elem = elem.firstChild; elem; elem = elem.nextSibling) {\n                            if (elem.nodeType < 6) {\n                                return false;\n                            }\n                        }\n                        return true;\n                    },\n\n                    \"parent\": function (elem) {\n                        return !Expr.pseudos[\"empty\"](elem);\n                    },\n\n                    // Element/input types\n                    \"header\": function (elem) {\n                        return rheader.test(elem.nodeName);\n                    },\n\n                    \"input\": function (elem) {\n                        return rinputs.test(elem.nodeName);\n                    },\n\n                    \"button\": function (elem) {\n                        var name = elem.nodeName.toLowerCase();\n                        return name === \"input\" && elem.type === \"button\" || name === \"button\";\n                    },\n\n                    \"text\": function (elem) {\n                        var attr;\n                        return elem.nodeName.toLowerCase() === \"input\" &&\n                            elem.type === \"text\" &&\n\n                            // Support: IE<8\n                            // New HTML5 attribute values (e.g., \"search\") appear with elem.type === \"text\"\n                            ( (attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === \"text\" );\n                    },\n\n                    // Position-in-collection\n                    \"first\": createPositionalPseudo(function () {\n                        return [0];\n                    }),\n\n                    \"last\": createPositionalPseudo(function (matchIndexes, length) {\n                        return [length - 1];\n                    }),\n\n                    \"eq\": createPositionalPseudo(function (matchIndexes, length, argument) {\n                        return [argument < 0 ? argument + length : argument];\n                    }),\n\n                    \"even\": createPositionalPseudo(function (matchIndexes, length) {\n                        var i = 0;\n                        for (; i < length; i += 2) {\n                            matchIndexes.push(i);\n                        }\n                        return matchIndexes;\n                    }),\n\n                    \"odd\": createPositionalPseudo(function (matchIndexes, length) {\n                        var i = 1;\n                        for (; i < length; i += 2) {\n                            matchIndexes.push(i);\n                        }\n                        return matchIndexes;\n                    }),\n\n                    \"lt\": createPositionalPseudo(function (matchIndexes, length, argument) {\n                        var i = argument < 0 ? argument + length : argument;\n                        for (; --i >= 0;) {\n                            matchIndexes.push(i);\n                        }\n                        return matchIndexes;\n                    }),\n\n                    \"gt\": createPositionalPseudo(function (matchIndexes, length, argument) {\n                        var i = argument < 0 ? argument + length : argument;\n                        for (; ++i < length;) {\n                            matchIndexes.push(i);\n                        }\n                        return matchIndexes;\n                    })\n                }\n            };\n\n            Expr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\n\n// Add button/input type pseudos\n            for (i in {radio: true, checkbox: true, file: true, password: true, image: true}) {\n                Expr.pseudos[i] = createInputPseudo(i);\n            }\n            for (i in {submit: true, reset: true}) {\n                Expr.pseudos[i] = createButtonPseudo(i);\n            }\n\n// Easy API for creating new setFilters\n            function setFilters() {\n            }\n\n            setFilters.prototype = Expr.filters = Expr.pseudos;\n            Expr.setFilters = new setFilters();\n\n            tokenize = Sizzle.tokenize = function (selector, parseOnly) {\n                var matched, match, tokens, type,\n                    soFar, groups, preFilters,\n                    cached = tokenCache[selector + \" \"];\n\n                if (cached) {\n                    return parseOnly ? 0 : cached.slice(0);\n                }\n\n                soFar = selector;\n                groups = [];\n                preFilters = Expr.preFilter;\n\n                while (soFar) {\n\n                    // Comma and first run\n                    if (!matched || (match = rcomma.exec(soFar))) {\n                        if (match) {\n                            // Don't consume trailing commas as valid\n                            soFar = soFar.slice(match[0].length) || soFar;\n                        }\n                        groups.push((tokens = []));\n                    }\n\n                    matched = false;\n\n                    // Combinators\n                    if ((match = rcombinators.exec(soFar))) {\n                        matched = match.shift();\n                        tokens.push({\n                            value: matched,\n                            // Cast descendant combinators to space\n                            type: match[0].replace(rtrim, \" \")\n                        });\n                        soFar = soFar.slice(matched.length);\n                    }\n\n                    // Filters\n                    for (type in Expr.filter) {\n                        if ((match = matchExpr[type].exec(soFar)) && (!preFilters[type] ||\n                            (match = preFilters[type](match)))) {\n                            matched = match.shift();\n                            tokens.push({\n                                value: matched,\n                                type: type,\n                                matches: match\n                            });\n                            soFar = soFar.slice(matched.length);\n                        }\n                    }\n\n                    if (!matched) {\n                        break;\n                    }\n                }\n\n                // Return the length of the invalid excess\n                // if we're just parsing\n                // Otherwise, throw an error or return tokens\n                return parseOnly ?\n                    soFar.length :\n                    soFar ?\n                        Sizzle.error(selector) :\n                        // Cache the tokens\n                        tokenCache(selector, groups).slice(0);\n            };\n\n            function toSelector(tokens) {\n                var i = 0,\n                    len = tokens.length,\n                    selector = \"\";\n                for (; i < len; i++) {\n                    selector += tokens[i].value;\n                }\n                return selector;\n            }\n\n            function addCombinator(matcher, combinator, base) {\n                var dir = combinator.dir,\n                    checkNonElements = base && dir === \"parentNode\",\n                    doneName = done++;\n\n                return combinator.first ?\n                    // Check against closest ancestor/preceding element\n                    function (elem, context, xml) {\n                        while ((elem = elem[dir])) {\n                            if (elem.nodeType === 1 || checkNonElements) {\n                                return matcher(elem, context, xml);\n                            }\n                        }\n                    } :\n\n                    // Check against all ancestor/preceding elements\n                    function (elem, context, xml) {\n                        var oldCache, outerCache,\n                            newCache = [dirruns, doneName];\n\n                        // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching\n                        if (xml) {\n                            while ((elem = elem[dir])) {\n                                if (elem.nodeType === 1 || checkNonElements) {\n                                    if (matcher(elem, context, xml)) {\n                                        return true;\n                                    }\n                                }\n                            }\n                        } else {\n                            while ((elem = elem[dir])) {\n                                if (elem.nodeType === 1 || checkNonElements) {\n                                    outerCache = elem[expando] || (elem[expando] = {});\n                                    if ((oldCache = outerCache[dir]) &&\n                                        oldCache[0] === dirruns && oldCache[1] === doneName) {\n\n                                        // Assign to newCache so results back-propagate to previous elements\n                                        return (newCache[2] = oldCache[2]);\n                                    } else {\n                                        // Reuse newcache so results back-propagate to previous elements\n                                        outerCache[dir] = newCache;\n\n                                        // A match means we're done; a fail means we have to keep checking\n                                        if ((newCache[2] = matcher(elem, context, xml))) {\n                                            return true;\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    };\n            }\n\n            function elementMatcher(matchers) {\n                return matchers.length > 1 ?\n                    function (elem, context, xml) {\n                        var i = matchers.length;\n                        while (i--) {\n                            if (!matchers[i](elem, context, xml)) {\n                                return false;\n                            }\n                        }\n                        return true;\n                    } :\n                    matchers[0];\n            }\n\n            function multipleContexts(selector, contexts, results) {\n                var i = 0,\n                    len = contexts.length;\n                for (; i < len; i++) {\n                    Sizzle(selector, contexts[i], results);\n                }\n                return results;\n            }\n\n            function condense(unmatched, map, filter, context, xml) {\n                var elem,\n                    newUnmatched = [],\n                    i = 0,\n                    len = unmatched.length,\n                    mapped = map != null;\n\n                for (; i < len; i++) {\n                    if ((elem = unmatched[i])) {\n                        if (!filter || filter(elem, context, xml)) {\n                            newUnmatched.push(elem);\n                            if (mapped) {\n                                map.push(i);\n                            }\n                        }\n                    }\n                }\n\n                return newUnmatched;\n            }\n\n            function setMatcher(preFilter, selector, matcher, postFilter, postFinder, postSelector) {\n                if (postFilter && !postFilter[expando]) {\n                    postFilter = setMatcher(postFilter);\n                }\n                if (postFinder && !postFinder[expando]) {\n                    postFinder = setMatcher(postFinder, postSelector);\n                }\n                return markFunction(function (seed, results, context, xml) {\n                    var temp, i, elem,\n                        preMap = [],\n                        postMap = [],\n                        preexisting = results.length,\n\n                    // Get initial elements from seed or context\n                        elems = seed || multipleContexts(selector || \"*\", context.nodeType ? [context] : context, []),\n\n                    // Prefilter to get matcher input, preserving a map for seed-results synchronization\n                        matcherIn = preFilter && ( seed || !selector ) ?\n                            condense(elems, preMap, preFilter, context, xml) :\n                            elems,\n\n                        matcherOut = matcher ?\n                            // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n                            postFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n                                // ...intermediate processing is necessary\n                                [] :\n\n                                // ...otherwise use results directly\n                                results :\n                            matcherIn;\n\n                    // Find primary matches\n                    if (matcher) {\n                        matcher(matcherIn, matcherOut, context, xml);\n                    }\n\n                    // Apply postFilter\n                    if (postFilter) {\n                        temp = condense(matcherOut, postMap);\n                        postFilter(temp, [], context, xml);\n\n                        // Un-match failing elements by moving them back to matcherIn\n                        i = temp.length;\n                        while (i--) {\n                            if ((elem = temp[i])) {\n                                matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem);\n                            }\n                        }\n                    }\n\n                    if (seed) {\n                        if (postFinder || preFilter) {\n                            if (postFinder) {\n                                // Get the final matcherOut by condensing this intermediate into postFinder contexts\n                                temp = [];\n                                i = matcherOut.length;\n                                while (i--) {\n                                    if ((elem = matcherOut[i])) {\n                                        // Restore matcherIn since elem is not yet a final match\n                                        temp.push((matcherIn[i] = elem));\n                                    }\n                                }\n                                postFinder(null, (matcherOut = []), temp, xml);\n                            }\n\n                            // Move matched elements from seed to results to keep them synchronized\n                            i = matcherOut.length;\n                            while (i--) {\n                                if ((elem = matcherOut[i]) &&\n                                    (temp = postFinder ? indexOf(seed, elem) : preMap[i]) > -1) {\n\n                                    seed[temp] = !(results[temp] = elem);\n                                }\n                            }\n                        }\n\n                        // Add elements to results, through postFinder if defined\n                    } else {\n                        matcherOut = condense(\n                            matcherOut === results ?\n                                matcherOut.splice(preexisting, matcherOut.length) :\n                                matcherOut\n                        );\n                        if (postFinder) {\n                            postFinder(null, results, matcherOut, xml);\n                        } else {\n                            push.apply(results, matcherOut);\n                        }\n                    }\n                });\n            }\n\n            function matcherFromTokens(tokens) {\n                var checkContext, matcher, j,\n                    len = tokens.length,\n                    leadingRelative = Expr.relative[tokens[0].type],\n                    implicitRelative = leadingRelative || Expr.relative[\" \"],\n                    i = leadingRelative ? 1 : 0,\n\n                // The foundational matcher ensures that elements are reachable from top-level context(s)\n                    matchContext = addCombinator(function (elem) {\n                        return elem === checkContext;\n                    }, implicitRelative, true),\n                    matchAnyContext = addCombinator(function (elem) {\n                        return indexOf(checkContext, elem) > -1;\n                    }, implicitRelative, true),\n                    matchers = [function (elem, context, xml) {\n                        var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n                                (checkContext = context).nodeType ?\n                                    matchContext(elem, context, xml) :\n                                    matchAnyContext(elem, context, xml) );\n                        // Avoid hanging onto element (issue #299)\n                        checkContext = null;\n                        return ret;\n                    }];\n\n                for (; i < len; i++) {\n                    if ((matcher = Expr.relative[tokens[i].type])) {\n                        matchers = [addCombinator(elementMatcher(matchers), matcher)];\n                    } else {\n                        matcher = Expr.filter[tokens[i].type].apply(null, tokens[i].matches);\n\n                        // Return special upon seeing a positional matcher\n                        if (matcher[expando]) {\n                            // Find the next relative operator (if any) for proper handling\n                            j = ++i;\n                            for (; j < len; j++) {\n                                if (Expr.relative[tokens[j].type]) {\n                                    break;\n                                }\n                            }\n                            return setMatcher(\n                                i > 1 && elementMatcher(matchers),\n                                i > 1 && toSelector(\n                                    // If the preceding token was a descendant combinator, insert an implicit any-element `*`\n                                    tokens.slice(0, i - 1).concat({value: tokens[i - 2].type === \" \" ? \"*\" : \"\"})\n                                ).replace(rtrim, \"$1\"),\n                                matcher,\n                                i < j && matcherFromTokens(tokens.slice(i, j)),\n                                j < len && matcherFromTokens((tokens = tokens.slice(j))),\n                                j < len && toSelector(tokens)\n                            );\n                        }\n                        matchers.push(matcher);\n                    }\n                }\n\n                return elementMatcher(matchers);\n            }\n\n            function matcherFromGroupMatchers(elementMatchers, setMatchers) {\n                var bySet = setMatchers.length > 0,\n                    byElement = elementMatchers.length > 0,\n                    superMatcher = function (seed, context, xml, results, outermost) {\n                        var elem, j, matcher,\n                            matchedCount = 0,\n                            i = \"0\",\n                            unmatched = seed && [],\n                            setMatched = [],\n                            contextBackup = outermostContext,\n                        // We must always have either seed elements or outermost context\n                            elems = seed || byElement && Expr.find[\"TAG\"](\"*\", outermost),\n                        // Use integer dirruns iff this is the outermost matcher\n                            dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),\n                            len = elems.length;\n\n                        if (outermost) {\n                            outermostContext = context !== document && context;\n                        }\n\n                        // Add elements passing elementMatchers directly to results\n                        // Keep `i` a string if there are no elements so `matchedCount` will be \"00\" below\n                        // Support: IE<9, Safari\n                        // Tolerate NodeList properties (IE: \"length\"; Safari: <number>) matching elements by id\n                        for (; i !== len && (elem = elems[i]) != null; i++) {\n                            if (byElement && elem) {\n                                j = 0;\n                                while ((matcher = elementMatchers[j++])) {\n                                    if (matcher(elem, context, xml)) {\n                                        results.push(elem);\n                                        break;\n                                    }\n                                }\n                                if (outermost) {\n                                    dirruns = dirrunsUnique;\n                                }\n                            }\n\n                            // Track unmatched elements for set filters\n                            if (bySet) {\n                                // They will have gone through all possible matchers\n                                if ((elem = !matcher && elem)) {\n                                    matchedCount--;\n                                }\n\n                                // Lengthen the array for every element, matched or not\n                                if (seed) {\n                                    unmatched.push(elem);\n                                }\n                            }\n                        }\n\n                        // Apply set filters to unmatched elements\n                        matchedCount += i;\n                        if (bySet && i !== matchedCount) {\n                            j = 0;\n                            while ((matcher = setMatchers[j++])) {\n                                matcher(unmatched, setMatched, context, xml);\n                            }\n\n                            if (seed) {\n                                // Reintegrate element matches to eliminate the need for sorting\n                                if (matchedCount > 0) {\n                                    while (i--) {\n                                        if (!(unmatched[i] || setMatched[i])) {\n                                            setMatched[i] = pop.call(results);\n                                        }\n                                    }\n                                }\n\n                                // Discard index placeholder values to get only actual matches\n                                setMatched = condense(setMatched);\n                            }\n\n                            // Add matches to results\n                            push.apply(results, setMatched);\n\n                            // Seedless set matches succeeding multiple successful matchers stipulate sorting\n                            if (outermost && !seed && setMatched.length > 0 &&\n                                ( matchedCount + setMatchers.length ) > 1) {\n\n                                Sizzle.uniqueSort(results);\n                            }\n                        }\n\n                        // Override manipulation of globals by nested matchers\n                        if (outermost) {\n                            dirruns = dirrunsUnique;\n                            outermostContext = contextBackup;\n                        }\n\n                        return unmatched;\n                    };\n\n                return bySet ?\n                    markFunction(superMatcher) :\n                    superMatcher;\n            }\n\n            compile = Sizzle.compile = function (selector, match /* Internal Use Only */) {\n                var i,\n                    setMatchers = [],\n                    elementMatchers = [],\n                    cached = compilerCache[selector + \" \"];\n\n                if (!cached) {\n                    // Generate a function of recursive functions that can be used to check each element\n                    if (!match) {\n                        match = tokenize(selector);\n                    }\n                    i = match.length;\n                    while (i--) {\n                        cached = matcherFromTokens(match[i]);\n                        if (cached[expando]) {\n                            setMatchers.push(cached);\n                        } else {\n                            elementMatchers.push(cached);\n                        }\n                    }\n\n                    // Cache the compiled function\n                    cached = compilerCache(selector, matcherFromGroupMatchers(elementMatchers, setMatchers));\n\n                    // Save selector and tokenization\n                    cached.selector = selector;\n                }\n                return cached;\n            };\n\n            /**\n             * A low-level selection function that works with Sizzle's compiled\n             *  selector functions\n             * @param {String|Function} selector A selector or a pre-compiled\n             *  selector function built with Sizzle.compile\n             * @param {Element} context\n             * @param {Array} [results]\n             * @param {Array} [seed] A set of elements to match against\n             */\n            select = Sizzle.select = function (selector, context, results, seed) {\n                var i, tokens, token, type, find,\n                    compiled = typeof selector === \"function\" && selector,\n                    match = !seed && tokenize((selector = compiled.selector || selector));\n\n                results = results || [];\n\n                // Try to minimize operations if there is no seed and only one group\n                if (match.length === 1) {\n\n                    // Take a shortcut and set the context if the root selector is an ID\n                    tokens = match[0] = match[0].slice(0);\n                    if (tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\n                        support.getById && context.nodeType === 9 && documentIsHTML &&\n                        Expr.relative[tokens[1].type]) {\n\n                        context = ( Expr.find[\"ID\"](token.matches[0].replace(runescape, funescape), context) || [] )[0];\n                        if (!context) {\n                            return results;\n\n                            // Precompiled matchers will still verify ancestry, so step up a level\n                        } else if (compiled) {\n                            context = context.parentNode;\n                        }\n\n                        selector = selector.slice(tokens.shift().value.length);\n                    }\n\n                    // Fetch a seed set for right-to-left matching\n                    i = matchExpr[\"needsContext\"].test(selector) ? 0 : tokens.length;\n                    while (i--) {\n                        token = tokens[i];\n\n                        // Abort if we hit a combinator\n                        if (Expr.relative[(type = token.type)]) {\n                            break;\n                        }\n                        if ((find = Expr.find[type])) {\n                            // Search, expanding context for leading sibling combinators\n                            if ((seed = find(\n                                    token.matches[0].replace(runescape, funescape),\n                                    rsibling.test(tokens[0].type) && testContext(context.parentNode) || context\n                                ))) {\n\n                                // If seed is empty or no tokens remain, we can return early\n                                tokens.splice(i, 1);\n                                selector = seed.length && toSelector(tokens);\n                                if (!selector) {\n                                    push.apply(results, seed);\n                                    return results;\n                                }\n\n                                break;\n                            }\n                        }\n                    }\n                }\n\n                // Compile and execute a filtering function if one is not provided\n                // Provide `match` to avoid retokenization if we modified the selector above\n                ( compiled || compile(selector, match) )(\n                    seed,\n                    context,\n                    !documentIsHTML,\n                    results,\n                    rsibling.test(selector) && testContext(context.parentNode) || context\n                );\n                return results;\n            };\n\n// One-time assignments\n\n// Sort stability\n            support.sortStable = expando.split(\"\").sort(sortOrder).join(\"\") === expando;\n\n// Support: Chrome 14-35+\n// Always assume duplicates if they aren't passed to the comparison function\n            support.detectDuplicates = !!hasDuplicate;\n\n// Initialize against the default document\n            setDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\n            support.sortDetached = assert(function (div1) {\n                // Should return 1, but returns 4 (following)\n                return div1.compareDocumentPosition(document.createElement(\"div\")) & 1;\n            });\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\n            if (!assert(function (div) {\n                    div.innerHTML = \"<a href='#'></a>\";\n                    return div.firstChild.getAttribute(\"href\") === \"#\";\n                })) {\n                addHandle(\"type|href|height|width\", function (elem, name, isXML) {\n                    if (!isXML) {\n                        return elem.getAttribute(name, name.toLowerCase() === \"type\" ? 1 : 2);\n                    }\n                });\n            }\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\n            if (!support.attributes || !assert(function (div) {\n                    div.innerHTML = \"<input/>\";\n                    div.firstChild.setAttribute(\"value\", \"\");\n                    return div.firstChild.getAttribute(\"value\") === \"\";\n                })) {\n                addHandle(\"value\", function (elem, name, isXML) {\n                    if (!isXML && elem.nodeName.toLowerCase() === \"input\") {\n                        return elem.defaultValue;\n                    }\n                });\n            }\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\n            if (!assert(function (div) {\n                    return div.getAttribute(\"disabled\") == null;\n                })) {\n                addHandle(booleans, function (elem, name, isXML) {\n                    var val;\n                    if (!isXML) {\n                        return elem[name] === true ? name.toLowerCase() :\n                            (val = elem.getAttributeNode(name)) && val.specified ?\n                                val.value :\n                                null;\n                    }\n                });\n            }\n\n            return Sizzle;\n\n        })(window);\n\n\n    jQuery.find = Sizzle;\n    jQuery.expr = Sizzle.selectors;\n    jQuery.expr[\":\"] = jQuery.expr.pseudos;\n    jQuery.unique = Sizzle.uniqueSort;\n    jQuery.text = Sizzle.getText;\n    jQuery.isXMLDoc = Sizzle.isXML;\n    jQuery.contains = Sizzle.contains;\n\n\n    var rneedsContext = jQuery.expr.match.needsContext;\n\n    var rsingleTag = (/^<(\\w+)\\s*\\/?>(?:<\\/\\1>|)$/);\n\n\n    var risSimple = /^.[^:#\\[\\.,]*$/;\n\n// Implement the identical functionality for filter and not\n    function winnow(elements, qualifier, not) {\n        if (jQuery.isFunction(qualifier)) {\n            return jQuery.grep(elements, function (elem, i) {\n                /* jshint -W018 */\n                return !!qualifier.call(elem, i, elem) !== not;\n            });\n\n        }\n\n        if (qualifier.nodeType) {\n            return jQuery.grep(elements, function (elem) {\n                return ( elem === qualifier ) !== not;\n            });\n\n        }\n\n        if (typeof qualifier === \"string\") {\n            if (risSimple.test(qualifier)) {\n                return jQuery.filter(qualifier, elements, not);\n            }\n\n            qualifier = jQuery.filter(qualifier, elements);\n        }\n\n        return jQuery.grep(elements, function (elem) {\n            return ( indexOf.call(qualifier, elem) >= 0 ) !== not;\n        });\n    }\n\n    jQuery.filter = function (expr, elems, not) {\n        var elem = elems[0];\n\n        if (not) {\n            expr = \":not(\" + expr + \")\";\n        }\n\n        return elems.length === 1 && elem.nodeType === 1 ?\n            jQuery.find.matchesSelector(elem, expr) ? [elem] : [] :\n            jQuery.find.matches(expr, jQuery.grep(elems, function (elem) {\n                return elem.nodeType === 1;\n            }));\n    };\n\n    jQuery.fn.extend({\n        find: function (selector) {\n            var i,\n                len = this.length,\n                ret = [],\n                self = this;\n\n            if (typeof selector !== \"string\") {\n                return this.pushStack(jQuery(selector).filter(function () {\n                    for (i = 0; i < len; i++) {\n                        if (jQuery.contains(self[i], this)) {\n                            return true;\n                        }\n                    }\n                }));\n            }\n\n            for (i = 0; i < len; i++) {\n                jQuery.find(selector, self[i], ret);\n            }\n\n            // Needed because $( selector, context ) becomes $( context ).find( selector )\n            ret = this.pushStack(len > 1 ? jQuery.unique(ret) : ret);\n            ret.selector = this.selector ? this.selector + \" \" + selector : selector;\n            return ret;\n        },\n        filter: function (selector) {\n            return this.pushStack(winnow(this, selector || [], false));\n        },\n        not: function (selector) {\n            return this.pushStack(winnow(this, selector || [], true));\n        },\n        is: function (selector) {\n            return !!winnow(\n                this,\n\n                // If this is a positional/relative selector, check membership in the returned set\n                // so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n                typeof selector === \"string\" && rneedsContext.test(selector) ?\n                    jQuery(selector) :\n                selector || [],\n                false\n            ).length;\n        }\n    });\n\n\n// Initialize a jQuery object\n\n\n// A central reference to the root jQuery(document)\n    var rootjQuery,\n\n    // A simple way to check for HTML strings\n    // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n    // Strict HTML recognition (#11290: must start with <)\n        rquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]*))$/,\n\n        init = jQuery.fn.init = function (selector, context) {\n            var match, elem;\n\n            // HANDLE: $(\"\"), $(null), $(undefined), $(false)\n            if (!selector) {\n                return this;\n            }\n\n            // Handle HTML strings\n            if (typeof selector === \"string\") {\n                if (selector[0] === \"<\" && selector[selector.length - 1] === \">\" && selector.length >= 3) {\n                    // Assume that strings that start and end with <> are HTML and skip the regex check\n                    match = [null, selector, null];\n\n                } else {\n                    match = rquickExpr.exec(selector);\n                }\n\n                // Match html or make sure no context is specified for #id\n                if (match && (match[1] || !context)) {\n\n                    // HANDLE: $(html) -> $(array)\n                    if (match[1]) {\n                        context = context instanceof jQuery ? context[0] : context;\n\n                        // Option to run scripts is true for back-compat\n                        // Intentionally let the error be thrown if parseHTML is not present\n                        jQuery.merge(this, jQuery.parseHTML(\n                            match[1],\n                            context && context.nodeType ? context.ownerDocument || context : document,\n                            true\n                        ));\n\n                        // HANDLE: $(html, props)\n                        if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {\n                            for (match in context) {\n                                // Properties of context are called as methods if possible\n                                if (jQuery.isFunction(this[match])) {\n                                    this[match](context[match]);\n\n                                    // ...and otherwise set as attributes\n                                } else {\n                                    this.attr(match, context[match]);\n                                }\n                            }\n                        }\n\n                        return this;\n\n                        // HANDLE: $(#id)\n                    } else {\n                        elem = document.getElementById(match[2]);\n\n                        // Support: Blackberry 4.6\n                        // gEBID returns nodes no longer in the document (#6963)\n                        if (elem && elem.parentNode) {\n                            // Inject the element directly into the jQuery object\n                            this.length = 1;\n                            this[0] = elem;\n                        }\n\n                        this.context = document;\n                        this.selector = selector;\n                        return this;\n                    }\n\n                    // HANDLE: $(expr, $(...))\n                } else if (!context || context.jquery) {\n                    return ( context || rootjQuery ).find(selector);\n\n                    // HANDLE: $(expr, context)\n                    // (which is just equivalent to: $(context).find(expr)\n                } else {\n                    return this.constructor(context).find(selector);\n                }\n\n                // HANDLE: $(DOMElement)\n            } else if (selector.nodeType) {\n                this.context = this[0] = selector;\n                this.length = 1;\n                return this;\n\n                // HANDLE: $(function)\n                // Shortcut for document ready\n            } else if (jQuery.isFunction(selector)) {\n                return typeof rootjQuery.ready !== \"undefined\" ?\n                    rootjQuery.ready(selector) :\n                    // Execute immediately if ready is not present\n                    selector(jQuery);\n            }\n\n            if (selector.selector !== undefined) {\n                this.selector = selector.selector;\n                this.context = selector.context;\n            }\n\n            return jQuery.makeArray(selector, this);\n        };\n\n// Give the init function the jQuery prototype for later instantiation\n    init.prototype = jQuery.fn;\n\n// Initialize central reference\n    rootjQuery = jQuery(document);\n\n\n    var rparentsprev = /^(?:parents|prev(?:Until|All))/,\n    // Methods guaranteed to produce a unique set when starting from a unique set\n        guaranteedUnique = {\n            children: true,\n            contents: true,\n            next: true,\n            prev: true\n        };\n\n    jQuery.extend({\n        dir: function (elem, dir, until) {\n            var matched = [],\n                truncate = until !== undefined;\n\n            while ((elem = elem[dir]) && elem.nodeType !== 9) {\n                if (elem.nodeType === 1) {\n                    if (truncate && jQuery(elem).is(until)) {\n                        break;\n                    }\n                    matched.push(elem);\n                }\n            }\n            return matched;\n        },\n\n        sibling: function (n, elem) {\n            var matched = [];\n\n            for (; n; n = n.nextSibling) {\n                if (n.nodeType === 1 && n !== elem) {\n                    matched.push(n);\n                }\n            }\n\n            return matched;\n        }\n    });\n\n    jQuery.fn.extend({\n        has: function (target) {\n            var targets = jQuery(target, this),\n                l = targets.length;\n\n            return this.filter(function () {\n                var i = 0;\n                for (; i < l; i++) {\n                    if (jQuery.contains(this, targets[i])) {\n                        return true;\n                    }\n                }\n            });\n        },\n\n        closest: function (selectors, context) {\n            var cur,\n                i = 0,\n                l = this.length,\n                matched = [],\n                pos = rneedsContext.test(selectors) || typeof selectors !== \"string\" ?\n                    jQuery(selectors, context || this.context) :\n                    0;\n\n            for (; i < l; i++) {\n                for (cur = this[i]; cur && cur !== context; cur = cur.parentNode) {\n                    // Always skip document fragments\n                    if (cur.nodeType < 11 && (pos ?\n                        pos.index(cur) > -1 :\n\n                            // Don't pass non-elements to Sizzle\n                        cur.nodeType === 1 &&\n                        jQuery.find.matchesSelector(cur, selectors))) {\n\n                        matched.push(cur);\n                        break;\n                    }\n                }\n            }\n\n            return this.pushStack(matched.length > 1 ? jQuery.unique(matched) : matched);\n        },\n\n        // Determine the position of an element within the set\n        index: function (elem) {\n\n            // No argument, return index in parent\n            if (!elem) {\n                return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;\n            }\n\n            // Index in selector\n            if (typeof elem === \"string\") {\n                return indexOf.call(jQuery(elem), this[0]);\n            }\n\n            // Locate the position of the desired element\n            return indexOf.call(this,\n\n                // If it receives a jQuery object, the first element is used\n                elem.jquery ? elem[0] : elem\n            );\n        },\n\n        add: function (selector, context) {\n            return this.pushStack(\n                jQuery.unique(\n                    jQuery.merge(this.get(), jQuery(selector, context))\n                )\n            );\n        },\n\n        addBack: function (selector) {\n            return this.add(selector == null ?\n                this.prevObject : this.prevObject.filter(selector)\n            );\n        }\n    });\n\n    function sibling(cur, dir) {\n        while ((cur = cur[dir]) && cur.nodeType !== 1) {\n        }\n        return cur;\n    }\n\n    jQuery.each({\n        parent: function (elem) {\n            var parent = elem.parentNode;\n            return parent && parent.nodeType !== 11 ? parent : null;\n        },\n        parents: function (elem) {\n            return jQuery.dir(elem, \"parentNode\");\n        },\n        parentsUntil: function (elem, i, until) {\n            return jQuery.dir(elem, \"parentNode\", until);\n        },\n        next: function (elem) {\n            return sibling(elem, \"nextSibling\");\n        },\n        prev: function (elem) {\n            return sibling(elem, \"previousSibling\");\n        },\n        nextAll: function (elem) {\n            return jQuery.dir(elem, \"nextSibling\");\n        },\n        prevAll: function (elem) {\n            return jQuery.dir(elem, \"previousSibling\");\n        },\n        nextUntil: function (elem, i, until) {\n            return jQuery.dir(elem, \"nextSibling\", until);\n        },\n        prevUntil: function (elem, i, until) {\n            return jQuery.dir(elem, \"previousSibling\", until);\n        },\n        siblings: function (elem) {\n            return jQuery.sibling(( elem.parentNode || {} ).firstChild, elem);\n        },\n        children: function (elem) {\n            return jQuery.sibling(elem.firstChild);\n        },\n        contents: function (elem) {\n            return elem.contentDocument || jQuery.merge([], elem.childNodes);\n        }\n    }, function (name, fn) {\n        jQuery.fn[name] = function (until, selector) {\n            var matched = jQuery.map(this, fn, until);\n\n            if (name.slice(-5) !== \"Until\") {\n                selector = until;\n            }\n\n            if (selector && typeof selector === \"string\") {\n                matched = jQuery.filter(selector, matched);\n            }\n\n            if (this.length > 1) {\n                // Remove duplicates\n                if (!guaranteedUnique[name]) {\n                    jQuery.unique(matched);\n                }\n\n                // Reverse order for parents* and prev-derivatives\n                if (rparentsprev.test(name)) {\n                    matched.reverse();\n                }\n            }\n\n            return this.pushStack(matched);\n        };\n    });\n    var rnotwhite = (/\\S+/g);\n\n\n// String to Object options format cache\n    var optionsCache = {};\n\n// Convert String-formatted options into Object-formatted ones and store in cache\n    function createOptions(options) {\n        var object = optionsCache[options] = {};\n        jQuery.each(options.match(rnotwhite) || [], function (_, flag) {\n            object[flag] = true;\n        });\n        return object;\n    }\n\n    /*\n     * Create a callback list using the following parameters:\n     *\n     *\toptions: an optional list of space-separated options that will change how\n     *\t\t\tthe callback list behaves or a more traditional option object\n     *\n     * By default a callback list will act like an event callback list and can be\n     * \"fired\" multiple times.\n     *\n     * Possible options:\n     *\n     *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n     *\n     *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n     *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n     *\t\t\t\t\tvalues (like a Deferred)\n     *\n     *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n     *\n     *\tstopOnFalse:\tinterrupt callings when a callback returns false\n     *\n     */\n    jQuery.Callbacks = function (options) {\n\n        // Convert options from String-formatted to Object-formatted if needed\n        // (we check in cache first)\n        options = typeof options === \"string\" ?\n            ( optionsCache[options] || createOptions(options) ) :\n            jQuery.extend({}, options);\n\n        var // Last fire value (for non-forgettable lists)\n            memory,\n        // Flag to know if list was already fired\n            fired,\n        // Flag to know if list is currently firing\n            firing,\n        // First callback to fire (used internally by add and fireWith)\n            firingStart,\n        // End of the loop when firing\n            firingLength,\n        // Index of currently firing callback (modified by remove if needed)\n            firingIndex,\n        // Actual callback list\n            list = [],\n        // Stack of fire calls for repeatable lists\n            stack = !options.once && [],\n        // Fire callbacks\n            fire = function (data) {\n                memory = options.memory && data;\n                fired = true;\n                firingIndex = firingStart || 0;\n                firingStart = 0;\n                firingLength = list.length;\n                firing = true;\n                for (; list && firingIndex < firingLength; firingIndex++) {\n                    if (list[firingIndex].apply(data[0], data[1]) === false && options.stopOnFalse) {\n                        memory = false; // To prevent further calls using add\n                        break;\n                    }\n                }\n                firing = false;\n                if (list) {\n                    if (stack) {\n                        if (stack.length) {\n                            fire(stack.shift());\n                        }\n                    } else if (memory) {\n                        list = [];\n                    } else {\n                        self.disable();\n                    }\n                }\n            },\n        // Actual Callbacks object\n            self = {\n                // Add a callback or a collection of callbacks to the list\n                add: function () {\n                    if (list) {\n                        // First, we save the current length\n                        var start = list.length;\n                        (function add(args) {\n                            jQuery.each(args, function (_, arg) {\n                                var type = jQuery.type(arg);\n                                if (type === \"function\") {\n                                    if (!options.unique || !self.has(arg)) {\n                                        list.push(arg);\n                                    }\n                                } else if (arg && arg.length && type !== \"string\") {\n                                    // Inspect recursively\n                                    add(arg);\n                                }\n                            });\n                        })(arguments);\n                        // Do we need to add the callbacks to the\n                        // current firing batch?\n                        if (firing) {\n                            firingLength = list.length;\n                            // With memory, if we're not firing then\n                            // we should call right away\n                        } else if (memory) {\n                            firingStart = start;\n                            fire(memory);\n                        }\n                    }\n                    return this;\n                },\n                // Remove a callback from the list\n                remove: function () {\n                    if (list) {\n                        jQuery.each(arguments, function (_, arg) {\n                            var index;\n                            while (( index = jQuery.inArray(arg, list, index) ) > -1) {\n                                list.splice(index, 1);\n                                // Handle firing indexes\n                                if (firing) {\n                                    if (index <= firingLength) {\n                                        firingLength--;\n                                    }\n                                    if (index <= firingIndex) {\n                                        firingIndex--;\n                                    }\n                                }\n                            }\n                        });\n                    }\n                    return this;\n                },\n                // Check if a given callback is in the list.\n                // If no argument is given, return whether or not list has callbacks attached.\n                has: function (fn) {\n                    return fn ? jQuery.inArray(fn, list) > -1 : !!( list && list.length );\n                },\n                // Remove all callbacks from the list\n                empty: function () {\n                    list = [];\n                    firingLength = 0;\n                    return this;\n                },\n                // Have the list do nothing anymore\n                disable: function () {\n                    list = stack = memory = undefined;\n                    return this;\n                },\n                // Is it disabled?\n                disabled: function () {\n                    return !list;\n                },\n                // Lock the list in its current state\n                lock: function () {\n                    stack = undefined;\n                    if (!memory) {\n                        self.disable();\n                    }\n                    return this;\n                },\n                // Is it locked?\n                locked: function () {\n                    return !stack;\n                },\n                // Call all callbacks with the given context and arguments\n                fireWith: function (context, args) {\n                    if (list && ( !fired || stack )) {\n                        args = args || [];\n                        args = [context, args.slice ? args.slice() : args];\n                        if (firing) {\n                            stack.push(args);\n                        } else {\n                            fire(args);\n                        }\n                    }\n                    return this;\n                },\n                // Call all the callbacks with the given arguments\n                fire: function () {\n                    self.fireWith(this, arguments);\n                    return this;\n                },\n                // To know if the callbacks have already been called at least once\n                fired: function () {\n                    return !!fired;\n                }\n            };\n\n        return self;\n    };\n\n\n    jQuery.extend({\n\n        Deferred: function (func) {\n            var tuples = [\n                    // action, add listener, listener list, final state\n                    [\"resolve\", \"done\", jQuery.Callbacks(\"once memory\"), \"resolved\"],\n                    [\"reject\", \"fail\", jQuery.Callbacks(\"once memory\"), \"rejected\"],\n                    [\"notify\", \"progress\", jQuery.Callbacks(\"memory\")]\n                ],\n                state = \"pending\",\n                promise = {\n                    state: function () {\n                        return state;\n                    },\n                    always: function () {\n                        deferred.done(arguments).fail(arguments);\n                        return this;\n                    },\n                    then: function (/* fnDone, fnFail, fnProgress */) {\n                        var fns = arguments;\n                        return jQuery.Deferred(function (newDefer) {\n                            jQuery.each(tuples, function (i, tuple) {\n                                var fn = jQuery.isFunction(fns[i]) && fns[i];\n                                // deferred[ done | fail | progress ] for forwarding actions to newDefer\n                                deferred[tuple[1]](function () {\n                                    var returned = fn && fn.apply(this, arguments);\n                                    if (returned && jQuery.isFunction(returned.promise)) {\n                                        returned.promise()\n                                            .done(newDefer.resolve)\n                                            .fail(newDefer.reject)\n                                            .progress(newDefer.notify);\n                                    } else {\n                                        newDefer[tuple[0] + \"With\"](this === promise ? newDefer.promise() : this, fn ? [returned] : arguments);\n                                    }\n                                });\n                            });\n                            fns = null;\n                        }).promise();\n                    },\n                    // Get a promise for this deferred\n                    // If obj is provided, the promise aspect is added to the object\n                    promise: function (obj) {\n                        return obj != null ? jQuery.extend(obj, promise) : promise;\n                    }\n                },\n                deferred = {};\n\n            // Keep pipe for back-compat\n            promise.pipe = promise.then;\n\n            // Add list-specific methods\n            jQuery.each(tuples, function (i, tuple) {\n                var list = tuple[2],\n                    stateString = tuple[3];\n\n                // promise[ done | fail | progress ] = list.add\n                promise[tuple[1]] = list.add;\n\n                // Handle state\n                if (stateString) {\n                    list.add(function () {\n                        // state = [ resolved | rejected ]\n                        state = stateString;\n\n                        // [ reject_list | resolve_list ].disable; progress_list.lock\n                    }, tuples[i ^ 1][2].disable, tuples[2][2].lock);\n                }\n\n                // deferred[ resolve | reject | notify ]\n                deferred[tuple[0]] = function () {\n                    deferred[tuple[0] + \"With\"](this === deferred ? promise : this, arguments);\n                    return this;\n                };\n                deferred[tuple[0] + \"With\"] = list.fireWith;\n            });\n\n            // Make the deferred a promise\n            promise.promise(deferred);\n\n            // Call given func if any\n            if (func) {\n                func.call(deferred, deferred);\n            }\n\n            // All done!\n            return deferred;\n        },\n\n        // Deferred helper\n        when: function (subordinate /* , ..., subordinateN */) {\n            var i = 0,\n                resolveValues = slice.call(arguments),\n                length = resolveValues.length,\n\n            // the count of uncompleted subordinates\n                remaining = length !== 1 || ( subordinate && jQuery.isFunction(subordinate.promise) ) ? length : 0,\n\n            // the master Deferred. If resolveValues consist of only a single Deferred, just use that.\n                deferred = remaining === 1 ? subordinate : jQuery.Deferred(),\n\n            // Update function for both resolve and progress values\n                updateFunc = function (i, contexts, values) {\n                    return function (value) {\n                        contexts[i] = this;\n                        values[i] = arguments.length > 1 ? slice.call(arguments) : value;\n                        if (values === progressValues) {\n                            deferred.notifyWith(contexts, values);\n                        } else if (!( --remaining )) {\n                            deferred.resolveWith(contexts, values);\n                        }\n                    };\n                },\n\n                progressValues, progressContexts, resolveContexts;\n\n            // Add listeners to Deferred subordinates; treat others as resolved\n            if (length > 1) {\n                progressValues = new Array(length);\n                progressContexts = new Array(length);\n                resolveContexts = new Array(length);\n                for (; i < length; i++) {\n                    if (resolveValues[i] && jQuery.isFunction(resolveValues[i].promise)) {\n                        resolveValues[i].promise()\n                            .done(updateFunc(i, resolveContexts, resolveValues))\n                            .fail(deferred.reject)\n                            .progress(updateFunc(i, progressContexts, progressValues));\n                    } else {\n                        --remaining;\n                    }\n                }\n            }\n\n            // If we're not waiting on anything, resolve the master\n            if (!remaining) {\n                deferred.resolveWith(resolveContexts, resolveValues);\n            }\n\n            return deferred.promise();\n        }\n    });\n\n\n// The deferred used on DOM ready\n    var readyList;\n\n    jQuery.fn.ready = function (fn) {\n        // Add the callback\n        jQuery.ready.promise().done(fn);\n\n        return this;\n    };\n\n    jQuery.extend({\n        // Is the DOM ready to be used? Set to true once it occurs.\n        isReady: false,\n\n        // A counter to track how many items to wait for before\n        // the ready event fires. See #6781\n        readyWait: 1,\n\n        // Hold (or release) the ready event\n        holdReady: function (hold) {\n            if (hold) {\n                jQuery.readyWait++;\n            } else {\n                jQuery.ready(true);\n            }\n        },\n\n        // Handle when the DOM is ready\n        ready: function (wait) {\n\n            // Abort if there are pending holds or we're already ready\n            if (wait === true ? --jQuery.readyWait : jQuery.isReady) {\n                return;\n            }\n\n            // Remember that the DOM is ready\n            jQuery.isReady = true;\n\n            // If a normal DOM Ready event fired, decrement, and wait if need be\n            if (wait !== true && --jQuery.readyWait > 0) {\n                return;\n            }\n\n            // If there are functions bound, to execute\n            readyList.resolveWith(document, [jQuery]);\n\n            // Trigger any bound ready events\n            if (jQuery.fn.triggerHandler) {\n                jQuery(document).triggerHandler(\"ready\");\n                jQuery(document).off(\"ready\");\n            }\n        }\n    });\n\n    /**\n     * The ready event handler and self cleanup method\n     */\n    function completed() {\n        document.removeEventListener(\"DOMContentLoaded\", completed, false);\n        window.removeEventListener(\"load\", completed, false);\n        jQuery.ready();\n    }\n\n    jQuery.ready.promise = function (obj) {\n        if (!readyList) {\n\n            readyList = jQuery.Deferred();\n\n            // Catch cases where $(document).ready() is called after the browser event has already occurred.\n            // We once tried to use readyState \"interactive\" here, but it caused issues like the one\n            // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15\n            if (document.readyState === \"complete\") {\n                // Handle it asynchronously to allow scripts the opportunity to delay ready\n                setTimeout(jQuery.ready);\n\n            } else {\n\n                // Use the handy event callback\n                document.addEventListener(\"DOMContentLoaded\", completed, false);\n\n                // A fallback to window.onload, that will always work\n                window.addEventListener(\"load\", completed, false);\n            }\n        }\n        return readyList.promise(obj);\n    };\n\n// Kick off the DOM ready check even if the user does not\n    jQuery.ready.promise();\n\n\n// Multifunctional method to get and set values of a collection\n// The value/s can optionally be executed if it's a function\n    var access = jQuery.access = function (elems, fn, key, value, chainable, emptyGet, raw) {\n        var i = 0,\n            len = elems.length,\n            bulk = key == null;\n\n        // Sets many values\n        if (jQuery.type(key) === \"object\") {\n            chainable = true;\n            for (i in key) {\n                jQuery.access(elems, fn, i, key[i], true, emptyGet, raw);\n            }\n\n            // Sets one value\n        } else if (value !== undefined) {\n            chainable = true;\n\n            if (!jQuery.isFunction(value)) {\n                raw = true;\n            }\n\n            if (bulk) {\n                // Bulk operations run against the entire set\n                if (raw) {\n                    fn.call(elems, value);\n                    fn = null;\n\n                    // ...except when executing function values\n                } else {\n                    bulk = fn;\n                    fn = function (elem, key, value) {\n                        return bulk.call(jQuery(elem), value);\n                    };\n                }\n            }\n\n            if (fn) {\n                for (; i < len; i++) {\n                    fn(elems[i], key, raw ? value : value.call(elems[i], i, fn(elems[i], key)));\n                }\n            }\n        }\n\n        return chainable ?\n            elems :\n\n            // Gets\n            bulk ?\n                fn.call(elems) :\n                len ? fn(elems[0], key) : emptyGet;\n    };\n\n\n    /**\n     * Determines whether an object can have data\n     */\n    jQuery.acceptData = function (owner) {\n        // Accepts only:\n        //  - Node\n        //    - Node.ELEMENT_NODE\n        //    - Node.DOCUMENT_NODE\n        //  - Object\n        //    - Any\n        /* jshint -W018 */\n        return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );\n    };\n\n\n    function Data() {\n        // Support: Android<4,\n        // Old WebKit does not have Object.preventExtensions/freeze method,\n        // return new empty object instead with no [[set]] accessor\n        Object.defineProperty(this.cache = {}, 0, {\n            get: function () {\n                return {};\n            }\n        });\n\n        this.expando = jQuery.expando + Data.uid++;\n    }\n\n    Data.uid = 1;\n    Data.accepts = jQuery.acceptData;\n\n    Data.prototype = {\n        key: function (owner) {\n            // We can accept data for non-element nodes in modern browsers,\n            // but we should not, see #8335.\n            // Always return the key for a frozen object.\n            if (!Data.accepts(owner)) {\n                return 0;\n            }\n\n            var descriptor = {},\n            // Check if the owner object already has a cache key\n                unlock = owner[this.expando];\n\n            // If not, create one\n            if (!unlock) {\n                unlock = Data.uid++;\n\n                // Secure it in a non-enumerable, non-writable property\n                try {\n                    descriptor[this.expando] = {value: unlock};\n                    Object.defineProperties(owner, descriptor);\n\n                    // Support: Android<4\n                    // Fallback to a less secure definition\n                } catch (e) {\n                    descriptor[this.expando] = unlock;\n                    jQuery.extend(owner, descriptor);\n                }\n            }\n\n            // Ensure the cache object\n            if (!this.cache[unlock]) {\n                this.cache[unlock] = {};\n            }\n\n            return unlock;\n        },\n        set: function (owner, data, value) {\n            var prop,\n            // There may be an unlock assigned to this node,\n            // if there is no entry for this \"owner\", create one inline\n            // and set the unlock as though an owner entry had always existed\n                unlock = this.key(owner),\n                cache = this.cache[unlock];\n\n            // Handle: [ owner, key, value ] args\n            if (typeof data === \"string\") {\n                cache[data] = value;\n\n                // Handle: [ owner, { properties } ] args\n            } else {\n                // Fresh assignments by object are shallow copied\n                if (jQuery.isEmptyObject(cache)) {\n                    jQuery.extend(this.cache[unlock], data);\n                    // Otherwise, copy the properties one-by-one to the cache object\n                } else {\n                    for (prop in data) {\n                        cache[prop] = data[prop];\n                    }\n                }\n            }\n            return cache;\n        },\n        get: function (owner, key) {\n            // Either a valid cache is found, or will be created.\n            // New caches will be created and the unlock returned,\n            // allowing direct access to the newly created\n            // empty data object. A valid owner object must be provided.\n            var cache = this.cache[this.key(owner)];\n\n            return key === undefined ?\n                cache : cache[key];\n        },\n        access: function (owner, key, value) {\n            var stored;\n            // In cases where either:\n            //\n            //   1. No key was specified\n            //   2. A string key was specified, but no value provided\n            //\n            // Take the \"read\" path and allow the get method to determine\n            // which value to return, respectively either:\n            //\n            //   1. The entire cache object\n            //   2. The data stored at the key\n            //\n            if (key === undefined ||\n                ((key && typeof key === \"string\") && value === undefined)) {\n\n                stored = this.get(owner, key);\n\n                return stored !== undefined ?\n                    stored : this.get(owner, jQuery.camelCase(key));\n            }\n\n            // [*]When the key is not a string, or both a key and value\n            // are specified, set or extend (existing objects) with either:\n            //\n            //   1. An object of properties\n            //   2. A key and value\n            //\n            this.set(owner, key, value);\n\n            // Since the \"set\" path can have two possible entry points\n            // return the expected data based on which path was taken[*]\n            return value !== undefined ? value : key;\n        },\n        remove: function (owner, key) {\n            var i, name, camel,\n                unlock = this.key(owner),\n                cache = this.cache[unlock];\n\n            if (key === undefined) {\n                this.cache[unlock] = {};\n\n            } else {\n                // Support array or space separated string of keys\n                if (jQuery.isArray(key)) {\n                    // If \"name\" is an array of keys...\n                    // When data is initially created, via (\"key\", \"val\") signature,\n                    // keys will be converted to camelCase.\n                    // Since there is no way to tell _how_ a key was added, remove\n                    // both plain key and camelCase key. #12786\n                    // This will only penalize the array argument path.\n                    name = key.concat(key.map(jQuery.camelCase));\n                } else {\n                    camel = jQuery.camelCase(key);\n                    // Try the string as a key before any manipulation\n                    if (key in cache) {\n                        name = [key, camel];\n                    } else {\n                        // If a key with the spaces exists, use it.\n                        // Otherwise, create an array by matching non-whitespace\n                        name = camel;\n                        name = name in cache ?\n                            [name] : ( name.match(rnotwhite) || [] );\n                    }\n                }\n\n                i = name.length;\n                while (i--) {\n                    delete cache[name[i]];\n                }\n            }\n        },\n        hasData: function (owner) {\n            return !jQuery.isEmptyObject(\n                this.cache[owner[this.expando]] || {}\n            );\n        },\n        discard: function (owner) {\n            if (owner[this.expando]) {\n                delete this.cache[owner[this.expando]];\n            }\n        }\n    };\n    var data_priv = new Data();\n\n    var data_user = new Data();\n\n\n//\tImplementation Summary\n//\n//\t1. Enforce API surface and semantic compatibility with 1.9.x branch\n//\t2. Improve the module's maintainability by reducing the storage\n//\t\tpaths to a single mechanism.\n//\t3. Use the same single mechanism to support \"private\" and \"user\" data.\n//\t4. _Never_ expose \"private\" data to user code (TODO: Drop _data, _removeData)\n//\t5. Avoid exposing implementation details on user objects (eg. expando properties)\n//\t6. Provide a clear path for implementation upgrade to WeakMap in 2014\n\n    var rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n        rmultiDash = /([A-Z])/g;\n\n    function dataAttr(elem, key, data) {\n        var name;\n\n        // If nothing was found internally, try to fetch any\n        // data from the HTML5 data-* attribute\n        if (data === undefined && elem.nodeType === 1) {\n            name = \"data-\" + key.replace(rmultiDash, \"-$1\").toLowerCase();\n            data = elem.getAttribute(name);\n\n            if (typeof data === \"string\") {\n                try {\n                    data = data === \"true\" ? true :\n                        data === \"false\" ? false :\n                            data === \"null\" ? null :\n                                // Only convert to a number if it doesn't change the string\n                                +data + \"\" === data ? +data :\n                                    rbrace.test(data) ? jQuery.parseJSON(data) :\n                                        data;\n                } catch (e) {\n                }\n\n                // Make sure we set the data so it isn't changed later\n                data_user.set(elem, key, data);\n            } else {\n                data = undefined;\n            }\n        }\n        return data;\n    }\n\n    jQuery.extend({\n        hasData: function (elem) {\n            return data_user.hasData(elem) || data_priv.hasData(elem);\n        },\n\n        data: function (elem, name, data) {\n            return data_user.access(elem, name, data);\n        },\n\n        removeData: function (elem, name) {\n            data_user.remove(elem, name);\n        },\n\n        // TODO: Now that all calls to _data and _removeData have been replaced\n        // with direct calls to data_priv methods, these can be deprecated.\n        _data: function (elem, name, data) {\n            return data_priv.access(elem, name, data);\n        },\n\n        _removeData: function (elem, name) {\n            data_priv.remove(elem, name);\n        }\n    });\n\n    jQuery.fn.extend({\n        data: function (key, value) {\n            var i, name, data,\n                elem = this[0],\n                attrs = elem && elem.attributes;\n\n            // Gets all values\n            if (key === undefined) {\n                if (this.length) {\n                    data = data_user.get(elem);\n\n                    if (elem.nodeType === 1 && !data_priv.get(elem, \"hasDataAttrs\")) {\n                        i = attrs.length;\n                        while (i--) {\n\n                            // Support: IE11+\n                            // The attrs elements can be null (#14894)\n                            if (attrs[i]) {\n                                name = attrs[i].name;\n                                if (name.indexOf(\"data-\") === 0) {\n                                    name = jQuery.camelCase(name.slice(5));\n                                    dataAttr(elem, name, data[name]);\n                                }\n                            }\n                        }\n                        data_priv.set(elem, \"hasDataAttrs\", true);\n                    }\n                }\n\n                return data;\n            }\n\n            // Sets multiple values\n            if (typeof key === \"object\") {\n                return this.each(function () {\n                    data_user.set(this, key);\n                });\n            }\n\n            return access(this, function (value) {\n                var data,\n                    camelKey = jQuery.camelCase(key);\n\n                // The calling jQuery object (element matches) is not empty\n                // (and therefore has an element appears at this[ 0 ]) and the\n                // `value` parameter was not undefined. An empty jQuery object\n                // will result in `undefined` for elem = this[ 0 ] which will\n                // throw an exception if an attempt to read a data cache is made.\n                if (elem && value === undefined) {\n                    // Attempt to get data from the cache\n                    // with the key as-is\n                    data = data_user.get(elem, key);\n                    if (data !== undefined) {\n                        return data;\n                    }\n\n                    // Attempt to get data from the cache\n                    // with the key camelized\n                    data = data_user.get(elem, camelKey);\n                    if (data !== undefined) {\n                        return data;\n                    }\n\n                    // Attempt to \"discover\" the data in\n                    // HTML5 custom data-* attrs\n                    data = dataAttr(elem, camelKey, undefined);\n                    if (data !== undefined) {\n                        return data;\n                    }\n\n                    // We tried really hard, but the data doesn't exist.\n                    return;\n                }\n\n                // Set the data...\n                this.each(function () {\n                    // First, attempt to store a copy or reference of any\n                    // data that might've been store with a camelCased key.\n                    var data = data_user.get(this, camelKey);\n\n                    // For HTML5 data-* attribute interop, we have to\n                    // store property names with dashes in a camelCase form.\n                    // This might not apply to all properties...*\n                    data_user.set(this, camelKey, value);\n\n                    // *... In the case of properties that might _actually_\n                    // have dashes, we need to also store a copy of that\n                    // unchanged property.\n                    if (key.indexOf(\"-\") !== -1 && data !== undefined) {\n                        data_user.set(this, key, value);\n                    }\n                });\n            }, null, value, arguments.length > 1, null, true);\n        },\n\n        removeData: function (key) {\n            return this.each(function () {\n                data_user.remove(this, key);\n            });\n        }\n    });\n\n\n    jQuery.extend({\n        queue: function (elem, type, data) {\n            var queue;\n\n            if (elem) {\n                type = ( type || \"fx\" ) + \"queue\";\n                queue = data_priv.get(elem, type);\n\n                // Speed up dequeue by getting out quickly if this is just a lookup\n                if (data) {\n                    if (!queue || jQuery.isArray(data)) {\n                        queue = data_priv.access(elem, type, jQuery.makeArray(data));\n                    } else {\n                        queue.push(data);\n                    }\n                }\n                return queue || [];\n            }\n        },\n\n        dequeue: function (elem, type) {\n            type = type || \"fx\";\n\n            var queue = jQuery.queue(elem, type),\n                startLength = queue.length,\n                fn = queue.shift(),\n                hooks = jQuery._queueHooks(elem, type),\n                next = function () {\n                    jQuery.dequeue(elem, type);\n                };\n\n            // If the fx queue is dequeued, always remove the progress sentinel\n            if (fn === \"inprogress\") {\n                fn = queue.shift();\n                startLength--;\n            }\n\n            if (fn) {\n\n                // Add a progress sentinel to prevent the fx queue from being\n                // automatically dequeued\n                if (type === \"fx\") {\n                    queue.unshift(\"inprogress\");\n                }\n\n                // Clear up the last queue stop function\n                delete hooks.stop;\n                fn.call(elem, next, hooks);\n            }\n\n            if (!startLength && hooks) {\n                hooks.empty.fire();\n            }\n        },\n\n        // Not public - generate a queueHooks object, or return the current one\n        _queueHooks: function (elem, type) {\n            var key = type + \"queueHooks\";\n            return data_priv.get(elem, key) || data_priv.access(elem, key, {\n                    empty: jQuery.Callbacks(\"once memory\").add(function () {\n                        data_priv.remove(elem, [type + \"queue\", key]);\n                    })\n                });\n        }\n    });\n\n    jQuery.fn.extend({\n        queue: function (type, data) {\n            var setter = 2;\n\n            if (typeof type !== \"string\") {\n                data = type;\n                type = \"fx\";\n                setter--;\n            }\n\n            if (arguments.length < setter) {\n                return jQuery.queue(this[0], type);\n            }\n\n            return data === undefined ?\n                this :\n                this.each(function () {\n                    var queue = jQuery.queue(this, type, data);\n\n                    // Ensure a hooks for this queue\n                    jQuery._queueHooks(this, type);\n\n                    if (type === \"fx\" && queue[0] !== \"inprogress\") {\n                        jQuery.dequeue(this, type);\n                    }\n                });\n        },\n        dequeue: function (type) {\n            return this.each(function () {\n                jQuery.dequeue(this, type);\n            });\n        },\n        clearQueue: function (type) {\n            return this.queue(type || \"fx\", []);\n        },\n        // Get a promise resolved when queues of a certain type\n        // are emptied (fx is the type by default)\n        promise: function (type, obj) {\n            var tmp,\n                count = 1,\n                defer = jQuery.Deferred(),\n                elements = this,\n                i = this.length,\n                resolve = function () {\n                    if (!( --count )) {\n                        defer.resolveWith(elements, [elements]);\n                    }\n                };\n\n            if (typeof type !== \"string\") {\n                obj = type;\n                type = undefined;\n            }\n            type = type || \"fx\";\n\n            while (i--) {\n                tmp = data_priv.get(elements[i], type + \"queueHooks\");\n                if (tmp && tmp.empty) {\n                    count++;\n                    tmp.empty.add(resolve);\n                }\n            }\n            resolve();\n            return defer.promise(obj);\n        }\n    });\n    var pnum = (/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/).source;\n\n    var cssExpand = [\"Top\", \"Right\", \"Bottom\", \"Left\"];\n\n    var isHidden = function (elem, el) {\n        // isHidden might be called from jQuery#filter function;\n        // in that case, element will be second argument\n        elem = el || elem;\n        return jQuery.css(elem, \"display\") === \"none\" || !jQuery.contains(elem.ownerDocument, elem);\n    };\n\n    var rcheckableType = (/^(?:checkbox|radio)$/i);\n\n\n    (function () {\n        var fragment = document.createDocumentFragment(),\n            div = fragment.appendChild(document.createElement(\"div\")),\n            input = document.createElement(\"input\");\n\n        // Support: Safari<=5.1\n        // Check state lost if the name is set (#11217)\n        // Support: Windows Web Apps (WWA)\n        // `name` and `type` must use .setAttribute for WWA (#14901)\n        input.setAttribute(\"type\", \"radio\");\n        input.setAttribute(\"checked\", \"checked\");\n        input.setAttribute(\"name\", \"t\");\n\n        div.appendChild(input);\n\n        // Support: Safari<=5.1, Android<4.2\n        // Older WebKit doesn't clone checked state correctly in fragments\n        support.checkClone = div.cloneNode(true).cloneNode(true).lastChild.checked;\n\n        // Support: IE<=11+\n        // Make sure textarea (and checkbox) defaultValue is properly cloned\n        div.innerHTML = \"<textarea>x</textarea>\";\n        support.noCloneChecked = !!div.cloneNode(true).lastChild.defaultValue;\n    })();\n    var strundefined = typeof undefined;\n\n\n    support.focusinBubbles = \"onfocusin\" in window;\n\n\n    var\n        rkeyEvent = /^key/,\n        rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,\n        rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n        rtypenamespace = /^([^.]*)(?:\\.(.+)|)$/;\n\n    function returnTrue() {\n        return true;\n    }\n\n    function returnFalse() {\n        return false;\n    }\n\n    function safeActiveElement() {\n        try {\n            return document.activeElement;\n        } catch (err) {\n        }\n    }\n\n    /*\n     * Helper functions for managing events -- not part of the public interface.\n     * Props to Dean Edwards' addEvent library for many of the ideas.\n     */\n    jQuery.event = {\n\n        global: {},\n\n        add: function (elem, types, handler, data, selector) {\n\n            var handleObjIn, eventHandle, tmp,\n                events, t, handleObj,\n                special, handlers, type, namespaces, origType,\n                elemData = data_priv.get(elem);\n\n            // Don't attach events to noData or text/comment nodes (but allow plain objects)\n            if (!elemData) {\n                return;\n            }\n\n            // Caller can pass in an object of custom data in lieu of the handler\n            if (handler.handler) {\n                handleObjIn = handler;\n                handler = handleObjIn.handler;\n                selector = handleObjIn.selector;\n            }\n\n            // Make sure that the handler has a unique ID, used to find/remove it later\n            if (!handler.guid) {\n                handler.guid = jQuery.guid++;\n            }\n\n            // Init the element's event structure and main handler, if this is the first\n            if (!(events = elemData.events)) {\n                events = elemData.events = {};\n            }\n            if (!(eventHandle = elemData.handle)) {\n                eventHandle = elemData.handle = function (e) {\n                    // Discard the second event of a jQuery.event.trigger() and\n                    // when an event is called after a page has unloaded\n                    return typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ?\n                        jQuery.event.dispatch.apply(elem, arguments) : undefined;\n                };\n            }\n\n            // Handle multiple events separated by a space\n            types = ( types || \"\" ).match(rnotwhite) || [\"\"];\n            t = types.length;\n            while (t--) {\n                tmp = rtypenamespace.exec(types[t]) || [];\n                type = origType = tmp[1];\n                namespaces = ( tmp[2] || \"\" ).split(\".\").sort();\n\n                // There *must* be a type, no attaching namespace-only handlers\n                if (!type) {\n                    continue;\n                }\n\n                // If event changes its type, use the special event handlers for the changed type\n                special = jQuery.event.special[type] || {};\n\n                // If selector defined, determine special event api type, otherwise given type\n                type = ( selector ? special.delegateType : special.bindType ) || type;\n\n                // Update special based on newly reset type\n                special = jQuery.event.special[type] || {};\n\n                // handleObj is passed to all event handlers\n                handleObj = jQuery.extend({\n                    type: type,\n                    origType: origType,\n                    data: data,\n                    handler: handler,\n                    guid: handler.guid,\n                    selector: selector,\n                    needsContext: selector && jQuery.expr.match.needsContext.test(selector),\n                    namespace: namespaces.join(\".\")\n                }, handleObjIn);\n\n                // Init the event handler queue if we're the first\n                if (!(handlers = events[type])) {\n                    handlers = events[type] = [];\n                    handlers.delegateCount = 0;\n\n                    // Only use addEventListener if the special events handler returns false\n                    if (!special.setup || special.setup.call(elem, data, namespaces, eventHandle) === false) {\n                        if (elem.addEventListener) {\n                            elem.addEventListener(type, eventHandle, false);\n                        }\n                    }\n                }\n\n                if (special.add) {\n                    special.add.call(elem, handleObj);\n\n                    if (!handleObj.handler.guid) {\n                        handleObj.handler.guid = handler.guid;\n                    }\n                }\n\n                // Add to the element's handler list, delegates in front\n                if (selector) {\n                    handlers.splice(handlers.delegateCount++, 0, handleObj);\n                } else {\n                    handlers.push(handleObj);\n                }\n\n                // Keep track of which events have ever been used, for event optimization\n                jQuery.event.global[type] = true;\n            }\n\n        },\n\n        // Detach an event or set of events from an element\n        remove: function (elem, types, handler, selector, mappedTypes) {\n\n            var j, origCount, tmp,\n                events, t, handleObj,\n                special, handlers, type, namespaces, origType,\n                elemData = data_priv.hasData(elem) && data_priv.get(elem);\n\n            if (!elemData || !(events = elemData.events)) {\n                return;\n            }\n\n            // Once for each type.namespace in types; type may be omitted\n            types = ( types || \"\" ).match(rnotwhite) || [\"\"];\n            t = types.length;\n            while (t--) {\n                tmp = rtypenamespace.exec(types[t]) || [];\n                type = origType = tmp[1];\n                namespaces = ( tmp[2] || \"\" ).split(\".\").sort();\n\n                // Unbind all events (on this namespace, if provided) for the element\n                if (!type) {\n                    for (type in events) {\n                        jQuery.event.remove(elem, type + types[t], handler, selector, true);\n                    }\n                    continue;\n                }\n\n                special = jQuery.event.special[type] || {};\n                type = ( selector ? special.delegateType : special.bindType ) || type;\n                handlers = events[type] || [];\n                tmp = tmp[2] && new RegExp(\"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\");\n\n                // Remove matching events\n                origCount = j = handlers.length;\n                while (j--) {\n                    handleObj = handlers[j];\n\n                    if (( mappedTypes || origType === handleObj.origType ) &&\n                        ( !handler || handler.guid === handleObj.guid ) &&\n                        ( !tmp || tmp.test(handleObj.namespace) ) &&\n                        ( !selector || selector === handleObj.selector || selector === \"**\" && handleObj.selector )) {\n                        handlers.splice(j, 1);\n\n                        if (handleObj.selector) {\n                            handlers.delegateCount--;\n                        }\n                        if (special.remove) {\n                            special.remove.call(elem, handleObj);\n                        }\n                    }\n                }\n\n                // Remove generic event handler if we removed something and no more handlers exist\n                // (avoids potential for endless recursion during removal of special event handlers)\n                if (origCount && !handlers.length) {\n                    if (!special.teardown || special.teardown.call(elem, namespaces, elemData.handle) === false) {\n                        jQuery.removeEvent(elem, type, elemData.handle);\n                    }\n\n                    delete events[type];\n                }\n            }\n\n            // Remove the expando if it's no longer used\n            if (jQuery.isEmptyObject(events)) {\n                delete elemData.handle;\n                data_priv.remove(elem, \"events\");\n            }\n        },\n\n        trigger: function (event, data, elem, onlyHandlers) {\n\n            var i, cur, tmp, bubbleType, ontype, handle, special,\n                eventPath = [elem || document],\n                type = hasOwn.call(event, \"type\") ? event.type : event,\n                namespaces = hasOwn.call(event, \"namespace\") ? event.namespace.split(\".\") : [];\n\n            cur = tmp = elem = elem || document;\n\n            // Don't do events on text and comment nodes\n            if (elem.nodeType === 3 || elem.nodeType === 8) {\n                return;\n            }\n\n            // focus/blur morphs to focusin/out; ensure we're not firing them right now\n            if (rfocusMorph.test(type + jQuery.event.triggered)) {\n                return;\n            }\n\n            if (type.indexOf(\".\") >= 0) {\n                // Namespaced trigger; create a regexp to match event type in handle()\n                namespaces = type.split(\".\");\n                type = namespaces.shift();\n                namespaces.sort();\n            }\n            ontype = type.indexOf(\":\") < 0 && \"on\" + type;\n\n            // Caller can pass in a jQuery.Event object, Object, or just an event type string\n            event = event[jQuery.expando] ?\n                event :\n                new jQuery.Event(type, typeof event === \"object\" && event);\n\n            // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n            event.isTrigger = onlyHandlers ? 2 : 3;\n            event.namespace = namespaces.join(\".\");\n            event.namespace_re = event.namespace ?\n                new RegExp(\"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\") :\n                null;\n\n            // Clean up the event in case it is being reused\n            event.result = undefined;\n            if (!event.target) {\n                event.target = elem;\n            }\n\n            // Clone any incoming data and prepend the event, creating the handler arg list\n            data = data == null ?\n                [event] :\n                jQuery.makeArray(data, [event]);\n\n            // Allow special events to draw outside the lines\n            special = jQuery.event.special[type] || {};\n            if (!onlyHandlers && special.trigger && special.trigger.apply(elem, data) === false) {\n                return;\n            }\n\n            // Determine event propagation path in advance, per W3C events spec (#9951)\n            // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n            if (!onlyHandlers && !special.noBubble && !jQuery.isWindow(elem)) {\n\n                bubbleType = special.delegateType || type;\n                if (!rfocusMorph.test(bubbleType + type)) {\n                    cur = cur.parentNode;\n                }\n                for (; cur; cur = cur.parentNode) {\n                    eventPath.push(cur);\n                    tmp = cur;\n                }\n\n                // Only add window if we got to document (e.g., not plain obj or detached DOM)\n                if (tmp === (elem.ownerDocument || document)) {\n                    eventPath.push(tmp.defaultView || tmp.parentWindow || window);\n                }\n            }\n\n            // Fire handlers on the event path\n            i = 0;\n            while ((cur = eventPath[i++]) && !event.isPropagationStopped()) {\n\n                event.type = i > 1 ?\n                    bubbleType :\n                special.bindType || type;\n\n                // jQuery handler\n                handle = ( data_priv.get(cur, \"events\") || {} )[event.type] && data_priv.get(cur, \"handle\");\n                if (handle) {\n                    handle.apply(cur, data);\n                }\n\n                // Native handler\n                handle = ontype && cur[ontype];\n                if (handle && handle.apply && jQuery.acceptData(cur)) {\n                    event.result = handle.apply(cur, data);\n                    if (event.result === false) {\n                        event.preventDefault();\n                    }\n                }\n            }\n            event.type = type;\n\n            // If nobody prevented the default action, do it now\n            if (!onlyHandlers && !event.isDefaultPrevented()) {\n\n                if ((!special._default || special._default.apply(eventPath.pop(), data) === false) &&\n                    jQuery.acceptData(elem)) {\n\n                    // Call a native DOM method on the target with the same name name as the event.\n                    // Don't do default actions on window, that's where global variables be (#6170)\n                    if (ontype && jQuery.isFunction(elem[type]) && !jQuery.isWindow(elem)) {\n\n                        // Don't re-trigger an onFOO event when we call its FOO() method\n                        tmp = elem[ontype];\n\n                        if (tmp) {\n                            elem[ontype] = null;\n                        }\n\n                        // Prevent re-triggering of the same event, since we already bubbled it above\n                        jQuery.event.triggered = type;\n                        elem[type]();\n                        jQuery.event.triggered = undefined;\n\n                        if (tmp) {\n                            elem[ontype] = tmp;\n                        }\n                    }\n                }\n            }\n\n            return event.result;\n        },\n\n        dispatch: function (event) {\n\n            // Make a writable jQuery.Event from the native event object\n            event = jQuery.event.fix(event);\n\n            var i, j, ret, matched, handleObj,\n                handlerQueue = [],\n                args = slice.call(arguments),\n                handlers = ( data_priv.get(this, \"events\") || {} )[event.type] || [],\n                special = jQuery.event.special[event.type] || {};\n\n            // Use the fix-ed jQuery.Event rather than the (read-only) native event\n            args[0] = event;\n            event.delegateTarget = this;\n\n            // Call the preDispatch hook for the mapped type, and let it bail if desired\n            if (special.preDispatch && special.preDispatch.call(this, event) === false) {\n                return;\n            }\n\n            // Determine handlers\n            handlerQueue = jQuery.event.handlers.call(this, event, handlers);\n\n            // Run delegates first; they may want to stop propagation beneath us\n            i = 0;\n            while ((matched = handlerQueue[i++]) && !event.isPropagationStopped()) {\n                event.currentTarget = matched.elem;\n\n                j = 0;\n                while ((handleObj = matched.handlers[j++]) && !event.isImmediatePropagationStopped()) {\n\n                    // Triggered event must either 1) have no namespace, or 2) have namespace(s)\n                    // a subset or equal to those in the bound event (both can have no namespace).\n                    if (!event.namespace_re || event.namespace_re.test(handleObj.namespace)) {\n\n                        event.handleObj = handleObj;\n                        event.data = handleObj.data;\n\n                        ret = ( (jQuery.event.special[handleObj.origType] || {}).handle || handleObj.handler )\n                            .apply(matched.elem, args);\n\n                        if (ret !== undefined) {\n                            if ((event.result = ret) === false) {\n                                event.preventDefault();\n                                event.stopPropagation();\n                            }\n                        }\n                    }\n                }\n            }\n\n            // Call the postDispatch hook for the mapped type\n            if (special.postDispatch) {\n                special.postDispatch.call(this, event);\n            }\n\n            return event.result;\n        },\n\n        handlers: function (event, handlers) {\n            var i, matches, sel, handleObj,\n                handlerQueue = [],\n                delegateCount = handlers.delegateCount,\n                cur = event.target;\n\n            // Find delegate handlers\n            // Black-hole SVG <use> instance trees (#13180)\n            // Avoid non-left-click bubbling in Firefox (#3861)\n            if (delegateCount && cur.nodeType && (!event.button || event.type !== \"click\")) {\n\n                for (; cur !== this; cur = cur.parentNode || this) {\n\n                    // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n                    if (cur.disabled !== true || event.type !== \"click\") {\n                        matches = [];\n                        for (i = 0; i < delegateCount; i++) {\n                            handleObj = handlers[i];\n\n                            // Don't conflict with Object.prototype properties (#13203)\n                            sel = handleObj.selector + \" \";\n\n                            if (matches[sel] === undefined) {\n                                matches[sel] = handleObj.needsContext ?\n                                jQuery(sel, this).index(cur) >= 0 :\n                                    jQuery.find(sel, this, null, [cur]).length;\n                            }\n                            if (matches[sel]) {\n                                matches.push(handleObj);\n                            }\n                        }\n                        if (matches.length) {\n                            handlerQueue.push({elem: cur, handlers: matches});\n                        }\n                    }\n                }\n            }\n\n            // Add the remaining (directly-bound) handlers\n            if (delegateCount < handlers.length) {\n                handlerQueue.push({elem: this, handlers: handlers.slice(delegateCount)});\n            }\n\n            return handlerQueue;\n        },\n\n        // Includes some event props shared by KeyEvent and MouseEvent\n        props: \"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which\".split(\" \"),\n\n        fixHooks: {},\n\n        keyHooks: {\n            props: \"char charCode key keyCode\".split(\" \"),\n            filter: function (event, original) {\n\n                // Add which for key events\n                if (event.which == null) {\n                    event.which = original.charCode != null ? original.charCode : original.keyCode;\n                }\n\n                return event;\n            }\n        },\n\n        mouseHooks: {\n            props: \"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement\".split(\" \"),\n            filter: function (event, original) {\n                var eventDoc, doc, body,\n                    button = original.button;\n\n                // Calculate pageX/Y if missing and clientX/Y available\n                if (event.pageX == null && original.clientX != null) {\n                    eventDoc = event.target.ownerDocument || document;\n                    doc = eventDoc.documentElement;\n                    body = eventDoc.body;\n\n                    event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );\n                    event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 );\n                }\n\n                // Add which for click: 1 === left; 2 === middle; 3 === right\n                // Note: button is not normalized, so don't use it\n                if (!event.which && button !== undefined) {\n                    event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );\n                }\n\n                return event;\n            }\n        },\n\n        fix: function (event) {\n            if (event[jQuery.expando]) {\n                return event;\n            }\n\n            // Create a writable copy of the event object and normalize some properties\n            var i, prop, copy,\n                type = event.type,\n                originalEvent = event,\n                fixHook = this.fixHooks[type];\n\n            if (!fixHook) {\n                this.fixHooks[type] = fixHook =\n                    rmouseEvent.test(type) ? this.mouseHooks :\n                        rkeyEvent.test(type) ? this.keyHooks :\n                        {};\n            }\n            copy = fixHook.props ? this.props.concat(fixHook.props) : this.props;\n\n            event = new jQuery.Event(originalEvent);\n\n            i = copy.length;\n            while (i--) {\n                prop = copy[i];\n                event[prop] = originalEvent[prop];\n            }\n\n            // Support: Cordova 2.5 (WebKit) (#13255)\n            // All events should have a target; Cordova deviceready doesn't\n            if (!event.target) {\n                event.target = document;\n            }\n\n            // Support: Safari 6.0+, Chrome<28\n            // Target should not be a text node (#504, #13143)\n            if (event.target.nodeType === 3) {\n                event.target = event.target.parentNode;\n            }\n\n            return fixHook.filter ? fixHook.filter(event, originalEvent) : event;\n        },\n\n        special: {\n            load: {\n                // Prevent triggered image.load events from bubbling to window.load\n                noBubble: true\n            },\n            focus: {\n                // Fire native event if possible so blur/focus sequence is correct\n                trigger: function () {\n                    if (this !== safeActiveElement() && this.focus) {\n                        this.focus();\n                        return false;\n                    }\n                },\n                delegateType: \"focusin\"\n            },\n            blur: {\n                trigger: function () {\n                    if (this === safeActiveElement() && this.blur) {\n                        this.blur();\n                        return false;\n                    }\n                },\n                delegateType: \"focusout\"\n            },\n            click: {\n                // For checkbox, fire native event so checked state will be right\n                trigger: function () {\n                    if (this.type === \"checkbox\" && this.click && jQuery.nodeName(this, \"input\")) {\n                        this.click();\n                        return false;\n                    }\n                },\n\n                // For cross-browser consistency, don't fire native .click() on links\n                _default: function (event) {\n                    return jQuery.nodeName(event.target, \"a\");\n                }\n            },\n\n            beforeunload: {\n                postDispatch: function (event) {\n\n                    // Support: Firefox 20+\n                    // Firefox doesn't alert if the returnValue field is not set.\n                    if (event.result !== undefined && event.originalEvent) {\n                        event.originalEvent.returnValue = event.result;\n                    }\n                }\n            }\n        },\n\n        simulate: function (type, elem, event, bubble) {\n            // Piggyback on a donor event to simulate a different one.\n            // Fake originalEvent to avoid donor's stopPropagation, but if the\n            // simulated event prevents default then we do the same on the donor.\n            var e = jQuery.extend(\n                new jQuery.Event(),\n                event,\n                {\n                    type: type,\n                    isSimulated: true,\n                    originalEvent: {}\n                }\n            );\n            if (bubble) {\n                jQuery.event.trigger(e, null, elem);\n            } else {\n                jQuery.event.dispatch.call(elem, e);\n            }\n            if (e.isDefaultPrevented()) {\n                event.preventDefault();\n            }\n        }\n    };\n\n    jQuery.removeEvent = function (elem, type, handle) {\n        if (elem.removeEventListener) {\n            elem.removeEventListener(type, handle, false);\n        }\n    };\n\n    jQuery.Event = function (src, props) {\n        // Allow instantiation without the 'new' keyword\n        if (!(this instanceof jQuery.Event)) {\n            return new jQuery.Event(src, props);\n        }\n\n        // Event object\n        if (src && src.type) {\n            this.originalEvent = src;\n            this.type = src.type;\n\n            // Events bubbling up the document may have been marked as prevented\n            // by a handler lower down the tree; reflect the correct value.\n            this.isDefaultPrevented = src.defaultPrevented ||\n            src.defaultPrevented === undefined &&\n            // Support: Android<4.0\n            src.returnValue === false ?\n                returnTrue :\n                returnFalse;\n\n            // Event type\n        } else {\n            this.type = src;\n        }\n\n        // Put explicitly provided properties onto the event object\n        if (props) {\n            jQuery.extend(this, props);\n        }\n\n        // Create a timestamp if incoming event doesn't have one\n        this.timeStamp = src && src.timeStamp || jQuery.now();\n\n        // Mark it as fixed\n        this[jQuery.expando] = true;\n    };\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\n    jQuery.Event.prototype = {\n        isDefaultPrevented: returnFalse,\n        isPropagationStopped: returnFalse,\n        isImmediatePropagationStopped: returnFalse,\n\n        preventDefault: function () {\n            var e = this.originalEvent;\n\n            this.isDefaultPrevented = returnTrue;\n\n            if (e && e.preventDefault) {\n                e.preventDefault();\n            }\n        },\n        stopPropagation: function () {\n            var e = this.originalEvent;\n\n            this.isPropagationStopped = returnTrue;\n\n            if (e && e.stopPropagation) {\n                e.stopPropagation();\n            }\n        },\n        stopImmediatePropagation: function () {\n            var e = this.originalEvent;\n\n            this.isImmediatePropagationStopped = returnTrue;\n\n            if (e && e.stopImmediatePropagation) {\n                e.stopImmediatePropagation();\n            }\n\n            this.stopPropagation();\n        }\n    };\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\n// Support: Chrome 15+\n    jQuery.each({\n        mouseenter: \"mouseover\",\n        mouseleave: \"mouseout\",\n        pointerenter: \"pointerover\",\n        pointerleave: \"pointerout\"\n    }, function (orig, fix) {\n        jQuery.event.special[orig] = {\n            delegateType: fix,\n            bindType: fix,\n\n            handle: function (event) {\n                var ret,\n                    target = this,\n                    related = event.relatedTarget,\n                    handleObj = event.handleObj;\n\n                // For mousenter/leave call the handler if related is outside the target.\n                // NB: No relatedTarget if the mouse left/entered the browser window\n                if (!related || (related !== target && !jQuery.contains(target, related))) {\n                    event.type = handleObj.origType;\n                    ret = handleObj.handler.apply(this, arguments);\n                    event.type = fix;\n                }\n                return ret;\n            }\n        };\n    });\n\n// Support: Firefox, Chrome, Safari\n// Create \"bubbling\" focus and blur events\n    if (!support.focusinBubbles) {\n        jQuery.each({focus: \"focusin\", blur: \"focusout\"}, function (orig, fix) {\n\n            // Attach a single capturing handler on the document while someone wants focusin/focusout\n            var handler = function (event) {\n                jQuery.event.simulate(fix, event.target, jQuery.event.fix(event), true);\n            };\n\n            jQuery.event.special[fix] = {\n                setup: function () {\n                    var doc = this.ownerDocument || this,\n                        attaches = data_priv.access(doc, fix);\n\n                    if (!attaches) {\n                        doc.addEventListener(orig, handler, true);\n                    }\n                    data_priv.access(doc, fix, ( attaches || 0 ) + 1);\n                },\n                teardown: function () {\n                    var doc = this.ownerDocument || this,\n                        attaches = data_priv.access(doc, fix) - 1;\n\n                    if (!attaches) {\n                        doc.removeEventListener(orig, handler, true);\n                        data_priv.remove(doc, fix);\n\n                    } else {\n                        data_priv.access(doc, fix, attaches);\n                    }\n                }\n            };\n        });\n    }\n\n    jQuery.fn.extend({\n\n        on: function (types, selector, data, fn, /*INTERNAL*/ one) {\n            var origFn, type;\n\n            // Types can be a map of types/handlers\n            if (typeof types === \"object\") {\n                // ( types-Object, selector, data )\n                if (typeof selector !== \"string\") {\n                    // ( types-Object, data )\n                    data = data || selector;\n                    selector = undefined;\n                }\n                for (type in types) {\n                    this.on(type, selector, data, types[type], one);\n                }\n                return this;\n            }\n\n            if (data == null && fn == null) {\n                // ( types, fn )\n                fn = selector;\n                data = selector = undefined;\n            } else if (fn == null) {\n                if (typeof selector === \"string\") {\n                    // ( types, selector, fn )\n                    fn = data;\n                    data = undefined;\n                } else {\n                    // ( types, data, fn )\n                    fn = data;\n                    data = selector;\n                    selector = undefined;\n                }\n            }\n            if (fn === false) {\n                fn = returnFalse;\n            } else if (!fn) {\n                return this;\n            }\n\n            if (one === 1) {\n                origFn = fn;\n                fn = function (event) {\n                    // Can use an empty set, since event contains the info\n                    jQuery().off(event);\n                    return origFn.apply(this, arguments);\n                };\n                // Use same guid so caller can remove using origFn\n                fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n            }\n            return this.each(function () {\n                jQuery.event.add(this, types, fn, data, selector);\n            });\n        },\n        one: function (types, selector, data, fn) {\n            return this.on(types, selector, data, fn, 1);\n        },\n        off: function (types, selector, fn) {\n            var handleObj, type;\n            if (types && types.preventDefault && types.handleObj) {\n                // ( event )  dispatched jQuery.Event\n                handleObj = types.handleObj;\n                jQuery(types.delegateTarget).off(\n                    handleObj.namespace ? handleObj.origType + \".\" + handleObj.namespace : handleObj.origType,\n                    handleObj.selector,\n                    handleObj.handler\n                );\n                return this;\n            }\n            if (typeof types === \"object\") {\n                // ( types-object [, selector] )\n                for (type in types) {\n                    this.off(type, selector, types[type]);\n                }\n                return this;\n            }\n            if (selector === false || typeof selector === \"function\") {\n                // ( types [, fn] )\n                fn = selector;\n                selector = undefined;\n            }\n            if (fn === false) {\n                fn = returnFalse;\n            }\n            return this.each(function () {\n                jQuery.event.remove(this, types, fn, selector);\n            });\n        },\n\n        trigger: function (type, data) {\n            return this.each(function () {\n                jQuery.event.trigger(type, data, this);\n            });\n        },\n        triggerHandler: function (type, data) {\n            var elem = this[0];\n            if (elem) {\n                return jQuery.event.trigger(type, data, elem, true);\n            }\n        }\n    });\n\n\n    var\n        rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:]+)[^>]*)\\/>/gi,\n        rtagName = /<([\\w:]+)/,\n        rhtml = /<|&#?\\w+;/,\n        rnoInnerhtml = /<(?:script|style|link)/i,\n    // checked=\"checked\" or checked\n        rchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n        rscriptType = /^$|\\/(?:java|ecma)script/i,\n        rscriptTypeMasked = /^true\\/(.*)/,\n        rcleanScript = /^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g,\n\n    // We have to close these tags to support XHTML (#13200)\n        wrapMap = {\n\n            // Support: IE9\n            option: [1, \"<select multiple='multiple'>\", \"</select>\"],\n\n            thead: [1, \"<table>\", \"</table>\"],\n            col: [2, \"<table><colgroup>\", \"</colgroup></table>\"],\n            tr: [2, \"<table><tbody>\", \"</tbody></table>\"],\n            td: [3, \"<table><tbody><tr>\", \"</tr></tbody></table>\"],\n\n            _default: [0, \"\", \"\"]\n        };\n\n// Support: IE9\n    wrapMap.optgroup = wrapMap.option;\n\n    wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\n    wrapMap.th = wrapMap.td;\n\n// Support: 1.x compatibility\n// Manipulating tables requires a tbody\n    function manipulationTarget(elem, content) {\n        return jQuery.nodeName(elem, \"table\") &&\n        jQuery.nodeName(content.nodeType !== 11 ? content : content.firstChild, \"tr\") ?\n\n        elem.getElementsByTagName(\"tbody\")[0] ||\n        elem.appendChild(elem.ownerDocument.createElement(\"tbody\")) :\n            elem;\n    }\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\n    function disableScript(elem) {\n        elem.type = (elem.getAttribute(\"type\") !== null) + \"/\" + elem.type;\n        return elem;\n    }\n\n    function restoreScript(elem) {\n        var match = rscriptTypeMasked.exec(elem.type);\n\n        if (match) {\n            elem.type = match[1];\n        } else {\n            elem.removeAttribute(\"type\");\n        }\n\n        return elem;\n    }\n\n// Mark scripts as having already been evaluated\n    function setGlobalEval(elems, refElements) {\n        var i = 0,\n            l = elems.length;\n\n        for (; i < l; i++) {\n            data_priv.set(\n                elems[i], \"globalEval\", !refElements || data_priv.get(refElements[i], \"globalEval\")\n            );\n        }\n    }\n\n    function cloneCopyEvent(src, dest) {\n        var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;\n\n        if (dest.nodeType !== 1) {\n            return;\n        }\n\n        // 1. Copy private data: events, handlers, etc.\n        if (data_priv.hasData(src)) {\n            pdataOld = data_priv.access(src);\n            pdataCur = data_priv.set(dest, pdataOld);\n            events = pdataOld.events;\n\n            if (events) {\n                delete pdataCur.handle;\n                pdataCur.events = {};\n\n                for (type in events) {\n                    for (i = 0, l = events[type].length; i < l; i++) {\n                        jQuery.event.add(dest, type, events[type][i]);\n                    }\n                }\n            }\n        }\n\n        // 2. Copy user data\n        if (data_user.hasData(src)) {\n            udataOld = data_user.access(src);\n            udataCur = jQuery.extend({}, udataOld);\n\n            data_user.set(dest, udataCur);\n        }\n    }\n\n    function getAll(context, tag) {\n        var ret = context.getElementsByTagName ? context.getElementsByTagName(tag || \"*\") :\n            context.querySelectorAll ? context.querySelectorAll(tag || \"*\") :\n                [];\n\n        return tag === undefined || tag && jQuery.nodeName(context, tag) ?\n            jQuery.merge([context], ret) :\n            ret;\n    }\n\n// Fix IE bugs, see support tests\n    function fixInput(src, dest) {\n        var nodeName = dest.nodeName.toLowerCase();\n\n        // Fails to persist the checked state of a cloned checkbox or radio button.\n        if (nodeName === \"input\" && rcheckableType.test(src.type)) {\n            dest.checked = src.checked;\n\n            // Fails to return the selected option to the default selected state when cloning options\n        } else if (nodeName === \"input\" || nodeName === \"textarea\") {\n            dest.defaultValue = src.defaultValue;\n        }\n    }\n\n    jQuery.extend({\n        clone: function (elem, dataAndEvents, deepDataAndEvents) {\n            var i, l, srcElements, destElements,\n                clone = elem.cloneNode(true),\n                inPage = jQuery.contains(elem.ownerDocument, elem);\n\n            // Fix IE cloning issues\n            if (!support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && !jQuery.isXMLDoc(elem)) {\n\n                // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2\n                destElements = getAll(clone);\n                srcElements = getAll(elem);\n\n                for (i = 0, l = srcElements.length; i < l; i++) {\n                    fixInput(srcElements[i], destElements[i]);\n                }\n            }\n\n            // Copy the events from the original to the clone\n            if (dataAndEvents) {\n                if (deepDataAndEvents) {\n                    srcElements = srcElements || getAll(elem);\n                    destElements = destElements || getAll(clone);\n\n                    for (i = 0, l = srcElements.length; i < l; i++) {\n                        cloneCopyEvent(srcElements[i], destElements[i]);\n                    }\n                } else {\n                    cloneCopyEvent(elem, clone);\n                }\n            }\n\n            // Preserve script evaluation history\n            destElements = getAll(clone, \"script\");\n            if (destElements.length > 0) {\n                setGlobalEval(destElements, !inPage && getAll(elem, \"script\"));\n            }\n\n            // Return the cloned set\n            return clone;\n        },\n\n        buildFragment: function (elems, context, scripts, selection) {\n            var elem, tmp, tag, wrap, contains, j,\n                fragment = context.createDocumentFragment(),\n                nodes = [],\n                i = 0,\n                l = elems.length;\n\n            for (; i < l; i++) {\n                elem = elems[i];\n\n                if (elem || elem === 0) {\n\n                    // Add nodes directly\n                    if (jQuery.type(elem) === \"object\") {\n                        // Support: QtWebKit, PhantomJS\n                        // push.apply(_, arraylike) throws on ancient WebKit\n                        jQuery.merge(nodes, elem.nodeType ? [elem] : elem);\n\n                        // Convert non-html into a text node\n                    } else if (!rhtml.test(elem)) {\n                        nodes.push(context.createTextNode(elem));\n\n                        // Convert html into DOM nodes\n                    } else {\n                        tmp = tmp || fragment.appendChild(context.createElement(\"div\"));\n\n                        // Deserialize a standard representation\n                        tag = ( rtagName.exec(elem) || [\"\", \"\"] )[1].toLowerCase();\n                        wrap = wrapMap[tag] || wrapMap._default;\n                        tmp.innerHTML = wrap[1] + elem.replace(rxhtmlTag, \"<$1></$2>\") + wrap[2];\n\n                        // Descend through wrappers to the right content\n                        j = wrap[0];\n                        while (j--) {\n                            tmp = tmp.lastChild;\n                        }\n\n                        // Support: QtWebKit, PhantomJS\n                        // push.apply(_, arraylike) throws on ancient WebKit\n                        jQuery.merge(nodes, tmp.childNodes);\n\n                        // Remember the top-level container\n                        tmp = fragment.firstChild;\n\n                        // Ensure the created nodes are orphaned (#12392)\n                        tmp.textContent = \"\";\n                    }\n                }\n            }\n\n            // Remove wrapper from fragment\n            fragment.textContent = \"\";\n\n            i = 0;\n            while ((elem = nodes[i++])) {\n\n                // #4087 - If origin and destination elements are the same, and this is\n                // that element, do not do anything\n                if (selection && jQuery.inArray(elem, selection) !== -1) {\n                    continue;\n                }\n\n                contains = jQuery.contains(elem.ownerDocument, elem);\n\n                // Append to fragment\n                tmp = getAll(fragment.appendChild(elem), \"script\");\n\n                // Preserve script evaluation history\n                if (contains) {\n                    setGlobalEval(tmp);\n                }\n\n                // Capture executables\n                if (scripts) {\n                    j = 0;\n                    while ((elem = tmp[j++])) {\n                        if (rscriptType.test(elem.type || \"\")) {\n                            scripts.push(elem);\n                        }\n                    }\n                }\n            }\n\n            return fragment;\n        },\n\n        cleanData: function (elems) {\n            var data, elem, type, key,\n                special = jQuery.event.special,\n                i = 0;\n\n            for (; (elem = elems[i]) !== undefined; i++) {\n                if (jQuery.acceptData(elem)) {\n                    key = elem[data_priv.expando];\n\n                    if (key && (data = data_priv.cache[key])) {\n                        if (data.events) {\n                            for (type in data.events) {\n                                if (special[type]) {\n                                    jQuery.event.remove(elem, type);\n\n                                    // This is a shortcut to avoid jQuery.event.remove's overhead\n                                } else {\n                                    jQuery.removeEvent(elem, type, data.handle);\n                                }\n                            }\n                        }\n                        if (data_priv.cache[key]) {\n                            // Discard any remaining `private` data\n                            delete data_priv.cache[key];\n                        }\n                    }\n                }\n                // Discard any remaining `user` data\n                delete data_user.cache[elem[data_user.expando]];\n            }\n        }\n    });\n\n    jQuery.fn.extend({\n        text: function (value) {\n            return access(this, function (value) {\n                return value === undefined ?\n                    jQuery.text(this) :\n                    this.empty().each(function () {\n                        if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {\n                            this.textContent = value;\n                        }\n                    });\n            }, null, value, arguments.length);\n        },\n\n        append: function () {\n            return this.domManip(arguments, function (elem) {\n                if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {\n                    var target = manipulationTarget(this, elem);\n                    target.appendChild(elem);\n                }\n            });\n        },\n\n        prepend: function () {\n            return this.domManip(arguments, function (elem) {\n                if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {\n                    var target = manipulationTarget(this, elem);\n                    target.insertBefore(elem, target.firstChild);\n                }\n            });\n        },\n\n        before: function () {\n            return this.domManip(arguments, function (elem) {\n                if (this.parentNode) {\n                    this.parentNode.insertBefore(elem, this);\n                }\n            });\n        },\n\n        after: function () {\n            return this.domManip(arguments, function (elem) {\n                if (this.parentNode) {\n                    this.parentNode.insertBefore(elem, this.nextSibling);\n                }\n            });\n        },\n\n        remove: function (selector, keepData /* Internal Use Only */) {\n            var elem,\n                elems = selector ? jQuery.filter(selector, this) : this,\n                i = 0;\n\n            for (; (elem = elems[i]) != null; i++) {\n                if (!keepData && elem.nodeType === 1) {\n                    jQuery.cleanData(getAll(elem));\n                }\n\n                if (elem.parentNode) {\n                    if (keepData && jQuery.contains(elem.ownerDocument, elem)) {\n                        setGlobalEval(getAll(elem, \"script\"));\n                    }\n                    elem.parentNode.removeChild(elem);\n                }\n            }\n\n            return this;\n        },\n\n        empty: function () {\n            var elem,\n                i = 0;\n\n            for (; (elem = this[i]) != null; i++) {\n                if (elem.nodeType === 1) {\n\n                    // Prevent memory leaks\n                    jQuery.cleanData(getAll(elem, false));\n\n                    // Remove any remaining nodes\n                    elem.textContent = \"\";\n                }\n            }\n\n            return this;\n        },\n\n        clone: function (dataAndEvents, deepDataAndEvents) {\n            dataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n            deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n            return this.map(function () {\n                return jQuery.clone(this, dataAndEvents, deepDataAndEvents);\n            });\n        },\n\n        html: function (value) {\n            return access(this, function (value) {\n                var elem = this[0] || {},\n                    i = 0,\n                    l = this.length;\n\n                if (value === undefined && elem.nodeType === 1) {\n                    return elem.innerHTML;\n                }\n\n                // See if we can take a shortcut and just use innerHTML\n                if (typeof value === \"string\" && !rnoInnerhtml.test(value) && !wrapMap[( rtagName.exec(value) || [\"\", \"\"] )[1].toLowerCase()]) {\n\n                    value = value.replace(rxhtmlTag, \"<$1></$2>\");\n\n                    try {\n                        for (; i < l; i++) {\n                            elem = this[i] || {};\n\n                            // Remove element nodes and prevent memory leaks\n                            if (elem.nodeType === 1) {\n                                jQuery.cleanData(getAll(elem, false));\n                                elem.innerHTML = value;\n                            }\n                        }\n\n                        elem = 0;\n\n                        // If using innerHTML throws an exception, use the fallback method\n                    } catch (e) {\n                    }\n                }\n\n                if (elem) {\n                    this.empty().append(value);\n                }\n            }, null, value, arguments.length);\n        },\n\n        replaceWith: function () {\n            var arg = arguments[0];\n\n            // Make the changes, replacing each context element with the new content\n            this.domManip(arguments, function (elem) {\n                arg = this.parentNode;\n\n                jQuery.cleanData(getAll(this));\n\n                if (arg) {\n                    arg.replaceChild(elem, this);\n                }\n            });\n\n            // Force removal if there was no new content (e.g., from empty arguments)\n            return arg && (arg.length || arg.nodeType) ? this : this.remove();\n        },\n\n        detach: function (selector) {\n            return this.remove(selector, true);\n        },\n\n        domManip: function (args, callback) {\n\n            // Flatten any nested arrays\n            args = concat.apply([], args);\n\n            var fragment, first, scripts, hasScripts, node, doc,\n                i = 0,\n                l = this.length,\n                set = this,\n                iNoClone = l - 1,\n                value = args[0],\n                isFunction = jQuery.isFunction(value);\n\n            // We can't cloneNode fragments that contain checked, in WebKit\n            if (isFunction ||\n                ( l > 1 && typeof value === \"string\" && !support.checkClone && rchecked.test(value) )) {\n                return this.each(function (index) {\n                    var self = set.eq(index);\n                    if (isFunction) {\n                        args[0] = value.call(this, index, self.html());\n                    }\n                    self.domManip(args, callback);\n                });\n            }\n\n            if (l) {\n                fragment = jQuery.buildFragment(args, this[0].ownerDocument, false, this);\n                first = fragment.firstChild;\n\n                if (fragment.childNodes.length === 1) {\n                    fragment = first;\n                }\n\n                if (first) {\n                    scripts = jQuery.map(getAll(fragment, \"script\"), disableScript);\n                    hasScripts = scripts.length;\n\n                    // Use the original fragment for the last item instead of the first because it can end up\n                    // being emptied incorrectly in certain situations (#8070).\n                    for (; i < l; i++) {\n                        node = fragment;\n\n                        if (i !== iNoClone) {\n                            node = jQuery.clone(node, true, true);\n\n                            // Keep references to cloned scripts for later restoration\n                            if (hasScripts) {\n                                // Support: QtWebKit\n                                // jQuery.merge because push.apply(_, arraylike) throws\n                                jQuery.merge(scripts, getAll(node, \"script\"));\n                            }\n                        }\n\n                        callback.call(this[i], node, i);\n                    }\n\n                    if (hasScripts) {\n                        doc = scripts[scripts.length - 1].ownerDocument;\n\n                        // Reenable scripts\n                        jQuery.map(scripts, restoreScript);\n\n                        // Evaluate executable scripts on first document insertion\n                        for (i = 0; i < hasScripts; i++) {\n                            node = scripts[i];\n                            if (rscriptType.test(node.type || \"\") && !data_priv.access(node, \"globalEval\") && jQuery.contains(doc, node)) {\n\n                                if (node.src) {\n                                    // Optional AJAX dependency, but won't run scripts if not present\n                                    if (jQuery._evalUrl) {\n                                        jQuery._evalUrl(node.src);\n                                    }\n                                } else {\n                                    jQuery.globalEval(node.textContent.replace(rcleanScript, \"\"));\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n\n            return this;\n        }\n    });\n\n    jQuery.each({\n        appendTo: \"append\",\n        prependTo: \"prepend\",\n        insertBefore: \"before\",\n        insertAfter: \"after\",\n        replaceAll: \"replaceWith\"\n    }, function (name, original) {\n        jQuery.fn[name] = function (selector) {\n            var elems,\n                ret = [],\n                insert = jQuery(selector),\n                last = insert.length - 1,\n                i = 0;\n\n            for (; i <= last; i++) {\n                elems = i === last ? this : this.clone(true);\n                jQuery(insert[i])[original](elems);\n\n                // Support: QtWebKit\n                // .get() because push.apply(_, arraylike) throws\n                push.apply(ret, elems.get());\n            }\n\n            return this.pushStack(ret);\n        };\n    });\n\n\n    var iframe,\n        elemdisplay = {};\n\n    /**\n     * Retrieve the actual display of a element\n     * @param {String} name nodeName of the element\n     * @param {Object} doc Document object\n     */\n// Called only from within defaultDisplay\n    function actualDisplay(name, doc) {\n        var style,\n            elem = jQuery(doc.createElement(name)).appendTo(doc.body),\n\n        // getDefaultComputedStyle might be reliably used only on attached element\n            display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle(elem[0]) ) ?\n\n                // Use of this method is a temporary fix (more like optimization) until something better comes along,\n                // since it was removed from specification and supported only in FF\n                style.display : jQuery.css(elem[0], \"display\");\n\n        // We don't have any data stored on the element,\n        // so use \"detach\" method as fast way to get rid of the element\n        elem.detach();\n\n        return display;\n    }\n\n    /**\n     * Try to determine the default display value of an element\n     * @param {String} nodeName\n     */\n    function defaultDisplay(nodeName) {\n        var doc = document,\n            display = elemdisplay[nodeName];\n\n        if (!display) {\n            display = actualDisplay(nodeName, doc);\n\n            // If the simple way fails, read from inside an iframe\n            if (display === \"none\" || !display) {\n\n                // Use the already-created iframe if possible\n                iframe = (iframe || jQuery(\"<iframe frameborder='0' width='0' height='0'/>\")).appendTo(doc.documentElement);\n\n                // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse\n                doc = iframe[0].contentDocument;\n\n                // Support: IE\n                doc.write();\n                doc.close();\n\n                display = actualDisplay(nodeName, doc);\n                iframe.detach();\n            }\n\n            // Store the correct default display\n            elemdisplay[nodeName] = display;\n        }\n\n        return display;\n    }\n\n    var rmargin = (/^margin/);\n\n    var rnumnonpx = new RegExp(\"^(\" + pnum + \")(?!px)[a-z%]+$\", \"i\");\n\n    var getStyles = function (elem) {\n        // Support: IE<=11+, Firefox<=30+ (#15098, #14150)\n        // IE throws on elements created in popups\n        // FF meanwhile throws on frame elements through \"defaultView.getComputedStyle\"\n        if (elem.ownerDocument.defaultView.opener) {\n            return elem.ownerDocument.defaultView.getComputedStyle(elem, null);\n        }\n\n        return window.getComputedStyle(elem, null);\n    };\n\n\n    function curCSS(elem, name, computed) {\n        var width, minWidth, maxWidth, ret,\n            style = elem.style;\n\n        computed = computed || getStyles(elem);\n\n        // Support: IE9\n        // getPropertyValue is only needed for .css('filter') (#12537)\n        if (computed) {\n            ret = computed.getPropertyValue(name) || computed[name];\n        }\n\n        if (computed) {\n\n            if (ret === \"\" && !jQuery.contains(elem.ownerDocument, elem)) {\n                ret = jQuery.style(elem, name);\n            }\n\n            // Support: iOS < 6\n            // A tribute to the \"awesome hack by Dean Edwards\"\n            // iOS < 6 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels\n            // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values\n            if (rnumnonpx.test(ret) && rmargin.test(name)) {\n\n                // Remember the original values\n                width = style.width;\n                minWidth = style.minWidth;\n                maxWidth = style.maxWidth;\n\n                // Put in the new values to get a computed value out\n                style.minWidth = style.maxWidth = style.width = ret;\n                ret = computed.width;\n\n                // Revert the changed values\n                style.width = width;\n                style.minWidth = minWidth;\n                style.maxWidth = maxWidth;\n            }\n        }\n\n        return ret !== undefined ?\n            // Support: IE\n            // IE returns zIndex value as an integer.\n        ret + \"\" :\n            ret;\n    }\n\n\n    function addGetHookIf(conditionFn, hookFn) {\n        // Define the hook, we'll check on the first run if it's really needed.\n        return {\n            get: function () {\n                if (conditionFn()) {\n                    // Hook not needed (or it's not possible to use it due\n                    // to missing dependency), remove it.\n                    delete this.get;\n                    return;\n                }\n\n                // Hook needed; redefine it so that the support test is not executed again.\n                return (this.get = hookFn).apply(this, arguments);\n            }\n        };\n    }\n\n\n    (function () {\n        var pixelPositionVal, boxSizingReliableVal,\n            docElem = document.documentElement,\n            container = document.createElement(\"div\"),\n            div = document.createElement(\"div\");\n\n        if (!div.style) {\n            return;\n        }\n\n        // Support: IE9-11+\n        // Style of cloned element affects source element cloned (#8908)\n        div.style.backgroundClip = \"content-box\";\n        div.cloneNode(true).style.backgroundClip = \"\";\n        support.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\n        container.style.cssText = \"border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;\" +\n            \"position:absolute\";\n        container.appendChild(div);\n\n        // Executing both pixelPosition & boxSizingReliable tests require only one layout\n        // so they're executed at the same time to save the second computation.\n        function computePixelPositionAndBoxSizingReliable() {\n            div.style.cssText =\n                // Support: Firefox<29, Android 2.3\n                // Vendor-prefix box-sizing\n                \"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;\" +\n                \"box-sizing:border-box;display:block;margin-top:1%;top:1%;\" +\n                \"border:1px;padding:1px;width:4px;position:absolute\";\n            div.innerHTML = \"\";\n            docElem.appendChild(container);\n\n            var divStyle = window.getComputedStyle(div, null);\n            pixelPositionVal = divStyle.top !== \"1%\";\n            boxSizingReliableVal = divStyle.width === \"4px\";\n\n            docElem.removeChild(container);\n        }\n\n        // Support: node.js jsdom\n        // Don't assume that getComputedStyle is a property of the global object\n        if (window.getComputedStyle) {\n            jQuery.extend(support, {\n                pixelPosition: function () {\n\n                    // This test is executed only once but we still do memoizing\n                    // since we can use the boxSizingReliable pre-computing.\n                    // No need to check if the test was already performed, though.\n                    computePixelPositionAndBoxSizingReliable();\n                    return pixelPositionVal;\n                },\n                boxSizingReliable: function () {\n                    if (boxSizingReliableVal == null) {\n                        computePixelPositionAndBoxSizingReliable();\n                    }\n                    return boxSizingReliableVal;\n                },\n                reliableMarginRight: function () {\n\n                    // Support: Android 2.3\n                    // Check if div with explicit width and no margin-right incorrectly\n                    // gets computed margin-right based on width of container. (#3333)\n                    // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n                    // This support function is only executed once so no memoizing is needed.\n                    var ret,\n                        marginDiv = div.appendChild(document.createElement(\"div\"));\n\n                    // Reset CSS: box-sizing; display; margin; border; padding\n                    marginDiv.style.cssText = div.style.cssText =\n                        // Support: Firefox<29, Android 2.3\n                        // Vendor-prefix box-sizing\n                        \"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;\" +\n                        \"box-sizing:content-box;display:block;margin:0;border:0;padding:0\";\n                    marginDiv.style.marginRight = marginDiv.style.width = \"0\";\n                    div.style.width = \"1px\";\n                    docElem.appendChild(container);\n\n                    ret = !parseFloat(window.getComputedStyle(marginDiv, null).marginRight);\n\n                    docElem.removeChild(container);\n                    div.removeChild(marginDiv);\n\n                    return ret;\n                }\n            });\n        }\n    })();\n\n\n// A method for quickly swapping in/out CSS properties to get correct calculations.\n    jQuery.swap = function (elem, options, callback, args) {\n        var ret, name,\n            old = {};\n\n        // Remember the old values, and insert the new ones\n        for (name in options) {\n            old[name] = elem.style[name];\n            elem.style[name] = options[name];\n        }\n\n        ret = callback.apply(elem, args || []);\n\n        // Revert the old values\n        for (name in options) {\n            elem.style[name] = old[name];\n        }\n\n        return ret;\n    };\n\n\n    var\n    // Swappable if display is none or starts with table except \"table\", \"table-cell\", or \"table-caption\"\n    // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n        rdisplayswap = /^(none|table(?!-c[ea]).+)/,\n        rnumsplit = new RegExp(\"^(\" + pnum + \")(.*)$\", \"i\"),\n        rrelNum = new RegExp(\"^([+-])=(\" + pnum + \")\", \"i\"),\n\n        cssShow = {position: \"absolute\", visibility: \"hidden\", display: \"block\"},\n        cssNormalTransform = {\n            letterSpacing: \"0\",\n            fontWeight: \"400\"\n        },\n\n        cssPrefixes = [\"Webkit\", \"O\", \"Moz\", \"ms\"];\n\n// Return a css property mapped to a potentially vendor prefixed property\n    function vendorPropName(style, name) {\n\n        // Shortcut for names that are not vendor prefixed\n        if (name in style) {\n            return name;\n        }\n\n        // Check for vendor prefixed names\n        var capName = name[0].toUpperCase() + name.slice(1),\n            origName = name,\n            i = cssPrefixes.length;\n\n        while (i--) {\n            name = cssPrefixes[i] + capName;\n            if (name in style) {\n                return name;\n            }\n        }\n\n        return origName;\n    }\n\n    function setPositiveNumber(elem, value, subtract) {\n        var matches = rnumsplit.exec(value);\n        return matches ?\n            // Guard against undefined \"subtract\", e.g., when used as in cssHooks\n        Math.max(0, matches[1] - ( subtract || 0 )) + ( matches[2] || \"px\" ) :\n            value;\n    }\n\n    function augmentWidthOrHeight(elem, name, extra, isBorderBox, styles) {\n        var i = extra === ( isBorderBox ? \"border\" : \"content\" ) ?\n                // If we already have the right measurement, avoid augmentation\n                4 :\n                // Otherwise initialize for horizontal or vertical properties\n                name === \"width\" ? 1 : 0,\n\n            val = 0;\n\n        for (; i < 4; i += 2) {\n            // Both box models exclude margin, so add it if we want it\n            if (extra === \"margin\") {\n                val += jQuery.css(elem, extra + cssExpand[i], true, styles);\n            }\n\n            if (isBorderBox) {\n                // border-box includes padding, so remove it if we want content\n                if (extra === \"content\") {\n                    val -= jQuery.css(elem, \"padding\" + cssExpand[i], true, styles);\n                }\n\n                // At this point, extra isn't border nor margin, so remove border\n                if (extra !== \"margin\") {\n                    val -= jQuery.css(elem, \"border\" + cssExpand[i] + \"Width\", true, styles);\n                }\n            } else {\n                // At this point, extra isn't content, so add padding\n                val += jQuery.css(elem, \"padding\" + cssExpand[i], true, styles);\n\n                // At this point, extra isn't content nor padding, so add border\n                if (extra !== \"padding\") {\n                    val += jQuery.css(elem, \"border\" + cssExpand[i] + \"Width\", true, styles);\n                }\n            }\n        }\n\n        return val;\n    }\n\n    function getWidthOrHeight(elem, name, extra) {\n\n        // Start with offset property, which is equivalent to the border-box value\n        var valueIsBorderBox = true,\n            val = name === \"width\" ? elem.offsetWidth : elem.offsetHeight,\n            styles = getStyles(elem),\n            isBorderBox = jQuery.css(elem, \"boxSizing\", false, styles) === \"border-box\";\n\n        // Some non-html elements return undefined for offsetWidth, so check for null/undefined\n        // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285\n        // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668\n        if (val <= 0 || val == null) {\n            // Fall back to computed then uncomputed css if necessary\n            val = curCSS(elem, name, styles);\n            if (val < 0 || val == null) {\n                val = elem.style[name];\n            }\n\n            // Computed unit is not pixels. Stop here and return.\n            if (rnumnonpx.test(val)) {\n                return val;\n            }\n\n            // Check for style in case a browser which returns unreliable values\n            // for getComputedStyle silently falls back to the reliable elem.style\n            valueIsBorderBox = isBorderBox &&\n                ( support.boxSizingReliable() || val === elem.style[name] );\n\n            // Normalize \"\", auto, and prepare for extra\n            val = parseFloat(val) || 0;\n        }\n\n        // Use the active box-sizing model to add/subtract irrelevant styles\n        return ( val +\n                augmentWidthOrHeight(\n                    elem,\n                    name,\n                    extra || ( isBorderBox ? \"border\" : \"content\" ),\n                    valueIsBorderBox,\n                    styles\n                )\n            ) + \"px\";\n    }\n\n    function showHide(elements, show) {\n        var display, elem, hidden,\n            values = [],\n            index = 0,\n            length = elements.length;\n\n        for (; index < length; index++) {\n            elem = elements[index];\n            if (!elem.style) {\n                continue;\n            }\n\n            values[index] = data_priv.get(elem, \"olddisplay\");\n            display = elem.style.display;\n            if (show) {\n                // Reset the inline display of this element to learn if it is\n                // being hidden by cascaded rules or not\n                if (!values[index] && display === \"none\") {\n                    elem.style.display = \"\";\n                }\n\n                // Set elements which have been overridden with display: none\n                // in a stylesheet to whatever the default browser style is\n                // for such an element\n                if (elem.style.display === \"\" && isHidden(elem)) {\n                    values[index] = data_priv.access(elem, \"olddisplay\", defaultDisplay(elem.nodeName));\n                }\n            } else {\n                hidden = isHidden(elem);\n\n                if (display !== \"none\" || !hidden) {\n                    data_priv.set(elem, \"olddisplay\", hidden ? display : jQuery.css(elem, \"display\"));\n                }\n            }\n        }\n\n        // Set the display of most of the elements in a second loop\n        // to avoid the constant reflow\n        for (index = 0; index < length; index++) {\n            elem = elements[index];\n            if (!elem.style) {\n                continue;\n            }\n            if (!show || elem.style.display === \"none\" || elem.style.display === \"\") {\n                elem.style.display = show ? values[index] || \"\" : \"none\";\n            }\n        }\n\n        return elements;\n    }\n\n    jQuery.extend({\n\n        // Add in style property hooks for overriding the default\n        // behavior of getting and setting a style property\n        cssHooks: {\n            opacity: {\n                get: function (elem, computed) {\n                    if (computed) {\n\n                        // We should always get a number back from opacity\n                        var ret = curCSS(elem, \"opacity\");\n                        return ret === \"\" ? \"1\" : ret;\n                    }\n                }\n            }\n        },\n\n        // Don't automatically add \"px\" to these possibly-unitless properties\n        cssNumber: {\n            \"columnCount\": true,\n            \"fillOpacity\": true,\n            \"flexGrow\": true,\n            \"flexShrink\": true,\n            \"fontWeight\": true,\n            \"lineHeight\": true,\n            \"opacity\": true,\n            \"order\": true,\n            \"orphans\": true,\n            \"widows\": true,\n            \"zIndex\": true,\n            \"zoom\": true\n        },\n\n        // Add in properties whose names you wish to fix before\n        // setting or getting the value\n        cssProps: {\n            \"float\": \"cssFloat\"\n        },\n\n        // Get and set the style property on a DOM Node\n        style: function (elem, name, value, extra) {\n\n            // Don't set styles on text and comment nodes\n            if (!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style) {\n                return;\n            }\n\n            // Make sure that we're working with the right name\n            var ret, type, hooks,\n                origName = jQuery.camelCase(name),\n                style = elem.style;\n\n            name = jQuery.cssProps[origName] || ( jQuery.cssProps[origName] = vendorPropName(style, origName) );\n\n            // Gets hook for the prefixed version, then unprefixed version\n            hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName];\n\n            // Check if we're setting a value\n            if (value !== undefined) {\n                type = typeof value;\n\n                // Convert \"+=\" or \"-=\" to relative numbers (#7345)\n                if (type === \"string\" && (ret = rrelNum.exec(value))) {\n                    value = ( ret[1] + 1 ) * ret[2] + parseFloat(jQuery.css(elem, name));\n                    // Fixes bug #9237\n                    type = \"number\";\n                }\n\n                // Make sure that null and NaN values aren't set (#7116)\n                if (value == null || value !== value) {\n                    return;\n                }\n\n                // If a number, add 'px' to the (except for certain CSS properties)\n                if (type === \"number\" && !jQuery.cssNumber[origName]) {\n                    value += \"px\";\n                }\n\n                // Support: IE9-11+\n                // background-* props affect original clone's values\n                if (!support.clearCloneStyle && value === \"\" && name.indexOf(\"background\") === 0) {\n                    style[name] = \"inherit\";\n                }\n\n                // If a hook was provided, use that value, otherwise just set the specified value\n                if (!hooks || !(\"set\" in hooks) || (value = hooks.set(elem, value, extra)) !== undefined) {\n                    style[name] = value;\n                }\n\n            } else {\n                // If a hook was provided get the non-computed value from there\n                if (hooks && \"get\" in hooks && (ret = hooks.get(elem, false, extra)) !== undefined) {\n                    return ret;\n                }\n\n                // Otherwise just get the value from the style object\n                return style[name];\n            }\n        },\n\n        css: function (elem, name, extra, styles) {\n            var val, num, hooks,\n                origName = jQuery.camelCase(name);\n\n            // Make sure that we're working with the right name\n            name = jQuery.cssProps[origName] || ( jQuery.cssProps[origName] = vendorPropName(elem.style, origName) );\n\n            // Try prefixed name followed by the unprefixed name\n            hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName];\n\n            // If a hook was provided get the computed value from there\n            if (hooks && \"get\" in hooks) {\n                val = hooks.get(elem, true, extra);\n            }\n\n            // Otherwise, if a way to get the computed value exists, use that\n            if (val === undefined) {\n                val = curCSS(elem, name, styles);\n            }\n\n            // Convert \"normal\" to computed value\n            if (val === \"normal\" && name in cssNormalTransform) {\n                val = cssNormalTransform[name];\n            }\n\n            // Make numeric if forced or a qualifier was provided and val looks numeric\n            if (extra === \"\" || extra) {\n                num = parseFloat(val);\n                return extra === true || jQuery.isNumeric(num) ? num || 0 : val;\n            }\n            return val;\n        }\n    });\n\n    jQuery.each([\"height\", \"width\"], function (i, name) {\n        jQuery.cssHooks[name] = {\n            get: function (elem, computed, extra) {\n                if (computed) {\n\n                    // Certain elements can have dimension info if we invisibly show them\n                    // but it must have a current display style that would benefit\n                    return rdisplayswap.test(jQuery.css(elem, \"display\")) && elem.offsetWidth === 0 ?\n                        jQuery.swap(elem, cssShow, function () {\n                            return getWidthOrHeight(elem, name, extra);\n                        }) :\n                        getWidthOrHeight(elem, name, extra);\n                }\n            },\n\n            set: function (elem, value, extra) {\n                var styles = extra && getStyles(elem);\n                return setPositiveNumber(elem, value, extra ?\n                    augmentWidthOrHeight(\n                        elem,\n                        name,\n                        extra,\n                        jQuery.css(elem, \"boxSizing\", false, styles) === \"border-box\",\n                        styles\n                    ) : 0\n                );\n            }\n        };\n    });\n\n// Support: Android 2.3\n    jQuery.cssHooks.marginRight = addGetHookIf(support.reliableMarginRight,\n        function (elem, computed) {\n            if (computed) {\n                return jQuery.swap(elem, {\"display\": \"inline-block\"},\n                    curCSS, [elem, \"marginRight\"]);\n            }\n        }\n    );\n\n// These hooks are used by animate to expand properties\n    jQuery.each({\n        margin: \"\",\n        padding: \"\",\n        border: \"Width\"\n    }, function (prefix, suffix) {\n        jQuery.cssHooks[prefix + suffix] = {\n            expand: function (value) {\n                var i = 0,\n                    expanded = {},\n\n                // Assumes a single number if not a string\n                    parts = typeof value === \"string\" ? value.split(\" \") : [value];\n\n                for (; i < 4; i++) {\n                    expanded[prefix + cssExpand[i] + suffix] =\n                        parts[i] || parts[i - 2] || parts[0];\n                }\n\n                return expanded;\n            }\n        };\n\n        if (!rmargin.test(prefix)) {\n            jQuery.cssHooks[prefix + suffix].set = setPositiveNumber;\n        }\n    });\n\n    jQuery.fn.extend({\n        css: function (name, value) {\n            return access(this, function (elem, name, value) {\n                var styles, len,\n                    map = {},\n                    i = 0;\n\n                if (jQuery.isArray(name)) {\n                    styles = getStyles(elem);\n                    len = name.length;\n\n                    for (; i < len; i++) {\n                        map[name[i]] = jQuery.css(elem, name[i], false, styles);\n                    }\n\n                    return map;\n                }\n\n                return value !== undefined ?\n                    jQuery.style(elem, name, value) :\n                    jQuery.css(elem, name);\n            }, name, value, arguments.length > 1);\n        },\n        show: function () {\n            return showHide(this, true);\n        },\n        hide: function () {\n            return showHide(this);\n        },\n        toggle: function (state) {\n            if (typeof state === \"boolean\") {\n                return state ? this.show() : this.hide();\n            }\n\n            return this.each(function () {\n                if (isHidden(this)) {\n                    jQuery(this).show();\n                } else {\n                    jQuery(this).hide();\n                }\n            });\n        }\n    });\n\n\n    function Tween(elem, options, prop, end, easing) {\n        return new Tween.prototype.init(elem, options, prop, end, easing);\n    }\n\n    jQuery.Tween = Tween;\n\n    Tween.prototype = {\n        constructor: Tween,\n        init: function (elem, options, prop, end, easing, unit) {\n            this.elem = elem;\n            this.prop = prop;\n            this.easing = easing || \"swing\";\n            this.options = options;\n            this.start = this.now = this.cur();\n            this.end = end;\n            this.unit = unit || ( jQuery.cssNumber[prop] ? \"\" : \"px\" );\n        },\n        cur: function () {\n            var hooks = Tween.propHooks[this.prop];\n\n            return hooks && hooks.get ?\n                hooks.get(this) :\n                Tween.propHooks._default.get(this);\n        },\n        run: function (percent) {\n            var eased,\n                hooks = Tween.propHooks[this.prop];\n\n            if (this.options.duration) {\n                this.pos = eased = jQuery.easing[this.easing](\n                    percent, this.options.duration * percent, 0, 1, this.options.duration\n                );\n            } else {\n                this.pos = eased = percent;\n            }\n            this.now = ( this.end - this.start ) * eased + this.start;\n\n            if (this.options.step) {\n                this.options.step.call(this.elem, this.now, this);\n            }\n\n            if (hooks && hooks.set) {\n                hooks.set(this);\n            } else {\n                Tween.propHooks._default.set(this);\n            }\n            return this;\n        }\n    };\n\n    Tween.prototype.init.prototype = Tween.prototype;\n\n    Tween.propHooks = {\n        _default: {\n            get: function (tween) {\n                var result;\n\n                if (tween.elem[tween.prop] != null &&\n                    (!tween.elem.style || tween.elem.style[tween.prop] == null)) {\n                    return tween.elem[tween.prop];\n                }\n\n                // Passing an empty string as a 3rd parameter to .css will automatically\n                // attempt a parseFloat and fallback to a string if the parse fails.\n                // Simple values such as \"10px\" are parsed to Float;\n                // complex values such as \"rotate(1rad)\" are returned as-is.\n                result = jQuery.css(tween.elem, tween.prop, \"\");\n                // Empty strings, null, undefined and \"auto\" are converted to 0.\n                return !result || result === \"auto\" ? 0 : result;\n            },\n            set: function (tween) {\n                // Use step hook for back compat.\n                // Use cssHook if its there.\n                // Use .style if available and use plain properties where available.\n                if (jQuery.fx.step[tween.prop]) {\n                    jQuery.fx.step[tween.prop](tween);\n                } else if (tween.elem.style && ( tween.elem.style[jQuery.cssProps[tween.prop]] != null || jQuery.cssHooks[tween.prop] )) {\n                    jQuery.style(tween.elem, tween.prop, tween.now + tween.unit);\n                } else {\n                    tween.elem[tween.prop] = tween.now;\n                }\n            }\n        }\n    };\n\n// Support: IE9\n// Panic based approach to setting things on disconnected nodes\n    Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n        set: function (tween) {\n            if (tween.elem.nodeType && tween.elem.parentNode) {\n                tween.elem[tween.prop] = tween.now;\n            }\n        }\n    };\n\n    jQuery.easing = {\n        linear: function (p) {\n            return p;\n        },\n        swing: function (p) {\n            return 0.5 - Math.cos(p * Math.PI) / 2;\n        }\n    };\n\n    jQuery.fx = Tween.prototype.init;\n\n// Back Compat <1.8 extension point\n    jQuery.fx.step = {};\n\n\n    var\n        fxNow, timerId,\n        rfxtypes = /^(?:toggle|show|hide)$/,\n        rfxnum = new RegExp(\"^(?:([+-])=|)(\" + pnum + \")([a-z%]*)$\", \"i\"),\n        rrun = /queueHooks$/,\n        animationPrefilters = [defaultPrefilter],\n        tweeners = {\n            \"*\": [function (prop, value) {\n                var tween = this.createTween(prop, value),\n                    target = tween.cur(),\n                    parts = rfxnum.exec(value),\n                    unit = parts && parts[3] || ( jQuery.cssNumber[prop] ? \"\" : \"px\" ),\n\n                // Starting value computation is required for potential unit mismatches\n                    start = ( jQuery.cssNumber[prop] || unit !== \"px\" && +target ) &&\n                        rfxnum.exec(jQuery.css(tween.elem, prop)),\n                    scale = 1,\n                    maxIterations = 20;\n\n                if (start && start[3] !== unit) {\n                    // Trust units reported by jQuery.css\n                    unit = unit || start[3];\n\n                    // Make sure we update the tween properties later on\n                    parts = parts || [];\n\n                    // Iteratively approximate from a nonzero starting point\n                    start = +target || 1;\n\n                    do {\n                        // If previous iteration zeroed out, double until we get *something*.\n                        // Use string for doubling so we don't accidentally see scale as unchanged below\n                        scale = scale || \".5\";\n\n                        // Adjust and apply\n                        start = start / scale;\n                        jQuery.style(tween.elem, prop, start + unit);\n\n                        // Update scale, tolerating zero or NaN from tween.cur(),\n                        // break the loop if scale is unchanged or perfect, or if we've just had enough\n                    } while (scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations);\n                }\n\n                // Update tween properties\n                if (parts) {\n                    start = tween.start = +start || +target || 0;\n                    tween.unit = unit;\n                    // If a +=/-= token was provided, we're doing a relative animation\n                    tween.end = parts[1] ?\n                    start + ( parts[1] + 1 ) * parts[2] :\n                        +parts[2];\n                }\n\n                return tween;\n            }]\n        };\n\n// Animations created synchronously will run synchronously\n    function createFxNow() {\n        setTimeout(function () {\n            fxNow = undefined;\n        });\n        return ( fxNow = jQuery.now() );\n    }\n\n// Generate parameters to create a standard animation\n    function genFx(type, includeWidth) {\n        var which,\n            i = 0,\n            attrs = {height: type};\n\n        // If we include width, step value is 1 to do all cssExpand values,\n        // otherwise step value is 2 to skip over Left and Right\n        includeWidth = includeWidth ? 1 : 0;\n        for (; i < 4; i += 2 - includeWidth) {\n            which = cssExpand[i];\n            attrs[\"margin\" + which] = attrs[\"padding\" + which] = type;\n        }\n\n        if (includeWidth) {\n            attrs.opacity = attrs.width = type;\n        }\n\n        return attrs;\n    }\n\n    function createTween(value, prop, animation) {\n        var tween,\n            collection = ( tweeners[prop] || [] ).concat(tweeners[\"*\"]),\n            index = 0,\n            length = collection.length;\n        for (; index < length; index++) {\n            if ((tween = collection[index].call(animation, prop, value))) {\n\n                // We're done with this property\n                return tween;\n            }\n        }\n    }\n\n    function defaultPrefilter(elem, props, opts) {\n        /* jshint validthis: true */\n        var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,\n            anim = this,\n            orig = {},\n            style = elem.style,\n            hidden = elem.nodeType && isHidden(elem),\n            dataShow = data_priv.get(elem, \"fxshow\");\n\n        // Handle queue: false promises\n        if (!opts.queue) {\n            hooks = jQuery._queueHooks(elem, \"fx\");\n            if (hooks.unqueued == null) {\n                hooks.unqueued = 0;\n                oldfire = hooks.empty.fire;\n                hooks.empty.fire = function () {\n                    if (!hooks.unqueued) {\n                        oldfire();\n                    }\n                };\n            }\n            hooks.unqueued++;\n\n            anim.always(function () {\n                // Ensure the complete handler is called before this completes\n                anim.always(function () {\n                    hooks.unqueued--;\n                    if (!jQuery.queue(elem, \"fx\").length) {\n                        hooks.empty.fire();\n                    }\n                });\n            });\n        }\n\n        // Height/width overflow pass\n        if (elem.nodeType === 1 && ( \"height\" in props || \"width\" in props )) {\n            // Make sure that nothing sneaks out\n            // Record all 3 overflow attributes because IE9-10 do not\n            // change the overflow attribute when overflowX and\n            // overflowY are set to the same value\n            opts.overflow = [style.overflow, style.overflowX, style.overflowY];\n\n            // Set display property to inline-block for height/width\n            // animations on inline elements that are having width/height animated\n            display = jQuery.css(elem, \"display\");\n\n            // Test default display if display is currently \"none\"\n            checkDisplay = display === \"none\" ?\n            data_priv.get(elem, \"olddisplay\") || defaultDisplay(elem.nodeName) : display;\n\n            if (checkDisplay === \"inline\" && jQuery.css(elem, \"float\") === \"none\") {\n                style.display = \"inline-block\";\n            }\n        }\n\n        if (opts.overflow) {\n            style.overflow = \"hidden\";\n            anim.always(function () {\n                style.overflow = opts.overflow[0];\n                style.overflowX = opts.overflow[1];\n                style.overflowY = opts.overflow[2];\n            });\n        }\n\n        // show/hide pass\n        for (prop in props) {\n            value = props[prop];\n            if (rfxtypes.exec(value)) {\n                delete props[prop];\n                toggle = toggle || value === \"toggle\";\n                if (value === ( hidden ? \"hide\" : \"show\" )) {\n\n                    // If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden\n                    if (value === \"show\" && dataShow && dataShow[prop] !== undefined) {\n                        hidden = true;\n                    } else {\n                        continue;\n                    }\n                }\n                orig[prop] = dataShow && dataShow[prop] || jQuery.style(elem, prop);\n\n                // Any non-fx value stops us from restoring the original display value\n            } else {\n                display = undefined;\n            }\n        }\n\n        if (!jQuery.isEmptyObject(orig)) {\n            if (dataShow) {\n                if (\"hidden\" in dataShow) {\n                    hidden = dataShow.hidden;\n                }\n            } else {\n                dataShow = data_priv.access(elem, \"fxshow\", {});\n            }\n\n            // Store state if its toggle - enables .stop().toggle() to \"reverse\"\n            if (toggle) {\n                dataShow.hidden = !hidden;\n            }\n            if (hidden) {\n                jQuery(elem).show();\n            } else {\n                anim.done(function () {\n                    jQuery(elem).hide();\n                });\n            }\n            anim.done(function () {\n                var prop;\n\n                data_priv.remove(elem, \"fxshow\");\n                for (prop in orig) {\n                    jQuery.style(elem, prop, orig[prop]);\n                }\n            });\n            for (prop in orig) {\n                tween = createTween(hidden ? dataShow[prop] : 0, prop, anim);\n\n                if (!( prop in dataShow )) {\n                    dataShow[prop] = tween.start;\n                    if (hidden) {\n                        tween.end = tween.start;\n                        tween.start = prop === \"width\" || prop === \"height\" ? 1 : 0;\n                    }\n                }\n            }\n\n            // If this is a noop like .hide().hide(), restore an overwritten display value\n        } else if ((display === \"none\" ? defaultDisplay(elem.nodeName) : display) === \"inline\") {\n            style.display = display;\n        }\n    }\n\n    function propFilter(props, specialEasing) {\n        var index, name, easing, value, hooks;\n\n        // camelCase, specialEasing and expand cssHook pass\n        for (index in props) {\n            name = jQuery.camelCase(index);\n            easing = specialEasing[name];\n            value = props[index];\n            if (jQuery.isArray(value)) {\n                easing = value[1];\n                value = props[index] = value[0];\n            }\n\n            if (index !== name) {\n                props[name] = value;\n                delete props[index];\n            }\n\n            hooks = jQuery.cssHooks[name];\n            if (hooks && \"expand\" in hooks) {\n                value = hooks.expand(value);\n                delete props[name];\n\n                // Not quite $.extend, this won't overwrite existing keys.\n                // Reusing 'index' because we have the correct \"name\"\n                for (index in value) {\n                    if (!( index in props )) {\n                        props[index] = value[index];\n                        specialEasing[index] = easing;\n                    }\n                }\n            } else {\n                specialEasing[name] = easing;\n            }\n        }\n    }\n\n    function Animation(elem, properties, options) {\n        var result,\n            stopped,\n            index = 0,\n            length = animationPrefilters.length,\n            deferred = jQuery.Deferred().always(function () {\n                // Don't match elem in the :animated selector\n                delete tick.elem;\n            }),\n            tick = function () {\n                if (stopped) {\n                    return false;\n                }\n                var currentTime = fxNow || createFxNow(),\n                    remaining = Math.max(0, animation.startTime + animation.duration - currentTime),\n                // Support: Android 2.3\n                // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)\n                    temp = remaining / animation.duration || 0,\n                    percent = 1 - temp,\n                    index = 0,\n                    length = animation.tweens.length;\n\n                for (; index < length; index++) {\n                    animation.tweens[index].run(percent);\n                }\n\n                deferred.notifyWith(elem, [animation, percent, remaining]);\n\n                if (percent < 1 && length) {\n                    return remaining;\n                } else {\n                    deferred.resolveWith(elem, [animation]);\n                    return false;\n                }\n            },\n            animation = deferred.promise({\n                elem: elem,\n                props: jQuery.extend({}, properties),\n                opts: jQuery.extend(true, {specialEasing: {}}, options),\n                originalProperties: properties,\n                originalOptions: options,\n                startTime: fxNow || createFxNow(),\n                duration: options.duration,\n                tweens: [],\n                createTween: function (prop, end) {\n                    var tween = jQuery.Tween(elem, animation.opts, prop, end,\n                        animation.opts.specialEasing[prop] || animation.opts.easing);\n                    animation.tweens.push(tween);\n                    return tween;\n                },\n                stop: function (gotoEnd) {\n                    var index = 0,\n                    // If we are going to the end, we want to run all the tweens\n                    // otherwise we skip this part\n                        length = gotoEnd ? animation.tweens.length : 0;\n                    if (stopped) {\n                        return this;\n                    }\n                    stopped = true;\n                    for (; index < length; index++) {\n                        animation.tweens[index].run(1);\n                    }\n\n                    // Resolve when we played the last frame; otherwise, reject\n                    if (gotoEnd) {\n                        deferred.resolveWith(elem, [animation, gotoEnd]);\n                    } else {\n                        deferred.rejectWith(elem, [animation, gotoEnd]);\n                    }\n                    return this;\n                }\n            }),\n            props = animation.props;\n\n        propFilter(props, animation.opts.specialEasing);\n\n        for (; index < length; index++) {\n            result = animationPrefilters[index].call(animation, elem, props, animation.opts);\n            if (result) {\n                return result;\n            }\n        }\n\n        jQuery.map(props, createTween, animation);\n\n        if (jQuery.isFunction(animation.opts.start)) {\n            animation.opts.start.call(elem, animation);\n        }\n\n        jQuery.fx.timer(\n            jQuery.extend(tick, {\n                elem: elem,\n                anim: animation,\n                queue: animation.opts.queue\n            })\n        );\n\n        // attach callbacks from options\n        return animation.progress(animation.opts.progress)\n            .done(animation.opts.done, animation.opts.complete)\n            .fail(animation.opts.fail)\n            .always(animation.opts.always);\n    }\n\n    jQuery.Animation = jQuery.extend(Animation, {\n\n        tweener: function (props, callback) {\n            if (jQuery.isFunction(props)) {\n                callback = props;\n                props = [\"*\"];\n            } else {\n                props = props.split(\" \");\n            }\n\n            var prop,\n                index = 0,\n                length = props.length;\n\n            for (; index < length; index++) {\n                prop = props[index];\n                tweeners[prop] = tweeners[prop] || [];\n                tweeners[prop].unshift(callback);\n            }\n        },\n\n        prefilter: function (callback, prepend) {\n            if (prepend) {\n                animationPrefilters.unshift(callback);\n            } else {\n                animationPrefilters.push(callback);\n            }\n        }\n    });\n\n    jQuery.speed = function (speed, easing, fn) {\n        var opt = speed && typeof speed === \"object\" ? jQuery.extend({}, speed) : {\n            complete: fn || !fn && easing ||\n            jQuery.isFunction(speed) && speed,\n            duration: speed,\n            easing: fn && easing || easing && !jQuery.isFunction(easing) && easing\n        };\n\n        opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === \"number\" ? opt.duration :\n            opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;\n\n        // Normalize opt.queue - true/undefined/null -> \"fx\"\n        if (opt.queue == null || opt.queue === true) {\n            opt.queue = \"fx\";\n        }\n\n        // Queueing\n        opt.old = opt.complete;\n\n        opt.complete = function () {\n            if (jQuery.isFunction(opt.old)) {\n                opt.old.call(this);\n            }\n\n            if (opt.queue) {\n                jQuery.dequeue(this, opt.queue);\n            }\n        };\n\n        return opt;\n    };\n\n    jQuery.fn.extend({\n        fadeTo: function (speed, to, easing, callback) {\n\n            // Show any hidden elements after setting opacity to 0\n            return this.filter(isHidden).css(\"opacity\", 0).show()\n\n            // Animate to the value specified\n                .end().animate({opacity: to}, speed, easing, callback);\n        },\n        animate: function (prop, speed, easing, callback) {\n            var empty = jQuery.isEmptyObject(prop),\n                optall = jQuery.speed(speed, easing, callback),\n                doAnimation = function () {\n                    // Operate on a copy of prop so per-property easing won't be lost\n                    var anim = Animation(this, jQuery.extend({}, prop), optall);\n\n                    // Empty animations, or finishing resolves immediately\n                    if (empty || data_priv.get(this, \"finish\")) {\n                        anim.stop(true);\n                    }\n                };\n            doAnimation.finish = doAnimation;\n\n            return empty || optall.queue === false ?\n                this.each(doAnimation) :\n                this.queue(optall.queue, doAnimation);\n        },\n        stop: function (type, clearQueue, gotoEnd) {\n            var stopQueue = function (hooks) {\n                var stop = hooks.stop;\n                delete hooks.stop;\n                stop(gotoEnd);\n            };\n\n            if (typeof type !== \"string\") {\n                gotoEnd = clearQueue;\n                clearQueue = type;\n                type = undefined;\n            }\n            if (clearQueue && type !== false) {\n                this.queue(type || \"fx\", []);\n            }\n\n            return this.each(function () {\n                var dequeue = true,\n                    index = type != null && type + \"queueHooks\",\n                    timers = jQuery.timers,\n                    data = data_priv.get(this);\n\n                if (index) {\n                    if (data[index] && data[index].stop) {\n                        stopQueue(data[index]);\n                    }\n                } else {\n                    for (index in data) {\n                        if (data[index] && data[index].stop && rrun.test(index)) {\n                            stopQueue(data[index]);\n                        }\n                    }\n                }\n\n                for (index = timers.length; index--;) {\n                    if (timers[index].elem === this && (type == null || timers[index].queue === type)) {\n                        timers[index].anim.stop(gotoEnd);\n                        dequeue = false;\n                        timers.splice(index, 1);\n                    }\n                }\n\n                // Start the next in the queue if the last step wasn't forced.\n                // Timers currently will call their complete callbacks, which\n                // will dequeue but only if they were gotoEnd.\n                if (dequeue || !gotoEnd) {\n                    jQuery.dequeue(this, type);\n                }\n            });\n        },\n        finish: function (type) {\n            if (type !== false) {\n                type = type || \"fx\";\n            }\n            return this.each(function () {\n                var index,\n                    data = data_priv.get(this),\n                    queue = data[type + \"queue\"],\n                    hooks = data[type + \"queueHooks\"],\n                    timers = jQuery.timers,\n                    length = queue ? queue.length : 0;\n\n                // Enable finishing flag on private data\n                data.finish = true;\n\n                // Empty the queue first\n                jQuery.queue(this, type, []);\n\n                if (hooks && hooks.stop) {\n                    hooks.stop.call(this, true);\n                }\n\n                // Look for any active animations, and finish them\n                for (index = timers.length; index--;) {\n                    if (timers[index].elem === this && timers[index].queue === type) {\n                        timers[index].anim.stop(true);\n                        timers.splice(index, 1);\n                    }\n                }\n\n                // Look for any animations in the old queue and finish them\n                for (index = 0; index < length; index++) {\n                    if (queue[index] && queue[index].finish) {\n                        queue[index].finish.call(this);\n                    }\n                }\n\n                // Turn off finishing flag\n                delete data.finish;\n            });\n        }\n    });\n\n    jQuery.each([\"toggle\", \"show\", \"hide\"], function (i, name) {\n        var cssFn = jQuery.fn[name];\n        jQuery.fn[name] = function (speed, easing, callback) {\n            return speed == null || typeof speed === \"boolean\" ?\n                cssFn.apply(this, arguments) :\n                this.animate(genFx(name, true), speed, easing, callback);\n        };\n    });\n\n// Generate shortcuts for custom animations\n    jQuery.each({\n        slideDown: genFx(\"show\"),\n        slideUp: genFx(\"hide\"),\n        slideToggle: genFx(\"toggle\"),\n        fadeIn: {opacity: \"show\"},\n        fadeOut: {opacity: \"hide\"},\n        fadeToggle: {opacity: \"toggle\"}\n    }, function (name, props) {\n        jQuery.fn[name] = function (speed, easing, callback) {\n            return this.animate(props, speed, easing, callback);\n        };\n    });\n\n    jQuery.timers = [];\n    jQuery.fx.tick = function () {\n        var timer,\n            i = 0,\n            timers = jQuery.timers;\n\n        fxNow = jQuery.now();\n\n        for (; i < timers.length; i++) {\n            timer = timers[i];\n            // Checks the timer has not already been removed\n            if (!timer() && timers[i] === timer) {\n                timers.splice(i--, 1);\n            }\n        }\n\n        if (!timers.length) {\n            jQuery.fx.stop();\n        }\n        fxNow = undefined;\n    };\n\n    jQuery.fx.timer = function (timer) {\n        jQuery.timers.push(timer);\n        if (timer()) {\n            jQuery.fx.start();\n        } else {\n            jQuery.timers.pop();\n        }\n    };\n\n    jQuery.fx.interval = 13;\n\n    jQuery.fx.start = function () {\n        if (!timerId) {\n            timerId = setInterval(jQuery.fx.tick, jQuery.fx.interval);\n        }\n    };\n\n    jQuery.fx.stop = function () {\n        clearInterval(timerId);\n        timerId = null;\n    };\n\n    jQuery.fx.speeds = {\n        slow: 600,\n        fast: 200,\n        // Default speed\n        _default: 400\n    };\n\n\n// Based off of the plugin by Clint Helfers, with permission.\n// http://blindsignals.com/index.php/2009/07/jquery-delay/\n    jQuery.fn.delay = function (time, type) {\n        time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;\n        type = type || \"fx\";\n\n        return this.queue(type, function (next, hooks) {\n            var timeout = setTimeout(next, time);\n            hooks.stop = function () {\n                clearTimeout(timeout);\n            };\n        });\n    };\n\n\n    (function () {\n        var input = document.createElement(\"input\"),\n            select = document.createElement(\"select\"),\n            opt = select.appendChild(document.createElement(\"option\"));\n\n        input.type = \"checkbox\";\n\n        // Support: iOS<=5.1, Android<=4.2+\n        // Default value for a checkbox should be \"on\"\n        support.checkOn = input.value !== \"\";\n\n        // Support: IE<=11+\n        // Must access selectedIndex to make default options select\n        support.optSelected = opt.selected;\n\n        // Support: Android<=2.3\n        // Options inside disabled selects are incorrectly marked as disabled\n        select.disabled = true;\n        support.optDisabled = !opt.disabled;\n\n        // Support: IE<=11+\n        // An input loses its value after becoming a radio\n        input = document.createElement(\"input\");\n        input.value = \"t\";\n        input.type = \"radio\";\n        support.radioValue = input.value === \"t\";\n    })();\n\n\n    var nodeHook, boolHook,\n        attrHandle = jQuery.expr.attrHandle;\n\n    jQuery.fn.extend({\n        attr: function (name, value) {\n            return access(this, jQuery.attr, name, value, arguments.length > 1);\n        },\n\n        removeAttr: function (name) {\n            return this.each(function () {\n                jQuery.removeAttr(this, name);\n            });\n        }\n    });\n\n    jQuery.extend({\n        attr: function (elem, name, value) {\n            var hooks, ret,\n                nType = elem.nodeType;\n\n            // don't get/set attributes on text, comment and attribute nodes\n            if (!elem || nType === 3 || nType === 8 || nType === 2) {\n                return;\n            }\n\n            // Fallback to prop when attributes are not supported\n            if (typeof elem.getAttribute === strundefined) {\n                return jQuery.prop(elem, name, value);\n            }\n\n            // All attributes are lowercase\n            // Grab necessary hook if one is defined\n            if (nType !== 1 || !jQuery.isXMLDoc(elem)) {\n                name = name.toLowerCase();\n                hooks = jQuery.attrHooks[name] ||\n                    ( jQuery.expr.match.bool.test(name) ? boolHook : nodeHook );\n            }\n\n            if (value !== undefined) {\n\n                if (value === null) {\n                    jQuery.removeAttr(elem, name);\n\n                } else if (hooks && \"set\" in hooks && (ret = hooks.set(elem, value, name)) !== undefined) {\n                    return ret;\n\n                } else {\n                    elem.setAttribute(name, value + \"\");\n                    return value;\n                }\n\n            } else if (hooks && \"get\" in hooks && (ret = hooks.get(elem, name)) !== null) {\n                return ret;\n\n            } else {\n                ret = jQuery.find.attr(elem, name);\n\n                // Non-existent attributes return null, we normalize to undefined\n                return ret == null ?\n                    undefined :\n                    ret;\n            }\n        },\n\n        removeAttr: function (elem, value) {\n            var name, propName,\n                i = 0,\n                attrNames = value && value.match(rnotwhite);\n\n            if (attrNames && elem.nodeType === 1) {\n                while ((name = attrNames[i++])) {\n                    propName = jQuery.propFix[name] || name;\n\n                    // Boolean attributes get special treatment (#10870)\n                    if (jQuery.expr.match.bool.test(name)) {\n                        // Set corresponding property to false\n                        elem[propName] = false;\n                    }\n\n                    elem.removeAttribute(name);\n                }\n            }\n        },\n\n        attrHooks: {\n            type: {\n                set: function (elem, value) {\n                    if (!support.radioValue && value === \"radio\" &&\n                        jQuery.nodeName(elem, \"input\")) {\n                        var val = elem.value;\n                        elem.setAttribute(\"type\", value);\n                        if (val) {\n                            elem.value = val;\n                        }\n                        return value;\n                    }\n                }\n            }\n        }\n    });\n\n// Hooks for boolean attributes\n    boolHook = {\n        set: function (elem, value, name) {\n            if (value === false) {\n                // Remove boolean attributes when set to false\n                jQuery.removeAttr(elem, name);\n            } else {\n                elem.setAttribute(name, name);\n            }\n            return name;\n        }\n    };\n    jQuery.each(jQuery.expr.match.bool.source.match(/\\w+/g), function (i, name) {\n        var getter = attrHandle[name] || jQuery.find.attr;\n\n        attrHandle[name] = function (elem, name, isXML) {\n            var ret, handle;\n            if (!isXML) {\n                // Avoid an infinite loop by temporarily removing this function from the getter\n                handle = attrHandle[name];\n                attrHandle[name] = ret;\n                ret = getter(elem, name, isXML) != null ?\n                    name.toLowerCase() :\n                    null;\n                attrHandle[name] = handle;\n            }\n            return ret;\n        };\n    });\n\n\n    var rfocusable = /^(?:input|select|textarea|button)$/i;\n\n    jQuery.fn.extend({\n        prop: function (name, value) {\n            return access(this, jQuery.prop, name, value, arguments.length > 1);\n        },\n\n        removeProp: function (name) {\n            return this.each(function () {\n                delete this[jQuery.propFix[name] || name];\n            });\n        }\n    });\n\n    jQuery.extend({\n        propFix: {\n            \"for\": \"htmlFor\",\n            \"class\": \"className\"\n        },\n\n        prop: function (elem, name, value) {\n            var ret, hooks, notxml,\n                nType = elem.nodeType;\n\n            // Don't get/set properties on text, comment and attribute nodes\n            if (!elem || nType === 3 || nType === 8 || nType === 2) {\n                return;\n            }\n\n            notxml = nType !== 1 || !jQuery.isXMLDoc(elem);\n\n            if (notxml) {\n                // Fix name and attach hooks\n                name = jQuery.propFix[name] || name;\n                hooks = jQuery.propHooks[name];\n            }\n\n            if (value !== undefined) {\n                return hooks && \"set\" in hooks && (ret = hooks.set(elem, value, name)) !== undefined ?\n                    ret :\n                    ( elem[name] = value );\n\n            } else {\n                return hooks && \"get\" in hooks && (ret = hooks.get(elem, name)) !== null ?\n                    ret :\n                    elem[name];\n            }\n        },\n\n        propHooks: {\n            tabIndex: {\n                get: function (elem) {\n                    return elem.hasAttribute(\"tabindex\") || rfocusable.test(elem.nodeName) || elem.href ?\n                        elem.tabIndex :\n                        -1;\n                }\n            }\n        }\n    });\n\n    if (!support.optSelected) {\n        jQuery.propHooks.selected = {\n            get: function (elem) {\n                var parent = elem.parentNode;\n                if (parent && parent.parentNode) {\n                    parent.parentNode.selectedIndex;\n                }\n                return null;\n            }\n        };\n    }\n\n    jQuery.each([\n        \"tabIndex\",\n        \"readOnly\",\n        \"maxLength\",\n        \"cellSpacing\",\n        \"cellPadding\",\n        \"rowSpan\",\n        \"colSpan\",\n        \"useMap\",\n        \"frameBorder\",\n        \"contentEditable\"\n    ], function () {\n        jQuery.propFix[this.toLowerCase()] = this;\n    });\n\n\n    var rclass = /[\\t\\r\\n\\f]/g;\n\n    jQuery.fn.extend({\n        addClass: function (value) {\n            var classes, elem, cur, clazz, j, finalValue,\n                proceed = typeof value === \"string\" && value,\n                i = 0,\n                len = this.length;\n\n            if (jQuery.isFunction(value)) {\n                return this.each(function (j) {\n                    jQuery(this).addClass(value.call(this, j, this.className));\n                });\n            }\n\n            if (proceed) {\n                // The disjunction here is for better compressibility (see removeClass)\n                classes = ( value || \"\" ).match(rnotwhite) || [];\n\n                for (; i < len; i++) {\n                    elem = this[i];\n                    cur = elem.nodeType === 1 && ( elem.className ?\n                                ( \" \" + elem.className + \" \" ).replace(rclass, \" \") :\n                                \" \"\n                        );\n\n                    if (cur) {\n                        j = 0;\n                        while ((clazz = classes[j++])) {\n                            if (cur.indexOf(\" \" + clazz + \" \") < 0) {\n                                cur += clazz + \" \";\n                            }\n                        }\n\n                        // only assign if different to avoid unneeded rendering.\n                        finalValue = jQuery.trim(cur);\n                        if (elem.className !== finalValue) {\n                            elem.className = finalValue;\n                        }\n                    }\n                }\n            }\n\n            return this;\n        },\n\n        removeClass: function (value) {\n            var classes, elem, cur, clazz, j, finalValue,\n                proceed = arguments.length === 0 || typeof value === \"string\" && value,\n                i = 0,\n                len = this.length;\n\n            if (jQuery.isFunction(value)) {\n                return this.each(function (j) {\n                    jQuery(this).removeClass(value.call(this, j, this.className));\n                });\n            }\n            if (proceed) {\n                classes = ( value || \"\" ).match(rnotwhite) || [];\n\n                for (; i < len; i++) {\n                    elem = this[i];\n                    // This expression is here for better compressibility (see addClass)\n                    cur = elem.nodeType === 1 && ( elem.className ?\n                                ( \" \" + elem.className + \" \" ).replace(rclass, \" \") :\n                                \"\"\n                        );\n\n                    if (cur) {\n                        j = 0;\n                        while ((clazz = classes[j++])) {\n                            // Remove *all* instances\n                            while (cur.indexOf(\" \" + clazz + \" \") >= 0) {\n                                cur = cur.replace(\" \" + clazz + \" \", \" \");\n                            }\n                        }\n\n                        // Only assign if different to avoid unneeded rendering.\n                        finalValue = value ? jQuery.trim(cur) : \"\";\n                        if (elem.className !== finalValue) {\n                            elem.className = finalValue;\n                        }\n                    }\n                }\n            }\n\n            return this;\n        },\n\n        toggleClass: function (value, stateVal) {\n            var type = typeof value;\n\n            if (typeof stateVal === \"boolean\" && type === \"string\") {\n                return stateVal ? this.addClass(value) : this.removeClass(value);\n            }\n\n            if (jQuery.isFunction(value)) {\n                return this.each(function (i) {\n                    jQuery(this).toggleClass(value.call(this, i, this.className, stateVal), stateVal);\n                });\n            }\n\n            return this.each(function () {\n                if (type === \"string\") {\n                    // Toggle individual class names\n                    var className,\n                        i = 0,\n                        self = jQuery(this),\n                        classNames = value.match(rnotwhite) || [];\n\n                    while ((className = classNames[i++])) {\n                        // Check each className given, space separated list\n                        if (self.hasClass(className)) {\n                            self.removeClass(className);\n                        } else {\n                            self.addClass(className);\n                        }\n                    }\n\n                    // Toggle whole class name\n                } else if (type === strundefined || type === \"boolean\") {\n                    if (this.className) {\n                        // store className if set\n                        data_priv.set(this, \"__className__\", this.className);\n                    }\n\n                    // If the element has a class name or if we're passed `false`,\n                    // then remove the whole classname (if there was one, the above saved it).\n                    // Otherwise bring back whatever was previously saved (if anything),\n                    // falling back to the empty string if nothing was stored.\n                    this.className = this.className || value === false ? \"\" : data_priv.get(this, \"__className__\") || \"\";\n                }\n            });\n        },\n\n        hasClass: function (selector) {\n            var className = \" \" + selector + \" \",\n                i = 0,\n                l = this.length;\n            for (; i < l; i++) {\n                if (this[i].nodeType === 1 && (\" \" + this[i].className + \" \").replace(rclass, \" \").indexOf(className) >= 0) {\n                    return true;\n                }\n            }\n\n            return false;\n        }\n    });\n\n\n    var rreturn = /\\r/g;\n\n    jQuery.fn.extend({\n        val: function (value) {\n            var hooks, ret, isFunction,\n                elem = this[0];\n\n            if (!arguments.length) {\n                if (elem) {\n                    hooks = jQuery.valHooks[elem.type] || jQuery.valHooks[elem.nodeName.toLowerCase()];\n\n                    if (hooks && \"get\" in hooks && (ret = hooks.get(elem, \"value\")) !== undefined) {\n                        return ret;\n                    }\n\n                    ret = elem.value;\n\n                    return typeof ret === \"string\" ?\n                        // Handle most common string cases\n                        ret.replace(rreturn, \"\") :\n                        // Handle cases where value is null/undef or number\n                        ret == null ? \"\" : ret;\n                }\n\n                return;\n            }\n\n            isFunction = jQuery.isFunction(value);\n\n            return this.each(function (i) {\n                var val;\n\n                if (this.nodeType !== 1) {\n                    return;\n                }\n\n                if (isFunction) {\n                    val = value.call(this, i, jQuery(this).val());\n                } else {\n                    val = value;\n                }\n\n                // Treat null/undefined as \"\"; convert numbers to string\n                if (val == null) {\n                    val = \"\";\n\n                } else if (typeof val === \"number\") {\n                    val += \"\";\n\n                } else if (jQuery.isArray(val)) {\n                    val = jQuery.map(val, function (value) {\n                        return value == null ? \"\" : value + \"\";\n                    });\n                }\n\n                hooks = jQuery.valHooks[this.type] || jQuery.valHooks[this.nodeName.toLowerCase()];\n\n                // If set returns undefined, fall back to normal setting\n                if (!hooks || !(\"set\" in hooks) || hooks.set(this, val, \"value\") === undefined) {\n                    this.value = val;\n                }\n            });\n        }\n    });\n\n    jQuery.extend({\n        valHooks: {\n            option: {\n                get: function (elem) {\n                    var val = jQuery.find.attr(elem, \"value\");\n                    return val != null ?\n                        val :\n                        // Support: IE10-11+\n                        // option.text throws exceptions (#14686, #14858)\n                        jQuery.trim(jQuery.text(elem));\n                }\n            },\n            select: {\n                get: function (elem) {\n                    var value, option,\n                        options = elem.options,\n                        index = elem.selectedIndex,\n                        one = elem.type === \"select-one\" || index < 0,\n                        values = one ? null : [],\n                        max = one ? index + 1 : options.length,\n                        i = index < 0 ?\n                            max :\n                            one ? index : 0;\n\n                    // Loop through all the selected options\n                    for (; i < max; i++) {\n                        option = options[i];\n\n                        // IE6-9 doesn't update selected after form reset (#2551)\n                        if (( option.selected || i === index ) &&\n                            // Don't return options that are disabled or in a disabled optgroup\n                            ( support.optDisabled ? !option.disabled : option.getAttribute(\"disabled\") === null ) &&\n                            ( !option.parentNode.disabled || !jQuery.nodeName(option.parentNode, \"optgroup\") )) {\n\n                            // Get the specific value for the option\n                            value = jQuery(option).val();\n\n                            // We don't need an array for one selects\n                            if (one) {\n                                return value;\n                            }\n\n                            // Multi-Selects return an array\n                            values.push(value);\n                        }\n                    }\n\n                    return values;\n                },\n\n                set: function (elem, value) {\n                    var optionSet, option,\n                        options = elem.options,\n                        values = jQuery.makeArray(value),\n                        i = options.length;\n\n                    while (i--) {\n                        option = options[i];\n                        if ((option.selected = jQuery.inArray(option.value, values) >= 0)) {\n                            optionSet = true;\n                        }\n                    }\n\n                    // Force browsers to behave consistently when non-matching value is set\n                    if (!optionSet) {\n                        elem.selectedIndex = -1;\n                    }\n                    return values;\n                }\n            }\n        }\n    });\n\n// Radios and checkboxes getter/setter\n    jQuery.each([\"radio\", \"checkbox\"], function () {\n        jQuery.valHooks[this] = {\n            set: function (elem, value) {\n                if (jQuery.isArray(value)) {\n                    return ( elem.checked = jQuery.inArray(jQuery(elem).val(), value) >= 0 );\n                }\n            }\n        };\n        if (!support.checkOn) {\n            jQuery.valHooks[this].get = function (elem) {\n                return elem.getAttribute(\"value\") === null ? \"on\" : elem.value;\n            };\n        }\n    });\n\n\n// Return jQuery for attributes-only inclusion\n\n\n    jQuery.each((\"blur focus focusin focusout load resize scroll unload click dblclick \" +\n    \"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n    \"change select submit keydown keypress keyup error contextmenu\").split(\" \"), function (i, name) {\n\n        // Handle event binding\n        jQuery.fn[name] = function (data, fn) {\n            return arguments.length > 0 ?\n                this.on(name, null, data, fn) :\n                this.trigger(name);\n        };\n    });\n\n    jQuery.fn.extend({\n        hover: function (fnOver, fnOut) {\n            return this.mouseenter(fnOver).mouseleave(fnOut || fnOver);\n        },\n\n        bind: function (types, data, fn) {\n            return this.on(types, null, data, fn);\n        },\n        unbind: function (types, fn) {\n            return this.off(types, null, fn);\n        },\n\n        delegate: function (selector, types, data, fn) {\n            return this.on(types, selector, data, fn);\n        },\n        undelegate: function (selector, types, fn) {\n            // ( namespace ) or ( selector, types [, fn] )\n            return arguments.length === 1 ? this.off(selector, \"**\") : this.off(types, selector || \"**\", fn);\n        }\n    });\n\n\n    var nonce = jQuery.now();\n\n    var rquery = (/\\?/);\n\n\n// Support: Android 2.3\n// Workaround failure to string-cast null input\n    jQuery.parseJSON = function (data) {\n        return JSON.parse(data + \"\");\n    };\n\n\n// Cross-browser xml parsing\n    jQuery.parseXML = function (data) {\n        var xml, tmp;\n        if (!data || typeof data !== \"string\") {\n            return null;\n        }\n\n        // Support: IE9\n        try {\n            tmp = new DOMParser();\n            xml = tmp.parseFromString(data, \"text/xml\");\n        } catch (e) {\n            xml = undefined;\n        }\n\n        if (!xml || xml.getElementsByTagName(\"parsererror\").length) {\n            jQuery.error(\"Invalid XML: \" + data);\n        }\n        return xml;\n    };\n\n\n    var\n        rhash = /#.*$/,\n        rts = /([?&])_=[^&]*/,\n        rheaders = /^(.*?):[ \\t]*([^\\r\\n]*)$/mg,\n    // #7653, #8125, #8152: local protocol detection\n        rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n        rnoContent = /^(?:GET|HEAD)$/,\n        rprotocol = /^\\/\\//,\n        rurl = /^([\\w.+-]+:)(?:\\/\\/(?:[^\\/?#]*@|)([^\\/?#:]*)(?::(\\d+)|)|)/,\n\n    /* Prefilters\n     * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n     * 2) These are called:\n     *    - BEFORE asking for a transport\n     *    - AFTER param serialization (s.data is a string if s.processData is true)\n     * 3) key is the dataType\n     * 4) the catchall symbol \"*\" can be used\n     * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n     */\n        prefilters = {},\n\n    /* Transports bindings\n     * 1) key is the dataType\n     * 2) the catchall symbol \"*\" can be used\n     * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n     */\n        transports = {},\n\n    // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n        allTypes = \"*/\".concat(\"*\"),\n\n    // Document location\n        ajaxLocation = window.location.href,\n\n    // Segment location into parts\n        ajaxLocParts = rurl.exec(ajaxLocation.toLowerCase()) || [];\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\n    function addToPrefiltersOrTransports(structure) {\n\n        // dataTypeExpression is optional and defaults to \"*\"\n        return function (dataTypeExpression, func) {\n\n            if (typeof dataTypeExpression !== \"string\") {\n                func = dataTypeExpression;\n                dataTypeExpression = \"*\";\n            }\n\n            var dataType,\n                i = 0,\n                dataTypes = dataTypeExpression.toLowerCase().match(rnotwhite) || [];\n\n            if (jQuery.isFunction(func)) {\n                // For each dataType in the dataTypeExpression\n                while ((dataType = dataTypes[i++])) {\n                    // Prepend if requested\n                    if (dataType[0] === \"+\") {\n                        dataType = dataType.slice(1) || \"*\";\n                        (structure[dataType] = structure[dataType] || []).unshift(func);\n\n                        // Otherwise append\n                    } else {\n                        (structure[dataType] = structure[dataType] || []).push(func);\n                    }\n                }\n            }\n        };\n    }\n\n// Base inspection function for prefilters and transports\n    function inspectPrefiltersOrTransports(structure, options, originalOptions, jqXHR) {\n\n        var inspected = {},\n            seekingTransport = ( structure === transports );\n\n        function inspect(dataType) {\n            var selected;\n            inspected[dataType] = true;\n            jQuery.each(structure[dataType] || [], function (_, prefilterOrFactory) {\n                var dataTypeOrTransport = prefilterOrFactory(options, originalOptions, jqXHR);\n                if (typeof dataTypeOrTransport === \"string\" && !seekingTransport && !inspected[dataTypeOrTransport]) {\n                    options.dataTypes.unshift(dataTypeOrTransport);\n                    inspect(dataTypeOrTransport);\n                    return false;\n                } else if (seekingTransport) {\n                    return !( selected = dataTypeOrTransport );\n                }\n            });\n            return selected;\n        }\n\n        return inspect(options.dataTypes[0]) || !inspected[\"*\"] && inspect(\"*\");\n    }\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\n    function ajaxExtend(target, src) {\n        var key, deep,\n            flatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n        for (key in src) {\n            if (src[key] !== undefined) {\n                ( flatOptions[key] ? target : ( deep || (deep = {}) ) )[key] = src[key];\n            }\n        }\n        if (deep) {\n            jQuery.extend(true, target, deep);\n        }\n\n        return target;\n    }\n\n    /* Handles responses to an ajax request:\n     * - finds the right dataType (mediates between content-type and expected dataType)\n     * - returns the corresponding response\n     */\n    function ajaxHandleResponses(s, jqXHR, responses) {\n\n        var ct, type, finalDataType, firstDataType,\n            contents = s.contents,\n            dataTypes = s.dataTypes;\n\n        // Remove auto dataType and get content-type in the process\n        while (dataTypes[0] === \"*\") {\n            dataTypes.shift();\n            if (ct === undefined) {\n                ct = s.mimeType || jqXHR.getResponseHeader(\"Content-Type\");\n            }\n        }\n\n        // Check if we're dealing with a known content-type\n        if (ct) {\n            for (type in contents) {\n                if (contents[type] && contents[type].test(ct)) {\n                    dataTypes.unshift(type);\n                    break;\n                }\n            }\n        }\n\n        // Check to see if we have a response for the expected dataType\n        if (dataTypes[0] in responses) {\n            finalDataType = dataTypes[0];\n        } else {\n            // Try convertible dataTypes\n            for (type in responses) {\n                if (!dataTypes[0] || s.converters[type + \" \" + dataTypes[0]]) {\n                    finalDataType = type;\n                    break;\n                }\n                if (!firstDataType) {\n                    firstDataType = type;\n                }\n            }\n            // Or just use first one\n            finalDataType = finalDataType || firstDataType;\n        }\n\n        // If we found a dataType\n        // We add the dataType to the list if needed\n        // and return the corresponding response\n        if (finalDataType) {\n            if (finalDataType !== dataTypes[0]) {\n                dataTypes.unshift(finalDataType);\n            }\n            return responses[finalDataType];\n        }\n    }\n\n    /* Chain conversions given the request and the original response\n     * Also sets the responseXXX fields on the jqXHR instance\n     */\n    function ajaxConvert(s, response, jqXHR, isSuccess) {\n        var conv2, current, conv, tmp, prev,\n            converters = {},\n        // Work with a copy of dataTypes in case we need to modify it for conversion\n            dataTypes = s.dataTypes.slice();\n\n        // Create converters map with lowercased keys\n        if (dataTypes[1]) {\n            for (conv in s.converters) {\n                converters[conv.toLowerCase()] = s.converters[conv];\n            }\n        }\n\n        current = dataTypes.shift();\n\n        // Convert to each sequential dataType\n        while (current) {\n\n            if (s.responseFields[current]) {\n                jqXHR[s.responseFields[current]] = response;\n            }\n\n            // Apply the dataFilter if provided\n            if (!prev && isSuccess && s.dataFilter) {\n                response = s.dataFilter(response, s.dataType);\n            }\n\n            prev = current;\n            current = dataTypes.shift();\n\n            if (current) {\n\n                // There's only work to do if current dataType is non-auto\n                if (current === \"*\") {\n\n                    current = prev;\n\n                    // Convert response if prev dataType is non-auto and differs from current\n                } else if (prev !== \"*\" && prev !== current) {\n\n                    // Seek a direct converter\n                    conv = converters[prev + \" \" + current] || converters[\"* \" + current];\n\n                    // If none found, seek a pair\n                    if (!conv) {\n                        for (conv2 in converters) {\n\n                            // If conv2 outputs current\n                            tmp = conv2.split(\" \");\n                            if (tmp[1] === current) {\n\n                                // If prev can be converted to accepted input\n                                conv = converters[prev + \" \" + tmp[0]] ||\n                                    converters[\"* \" + tmp[0]];\n                                if (conv) {\n                                    // Condense equivalence converters\n                                    if (conv === true) {\n                                        conv = converters[conv2];\n\n                                        // Otherwise, insert the intermediate dataType\n                                    } else if (converters[conv2] !== true) {\n                                        current = tmp[0];\n                                        dataTypes.unshift(tmp[1]);\n                                    }\n                                    break;\n                                }\n                            }\n                        }\n                    }\n\n                    // Apply converter (if not an equivalence)\n                    if (conv !== true) {\n\n                        // Unless errors are allowed to bubble, catch and return them\n                        if (conv && s[\"throws\"]) {\n                            response = conv(response);\n                        } else {\n                            try {\n                                response = conv(response);\n                            } catch (e) {\n                                return {\n                                    state: \"parsererror\",\n                                    error: conv ? e : \"No conversion from \" + prev + \" to \" + current\n                                };\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        return {state: \"success\", data: response};\n    }\n\n    jQuery.extend({\n\n        // Counter for holding the number of active queries\n        active: 0,\n\n        // Last-Modified header cache for next request\n        lastModified: {},\n        etag: {},\n\n        ajaxSettings: {\n            url: ajaxLocation,\n            type: \"GET\",\n            isLocal: rlocalProtocol.test(ajaxLocParts[1]),\n            global: true,\n            processData: true,\n            async: true,\n            contentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n            /*\n             timeout: 0,\n             data: null,\n             dataType: null,\n             username: null,\n             password: null,\n             cache: null,\n             throws: false,\n             traditional: false,\n             headers: {},\n             */\n\n            accepts: {\n                \"*\": allTypes,\n                text: \"text/plain\",\n                html: \"text/html\",\n                xml: \"application/xml, text/xml\",\n                json: \"application/json, text/javascript\"\n            },\n\n            contents: {\n                xml: /xml/,\n                html: /html/,\n                json: /json/\n            },\n\n            responseFields: {\n                xml: \"responseXML\",\n                text: \"responseText\",\n                json: \"responseJSON\"\n            },\n\n            // Data converters\n            // Keys separate source (or catchall \"*\") and destination types with a single space\n            converters: {\n\n                // Convert anything to text\n                \"* text\": String,\n\n                // Text to html (true = no transformation)\n                \"text html\": true,\n\n                // Evaluate text as a json expression\n                \"text json\": jQuery.parseJSON,\n\n                // Parse text as xml\n                \"text xml\": jQuery.parseXML\n            },\n\n            // For options that shouldn't be deep extended:\n            // you can add your own custom options here if\n            // and when you create one that shouldn't be\n            // deep extended (see ajaxExtend)\n            flatOptions: {\n                url: true,\n                context: true\n            }\n        },\n\n        // Creates a full fledged settings object into target\n        // with both ajaxSettings and settings fields.\n        // If target is omitted, writes into ajaxSettings.\n        ajaxSetup: function (target, settings) {\n            return settings ?\n\n                // Building a settings object\n                ajaxExtend(ajaxExtend(target, jQuery.ajaxSettings), settings) :\n\n                // Extending ajaxSettings\n                ajaxExtend(jQuery.ajaxSettings, target);\n        },\n\n        ajaxPrefilter: addToPrefiltersOrTransports(prefilters),\n        ajaxTransport: addToPrefiltersOrTransports(transports),\n\n        // Main method\n        ajax: function (url, options) {\n\n            // If url is an object, simulate pre-1.5 signature\n            if (typeof url === \"object\") {\n                options = url;\n                url = undefined;\n            }\n\n            // Force options to be an object\n            options = options || {};\n\n            var transport,\n            // URL without anti-cache param\n                cacheURL,\n            // Response headers\n                responseHeadersString,\n                responseHeaders,\n            // timeout handle\n                timeoutTimer,\n            // Cross-domain detection vars\n                parts,\n            // To know if global events are to be dispatched\n                fireGlobals,\n            // Loop variable\n                i,\n            // Create the final options object\n                s = jQuery.ajaxSetup({}, options),\n            // Callbacks context\n                callbackContext = s.context || s,\n            // Context for global events is callbackContext if it is a DOM node or jQuery collection\n                globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?\n                    jQuery(callbackContext) :\n                    jQuery.event,\n            // Deferreds\n                deferred = jQuery.Deferred(),\n                completeDeferred = jQuery.Callbacks(\"once memory\"),\n            // Status-dependent callbacks\n                statusCode = s.statusCode || {},\n            // Headers (they are sent all at once)\n                requestHeaders = {},\n                requestHeadersNames = {},\n            // The jqXHR state\n                state = 0,\n            // Default abort message\n                strAbort = \"canceled\",\n            // Fake xhr\n                jqXHR = {\n                    readyState: 0,\n\n                    // Builds headers hashtable if needed\n                    getResponseHeader: function (key) {\n                        var match;\n                        if (state === 2) {\n                            if (!responseHeaders) {\n                                responseHeaders = {};\n                                while ((match = rheaders.exec(responseHeadersString))) {\n                                    responseHeaders[match[1].toLowerCase()] = match[2];\n                                }\n                            }\n                            match = responseHeaders[key.toLowerCase()];\n                        }\n                        return match == null ? null : match;\n                    },\n\n                    // Raw string\n                    getAllResponseHeaders: function () {\n                        return state === 2 ? responseHeadersString : null;\n                    },\n\n                    // Caches the header\n                    setRequestHeader: function (name, value) {\n                        var lname = name.toLowerCase();\n                        if (!state) {\n                            name = requestHeadersNames[lname] = requestHeadersNames[lname] || name;\n                            requestHeaders[name] = value;\n                        }\n                        return this;\n                    },\n\n                    // Overrides response content-type header\n                    overrideMimeType: function (type) {\n                        if (!state) {\n                            s.mimeType = type;\n                        }\n                        return this;\n                    },\n\n                    // Status-dependent callbacks\n                    statusCode: function (map) {\n                        var code;\n                        if (map) {\n                            if (state < 2) {\n                                for (code in map) {\n                                    // Lazy-add the new callback in a way that preserves old ones\n                                    statusCode[code] = [statusCode[code], map[code]];\n                                }\n                            } else {\n                                // Execute the appropriate callbacks\n                                jqXHR.always(map[jqXHR.status]);\n                            }\n                        }\n                        return this;\n                    },\n\n                    // Cancel the request\n                    abort: function (statusText) {\n                        var finalText = statusText || strAbort;\n                        if (transport) {\n                            transport.abort(finalText);\n                        }\n                        done(0, finalText);\n                        return this;\n                    }\n                };\n\n            // Attach deferreds\n            deferred.promise(jqXHR).complete = completeDeferred.add;\n            jqXHR.success = jqXHR.done;\n            jqXHR.error = jqXHR.fail;\n\n            // Remove hash character (#7531: and string promotion)\n            // Add protocol if not provided (prefilters might expect it)\n            // Handle falsy url in the settings object (#10093: consistency with old signature)\n            // We also use the url parameter if available\n            s.url = ( ( url || s.url || ajaxLocation ) + \"\" ).replace(rhash, \"\")\n                .replace(rprotocol, ajaxLocParts[1] + \"//\");\n\n            // Alias method option to type as per ticket #12004\n            s.type = options.method || options.type || s.method || s.type;\n\n            // Extract dataTypes list\n            s.dataTypes = jQuery.trim(s.dataType || \"*\").toLowerCase().match(rnotwhite) || [\"\"];\n\n            // A cross-domain request is in order when we have a protocol:host:port mismatch\n            if (s.crossDomain == null) {\n                parts = rurl.exec(s.url.toLowerCase());\n                s.crossDomain = !!( parts &&\n                    ( parts[1] !== ajaxLocParts[1] || parts[2] !== ajaxLocParts[2] ||\n                    ( parts[3] || ( parts[1] === \"http:\" ? \"80\" : \"443\" ) ) !==\n                    ( ajaxLocParts[3] || ( ajaxLocParts[1] === \"http:\" ? \"80\" : \"443\" ) ) )\n                );\n            }\n\n            // Convert data if not already a string\n            if (s.data && s.processData && typeof s.data !== \"string\") {\n                s.data = jQuery.param(s.data, s.traditional);\n            }\n\n            // Apply prefilters\n            inspectPrefiltersOrTransports(prefilters, s, options, jqXHR);\n\n            // If request was aborted inside a prefilter, stop there\n            if (state === 2) {\n                return jqXHR;\n            }\n\n            // We can fire global events as of now if asked to\n            // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)\n            fireGlobals = jQuery.event && s.global;\n\n            // Watch for a new set of requests\n            if (fireGlobals && jQuery.active++ === 0) {\n                jQuery.event.trigger(\"ajaxStart\");\n            }\n\n            // Uppercase the type\n            s.type = s.type.toUpperCase();\n\n            // Determine if request has content\n            s.hasContent = !rnoContent.test(s.type);\n\n            // Save the URL in case we're toying with the If-Modified-Since\n            // and/or If-None-Match header later on\n            cacheURL = s.url;\n\n            // More options handling for requests with no content\n            if (!s.hasContent) {\n\n                // If data is available, append data to url\n                if (s.data) {\n                    cacheURL = ( s.url += ( rquery.test(cacheURL) ? \"&\" : \"?\" ) + s.data );\n                    // #9682: remove data so that it's not used in an eventual retry\n                    delete s.data;\n                }\n\n                // Add anti-cache in url if needed\n                if (s.cache === false) {\n                    s.url = rts.test(cacheURL) ?\n\n                        // If there is already a '_' parameter, set its value\n                        cacheURL.replace(rts, \"$1_=\" + nonce++) :\n\n                        // Otherwise add one to the end\n                    cacheURL + ( rquery.test(cacheURL) ? \"&\" : \"?\" ) + \"_=\" + nonce++;\n                }\n            }\n\n            // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n            if (s.ifModified) {\n                if (jQuery.lastModified[cacheURL]) {\n                    jqXHR.setRequestHeader(\"If-Modified-Since\", jQuery.lastModified[cacheURL]);\n                }\n                if (jQuery.etag[cacheURL]) {\n                    jqXHR.setRequestHeader(\"If-None-Match\", jQuery.etag[cacheURL]);\n                }\n            }\n\n            // Set the correct header, if data is being sent\n            if (s.data && s.hasContent && s.contentType !== false || options.contentType) {\n                jqXHR.setRequestHeader(\"Content-Type\", s.contentType);\n            }\n\n            // Set the Accepts header for the server, depending on the dataType\n            jqXHR.setRequestHeader(\n                \"Accept\",\n                s.dataTypes[0] && s.accepts[s.dataTypes[0]] ?\n                s.accepts[s.dataTypes[0]] + ( s.dataTypes[0] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n                    s.accepts[\"*\"]\n            );\n\n            // Check for headers option\n            for (i in s.headers) {\n                jqXHR.setRequestHeader(i, s.headers[i]);\n            }\n\n            // Allow custom headers/mimetypes and early abort\n            if (s.beforeSend && ( s.beforeSend.call(callbackContext, jqXHR, s) === false || state === 2 )) {\n                // Abort if not done already and return\n                return jqXHR.abort();\n            }\n\n            // Aborting is no longer a cancellation\n            strAbort = \"abort\";\n\n            // Install callbacks on deferreds\n            for (i in {success: 1, error: 1, complete: 1}) {\n                jqXHR[i](s[i]);\n            }\n\n            // Get transport\n            transport = inspectPrefiltersOrTransports(transports, s, options, jqXHR);\n\n            // If no transport, we auto-abort\n            if (!transport) {\n                done(-1, \"No Transport\");\n            } else {\n                jqXHR.readyState = 1;\n\n                // Send global event\n                if (fireGlobals) {\n                    globalEventContext.trigger(\"ajaxSend\", [jqXHR, s]);\n                }\n                // Timeout\n                if (s.async && s.timeout > 0) {\n                    timeoutTimer = setTimeout(function () {\n                        jqXHR.abort(\"timeout\");\n                    }, s.timeout);\n                }\n\n                try {\n                    state = 1;\n                    transport.send(requestHeaders, done);\n                } catch (e) {\n                    // Propagate exception as error if not done\n                    if (state < 2) {\n                        done(-1, e);\n                        // Simply rethrow otherwise\n                    } else {\n                        throw e;\n                    }\n                }\n            }\n\n            // Callback for when everything is done\n            function done(status, nativeStatusText, responses, headers) {\n                var isSuccess, success, error, response, modified,\n                    statusText = nativeStatusText;\n\n                // Called once\n                if (state === 2) {\n                    return;\n                }\n\n                // State is \"done\" now\n                state = 2;\n\n                // Clear timeout if it exists\n                if (timeoutTimer) {\n                    clearTimeout(timeoutTimer);\n                }\n\n                // Dereference transport for early garbage collection\n                // (no matter how long the jqXHR object will be used)\n                transport = undefined;\n\n                // Cache response headers\n                responseHeadersString = headers || \"\";\n\n                // Set readyState\n                jqXHR.readyState = status > 0 ? 4 : 0;\n\n                // Determine if successful\n                isSuccess = status >= 200 && status < 300 || status === 304;\n\n                // Get response data\n                if (responses) {\n                    response = ajaxHandleResponses(s, jqXHR, responses);\n                }\n\n                // Convert no matter what (that way responseXXX fields are always set)\n                response = ajaxConvert(s, response, jqXHR, isSuccess);\n\n                // If successful, handle type chaining\n                if (isSuccess) {\n\n                    // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n                    if (s.ifModified) {\n                        modified = jqXHR.getResponseHeader(\"Last-Modified\");\n                        if (modified) {\n                            jQuery.lastModified[cacheURL] = modified;\n                        }\n                        modified = jqXHR.getResponseHeader(\"etag\");\n                        if (modified) {\n                            jQuery.etag[cacheURL] = modified;\n                        }\n                    }\n\n                    // if no content\n                    if (status === 204 || s.type === \"HEAD\") {\n                        statusText = \"nocontent\";\n\n                        // if not modified\n                    } else if (status === 304) {\n                        statusText = \"notmodified\";\n\n                        // If we have data, let's convert it\n                    } else {\n                        statusText = response.state;\n                        success = response.data;\n                        error = response.error;\n                        isSuccess = !error;\n                    }\n                } else {\n                    // Extract error from statusText and normalize for non-aborts\n                    error = statusText;\n                    if (status || !statusText) {\n                        statusText = \"error\";\n                        if (status < 0) {\n                            status = 0;\n                        }\n                    }\n                }\n\n                // Set data for the fake xhr object\n                jqXHR.status = status;\n                jqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n                // Success/Error\n                if (isSuccess) {\n                    deferred.resolveWith(callbackContext, [success, statusText, jqXHR]);\n                } else {\n                    deferred.rejectWith(callbackContext, [jqXHR, statusText, error]);\n                }\n\n                // Status-dependent callbacks\n                jqXHR.statusCode(statusCode);\n                statusCode = undefined;\n\n                if (fireGlobals) {\n                    globalEventContext.trigger(isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n                        [jqXHR, s, isSuccess ? success : error]);\n                }\n\n                // Complete\n                completeDeferred.fireWith(callbackContext, [jqXHR, statusText]);\n\n                if (fireGlobals) {\n                    globalEventContext.trigger(\"ajaxComplete\", [jqXHR, s]);\n                    // Handle the global AJAX counter\n                    if (!( --jQuery.active )) {\n                        jQuery.event.trigger(\"ajaxStop\");\n                    }\n                }\n            }\n\n            return jqXHR;\n        },\n\n        getJSON: function (url, data, callback) {\n            return jQuery.get(url, data, callback, \"json\");\n        },\n\n        getScript: function (url, callback) {\n            return jQuery.get(url, undefined, callback, \"script\");\n        }\n    });\n\n    jQuery.each([\"get\", \"post\"], function (i, method) {\n        jQuery[method] = function (url, data, callback, type) {\n            // Shift arguments if data argument was omitted\n            if (jQuery.isFunction(data)) {\n                type = type || callback;\n                callback = data;\n                data = undefined;\n            }\n\n            return jQuery.ajax({\n                url: url,\n                type: method,\n                dataType: type,\n                data: data,\n                success: callback\n            });\n        };\n    });\n\n\n    jQuery._evalUrl = function (url) {\n        return jQuery.ajax({\n            url: url,\n            type: \"GET\",\n            dataType: \"script\",\n            async: false,\n            global: false,\n            \"throws\": true\n        });\n    };\n\n\n    jQuery.fn.extend({\n        wrapAll: function (html) {\n            var wrap;\n\n            if (jQuery.isFunction(html)) {\n                return this.each(function (i) {\n                    jQuery(this).wrapAll(html.call(this, i));\n                });\n            }\n\n            if (this[0]) {\n\n                // The elements to wrap the target around\n                wrap = jQuery(html, this[0].ownerDocument).eq(0).clone(true);\n\n                if (this[0].parentNode) {\n                    wrap.insertBefore(this[0]);\n                }\n\n                wrap.map(function () {\n                    var elem = this;\n\n                    while (elem.firstElementChild) {\n                        elem = elem.firstElementChild;\n                    }\n\n                    return elem;\n                }).append(this);\n            }\n\n            return this;\n        },\n\n        wrapInner: function (html) {\n            if (jQuery.isFunction(html)) {\n                return this.each(function (i) {\n                    jQuery(this).wrapInner(html.call(this, i));\n                });\n            }\n\n            return this.each(function () {\n                var self = jQuery(this),\n                    contents = self.contents();\n\n                if (contents.length) {\n                    contents.wrapAll(html);\n\n                } else {\n                    self.append(html);\n                }\n            });\n        },\n\n        wrap: function (html) {\n            var isFunction = jQuery.isFunction(html);\n\n            return this.each(function (i) {\n                jQuery(this).wrapAll(isFunction ? html.call(this, i) : html);\n            });\n        },\n\n        unwrap: function () {\n            return this.parent().each(function () {\n                if (!jQuery.nodeName(this, \"body\")) {\n                    jQuery(this).replaceWith(this.childNodes);\n                }\n            }).end();\n        }\n    });\n\n\n    jQuery.expr.filters.hidden = function (elem) {\n        // Support: Opera <= 12.12\n        // Opera reports offsetWidths and offsetHeights less than zero on some elements\n        return elem.offsetWidth <= 0 && elem.offsetHeight <= 0;\n    };\n    jQuery.expr.filters.visible = function (elem) {\n        return !jQuery.expr.filters.hidden(elem);\n    };\n\n\n    var r20 = /%20/g,\n        rbracket = /\\[\\]$/,\n        rCRLF = /\\r?\\n/g,\n        rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n        rsubmittable = /^(?:input|select|textarea|keygen)/i;\n\n    function buildParams(prefix, obj, traditional, add) {\n        var name;\n\n        if (jQuery.isArray(obj)) {\n            // Serialize array item.\n            jQuery.each(obj, function (i, v) {\n                if (traditional || rbracket.test(prefix)) {\n                    // Treat each array item as a scalar.\n                    add(prefix, v);\n\n                } else {\n                    // Item is non-scalar (array or object), encode its numeric index.\n                    buildParams(prefix + \"[\" + ( typeof v === \"object\" ? i : \"\" ) + \"]\", v, traditional, add);\n                }\n            });\n\n        } else if (!traditional && jQuery.type(obj) === \"object\") {\n            // Serialize object item.\n            for (name in obj) {\n                buildParams(prefix + \"[\" + name + \"]\", obj[name], traditional, add);\n            }\n\n        } else {\n            // Serialize scalar item.\n            add(prefix, obj);\n        }\n    }\n\n// Serialize an array of form elements or a set of\n// key/values into a query string\n    jQuery.param = function (a, traditional) {\n        var prefix,\n            s = [],\n            add = function (key, value) {\n                // If value is a function, invoke it and return its value\n                value = jQuery.isFunction(value) ? value() : ( value == null ? \"\" : value );\n                s[s.length] = encodeURIComponent(key) + \"=\" + encodeURIComponent(value);\n            };\n\n        // Set traditional to true for jQuery <= 1.3.2 behavior.\n        if (traditional === undefined) {\n            traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;\n        }\n\n        // If an array was passed in, assume that it is an array of form elements.\n        if (jQuery.isArray(a) || ( a.jquery && !jQuery.isPlainObject(a) )) {\n            // Serialize the form elements\n            jQuery.each(a, function () {\n                add(this.name, this.value);\n            });\n\n        } else {\n            // If traditional, encode the \"old\" way (the way 1.3.2 or older\n            // did it), otherwise encode params recursively.\n            for (prefix in a) {\n                buildParams(prefix, a[prefix], traditional, add);\n            }\n        }\n\n        // Return the resulting serialization\n        return s.join(\"&\").replace(r20, \"+\");\n    };\n\n    jQuery.fn.extend({\n        serialize: function () {\n            return jQuery.param(this.serializeArray());\n        },\n        serializeArray: function () {\n            return this.map(function () {\n                // Can add propHook for \"elements\" to filter or add form elements\n                var elements = jQuery.prop(this, \"elements\");\n                return elements ? jQuery.makeArray(elements) : this;\n            })\n                .filter(function () {\n                    var type = this.type;\n\n                    // Use .is( \":disabled\" ) so that fieldset[disabled] works\n                    return this.name && !jQuery(this).is(\":disabled\") &&\n                        rsubmittable.test(this.nodeName) && !rsubmitterTypes.test(type) &&\n                        ( this.checked || !rcheckableType.test(type) );\n                })\n                .map(function (i, elem) {\n                    var val = jQuery(this).val();\n\n                    return val == null ?\n                        null :\n                        jQuery.isArray(val) ?\n                            jQuery.map(val, function (val) {\n                                return {name: elem.name, value: val.replace(rCRLF, \"\\r\\n\")};\n                            }) :\n                        {name: elem.name, value: val.replace(rCRLF, \"\\r\\n\")};\n                }).get();\n        }\n    });\n\n\n    jQuery.ajaxSettings.xhr = function () {\n        try {\n            return new XMLHttpRequest();\n        } catch (e) {\n        }\n    };\n\n    var xhrId = 0,\n        xhrCallbacks = {},\n        xhrSuccessStatus = {\n            // file protocol always yields status code 0, assume 200\n            0: 200,\n            // Support: IE9\n            // #1450: sometimes IE returns 1223 when it should be 204\n            1223: 204\n        },\n        xhrSupported = jQuery.ajaxSettings.xhr();\n\n// Support: IE9\n// Open requests must be manually aborted on unload (#5280)\n// See https://support.microsoft.com/kb/2856746 for more info\n    if (window.attachEvent) {\n        window.attachEvent(\"onunload\", function () {\n            for (var key in xhrCallbacks) {\n                xhrCallbacks[key]();\n            }\n        });\n    }\n\n    support.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\n    support.ajax = xhrSupported = !!xhrSupported;\n\n    jQuery.ajaxTransport(function (options) {\n        var callback;\n\n        // Cross domain only allowed if supported through XMLHttpRequest\n        if (support.cors || xhrSupported && !options.crossDomain) {\n            return {\n                send: function (headers, complete) {\n                    var i,\n                        xhr = options.xhr(),\n                        id = ++xhrId;\n\n                    xhr.open(options.type, options.url, options.async, options.username, options.password);\n\n                    // Apply custom fields if provided\n                    if (options.xhrFields) {\n                        for (i in options.xhrFields) {\n                            xhr[i] = options.xhrFields[i];\n                        }\n                    }\n\n                    // Override mime type if needed\n                    if (options.mimeType && xhr.overrideMimeType) {\n                        xhr.overrideMimeType(options.mimeType);\n                    }\n\n                    // X-Requested-With header\n                    // For cross-domain requests, seeing as conditions for a preflight are\n                    // akin to a jigsaw puzzle, we simply never set it to be sure.\n                    // (it can always be set on a per-request basis or even using ajaxSetup)\n                    // For same-domain requests, won't change header if already provided.\n                    if (!options.crossDomain && !headers[\"X-Requested-With\"]) {\n                        headers[\"X-Requested-With\"] = \"XMLHttpRequest\";\n                    }\n\n                    // Set headers\n                    for (i in headers) {\n                        xhr.setRequestHeader(i, headers[i]);\n                    }\n\n                    // Callback\n                    callback = function (type) {\n                        return function () {\n                            if (callback) {\n                                delete xhrCallbacks[id];\n                                callback = xhr.onload = xhr.onerror = null;\n\n                                if (type === \"abort\") {\n                                    xhr.abort();\n                                } else if (type === \"error\") {\n                                    complete(\n                                        // file: protocol always yields status 0; see #8605, #14207\n                                        xhr.status,\n                                        xhr.statusText\n                                    );\n                                } else {\n                                    complete(\n                                        xhrSuccessStatus[xhr.status] || xhr.status,\n                                        xhr.statusText,\n                                        // Support: IE9\n                                        // Accessing binary-data responseText throws an exception\n                                        // (#11426)\n                                        typeof xhr.responseText === \"string\" ? {\n                                            text: xhr.responseText\n                                        } : undefined,\n                                        xhr.getAllResponseHeaders()\n                                    );\n                                }\n                            }\n                        };\n                    };\n\n                    // Listen to events\n                    xhr.onload = callback();\n                    xhr.onerror = callback(\"error\");\n\n                    // Create the abort callback\n                    callback = xhrCallbacks[id] = callback(\"abort\");\n\n                    try {\n                        // Do send the request (this may raise an exception)\n                        xhr.send(options.hasContent && options.data || null);\n                    } catch (e) {\n                        // #14683: Only rethrow if this hasn't been notified as an error yet\n                        if (callback) {\n                            throw e;\n                        }\n                    }\n                },\n\n                abort: function () {\n                    if (callback) {\n                        callback();\n                    }\n                }\n            };\n        }\n    });\n\n\n// Install script dataType\n    jQuery.ajaxSetup({\n        accepts: {\n            script: \"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"\n        },\n        contents: {\n            script: /(?:java|ecma)script/\n        },\n        converters: {\n            \"text script\": function (text) {\n                jQuery.globalEval(text);\n                return text;\n            }\n        }\n    });\n\n// Handle cache's special case and crossDomain\n    jQuery.ajaxPrefilter(\"script\", function (s) {\n        if (s.cache === undefined) {\n            s.cache = false;\n        }\n        if (s.crossDomain) {\n            s.type = \"GET\";\n        }\n    });\n\n// Bind script tag hack transport\n    jQuery.ajaxTransport(\"script\", function (s) {\n        // This transport only deals with cross domain requests\n        if (s.crossDomain) {\n            var script, callback;\n            return {\n                send: function (_, complete) {\n                    script = jQuery(\"<script>\").prop({\n                        async: true,\n                        charset: s.scriptCharset,\n                        src: s.url\n                    }).on(\n                        \"load error\",\n                        callback = function (evt) {\n                            script.remove();\n                            callback = null;\n                            if (evt) {\n                                complete(evt.type === \"error\" ? 404 : 200, evt.type);\n                            }\n                        }\n                    );\n                    document.head.appendChild(script[0]);\n                },\n                abort: function () {\n                    if (callback) {\n                        callback();\n                    }\n                }\n            };\n        }\n    });\n\n\n    var oldCallbacks = [],\n        rjsonp = /(=)\\?(?=&|$)|\\?\\?/;\n\n// Default jsonp settings\n    jQuery.ajaxSetup({\n        jsonp: \"callback\",\n        jsonpCallback: function () {\n            var callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce++ ) );\n            this[callback] = true;\n            return callback;\n        }\n    });\n\n// Detect, normalize options and install callbacks for jsonp requests\n    jQuery.ajaxPrefilter(\"json jsonp\", function (s, originalSettings, jqXHR) {\n\n        var callbackName, overwritten, responseContainer,\n            jsonProp = s.jsonp !== false && ( rjsonp.test(s.url) ?\n                        \"url\" :\n                    typeof s.data === \"string\" && !( s.contentType || \"\" ).indexOf(\"application/x-www-form-urlencoded\") && rjsonp.test(s.data) && \"data\"\n                );\n\n        // Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n        if (jsonProp || s.dataTypes[0] === \"jsonp\") {\n\n            // Get callback name, remembering preexisting value associated with it\n            callbackName = s.jsonpCallback = jQuery.isFunction(s.jsonpCallback) ?\n                s.jsonpCallback() :\n                s.jsonpCallback;\n\n            // Insert callback into url or form data\n            if (jsonProp) {\n                s[jsonProp] = s[jsonProp].replace(rjsonp, \"$1\" + callbackName);\n            } else if (s.jsonp !== false) {\n                s.url += ( rquery.test(s.url) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n            }\n\n            // Use data converter to retrieve json after script execution\n            s.converters[\"script json\"] = function () {\n                if (!responseContainer) {\n                    jQuery.error(callbackName + \" was not called\");\n                }\n                return responseContainer[0];\n            };\n\n            // force json dataType\n            s.dataTypes[0] = \"json\";\n\n            // Install callback\n            overwritten = window[callbackName];\n            window[callbackName] = function () {\n                responseContainer = arguments;\n            };\n\n            // Clean-up function (fires after converters)\n            jqXHR.always(function () {\n                // Restore preexisting value\n                window[callbackName] = overwritten;\n\n                // Save back as free\n                if (s[callbackName]) {\n                    // make sure that re-using the options doesn't screw things around\n                    s.jsonpCallback = originalSettings.jsonpCallback;\n\n                    // save the callback name for future use\n                    oldCallbacks.push(callbackName);\n                }\n\n                // Call if it was a function and we have a response\n                if (responseContainer && jQuery.isFunction(overwritten)) {\n                    overwritten(responseContainer[0]);\n                }\n\n                responseContainer = overwritten = undefined;\n            });\n\n            // Delegate to script\n            return \"script\";\n        }\n    });\n\n\n// data: string of html\n// context (optional): If specified, the fragment will be created in this context, defaults to document\n// keepScripts (optional): If true, will include scripts passed in the html string\n    jQuery.parseHTML = function (data, context, keepScripts) {\n        if (!data || typeof data !== \"string\") {\n            return null;\n        }\n        if (typeof context === \"boolean\") {\n            keepScripts = context;\n            context = false;\n        }\n        context = context || document;\n\n        var parsed = rsingleTag.exec(data),\n            scripts = !keepScripts && [];\n\n        // Single tag\n        if (parsed) {\n            return [context.createElement(parsed[1])];\n        }\n\n        parsed = jQuery.buildFragment([data], context, scripts);\n\n        if (scripts && scripts.length) {\n            jQuery(scripts).remove();\n        }\n\n        return jQuery.merge([], parsed.childNodes);\n    };\n\n\n// Keep a copy of the old load method\n    var _load = jQuery.fn.load;\n\n    /**\n     * Load a url into a page\n     */\n    jQuery.fn.load = function (url, params, callback) {\n        if (typeof url !== \"string\" && _load) {\n            return _load.apply(this, arguments);\n        }\n\n        var selector, type, response,\n            self = this,\n            off = url.indexOf(\" \");\n\n        if (off >= 0) {\n            selector = jQuery.trim(url.slice(off));\n            url = url.slice(0, off);\n        }\n\n        // If it's a function\n        if (jQuery.isFunction(params)) {\n\n            // We assume that it's the callback\n            callback = params;\n            params = undefined;\n\n            // Otherwise, build a param string\n        } else if (params && typeof params === \"object\") {\n            type = \"POST\";\n        }\n\n        // If we have elements to modify, make the request\n        if (self.length > 0) {\n            jQuery.ajax({\n                url: url,\n\n                // if \"type\" variable is undefined, then \"GET\" method will be used\n                type: type,\n                dataType: \"html\",\n                data: params\n            }).done(function (responseText) {\n\n                // Save response for use in complete callback\n                response = arguments;\n\n                self.html(selector ?\n\n                    // If a selector was specified, locate the right elements in a dummy div\n                    // Exclude scripts to avoid IE 'Permission Denied' errors\n                    jQuery(\"<div>\").append(jQuery.parseHTML(responseText)).find(selector) :\n\n                    // Otherwise use the full result\n                    responseText);\n\n            }).complete(callback && function (jqXHR, status) {\n                    self.each(callback, response || [jqXHR.responseText, status, jqXHR]);\n                });\n        }\n\n        return this;\n    };\n\n\n// Attach a bunch of functions for handling common AJAX events\n    jQuery.each([\"ajaxStart\", \"ajaxStop\", \"ajaxComplete\", \"ajaxError\", \"ajaxSuccess\", \"ajaxSend\"], function (i, type) {\n        jQuery.fn[type] = function (fn) {\n            return this.on(type, fn);\n        };\n    });\n\n\n    jQuery.expr.filters.animated = function (elem) {\n        return jQuery.grep(jQuery.timers, function (fn) {\n            return elem === fn.elem;\n        }).length;\n    };\n\n\n    var docElem = window.document.documentElement;\n\n    /**\n     * Gets a window from an element\n     */\n    function getWindow(elem) {\n        return jQuery.isWindow(elem) ? elem : elem.nodeType === 9 && elem.defaultView;\n    }\n\n    jQuery.offset = {\n        setOffset: function (elem, options, i) {\n            var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,\n                position = jQuery.css(elem, \"position\"),\n                curElem = jQuery(elem),\n                props = {};\n\n            // Set position first, in-case top/left are set even on static elem\n            if (position === \"static\") {\n                elem.style.position = \"relative\";\n            }\n\n            curOffset = curElem.offset();\n            curCSSTop = jQuery.css(elem, \"top\");\n            curCSSLeft = jQuery.css(elem, \"left\");\n            calculatePosition = ( position === \"absolute\" || position === \"fixed\" ) &&\n                ( curCSSTop + curCSSLeft ).indexOf(\"auto\") > -1;\n\n            // Need to be able to calculate position if either\n            // top or left is auto and position is either absolute or fixed\n            if (calculatePosition) {\n                curPosition = curElem.position();\n                curTop = curPosition.top;\n                curLeft = curPosition.left;\n\n            } else {\n                curTop = parseFloat(curCSSTop) || 0;\n                curLeft = parseFloat(curCSSLeft) || 0;\n            }\n\n            if (jQuery.isFunction(options)) {\n                options = options.call(elem, i, curOffset);\n            }\n\n            if (options.top != null) {\n                props.top = ( options.top - curOffset.top ) + curTop;\n            }\n            if (options.left != null) {\n                props.left = ( options.left - curOffset.left ) + curLeft;\n            }\n\n            if (\"using\" in options) {\n                options.using.call(elem, props);\n\n            } else {\n                curElem.css(props);\n            }\n        }\n    };\n\n    jQuery.fn.extend({\n        offset: function (options) {\n            if (arguments.length) {\n                return options === undefined ?\n                    this :\n                    this.each(function (i) {\n                        jQuery.offset.setOffset(this, options, i);\n                    });\n            }\n\n            var docElem, win,\n                elem = this[0],\n                box = {top: 0, left: 0},\n                doc = elem && elem.ownerDocument;\n\n            if (!doc) {\n                return;\n            }\n\n            docElem = doc.documentElement;\n\n            // Make sure it's not a disconnected DOM node\n            if (!jQuery.contains(docElem, elem)) {\n                return box;\n            }\n\n            // Support: BlackBerry 5, iOS 3 (original iPhone)\n            // If we don't have gBCR, just use 0,0 rather than error\n            if (typeof elem.getBoundingClientRect !== strundefined) {\n                box = elem.getBoundingClientRect();\n            }\n            win = getWindow(doc);\n            return {\n                top: box.top + win.pageYOffset - docElem.clientTop,\n                left: box.left + win.pageXOffset - docElem.clientLeft\n            };\n        },\n\n        position: function () {\n            if (!this[0]) {\n                return;\n            }\n\n            var offsetParent, offset,\n                elem = this[0],\n                parentOffset = {top: 0, left: 0};\n\n            // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent\n            if (jQuery.css(elem, \"position\") === \"fixed\") {\n                // Assume getBoundingClientRect is there when computed position is fixed\n                offset = elem.getBoundingClientRect();\n\n            } else {\n                // Get *real* offsetParent\n                offsetParent = this.offsetParent();\n\n                // Get correct offsets\n                offset = this.offset();\n                if (!jQuery.nodeName(offsetParent[0], \"html\")) {\n                    parentOffset = offsetParent.offset();\n                }\n\n                // Add offsetParent borders\n                parentOffset.top += jQuery.css(offsetParent[0], \"borderTopWidth\", true);\n                parentOffset.left += jQuery.css(offsetParent[0], \"borderLeftWidth\", true);\n            }\n\n            // Subtract parent offsets and element margins\n            return {\n                top: offset.top - parentOffset.top - jQuery.css(elem, \"marginTop\", true),\n                left: offset.left - parentOffset.left - jQuery.css(elem, \"marginLeft\", true)\n            };\n        },\n\n        offsetParent: function () {\n            return this.map(function () {\n                var offsetParent = this.offsetParent || docElem;\n\n                while (offsetParent && ( !jQuery.nodeName(offsetParent, \"html\") && jQuery.css(offsetParent, \"position\") === \"static\" )) {\n                    offsetParent = offsetParent.offsetParent;\n                }\n\n                return offsetParent || docElem;\n            });\n        }\n    });\n\n// Create scrollLeft and scrollTop methods\n    jQuery.each({scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\"}, function (method, prop) {\n        var top = \"pageYOffset\" === prop;\n\n        jQuery.fn[method] = function (val) {\n            return access(this, function (elem, method, val) {\n                var win = getWindow(elem);\n\n                if (val === undefined) {\n                    return win ? win[prop] : elem[method];\n                }\n\n                if (win) {\n                    win.scrollTo(\n                        !top ? val : window.pageXOffset,\n                        top ? val : window.pageYOffset\n                    );\n\n                } else {\n                    elem[method] = val;\n                }\n            }, method, val, arguments.length, null);\n        };\n    });\n\n// Support: Safari<7+, Chrome<37+\n// Add the top/left cssHooks using jQuery.fn.position\n// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n// Blink bug: https://code.google.com/p/chromium/issues/detail?id=229280\n// getComputedStyle returns percent when specified for top/left/bottom/right;\n// rather than make the css module depend on the offset module, just check for it here\n    jQuery.each([\"top\", \"left\"], function (i, prop) {\n        jQuery.cssHooks[prop] = addGetHookIf(support.pixelPosition,\n            function (elem, computed) {\n                if (computed) {\n                    computed = curCSS(elem, prop);\n                    // If curCSS returns percentage, fallback to offset\n                    return rnumnonpx.test(computed) ?\n                    jQuery(elem).position()[prop] + \"px\" :\n                        computed;\n                }\n            }\n        );\n    });\n\n\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\n    jQuery.each({Height: \"height\", Width: \"width\"}, function (name, type) {\n        jQuery.each({padding: \"inner\" + name, content: type, \"\": \"outer\" + name}, function (defaultExtra, funcName) {\n            // Margin is only for outerHeight, outerWidth\n            jQuery.fn[funcName] = function (margin, value) {\n                var chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n                    extra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n                return access(this, function (elem, type, value) {\n                    var doc;\n\n                    if (jQuery.isWindow(elem)) {\n                        // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there\n                        // isn't a whole lot we can do. See pull request at this URL for discussion:\n                        // https://github.com/jquery/jquery/pull/764\n                        return elem.document.documentElement[\"client\" + name];\n                    }\n\n                    // Get document width or height\n                    if (elem.nodeType === 9) {\n                        doc = elem.documentElement;\n\n                        // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],\n                        // whichever is greatest\n                        return Math.max(\n                            elem.body[\"scroll\" + name], doc[\"scroll\" + name],\n                            elem.body[\"offset\" + name], doc[\"offset\" + name],\n                            doc[\"client\" + name]\n                        );\n                    }\n\n                    return value === undefined ?\n                        // Get width or height on the element, requesting but not forcing parseFloat\n                        jQuery.css(elem, type, extra) :\n\n                        // Set width or height on the element\n                        jQuery.style(elem, type, value, extra);\n                }, type, chainable ? margin : undefined, chainable, null);\n            };\n        });\n    });\n\n\n// The number of elements contained in the matched element set\n    jQuery.fn.size = function () {\n        return this.length;\n    };\n\n    jQuery.fn.andSelf = jQuery.fn.addBack;\n\n\n// Register as a named AMD module, since jQuery can be concatenated with other\n// files that may use define, but not via a proper concatenation script that\n// understands anonymous AMD modules. A named AMD is safest and most robust\n// way to register. Lowercase jquery is used because AMD module names are\n// derived from file names, and jQuery is normally delivered in a lowercase\n// file name. Do this after creating the global so that if an AMD module wants\n// to call noConflict to hide this version of jQuery, it will work.\n\n// Note that for maximum portability, libraries that are not jQuery should\n// declare themselves as anonymous modules, and avoid setting a global if an\n// AMD loader is present. jQuery is a special case. For more information, see\n// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon\n\n    if (typeof define === \"function\" && define.amd) {\n        define(\"jquery\", [], function () {\n            return jQuery;\n        });\n    }\n\n\n    var\n    // Map over jQuery in case of overwrite\n        _jQuery = window.jQuery,\n\n    // Map over the $ in case of overwrite\n        _$ = window.$;\n\n    jQuery.noConflict = function (deep) {\n        if (window.$ === jQuery) {\n            window.$ = _$;\n        }\n\n        if (deep && window.jQuery === jQuery) {\n            window.jQuery = _jQuery;\n        }\n\n        return jQuery;\n    };\n\n// Expose jQuery and $ identifiers, even in AMD\n// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)\n// and CommonJS for browser emulators (#13566)\n    if (typeof noGlobal === strundefined) {\n        window.jQuery = window.$ = jQuery;\n    }\n\n\n    return jQuery;\n\n}));\n"
  },
  {
    "path": "assets/lib/keymaster.js",
    "content": "//     keymaster.js\n//     (c) 2011-2013 Thomas Fuchs\n//     keymaster.js may be freely distributed under the MIT license.\n\n;(function (global) {\n    var k,\n        _handlers = {},\n        _mods = {16: false, 18: false, 17: false, 91: false},\n        _scope = 'all',\n\n    // modifier keys\n        _MODIFIERS = {\n            '⇧': 16, shift: 16,\n            '⌥': 18, alt: 18, option: 18,\n            '⌃': 17, ctrl: 17, control: 17,\n            '⌘': 91, command: 91\n        },\n    // special keys\n        _MAP = {\n            backspace: 8, tab: 9, clear: 12,\n            enter: 13, 'return': 13,\n            esc: 27, escape: 27, space: 32,\n            left: 37, up: 38,\n            right: 39, down: 40,\n            del: 46, 'delete': 46,\n            home: 36, end: 35,\n            pageup: 33, pagedown: 34,\n            ',': 188, '.': 190, '/': 191,\n            '`': 192, '-': 189, '=': 187,\n            ';': 186, '\\'': 222,\n            '[': 219, ']': 221, '\\\\': 220\n        },\n        code = function (x) {\n            return _MAP[x] || x.toUpperCase().charCodeAt(0);\n        },\n        _downKeys = [];\n\n    for (k = 1; k < 20; k++) _MAP['f' + k] = 111 + k;\n\n    // IE doesn't support Array#indexOf, so have a simple replacement\n    function index(array, item) {\n        var i = array.length;\n        while (i--) if (array[i] === item) return i;\n        return -1;\n    }\n\n    // for comparing mods before unassignment\n    function compareArray(a1, a2) {\n        if (a1.length != a2.length) return false;\n        for (var i = 0; i < a1.length; i++) {\n            if (a1[i] !== a2[i]) return false;\n        }\n        return true;\n    }\n\n    var modifierMap = {\n        16: 'shiftKey',\n        18: 'altKey',\n        17: 'ctrlKey',\n        91: 'metaKey'\n    };\n\n    function updateModifierKey(event) {\n        for (k in _mods) _mods[k] = event[modifierMap[k]];\n    };\n\n    // handle keydown event\n    function dispatch(event) {\n        var key, handler, k, i, modifiersMatch, scope;\n        key = event.keyCode;\n\n        if (index(_downKeys, key) == -1) {\n            _downKeys.push(key);\n        }\n\n        // if a modifier key, set the key.<modifierkeyname> property to true and return\n        if (key == 93 || key == 224) key = 91; // right command on webkit, command on Gecko\n        if (key in _mods) {\n            _mods[key] = true;\n            // 'assignKey' from inside this closure is exported to window.key\n            for (k in _MODIFIERS) if (_MODIFIERS[k] == key) assignKey[k] = true;\n            return;\n        }\n        updateModifierKey(event);\n\n        // see if we need to ignore the keypress (filter() can can be overridden)\n        // by default ignore key presses if a select, textarea, or input is focused\n        if (!assignKey.filter.call(this, event)) return;\n\n        // abort if no potentially matching shortcuts found\n        if (!(key in _handlers)) return;\n\n        scope = getScope();\n\n        // for each potential shortcut\n        for (i = 0; i < _handlers[key].length; i++) {\n            handler = _handlers[key][i];\n\n            // see if it's in the current scope\n            if (handler.scope == scope || handler.scope == 'all') {\n                // check if modifiers match if any\n                modifiersMatch = handler.mods.length > 0;\n                for (k in _mods)\n                    if ((!_mods[k] && index(handler.mods, +k) > -1) ||\n                        (_mods[k] && index(handler.mods, +k) == -1)) modifiersMatch = false;\n                // call the handler and stop the event if neccessary\n                if ((handler.mods.length == 0 && !_mods[16] && !_mods[18] && !_mods[17] && !_mods[91]) || modifiersMatch) {\n                    if (handler.method(event, handler) === false) {\n                        if (event.preventDefault) event.preventDefault();\n                        else event.returnValue = false;\n                        if (event.stopPropagation) event.stopPropagation();\n                        if (event.cancelBubble) event.cancelBubble = true;\n                    }\n                }\n            }\n        }\n    };\n\n    // unset modifier keys on keyup\n    function clearModifier(event) {\n        var key = event.keyCode, k,\n            i = index(_downKeys, key);\n\n        // remove key from _downKeys\n        if (i >= 0) {\n            _downKeys.splice(i, 1);\n        }\n\n        if (key == 93 || key == 224) key = 91;\n        if (key in _mods) {\n            _mods[key] = false;\n            for (k in _MODIFIERS) if (_MODIFIERS[k] == key) assignKey[k] = false;\n        }\n    };\n\n    function resetModifiers() {\n        for (k in _mods) _mods[k] = false;\n        for (k in _MODIFIERS) assignKey[k] = false;\n    };\n\n    // parse and assign shortcut\n    function assignKey(key, scope, method) {\n        var keys, mods;\n        keys = getKeys(key);\n        if (method === undefined) {\n            method = scope;\n            scope = 'all';\n        }\n\n        // for each shortcut\n        for (var i = 0; i < keys.length; i++) {\n            // set modifier keys if any\n            mods = [];\n            key = keys[i].split('+');\n            if (key.length > 1) {\n                mods = getMods(key);\n                key = [key[key.length - 1]];\n            }\n            // convert to keycode and...\n            key = key[0]\n            key = code(key);\n            // ...store handler\n            if (!(key in _handlers)) _handlers[key] = [];\n            _handlers[key].push({shortcut: keys[i], scope: scope, method: method, key: keys[i], mods: mods});\n        }\n    };\n\n    // unbind all handlers for given key in current scope\n    function unbindKey(key, scope) {\n        var multipleKeys, keys,\n            mods = [],\n            i, j, obj;\n\n        multipleKeys = getKeys(key);\n\n        for (j = 0; j < multipleKeys.length; j++) {\n            keys = multipleKeys[j].split('+');\n\n            if (keys.length > 1) {\n                mods = getMods(keys);\n            }\n\n            key = keys[keys.length - 1];\n            key = code(key);\n\n            if (scope === undefined) {\n                scope = getScope();\n            }\n            if (!_handlers[key]) {\n                return;\n            }\n            for (i = 0; i < _handlers[key].length; i++) {\n                obj = _handlers[key][i];\n                // only clear handlers if correct scope and mods match\n                if (obj.scope === scope && compareArray(obj.mods, mods)) {\n                    _handlers[key][i] = {};\n                }\n            }\n        }\n    };\n\n    // Returns true if the key with code 'keyCode' is currently down\n    // Converts strings into key codes.\n    function isPressed(keyCode) {\n        if (typeof(keyCode) == 'string') {\n            keyCode = code(keyCode);\n        }\n        return index(_downKeys, keyCode) != -1;\n    }\n\n    function getPressedKeyCodes() {\n        return _downKeys.slice(0);\n    }\n\n    function filter(event) {\n        var tagName = (event.target || event.srcElement).tagName;\n        // ignore keypressed in any elements that support keyboard data input\n        return !(tagName == 'INPUT' || tagName == 'SELECT' || tagName == 'TEXTAREA');\n    }\n\n    // initialize key.<modifier> to false\n    for (k in _MODIFIERS) assignKey[k] = false;\n\n    // set current scope (default 'all')\n    function setScope(scope) {\n        _scope = scope || 'all'\n    };\n    function getScope() {\n        return _scope || 'all'\n    };\n\n    // delete all handlers for a given scope\n    function deleteScope(scope) {\n        var key, handlers, i;\n\n        for (key in _handlers) {\n            handlers = _handlers[key];\n            for (i = 0; i < handlers.length;) {\n                if (handlers[i].scope === scope) handlers.splice(i, 1);\n                else i++;\n            }\n        }\n    };\n\n    // abstract key logic for assign and unassign\n    function getKeys(key) {\n        var keys;\n        key = key.replace(/\\s/g, '');\n        keys = key.split(',');\n        if ((keys[keys.length - 1]) == '') {\n            keys[keys.length - 2] += ',';\n        }\n        return keys;\n    }\n\n    // abstract mods logic for assign and unassign\n    function getMods(key) {\n        var mods = key.slice(0, key.length - 1);\n        for (var mi = 0; mi < mods.length; mi++)\n            mods[mi] = _MODIFIERS[mods[mi]];\n        return mods;\n    }\n\n    // cross-browser events\n    function addEvent(object, event, method) {\n        if (object.addEventListener)\n            object.addEventListener(event, method, false);\n        else if (object.attachEvent)\n            object.attachEvent('on' + event, function () {\n                method(window.event)\n            });\n    };\n\n    // set the handlers globally on document\n    addEvent(document, 'keydown', function (event) {\n        dispatch(event)\n    }); // Passing _scope to a callback to ensure it remains the same by execution. Fixes #48\n    addEvent(document, 'keyup', clearModifier);\n\n    // reset modifiers to false whenever the window is (re)focused.\n    addEvent(window, 'focus', resetModifiers);\n\n    // store previously defined key\n    var previousKey = global.key;\n\n    // restore previously defined key and return reference to our key object\n    function noConflict() {\n        var k = global.key;\n        global.key = previousKey;\n        return k;\n    }\n\n    // set window.key and window.key.set/get/deleteScope, and the default filter\n    global.key = assignKey;\n    global.key.setScope = setScope;\n    global.key.getScope = getScope;\n    global.key.deleteScope = deleteScope;\n    global.key.filter = filter;\n    global.key.isPressed = isPressed;\n    global.key.getPressedKeyCodes = getPressedKeyCodes;\n    global.key.noConflict = noConflict;\n    global.key.unbind = unbindKey;\n\n    if (typeof module !== 'undefined') module.exports = assignKey;\n\n})(this);\n"
  },
  {
    "path": "assets/lib/sanitize-html.js",
    "content": "(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.sanitizeHtml = f()}})(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);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.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(require,module,exports){\nvar htmlparser = require('htmlparser2');\nvar extend = require('xtend');\nvar quoteRegexp = require('regexp-quote');\n\nfunction each(obj, cb) {\n  if (obj) Object.keys(obj).forEach(function (key) {\n    cb(obj[key], key);\n  });\n}\n\n// Avoid false positives with .__proto__, .hasOwnProperty, etc.\nfunction has(obj, key) {\n  return ({}).hasOwnProperty.call(obj, key);\n}\n\nmodule.exports = sanitizeHtml;\n\n// Ignore the _recursing flag; it's there for recursive\n// invocation as a guard against this exploit:\n// https://github.com/fb55/htmlparser2/issues/105\n\nfunction sanitizeHtml(html, options, _recursing) {\n  var result = '';\n\n  function Frame(tag, attribs) {\n    var that = this;\n    this.tag = tag;\n    this.attribs = attribs || {};\n    this.tagPosition = result.length;\n    this.text = ''; // Node inner text\n\n    this.updateParentNodeText = function() {\n      if (stack.length) {\n          var parentFrame = stack[stack.length - 1];\n          parentFrame.text += that.text;\n      }\n    };\n  }\n\n  if (!options) {\n    options = sanitizeHtml.defaults;\n    options.parser = htmlParserDefaults;\n  } else {\n    options = extend(sanitizeHtml.defaults, options);\n    if (options.parser) {\n      options.parser = extend(htmlParserDefaults, options.parser);\n    } else {\n      options.parser = htmlParserDefaults;\n    }\n  }\n\n  // Tags that contain something other than HTML, or where discarding\n  // the text when the tag is disallowed makes sense for other reasons.\n  // If we are not allowing these tags, we should drop their content too.\n  // For other tags you would drop the tag but keep its content.\n  var nonTextTagsArray = options.nonTextTags || [ 'script', 'style', 'textarea' ];\n  var allowedAttributesMap;\n  var allowedAttributesGlobMap;\n  if(options.allowedAttributes) {\n    allowedAttributesMap = {};\n    allowedAttributesGlobMap = {};\n    each(options.allowedAttributes, function(attributes, tag) {\n      allowedAttributesMap[tag] = [];\n      var globRegex = [];\n      attributes.forEach(function(name) {\n        if(name.indexOf('*') >= 0) {\n          globRegex.push(quoteRegexp(name).replace(/\\\\\\*/g, '.*'));\n        } else {\n          allowedAttributesMap[tag].push(name);\n        }\n      });\n      allowedAttributesGlobMap[tag] = new RegExp('^(' + globRegex.join('|') + ')$');\n    });\n  }\n  var allowedClassesMap = {};\n  each(options.allowedClasses, function(classes, tag) {\n    // Implicitly allows the class attribute\n    if(allowedAttributesMap) {\n      if (!has(allowedAttributesMap, tag)) {\n        allowedAttributesMap[tag] = [];\n      }\n      allowedAttributesMap[tag].push('class');\n    }\n\n    allowedClassesMap[tag] = classes;\n  });\n\n  var transformTagsMap = {};\n  var transformTagsAll;\n  each(options.transformTags, function(transform, tag) {\n    var transFun;\n    if (typeof transform === 'function') {\n      transFun = transform;\n    } else if (typeof transform === \"string\") {\n      transFun = sanitizeHtml.simpleTransform(transform);\n    }\n    if (tag === '*') {\n      transformTagsAll = transFun;\n    } else {\n      transformTagsMap[tag] = transFun;\n    }\n  });\n\n  var depth = 0;\n  var stack = [];\n  var skipMap = {};\n  var transformMap = {};\n  var skipText = false;\n  var skipTextDepth = 0;\n\n  var parser = new htmlparser.Parser({\n    onopentag: function(name, attribs) {\n      if (skipText) {\n        skipTextDepth++;\n        return;\n      }\n      var frame = new Frame(name, attribs);\n      stack.push(frame);\n\n      var skip = false;\n      var hasText = frame.text ? true : false;\n      var transformedTag;\n      if (has(transformTagsMap, name)) {\n        transformedTag = transformTagsMap[name](name, attribs);\n\n        frame.attribs = attribs = transformedTag.attribs;\n\n        if (transformedTag.text !== undefined) {\n          frame.innerText = transformedTag.text;\n        }\n\n        if (name !== transformedTag.tagName) {\n          frame.name = name = transformedTag.tagName;\n          transformMap[depth] = transformedTag.tagName;\n        }\n      }\n      if (transformTagsAll) {\n        transformedTag = transformTagsAll(name, attribs);\n\n        frame.attribs = attribs = transformedTag.attribs;\n        if (name !== transformedTag.tagName) {\n          frame.name = name = transformedTag.tagName;\n          transformMap[depth] = transformedTag.tagName;\n        }\n      }\n\n      if (options.allowedTags && options.allowedTags.indexOf(name) === -1) {\n        skip = true;\n        if (nonTextTagsArray.indexOf(name) !== -1) {\n          skipText = true;\n          skipTextDepth = 1;\n        }\n        skipMap[depth] = true;\n      }\n      depth++;\n      if (skip) {\n        // We want the contents but not this tag\n        return;\n      }\n      result += '<' + name;\n      if (!allowedAttributesMap || has(allowedAttributesMap, name) || allowedAttributesMap['*']) {\n        each(attribs, function(value, a) {\n          if (!allowedAttributesMap ||\n              (has(allowedAttributesMap, name) && allowedAttributesMap[name].indexOf(a) !== -1 ) ||\n              (allowedAttributesMap['*'] && allowedAttributesMap['*'].indexOf(a) !== -1 ) ||\n              (has(allowedAttributesGlobMap, name) && allowedAttributesGlobMap[name].test(a)) ||\n              (allowedAttributesGlobMap['*'] && allowedAttributesGlobMap['*'].test(a))) {\n            if ((a === 'href') || (a === 'src')) {\n              if (naughtyHref(name, value)) {\n                delete frame.attribs[a];\n                return;\n              }\n            }\n            if (a === 'class') {\n              value = filterClasses(value, allowedClassesMap[name]);\n              if (!value.length) {\n                delete frame.attribs[a];\n                return;\n              }\n            }\n            result += ' ' + a;\n            if (value.length) {\n              result += '=\"' + escapeHtml(value) + '\"';\n            }\n          } else {\n            delete frame.attribs[a];\n          }\n        });\n      }\n      if (options.selfClosing.indexOf(name) !== -1) {\n        result += \" />\";\n      } else {\n        result += \">\";\n        if (frame.innerText && !hasText && !options.textFilter) {\n          result += frame.innerText;\n        }\n      }\n    },\n    ontext: function(text) {\n      if (skipText) {\n        return;\n      }\n      var lastFrame = stack[stack.length-1];\n      var tag;\n\n      if (lastFrame) {\n        tag = lastFrame.tag;\n        // If inner text was set by transform function then let's use it\n        text = lastFrame.innerText !== undefined ? lastFrame.innerText : text;\n      }\n\n      if ((tag === 'script') || (tag === 'style')) {\n        // htmlparser2 gives us these as-is. Escaping them ruins the content. Allowing\n        // script tags is, by definition, game over for XSS protection, so if that's\n        // your concern, don't allow them. The same is essentially true for style tags\n        // which have their own collection of XSS vectors.\n        result += text;\n      } else {\n        var escaped = escapeHtml(text);\n        if (options.textFilter) {\n          result += options.textFilter(escaped);\n        } else {\n          result += escaped;\n        }\n      }\n      if (stack.length) {\n           var frame = stack[stack.length - 1];\n           frame.text += text;\n      }\n    },\n    onclosetag: function(name) {\n\n      if (skipText) {\n        skipTextDepth--;\n        if (!skipTextDepth) {\n          skipText = false;\n        } else {\n          return;\n        }\n      }\n\n      var frame = stack.pop();\n      if (!frame) {\n        // Do not crash on bad markup\n        return;\n      }\n      skipText = false;\n      depth--;\n      if (skipMap[depth]) {\n        delete skipMap[depth];\n        frame.updateParentNodeText();\n        return;\n      }\n\n      if (transformMap[depth]) {\n        name = transformMap[depth];\n        delete transformMap[depth];\n      }\n\n      if (options.exclusiveFilter && options.exclusiveFilter(frame)) {\n         result = result.substr(0, frame.tagPosition);\n         return;\n      }\n\n      frame.updateParentNodeText();\n\n      if (options.selfClosing.indexOf(name) !== -1) {\n         // Already output />\n         return;\n      }\n\n      result += \"</\" + name + \">\";\n    }\n  }, options.parser);\n  parser.write(html);\n  parser.end();\n\n  return result;\n\n  function escapeHtml(s) {\n    if (typeof(s) !== 'string') {\n      s = s + '';\n    }\n    return s.replace(/\\&/g, '&amp;').replace(/</g, '&lt;').replace(/\\>/g, '&gt;').replace(/\\\"/g, '&quot;');\n  }\n\n  function naughtyHref(name, href) {\n    // Browsers ignore character codes of 32 (space) and below in a surprising\n    // number of situations. Start reading here:\n    // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#Embedded_tab\n    href = href.replace(/[\\x00-\\x20]+/g, '');\n    // Clobber any comments in URLs, which the browser might\n    // interpret inside an XML data island, allowing\n    // a javascript: URL to be snuck through\n    href = href.replace(/<\\!\\-\\-.*?\\-\\-\\>/g, '');\n    // Case insensitive so we don't get faked out by JAVASCRIPT #1\n    var matches = href.match(/^([a-zA-Z]+)\\:/);\n    if (!matches) {\n      // No scheme = no way to inject js (right?)\n      return false;\n    }\n    var scheme = matches[1].toLowerCase();\n\n    if (has(options.allowedSchemesByTag, name)) {\n      return options.allowedSchemesByTag[name].indexOf(scheme) === -1;\n    }\n\n    return !options.allowedSchemes || options.allowedSchemes.indexOf(scheme) === -1;\n  }\n\n  function filterClasses(classes, allowed) {\n    if (!allowed) {\n      // The class attribute is allowed without filtering on this tag\n      return classes;\n    }\n    classes = classes.split(/\\s+/);\n    return classes.filter(function(clss) {\n      return allowed.indexOf(clss) !== -1;\n    }).join(' ');\n  }\n}\n\n// Defaults are accessible to you so that you can use them as a starting point\n// programmatically if you wish\n\nvar htmlParserDefaults = {\n  decodeEntities: true\n};\nsanitizeHtml.defaults = {\n  allowedTags: [ 'h3', 'h4', 'h5', 'h6', 'blockquote', 'p', 'a', 'ul', 'ol',\n    'nl', 'li', 'b', 'i', 'strong', 'em', 'strike', 'code', 'hr', 'br', 'div',\n    'table', 'thead', 'caption', 'tbody', 'tr', 'th', 'td', 'pre' ],\n  allowedAttributes: {\n    a: [ 'href', 'name', 'target' ],\n    // We don't currently allow img itself by default, but this\n    // would make sense if we did\n    img: [ 'src' ]\n  },\n  // Lots of these won't come up by default because we don't allow them\n  selfClosing: [ 'img', 'br', 'hr', 'area', 'base', 'basefont', 'input', 'link', 'meta' ],\n  // URL schemes we permit\n  allowedSchemes: [ 'http', 'https', 'ftp', 'mailto' ],\n  allowedSchemesByTag: {}\n};\n\nsanitizeHtml.simpleTransform = function(newTagName, newAttribs, merge) {\n  merge = (merge === undefined) ? true : merge;\n  newAttribs = newAttribs || {};\n\n  return function(tagName, attribs) {\n    var attrib;\n    if (merge) {\n      for (attrib in newAttribs) {\n        attribs[attrib] = newAttribs[attrib];\n      }\n    } else {\n      attribs = newAttribs;\n    }\n\n    return {\n      tagName: newTagName,\n      attribs: attribs\n    };\n  };\n};\n\n},{\"htmlparser2\":36,\"regexp-quote\":54,\"xtend\":58}],2:[function(require,module,exports){\n'use strict'\n\nexports.byteLength = byteLength\nexports.toByteArray = toByteArray\nexports.fromByteArray = fromByteArray\n\nvar lookup = []\nvar revLookup = []\nvar Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array\n\nvar code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\nfor (var i = 0, len = code.length; i < len; ++i) {\n  lookup[i] = code[i]\n  revLookup[code.charCodeAt(i)] = i\n}\n\nrevLookup['-'.charCodeAt(0)] = 62\nrevLookup['_'.charCodeAt(0)] = 63\n\nfunction placeHoldersCount (b64) {\n  var len = b64.length\n  if (len % 4 > 0) {\n    throw new Error('Invalid string. Length must be a multiple of 4')\n  }\n\n  // the number of equal signs (place holders)\n  // if there are two placeholders, than the two characters before it\n  // represent one byte\n  // if there is only one, then the three characters before it represent 2 bytes\n  // this is just a cheap hack to not do indexOf twice\n  return b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0\n}\n\nfunction byteLength (b64) {\n  // base64 is 4/3 + up to two characters of the original data\n  return b64.length * 3 / 4 - placeHoldersCount(b64)\n}\n\nfunction toByteArray (b64) {\n  var i, j, l, tmp, placeHolders, arr\n  var len = b64.length\n  placeHolders = placeHoldersCount(b64)\n\n  arr = new Arr(len * 3 / 4 - placeHolders)\n\n  // if there are placeholders, only get up to the last complete 4 chars\n  l = placeHolders > 0 ? len - 4 : len\n\n  var L = 0\n\n  for (i = 0, j = 0; i < l; i += 4, j += 3) {\n    tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]\n    arr[L++] = (tmp >> 16) & 0xFF\n    arr[L++] = (tmp >> 8) & 0xFF\n    arr[L++] = tmp & 0xFF\n  }\n\n  if (placeHolders === 2) {\n    tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4)\n    arr[L++] = tmp & 0xFF\n  } else if (placeHolders === 1) {\n    tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2)\n    arr[L++] = (tmp >> 8) & 0xFF\n    arr[L++] = tmp & 0xFF\n  }\n\n  return arr\n}\n\nfunction tripletToBase64 (num) {\n  return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]\n}\n\nfunction encodeChunk (uint8, start, end) {\n  var tmp\n  var output = []\n  for (var i = start; i < end; i += 3) {\n    tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])\n    output.push(tripletToBase64(tmp))\n  }\n  return output.join('')\n}\n\nfunction fromByteArray (uint8) {\n  var tmp\n  var len = uint8.length\n  var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes\n  var output = ''\n  var parts = []\n  var maxChunkLength = 16383 // must be multiple of 3\n\n  // go through the array every three bytes, we'll deal with trailing stuff later\n  for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n    parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))\n  }\n\n  // pad the end with zeros, but make sure to not forget the extra bytes\n  if (extraBytes === 1) {\n    tmp = uint8[len - 1]\n    output += lookup[tmp >> 2]\n    output += lookup[(tmp << 4) & 0x3F]\n    output += '=='\n  } else if (extraBytes === 2) {\n    tmp = (uint8[len - 2] << 8) + (uint8[len - 1])\n    output += lookup[tmp >> 10]\n    output += lookup[(tmp >> 4) & 0x3F]\n    output += lookup[(tmp << 2) & 0x3F]\n    output += '='\n  }\n\n  parts.push(output)\n\n  return parts.join('')\n}\n\n},{}],3:[function(require,module,exports){\n\n},{}],4:[function(require,module,exports){\n(function (global){\n'use strict';\n\nvar buffer = require('buffer');\nvar Buffer = buffer.Buffer;\nvar SlowBuffer = buffer.SlowBuffer;\nvar MAX_LEN = buffer.kMaxLength || 2147483647;\nexports.alloc = function alloc(size, fill, encoding) {\n  if (typeof Buffer.alloc === 'function') {\n    return Buffer.alloc(size, fill, encoding);\n  }\n  if (typeof encoding === 'number') {\n    throw new TypeError('encoding must not be number');\n  }\n  if (typeof size !== 'number') {\n    throw new TypeError('size must be a number');\n  }\n  if (size > MAX_LEN) {\n    throw new RangeError('size is too large');\n  }\n  var enc = encoding;\n  var _fill = fill;\n  if (_fill === undefined) {\n    enc = undefined;\n    _fill = 0;\n  }\n  var buf = new Buffer(size);\n  if (typeof _fill === 'string') {\n    var fillBuf = new Buffer(_fill, enc);\n    var flen = fillBuf.length;\n    var i = -1;\n    while (++i < size) {\n      buf[i] = fillBuf[i % flen];\n    }\n  } else {\n    buf.fill(_fill);\n  }\n  return buf;\n}\nexports.allocUnsafe = function allocUnsafe(size) {\n  if (typeof Buffer.allocUnsafe === 'function') {\n    return Buffer.allocUnsafe(size);\n  }\n  if (typeof size !== 'number') {\n    throw new TypeError('size must be a number');\n  }\n  if (size > MAX_LEN) {\n    throw new RangeError('size is too large');\n  }\n  return new Buffer(size);\n}\nexports.from = function from(value, encodingOrOffset, length) {\n  if (typeof Buffer.from === 'function' && (!global.Uint8Array || Uint8Array.from !== Buffer.from)) {\n    return Buffer.from(value, encodingOrOffset, length);\n  }\n  if (typeof value === 'number') {\n    throw new TypeError('\"value\" argument must not be a number');\n  }\n  if (typeof value === 'string') {\n    return new Buffer(value, encodingOrOffset);\n  }\n  if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n    var offset = encodingOrOffset;\n    if (arguments.length === 1) {\n      return new Buffer(value);\n    }\n    if (typeof offset === 'undefined') {\n      offset = 0;\n    }\n    var len = length;\n    if (typeof len === 'undefined') {\n      len = value.byteLength - offset;\n    }\n    if (offset >= value.byteLength) {\n      throw new RangeError('\\'offset\\' is out of bounds');\n    }\n    if (len > value.byteLength - offset) {\n      throw new RangeError('\\'length\\' is out of bounds');\n    }\n    return new Buffer(value.slice(offset, offset + len));\n  }\n  if (Buffer.isBuffer(value)) {\n    var out = new Buffer(value.length);\n    value.copy(out, 0, 0, value.length);\n    return out;\n  }\n  if (value) {\n    if (Array.isArray(value) || (typeof ArrayBuffer !== 'undefined' && value.buffer instanceof ArrayBuffer) || 'length' in value) {\n      return new Buffer(value);\n    }\n    if (value.type === 'Buffer' && Array.isArray(value.data)) {\n      return new Buffer(value.data);\n    }\n  }\n\n  throw new TypeError('First argument must be a string, Buffer, ' + 'ArrayBuffer, Array, or array-like object.');\n}\nexports.allocUnsafeSlow = function allocUnsafeSlow(size) {\n  if (typeof Buffer.allocUnsafeSlow === 'function') {\n    return Buffer.allocUnsafeSlow(size);\n  }\n  if (typeof size !== 'number') {\n    throw new TypeError('size must be a number');\n  }\n  if (size >= MAX_LEN) {\n    throw new RangeError('size is too large');\n  }\n  return new SlowBuffer(size);\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"buffer\":5}],5:[function(require,module,exports){\n(function (global){\n/*!\n * The buffer module from node.js, for the browser.\n *\n * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>\n * @license  MIT\n */\n/* eslint-disable no-proto */\n\n'use strict'\n\nvar base64 = require('base64-js')\nvar ieee754 = require('ieee754')\nvar isArray = require('isarray')\n\nexports.Buffer = Buffer\nexports.SlowBuffer = SlowBuffer\nexports.INSPECT_MAX_BYTES = 50\n\n/**\n * If `Buffer.TYPED_ARRAY_SUPPORT`:\n *   === true    Use Uint8Array implementation (fastest)\n *   === false   Use Object implementation (most compatible, even IE6)\n *\n * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,\n * Opera 11.6+, iOS 4.2+.\n *\n * Due to various browser bugs, sometimes the Object implementation will be used even\n * when the browser supports typed arrays.\n *\n * Note:\n *\n *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,\n *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.\n *\n *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.\n *\n *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of\n *     incorrect length in some situations.\n\n * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they\n * get the Object implementation, which is slower but behaves correctly.\n */\nBuffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined\n  ? global.TYPED_ARRAY_SUPPORT\n  : typedArraySupport()\n\n/*\n * Export kMaxLength after typed array support is determined.\n */\nexports.kMaxLength = kMaxLength()\n\nfunction typedArraySupport () {\n  try {\n    var arr = new Uint8Array(1)\n    arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}\n    return arr.foo() === 42 && // typed array instances can be augmented\n        typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`\n        arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`\n  } catch (e) {\n    return false\n  }\n}\n\nfunction kMaxLength () {\n  return Buffer.TYPED_ARRAY_SUPPORT\n    ? 0x7fffffff\n    : 0x3fffffff\n}\n\nfunction createBuffer (that, length) {\n  if (kMaxLength() < length) {\n    throw new RangeError('Invalid typed array length')\n  }\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    // Return an augmented `Uint8Array` instance, for best performance\n    that = new Uint8Array(length)\n    that.__proto__ = Buffer.prototype\n  } else {\n    // Fallback: Return an object instance of the Buffer class\n    if (that === null) {\n      that = new Buffer(length)\n    }\n    that.length = length\n  }\n\n  return that\n}\n\n/**\n * The Buffer constructor returns instances of `Uint8Array` that have their\n * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of\n * `Uint8Array`, so the returned instances will have all the node `Buffer` methods\n * and the `Uint8Array` methods. Square bracket notation works as expected -- it\n * returns a single octet.\n *\n * The `Uint8Array` prototype remains unmodified.\n */\n\nfunction Buffer (arg, encodingOrOffset, length) {\n  if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {\n    return new Buffer(arg, encodingOrOffset, length)\n  }\n\n  // Common case.\n  if (typeof arg === 'number') {\n    if (typeof encodingOrOffset === 'string') {\n      throw new Error(\n        'If encoding is specified then the first argument must be a string'\n      )\n    }\n    return allocUnsafe(this, arg)\n  }\n  return from(this, arg, encodingOrOffset, length)\n}\n\nBuffer.poolSize = 8192 // not used by this implementation\n\n// TODO: Legacy, not needed anymore. Remove in next major version.\nBuffer._augment = function (arr) {\n  arr.__proto__ = Buffer.prototype\n  return arr\n}\n\nfunction from (that, value, encodingOrOffset, length) {\n  if (typeof value === 'number') {\n    throw new TypeError('\"value\" argument must not be a number')\n  }\n\n  if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n    return fromArrayBuffer(that, value, encodingOrOffset, length)\n  }\n\n  if (typeof value === 'string') {\n    return fromString(that, value, encodingOrOffset)\n  }\n\n  return fromObject(that, value)\n}\n\n/**\n * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError\n * if value is a number.\n * Buffer.from(str[, encoding])\n * Buffer.from(array)\n * Buffer.from(buffer)\n * Buffer.from(arrayBuffer[, byteOffset[, length]])\n **/\nBuffer.from = function (value, encodingOrOffset, length) {\n  return from(null, value, encodingOrOffset, length)\n}\n\nif (Buffer.TYPED_ARRAY_SUPPORT) {\n  Buffer.prototype.__proto__ = Uint8Array.prototype\n  Buffer.__proto__ = Uint8Array\n  if (typeof Symbol !== 'undefined' && Symbol.species &&\n      Buffer[Symbol.species] === Buffer) {\n    // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97\n    Object.defineProperty(Buffer, Symbol.species, {\n      value: null,\n      configurable: true\n    })\n  }\n}\n\nfunction assertSize (size) {\n  if (typeof size !== 'number') {\n    throw new TypeError('\"size\" argument must be a number')\n  } else if (size < 0) {\n    throw new RangeError('\"size\" argument must not be negative')\n  }\n}\n\nfunction alloc (that, size, fill, encoding) {\n  assertSize(size)\n  if (size <= 0) {\n    return createBuffer(that, size)\n  }\n  if (fill !== undefined) {\n    // Only pay attention to encoding if it's a string. This\n    // prevents accidentally sending in a number that would\n    // be interpretted as a start offset.\n    return typeof encoding === 'string'\n      ? createBuffer(that, size).fill(fill, encoding)\n      : createBuffer(that, size).fill(fill)\n  }\n  return createBuffer(that, size)\n}\n\n/**\n * Creates a new filled Buffer instance.\n * alloc(size[, fill[, encoding]])\n **/\nBuffer.alloc = function (size, fill, encoding) {\n  return alloc(null, size, fill, encoding)\n}\n\nfunction allocUnsafe (that, size) {\n  assertSize(size)\n  that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) {\n    for (var i = 0; i < size; ++i) {\n      that[i] = 0\n    }\n  }\n  return that\n}\n\n/**\n * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.\n * */\nBuffer.allocUnsafe = function (size) {\n  return allocUnsafe(null, size)\n}\n/**\n * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.\n */\nBuffer.allocUnsafeSlow = function (size) {\n  return allocUnsafe(null, size)\n}\n\nfunction fromString (that, string, encoding) {\n  if (typeof encoding !== 'string' || encoding === '') {\n    encoding = 'utf8'\n  }\n\n  if (!Buffer.isEncoding(encoding)) {\n    throw new TypeError('\"encoding\" must be a valid string encoding')\n  }\n\n  var length = byteLength(string, encoding) | 0\n  that = createBuffer(that, length)\n\n  var actual = that.write(string, encoding)\n\n  if (actual !== length) {\n    // Writing a hex string, for example, that contains invalid characters will\n    // cause everything after the first invalid character to be ignored. (e.g.\n    // 'abxxcd' will be treated as 'ab')\n    that = that.slice(0, actual)\n  }\n\n  return that\n}\n\nfunction fromArrayLike (that, array) {\n  var length = array.length < 0 ? 0 : checked(array.length) | 0\n  that = createBuffer(that, length)\n  for (var i = 0; i < length; i += 1) {\n    that[i] = array[i] & 255\n  }\n  return that\n}\n\nfunction fromArrayBuffer (that, array, byteOffset, length) {\n  array.byteLength // this throws if `array` is not a valid ArrayBuffer\n\n  if (byteOffset < 0 || array.byteLength < byteOffset) {\n    throw new RangeError('\\'offset\\' is out of bounds')\n  }\n\n  if (array.byteLength < byteOffset + (length || 0)) {\n    throw new RangeError('\\'length\\' is out of bounds')\n  }\n\n  if (byteOffset === undefined && length === undefined) {\n    array = new Uint8Array(array)\n  } else if (length === undefined) {\n    array = new Uint8Array(array, byteOffset)\n  } else {\n    array = new Uint8Array(array, byteOffset, length)\n  }\n\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    // Return an augmented `Uint8Array` instance, for best performance\n    that = array\n    that.__proto__ = Buffer.prototype\n  } else {\n    // Fallback: Return an object instance of the Buffer class\n    that = fromArrayLike(that, array)\n  }\n  return that\n}\n\nfunction fromObject (that, obj) {\n  if (Buffer.isBuffer(obj)) {\n    var len = checked(obj.length) | 0\n    that = createBuffer(that, len)\n\n    if (that.length === 0) {\n      return that\n    }\n\n    obj.copy(that, 0, 0, len)\n    return that\n  }\n\n  if (obj) {\n    if ((typeof ArrayBuffer !== 'undefined' &&\n        obj.buffer instanceof ArrayBuffer) || 'length' in obj) {\n      if (typeof obj.length !== 'number' || isnan(obj.length)) {\n        return createBuffer(that, 0)\n      }\n      return fromArrayLike(that, obj)\n    }\n\n    if (obj.type === 'Buffer' && isArray(obj.data)) {\n      return fromArrayLike(that, obj.data)\n    }\n  }\n\n  throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')\n}\n\nfunction checked (length) {\n  // Note: cannot use `length < kMaxLength()` here because that fails when\n  // length is NaN (which is otherwise coerced to zero.)\n  if (length >= kMaxLength()) {\n    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +\n                         'size: 0x' + kMaxLength().toString(16) + ' bytes')\n  }\n  return length | 0\n}\n\nfunction SlowBuffer (length) {\n  if (+length != length) { // eslint-disable-line eqeqeq\n    length = 0\n  }\n  return Buffer.alloc(+length)\n}\n\nBuffer.isBuffer = function isBuffer (b) {\n  return !!(b != null && b._isBuffer)\n}\n\nBuffer.compare = function compare (a, b) {\n  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {\n    throw new TypeError('Arguments must be Buffers')\n  }\n\n  if (a === b) return 0\n\n  var x = a.length\n  var y = b.length\n\n  for (var i = 0, len = Math.min(x, y); i < len; ++i) {\n    if (a[i] !== b[i]) {\n      x = a[i]\n      y = b[i]\n      break\n    }\n  }\n\n  if (x < y) return -1\n  if (y < x) return 1\n  return 0\n}\n\nBuffer.isEncoding = function isEncoding (encoding) {\n  switch (String(encoding).toLowerCase()) {\n    case 'hex':\n    case 'utf8':\n    case 'utf-8':\n    case 'ascii':\n    case 'latin1':\n    case 'binary':\n    case 'base64':\n    case 'ucs2':\n    case 'ucs-2':\n    case 'utf16le':\n    case 'utf-16le':\n      return true\n    default:\n      return false\n  }\n}\n\nBuffer.concat = function concat (list, length) {\n  if (!isArray(list)) {\n    throw new TypeError('\"list\" argument must be an Array of Buffers')\n  }\n\n  if (list.length === 0) {\n    return Buffer.alloc(0)\n  }\n\n  var i\n  if (length === undefined) {\n    length = 0\n    for (i = 0; i < list.length; ++i) {\n      length += list[i].length\n    }\n  }\n\n  var buffer = Buffer.allocUnsafe(length)\n  var pos = 0\n  for (i = 0; i < list.length; ++i) {\n    var buf = list[i]\n    if (!Buffer.isBuffer(buf)) {\n      throw new TypeError('\"list\" argument must be an Array of Buffers')\n    }\n    buf.copy(buffer, pos)\n    pos += buf.length\n  }\n  return buffer\n}\n\nfunction byteLength (string, encoding) {\n  if (Buffer.isBuffer(string)) {\n    return string.length\n  }\n  if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&\n      (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {\n    return string.byteLength\n  }\n  if (typeof string !== 'string') {\n    string = '' + string\n  }\n\n  var len = string.length\n  if (len === 0) return 0\n\n  // Use a for loop to avoid recursion\n  var loweredCase = false\n  for (;;) {\n    switch (encoding) {\n      case 'ascii':\n      case 'latin1':\n      case 'binary':\n        return len\n      case 'utf8':\n      case 'utf-8':\n      case undefined:\n        return utf8ToBytes(string).length\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return len * 2\n      case 'hex':\n        return len >>> 1\n      case 'base64':\n        return base64ToBytes(string).length\n      default:\n        if (loweredCase) return utf8ToBytes(string).length // assume utf8\n        encoding = ('' + encoding).toLowerCase()\n        loweredCase = true\n    }\n  }\n}\nBuffer.byteLength = byteLength\n\nfunction slowToString (encoding, start, end) {\n  var loweredCase = false\n\n  // No need to verify that \"this.length <= MAX_UINT32\" since it's a read-only\n  // property of a typed array.\n\n  // This behaves neither like String nor Uint8Array in that we set start/end\n  // to their upper/lower bounds if the value passed is out of range.\n  // undefined is handled specially as per ECMA-262 6th Edition,\n  // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.\n  if (start === undefined || start < 0) {\n    start = 0\n  }\n  // Return early if start > this.length. Done here to prevent potential uint32\n  // coercion fail below.\n  if (start > this.length) {\n    return ''\n  }\n\n  if (end === undefined || end > this.length) {\n    end = this.length\n  }\n\n  if (end <= 0) {\n    return ''\n  }\n\n  // Force coersion to uint32. This will also coerce falsey/NaN values to 0.\n  end >>>= 0\n  start >>>= 0\n\n  if (end <= start) {\n    return ''\n  }\n\n  if (!encoding) encoding = 'utf8'\n\n  while (true) {\n    switch (encoding) {\n      case 'hex':\n        return hexSlice(this, start, end)\n\n      case 'utf8':\n      case 'utf-8':\n        return utf8Slice(this, start, end)\n\n      case 'ascii':\n        return asciiSlice(this, start, end)\n\n      case 'latin1':\n      case 'binary':\n        return latin1Slice(this, start, end)\n\n      case 'base64':\n        return base64Slice(this, start, end)\n\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return utf16leSlice(this, start, end)\n\n      default:\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n        encoding = (encoding + '').toLowerCase()\n        loweredCase = true\n    }\n  }\n}\n\n// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect\n// Buffer instances.\nBuffer.prototype._isBuffer = true\n\nfunction swap (b, n, m) {\n  var i = b[n]\n  b[n] = b[m]\n  b[m] = i\n}\n\nBuffer.prototype.swap16 = function swap16 () {\n  var len = this.length\n  if (len % 2 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 16-bits')\n  }\n  for (var i = 0; i < len; i += 2) {\n    swap(this, i, i + 1)\n  }\n  return this\n}\n\nBuffer.prototype.swap32 = function swap32 () {\n  var len = this.length\n  if (len % 4 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 32-bits')\n  }\n  for (var i = 0; i < len; i += 4) {\n    swap(this, i, i + 3)\n    swap(this, i + 1, i + 2)\n  }\n  return this\n}\n\nBuffer.prototype.swap64 = function swap64 () {\n  var len = this.length\n  if (len % 8 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 64-bits')\n  }\n  for (var i = 0; i < len; i += 8) {\n    swap(this, i, i + 7)\n    swap(this, i + 1, i + 6)\n    swap(this, i + 2, i + 5)\n    swap(this, i + 3, i + 4)\n  }\n  return this\n}\n\nBuffer.prototype.toString = function toString () {\n  var length = this.length | 0\n  if (length === 0) return ''\n  if (arguments.length === 0) return utf8Slice(this, 0, length)\n  return slowToString.apply(this, arguments)\n}\n\nBuffer.prototype.equals = function equals (b) {\n  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\n  if (this === b) return true\n  return Buffer.compare(this, b) === 0\n}\n\nBuffer.prototype.inspect = function inspect () {\n  var str = ''\n  var max = exports.INSPECT_MAX_BYTES\n  if (this.length > 0) {\n    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')\n    if (this.length > max) str += ' ... '\n  }\n  return '<Buffer ' + str + '>'\n}\n\nBuffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {\n  if (!Buffer.isBuffer(target)) {\n    throw new TypeError('Argument must be a Buffer')\n  }\n\n  if (start === undefined) {\n    start = 0\n  }\n  if (end === undefined) {\n    end = target ? target.length : 0\n  }\n  if (thisStart === undefined) {\n    thisStart = 0\n  }\n  if (thisEnd === undefined) {\n    thisEnd = this.length\n  }\n\n  if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {\n    throw new RangeError('out of range index')\n  }\n\n  if (thisStart >= thisEnd && start >= end) {\n    return 0\n  }\n  if (thisStart >= thisEnd) {\n    return -1\n  }\n  if (start >= end) {\n    return 1\n  }\n\n  start >>>= 0\n  end >>>= 0\n  thisStart >>>= 0\n  thisEnd >>>= 0\n\n  if (this === target) return 0\n\n  var x = thisEnd - thisStart\n  var y = end - start\n  var len = Math.min(x, y)\n\n  var thisCopy = this.slice(thisStart, thisEnd)\n  var targetCopy = target.slice(start, end)\n\n  for (var i = 0; i < len; ++i) {\n    if (thisCopy[i] !== targetCopy[i]) {\n      x = thisCopy[i]\n      y = targetCopy[i]\n      break\n    }\n  }\n\n  if (x < y) return -1\n  if (y < x) return 1\n  return 0\n}\n\n// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,\n// OR the last index of `val` in `buffer` at offset <= `byteOffset`.\n//\n// Arguments:\n// - buffer - a Buffer to search\n// - val - a string, Buffer, or number\n// - byteOffset - an index into `buffer`; will be clamped to an int32\n// - encoding - an optional encoding, relevant is val is a string\n// - dir - true for indexOf, false for lastIndexOf\nfunction bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {\n  // Empty buffer means no match\n  if (buffer.length === 0) return -1\n\n  // Normalize byteOffset\n  if (typeof byteOffset === 'string') {\n    encoding = byteOffset\n    byteOffset = 0\n  } else if (byteOffset > 0x7fffffff) {\n    byteOffset = 0x7fffffff\n  } else if (byteOffset < -0x80000000) {\n    byteOffset = -0x80000000\n  }\n  byteOffset = +byteOffset  // Coerce to Number.\n  if (isNaN(byteOffset)) {\n    // byteOffset: it it's undefined, null, NaN, \"foo\", etc, search whole buffer\n    byteOffset = dir ? 0 : (buffer.length - 1)\n  }\n\n  // Normalize byteOffset: negative offsets start from the end of the buffer\n  if (byteOffset < 0) byteOffset = buffer.length + byteOffset\n  if (byteOffset >= buffer.length) {\n    if (dir) return -1\n    else byteOffset = buffer.length - 1\n  } else if (byteOffset < 0) {\n    if (dir) byteOffset = 0\n    else return -1\n  }\n\n  // Normalize val\n  if (typeof val === 'string') {\n    val = Buffer.from(val, encoding)\n  }\n\n  // Finally, search either indexOf (if dir is true) or lastIndexOf\n  if (Buffer.isBuffer(val)) {\n    // Special case: looking for empty string/buffer always fails\n    if (val.length === 0) {\n      return -1\n    }\n    return arrayIndexOf(buffer, val, byteOffset, encoding, dir)\n  } else if (typeof val === 'number') {\n    val = val & 0xFF // Search for a byte value [0-255]\n    if (Buffer.TYPED_ARRAY_SUPPORT &&\n        typeof Uint8Array.prototype.indexOf === 'function') {\n      if (dir) {\n        return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)\n      } else {\n        return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)\n      }\n    }\n    return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)\n  }\n\n  throw new TypeError('val must be string, number or Buffer')\n}\n\nfunction arrayIndexOf (arr, val, byteOffset, encoding, dir) {\n  var indexSize = 1\n  var arrLength = arr.length\n  var valLength = val.length\n\n  if (encoding !== undefined) {\n    encoding = String(encoding).toLowerCase()\n    if (encoding === 'ucs2' || encoding === 'ucs-2' ||\n        encoding === 'utf16le' || encoding === 'utf-16le') {\n      if (arr.length < 2 || val.length < 2) {\n        return -1\n      }\n      indexSize = 2\n      arrLength /= 2\n      valLength /= 2\n      byteOffset /= 2\n    }\n  }\n\n  function read (buf, i) {\n    if (indexSize === 1) {\n      return buf[i]\n    } else {\n      return buf.readUInt16BE(i * indexSize)\n    }\n  }\n\n  var i\n  if (dir) {\n    var foundIndex = -1\n    for (i = byteOffset; i < arrLength; i++) {\n      if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {\n        if (foundIndex === -1) foundIndex = i\n        if (i - foundIndex + 1 === valLength) return foundIndex * indexSize\n      } else {\n        if (foundIndex !== -1) i -= i - foundIndex\n        foundIndex = -1\n      }\n    }\n  } else {\n    if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength\n    for (i = byteOffset; i >= 0; i--) {\n      var found = true\n      for (var j = 0; j < valLength; j++) {\n        if (read(arr, i + j) !== read(val, j)) {\n          found = false\n          break\n        }\n      }\n      if (found) return i\n    }\n  }\n\n  return -1\n}\n\nBuffer.prototype.includes = function includes (val, byteOffset, encoding) {\n  return this.indexOf(val, byteOffset, encoding) !== -1\n}\n\nBuffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {\n  return bidirectionalIndexOf(this, val, byteOffset, encoding, true)\n}\n\nBuffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {\n  return bidirectionalIndexOf(this, val, byteOffset, encoding, false)\n}\n\nfunction hexWrite (buf, string, offset, length) {\n  offset = Number(offset) || 0\n  var remaining = buf.length - offset\n  if (!length) {\n    length = remaining\n  } else {\n    length = Number(length)\n    if (length > remaining) {\n      length = remaining\n    }\n  }\n\n  // must be an even number of digits\n  var strLen = string.length\n  if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')\n\n  if (length > strLen / 2) {\n    length = strLen / 2\n  }\n  for (var i = 0; i < length; ++i) {\n    var parsed = parseInt(string.substr(i * 2, 2), 16)\n    if (isNaN(parsed)) return i\n    buf[offset + i] = parsed\n  }\n  return i\n}\n\nfunction utf8Write (buf, string, offset, length) {\n  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nfunction asciiWrite (buf, string, offset, length) {\n  return blitBuffer(asciiToBytes(string), buf, offset, length)\n}\n\nfunction latin1Write (buf, string, offset, length) {\n  return asciiWrite(buf, string, offset, length)\n}\n\nfunction base64Write (buf, string, offset, length) {\n  return blitBuffer(base64ToBytes(string), buf, offset, length)\n}\n\nfunction ucs2Write (buf, string, offset, length) {\n  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nBuffer.prototype.write = function write (string, offset, length, encoding) {\n  // Buffer#write(string)\n  if (offset === undefined) {\n    encoding = 'utf8'\n    length = this.length\n    offset = 0\n  // Buffer#write(string, encoding)\n  } else if (length === undefined && typeof offset === 'string') {\n    encoding = offset\n    length = this.length\n    offset = 0\n  // Buffer#write(string, offset[, length][, encoding])\n  } else if (isFinite(offset)) {\n    offset = offset | 0\n    if (isFinite(length)) {\n      length = length | 0\n      if (encoding === undefined) encoding = 'utf8'\n    } else {\n      encoding = length\n      length = undefined\n    }\n  // legacy write(string, encoding, offset, length) - remove in v0.13\n  } else {\n    throw new Error(\n      'Buffer.write(string, encoding, offset[, length]) is no longer supported'\n    )\n  }\n\n  var remaining = this.length - offset\n  if (length === undefined || length > remaining) length = remaining\n\n  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {\n    throw new RangeError('Attempt to write outside buffer bounds')\n  }\n\n  if (!encoding) encoding = 'utf8'\n\n  var loweredCase = false\n  for (;;) {\n    switch (encoding) {\n      case 'hex':\n        return hexWrite(this, string, offset, length)\n\n      case 'utf8':\n      case 'utf-8':\n        return utf8Write(this, string, offset, length)\n\n      case 'ascii':\n        return asciiWrite(this, string, offset, length)\n\n      case 'latin1':\n      case 'binary':\n        return latin1Write(this, string, offset, length)\n\n      case 'base64':\n        // Warning: maxLength not taken into account in base64Write\n        return base64Write(this, string, offset, length)\n\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return ucs2Write(this, string, offset, length)\n\n      default:\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n        encoding = ('' + encoding).toLowerCase()\n        loweredCase = true\n    }\n  }\n}\n\nBuffer.prototype.toJSON = function toJSON () {\n  return {\n    type: 'Buffer',\n    data: Array.prototype.slice.call(this._arr || this, 0)\n  }\n}\n\nfunction base64Slice (buf, start, end) {\n  if (start === 0 && end === buf.length) {\n    return base64.fromByteArray(buf)\n  } else {\n    return base64.fromByteArray(buf.slice(start, end))\n  }\n}\n\nfunction utf8Slice (buf, start, end) {\n  end = Math.min(buf.length, end)\n  var res = []\n\n  var i = start\n  while (i < end) {\n    var firstByte = buf[i]\n    var codePoint = null\n    var bytesPerSequence = (firstByte > 0xEF) ? 4\n      : (firstByte > 0xDF) ? 3\n      : (firstByte > 0xBF) ? 2\n      : 1\n\n    if (i + bytesPerSequence <= end) {\n      var secondByte, thirdByte, fourthByte, tempCodePoint\n\n      switch (bytesPerSequence) {\n        case 1:\n          if (firstByte < 0x80) {\n            codePoint = firstByte\n          }\n          break\n        case 2:\n          secondByte = buf[i + 1]\n          if ((secondByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)\n            if (tempCodePoint > 0x7F) {\n              codePoint = tempCodePoint\n            }\n          }\n          break\n        case 3:\n          secondByte = buf[i + 1]\n          thirdByte = buf[i + 2]\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)\n            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {\n              codePoint = tempCodePoint\n            }\n          }\n          break\n        case 4:\n          secondByte = buf[i + 1]\n          thirdByte = buf[i + 2]\n          fourthByte = buf[i + 3]\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)\n            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {\n              codePoint = tempCodePoint\n            }\n          }\n      }\n    }\n\n    if (codePoint === null) {\n      // we did not generate a valid codePoint so insert a\n      // replacement char (U+FFFD) and advance only 1 byte\n      codePoint = 0xFFFD\n      bytesPerSequence = 1\n    } else if (codePoint > 0xFFFF) {\n      // encode to utf16 (surrogate pair dance)\n      codePoint -= 0x10000\n      res.push(codePoint >>> 10 & 0x3FF | 0xD800)\n      codePoint = 0xDC00 | codePoint & 0x3FF\n    }\n\n    res.push(codePoint)\n    i += bytesPerSequence\n  }\n\n  return decodeCodePointsArray(res)\n}\n\n// Based on http://stackoverflow.com/a/22747272/680742, the browser with\n// the lowest limit is Chrome, with 0x10000 args.\n// We go 1 magnitude less, for safety\nvar MAX_ARGUMENTS_LENGTH = 0x1000\n\nfunction decodeCodePointsArray (codePoints) {\n  var len = codePoints.length\n  if (len <= MAX_ARGUMENTS_LENGTH) {\n    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()\n  }\n\n  // Decode in chunks to avoid \"call stack size exceeded\".\n  var res = ''\n  var i = 0\n  while (i < len) {\n    res += String.fromCharCode.apply(\n      String,\n      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)\n    )\n  }\n  return res\n}\n\nfunction asciiSlice (buf, start, end) {\n  var ret = ''\n  end = Math.min(buf.length, end)\n\n  for (var i = start; i < end; ++i) {\n    ret += String.fromCharCode(buf[i] & 0x7F)\n  }\n  return ret\n}\n\nfunction latin1Slice (buf, start, end) {\n  var ret = ''\n  end = Math.min(buf.length, end)\n\n  for (var i = start; i < end; ++i) {\n    ret += String.fromCharCode(buf[i])\n  }\n  return ret\n}\n\nfunction hexSlice (buf, start, end) {\n  var len = buf.length\n\n  if (!start || start < 0) start = 0\n  if (!end || end < 0 || end > len) end = len\n\n  var out = ''\n  for (var i = start; i < end; ++i) {\n    out += toHex(buf[i])\n  }\n  return out\n}\n\nfunction utf16leSlice (buf, start, end) {\n  var bytes = buf.slice(start, end)\n  var res = ''\n  for (var i = 0; i < bytes.length; i += 2) {\n    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)\n  }\n  return res\n}\n\nBuffer.prototype.slice = function slice (start, end) {\n  var len = this.length\n  start = ~~start\n  end = end === undefined ? len : ~~end\n\n  if (start < 0) {\n    start += len\n    if (start < 0) start = 0\n  } else if (start > len) {\n    start = len\n  }\n\n  if (end < 0) {\n    end += len\n    if (end < 0) end = 0\n  } else if (end > len) {\n    end = len\n  }\n\n  if (end < start) end = start\n\n  var newBuf\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    newBuf = this.subarray(start, end)\n    newBuf.__proto__ = Buffer.prototype\n  } else {\n    var sliceLen = end - start\n    newBuf = new Buffer(sliceLen, undefined)\n    for (var i = 0; i < sliceLen; ++i) {\n      newBuf[i] = this[i + start]\n    }\n  }\n\n  return newBuf\n}\n\n/*\n * Need to make sure that buffer isn't trying to write out of bounds.\n */\nfunction checkOffset (offset, ext, length) {\n  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')\n  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')\n}\n\nBuffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var val = this[offset]\n  var mul = 1\n  var i = 0\n  while (++i < byteLength && (mul *= 0x100)) {\n    val += this[offset + i] * mul\n  }\n\n  return val\n}\n\nBuffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    checkOffset(offset, byteLength, this.length)\n  }\n\n  var val = this[offset + --byteLength]\n  var mul = 1\n  while (byteLength > 0 && (mul *= 0x100)) {\n    val += this[offset + --byteLength] * mul\n  }\n\n  return val\n}\n\nBuffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 1, this.length)\n  return this[offset]\n}\n\nBuffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  return this[offset] | (this[offset + 1] << 8)\n}\n\nBuffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  return (this[offset] << 8) | this[offset + 1]\n}\n\nBuffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return ((this[offset]) |\n      (this[offset + 1] << 8) |\n      (this[offset + 2] << 16)) +\n      (this[offset + 3] * 0x1000000)\n}\n\nBuffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset] * 0x1000000) +\n    ((this[offset + 1] << 16) |\n    (this[offset + 2] << 8) |\n    this[offset + 3])\n}\n\nBuffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var val = this[offset]\n  var mul = 1\n  var i = 0\n  while (++i < byteLength && (mul *= 0x100)) {\n    val += this[offset + i] * mul\n  }\n  mul *= 0x80\n\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n  return val\n}\n\nBuffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var i = byteLength\n  var mul = 1\n  var val = this[offset + --i]\n  while (i > 0 && (mul *= 0x100)) {\n    val += this[offset + --i] * mul\n  }\n  mul *= 0x80\n\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n  return val\n}\n\nBuffer.prototype.readInt8 = function readInt8 (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 1, this.length)\n  if (!(this[offset] & 0x80)) return (this[offset])\n  return ((0xff - this[offset] + 1) * -1)\n}\n\nBuffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  var val = this[offset] | (this[offset + 1] << 8)\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  var val = this[offset + 1] | (this[offset] << 8)\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset]) |\n    (this[offset + 1] << 8) |\n    (this[offset + 2] << 16) |\n    (this[offset + 3] << 24)\n}\n\nBuffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset] << 24) |\n    (this[offset + 1] << 16) |\n    (this[offset + 2] << 8) |\n    (this[offset + 3])\n}\n\nBuffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n  return ieee754.read(this, offset, true, 23, 4)\n}\n\nBuffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n  return ieee754.read(this, offset, false, 23, 4)\n}\n\nBuffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 8, this.length)\n  return ieee754.read(this, offset, true, 52, 8)\n}\n\nBuffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 8, this.length)\n  return ieee754.read(this, offset, false, 52, 8)\n}\n\nfunction checkInt (buf, value, offset, ext, max, min) {\n  if (!Buffer.isBuffer(buf)) throw new TypeError('\"buffer\" argument must be a Buffer instance')\n  if (value > max || value < min) throw new RangeError('\"value\" argument is out of bounds')\n  if (offset + ext > buf.length) throw new RangeError('Index out of range')\n}\n\nBuffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    var maxBytes = Math.pow(2, 8 * byteLength) - 1\n    checkInt(this, value, offset, byteLength, maxBytes, 0)\n  }\n\n  var mul = 1\n  var i = 0\n  this[offset] = value & 0xFF\n  while (++i < byteLength && (mul *= 0x100)) {\n    this[offset + i] = (value / mul) & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    var maxBytes = Math.pow(2, 8 * byteLength) - 1\n    checkInt(this, value, offset, byteLength, maxBytes, 0)\n  }\n\n  var i = byteLength - 1\n  var mul = 1\n  this[offset + i] = value & 0xFF\n  while (--i >= 0 && (mul *= 0x100)) {\n    this[offset + i] = (value / mul) & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n  this[offset] = (value & 0xff)\n  return offset + 1\n}\n\nfunction objectWriteUInt16 (buf, value, offset, littleEndian) {\n  if (value < 0) value = 0xffff + value + 1\n  for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {\n    buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>\n      (littleEndian ? i : 1 - i) * 8\n  }\n}\n\nBuffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n  } else {\n    objectWriteUInt16(this, value, offset, true)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 8)\n    this[offset + 1] = (value & 0xff)\n  } else {\n    objectWriteUInt16(this, value, offset, false)\n  }\n  return offset + 2\n}\n\nfunction objectWriteUInt32 (buf, value, offset, littleEndian) {\n  if (value < 0) value = 0xffffffff + value + 1\n  for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {\n    buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff\n  }\n}\n\nBuffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset + 3] = (value >>> 24)\n    this[offset + 2] = (value >>> 16)\n    this[offset + 1] = (value >>> 8)\n    this[offset] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, true)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 24)\n    this[offset + 1] = (value >>> 16)\n    this[offset + 2] = (value >>> 8)\n    this[offset + 3] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, false)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) {\n    var limit = Math.pow(2, 8 * byteLength - 1)\n\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\n  }\n\n  var i = 0\n  var mul = 1\n  var sub = 0\n  this[offset] = value & 0xFF\n  while (++i < byteLength && (mul *= 0x100)) {\n    if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {\n      sub = 1\n    }\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) {\n    var limit = Math.pow(2, 8 * byteLength - 1)\n\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\n  }\n\n  var i = byteLength - 1\n  var mul = 1\n  var sub = 0\n  this[offset + i] = value & 0xFF\n  while (--i >= 0 && (mul *= 0x100)) {\n    if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {\n      sub = 1\n    }\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n  if (value < 0) value = 0xff + value + 1\n  this[offset] = (value & 0xff)\n  return offset + 1\n}\n\nBuffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n  } else {\n    objectWriteUInt16(this, value, offset, true)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 8)\n    this[offset + 1] = (value & 0xff)\n  } else {\n    objectWriteUInt16(this, value, offset, false)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n    this[offset + 2] = (value >>> 16)\n    this[offset + 3] = (value >>> 24)\n  } else {\n    objectWriteUInt32(this, value, offset, true)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n  if (value < 0) value = 0xffffffff + value + 1\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 24)\n    this[offset + 1] = (value >>> 16)\n    this[offset + 2] = (value >>> 8)\n    this[offset + 3] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, false)\n  }\n  return offset + 4\n}\n\nfunction checkIEEE754 (buf, value, offset, ext, max, min) {\n  if (offset + ext > buf.length) throw new RangeError('Index out of range')\n  if (offset < 0) throw new RangeError('Index out of range')\n}\n\nfunction writeFloat (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)\n  }\n  ieee754.write(buf, value, offset, littleEndian, 23, 4)\n  return offset + 4\n}\n\nBuffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {\n  return writeFloat(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {\n  return writeFloat(this, value, offset, false, noAssert)\n}\n\nfunction writeDouble (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)\n  }\n  ieee754.write(buf, value, offset, littleEndian, 52, 8)\n  return offset + 8\n}\n\nBuffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {\n  return writeDouble(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {\n  return writeDouble(this, value, offset, false, noAssert)\n}\n\n// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)\nBuffer.prototype.copy = function copy (target, targetStart, start, end) {\n  if (!start) start = 0\n  if (!end && end !== 0) end = this.length\n  if (targetStart >= target.length) targetStart = target.length\n  if (!targetStart) targetStart = 0\n  if (end > 0 && end < start) end = start\n\n  // Copy 0 bytes; we're done\n  if (end === start) return 0\n  if (target.length === 0 || this.length === 0) return 0\n\n  // Fatal error conditions\n  if (targetStart < 0) {\n    throw new RangeError('targetStart out of bounds')\n  }\n  if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')\n  if (end < 0) throw new RangeError('sourceEnd out of bounds')\n\n  // Are we oob?\n  if (end > this.length) end = this.length\n  if (target.length - targetStart < end - start) {\n    end = target.length - targetStart + start\n  }\n\n  var len = end - start\n  var i\n\n  if (this === target && start < targetStart && targetStart < end) {\n    // descending copy from end\n    for (i = len - 1; i >= 0; --i) {\n      target[i + targetStart] = this[i + start]\n    }\n  } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {\n    // ascending copy from start\n    for (i = 0; i < len; ++i) {\n      target[i + targetStart] = this[i + start]\n    }\n  } else {\n    Uint8Array.prototype.set.call(\n      target,\n      this.subarray(start, start + len),\n      targetStart\n    )\n  }\n\n  return len\n}\n\n// Usage:\n//    buffer.fill(number[, offset[, end]])\n//    buffer.fill(buffer[, offset[, end]])\n//    buffer.fill(string[, offset[, end]][, encoding])\nBuffer.prototype.fill = function fill (val, start, end, encoding) {\n  // Handle string cases:\n  if (typeof val === 'string') {\n    if (typeof start === 'string') {\n      encoding = start\n      start = 0\n      end = this.length\n    } else if (typeof end === 'string') {\n      encoding = end\n      end = this.length\n    }\n    if (val.length === 1) {\n      var code = val.charCodeAt(0)\n      if (code < 256) {\n        val = code\n      }\n    }\n    if (encoding !== undefined && typeof encoding !== 'string') {\n      throw new TypeError('encoding must be a string')\n    }\n    if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {\n      throw new TypeError('Unknown encoding: ' + encoding)\n    }\n  } else if (typeof val === 'number') {\n    val = val & 255\n  }\n\n  // Invalid ranges are not set to a default, so can range check early.\n  if (start < 0 || this.length < start || this.length < end) {\n    throw new RangeError('Out of range index')\n  }\n\n  if (end <= start) {\n    return this\n  }\n\n  start = start >>> 0\n  end = end === undefined ? this.length : end >>> 0\n\n  if (!val) val = 0\n\n  var i\n  if (typeof val === 'number') {\n    for (i = start; i < end; ++i) {\n      this[i] = val\n    }\n  } else {\n    var bytes = Buffer.isBuffer(val)\n      ? val\n      : utf8ToBytes(new Buffer(val, encoding).toString())\n    var len = bytes.length\n    for (i = 0; i < end - start; ++i) {\n      this[i + start] = bytes[i % len]\n    }\n  }\n\n  return this\n}\n\n// HELPER FUNCTIONS\n// ================\n\nvar INVALID_BASE64_RE = /[^+\\/0-9A-Za-z-_]/g\n\nfunction base64clean (str) {\n  // Node strips out invalid characters like \\n and \\t from the string, base64-js does not\n  str = stringtrim(str).replace(INVALID_BASE64_RE, '')\n  // Node converts strings with length < 2 to ''\n  if (str.length < 2) return ''\n  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not\n  while (str.length % 4 !== 0) {\n    str = str + '='\n  }\n  return str\n}\n\nfunction stringtrim (str) {\n  if (str.trim) return str.trim()\n  return str.replace(/^\\s+|\\s+$/g, '')\n}\n\nfunction toHex (n) {\n  if (n < 16) return '0' + n.toString(16)\n  return n.toString(16)\n}\n\nfunction utf8ToBytes (string, units) {\n  units = units || Infinity\n  var codePoint\n  var length = string.length\n  var leadSurrogate = null\n  var bytes = []\n\n  for (var i = 0; i < length; ++i) {\n    codePoint = string.charCodeAt(i)\n\n    // is surrogate component\n    if (codePoint > 0xD7FF && codePoint < 0xE000) {\n      // last char was a lead\n      if (!leadSurrogate) {\n        // no lead yet\n        if (codePoint > 0xDBFF) {\n          // unexpected trail\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n          continue\n        } else if (i + 1 === length) {\n          // unpaired lead\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n          continue\n        }\n\n        // valid lead\n        leadSurrogate = codePoint\n\n        continue\n      }\n\n      // 2 leads in a row\n      if (codePoint < 0xDC00) {\n        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n        leadSurrogate = codePoint\n        continue\n      }\n\n      // valid surrogate pair\n      codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000\n    } else if (leadSurrogate) {\n      // valid bmp char, but last char was a lead\n      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n    }\n\n    leadSurrogate = null\n\n    // encode utf8\n    if (codePoint < 0x80) {\n      if ((units -= 1) < 0) break\n      bytes.push(codePoint)\n    } else if (codePoint < 0x800) {\n      if ((units -= 2) < 0) break\n      bytes.push(\n        codePoint >> 0x6 | 0xC0,\n        codePoint & 0x3F | 0x80\n      )\n    } else if (codePoint < 0x10000) {\n      if ((units -= 3) < 0) break\n      bytes.push(\n        codePoint >> 0xC | 0xE0,\n        codePoint >> 0x6 & 0x3F | 0x80,\n        codePoint & 0x3F | 0x80\n      )\n    } else if (codePoint < 0x110000) {\n      if ((units -= 4) < 0) break\n      bytes.push(\n        codePoint >> 0x12 | 0xF0,\n        codePoint >> 0xC & 0x3F | 0x80,\n        codePoint >> 0x6 & 0x3F | 0x80,\n        codePoint & 0x3F | 0x80\n      )\n    } else {\n      throw new Error('Invalid code point')\n    }\n  }\n\n  return bytes\n}\n\nfunction asciiToBytes (str) {\n  var byteArray = []\n  for (var i = 0; i < str.length; ++i) {\n    // Node's code seems to be doing this and not & 0x7F..\n    byteArray.push(str.charCodeAt(i) & 0xFF)\n  }\n  return byteArray\n}\n\nfunction utf16leToBytes (str, units) {\n  var c, hi, lo\n  var byteArray = []\n  for (var i = 0; i < str.length; ++i) {\n    if ((units -= 2) < 0) break\n\n    c = str.charCodeAt(i)\n    hi = c >> 8\n    lo = c % 256\n    byteArray.push(lo)\n    byteArray.push(hi)\n  }\n\n  return byteArray\n}\n\nfunction base64ToBytes (str) {\n  return base64.toByteArray(base64clean(str))\n}\n\nfunction blitBuffer (src, dst, offset, length) {\n  for (var i = 0; i < length; ++i) {\n    if ((i + offset >= dst.length) || (i >= src.length)) break\n    dst[i + offset] = src[i]\n  }\n  return i\n}\n\nfunction isnan (val) {\n  return val !== val // eslint-disable-line no-self-compare\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"base64-js\":2,\"ieee754\":37,\"isarray\":40}],6:[function(require,module,exports){\n(function (Buffer){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n// NOTE: These type checking functions intentionally don't use `instanceof`\n// because it is fragile and can be easily faked with `Object.create()`.\n\nfunction isArray(arg) {\n  if (Array.isArray) {\n    return Array.isArray(arg);\n  }\n  return objectToString(arg) === '[object Array]';\n}\nexports.isArray = isArray;\n\nfunction isBoolean(arg) {\n  return typeof arg === 'boolean';\n}\nexports.isBoolean = isBoolean;\n\nfunction isNull(arg) {\n  return arg === null;\n}\nexports.isNull = isNull;\n\nfunction isNullOrUndefined(arg) {\n  return arg == null;\n}\nexports.isNullOrUndefined = isNullOrUndefined;\n\nfunction isNumber(arg) {\n  return typeof arg === 'number';\n}\nexports.isNumber = isNumber;\n\nfunction isString(arg) {\n  return typeof arg === 'string';\n}\nexports.isString = isString;\n\nfunction isSymbol(arg) {\n  return typeof arg === 'symbol';\n}\nexports.isSymbol = isSymbol;\n\nfunction isUndefined(arg) {\n  return arg === void 0;\n}\nexports.isUndefined = isUndefined;\n\nfunction isRegExp(re) {\n  return objectToString(re) === '[object RegExp]';\n}\nexports.isRegExp = isRegExp;\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\nexports.isObject = isObject;\n\nfunction isDate(d) {\n  return objectToString(d) === '[object Date]';\n}\nexports.isDate = isDate;\n\nfunction isError(e) {\n  return (objectToString(e) === '[object Error]' || e instanceof Error);\n}\nexports.isError = isError;\n\nfunction isFunction(arg) {\n  return typeof arg === 'function';\n}\nexports.isFunction = isFunction;\n\nfunction isPrimitive(arg) {\n  return arg === null ||\n         typeof arg === 'boolean' ||\n         typeof arg === 'number' ||\n         typeof arg === 'string' ||\n         typeof arg === 'symbol' ||  // ES6 symbol\n         typeof arg === 'undefined';\n}\nexports.isPrimitive = isPrimitive;\n\nexports.isBuffer = Buffer.isBuffer;\n\nfunction objectToString(o) {\n  return Object.prototype.toString.call(o);\n}\n\n}).call(this,{\"isBuffer\":require(\"../../is-buffer/index.js\")})\n},{\"../../is-buffer/index.js\":39}],7:[function(require,module,exports){\n/*\n  Module dependencies\n*/\nvar ElementType = require('domelementtype');\nvar entities = require('entities');\n\n/*\n  Boolean Attributes\n*/\nvar booleanAttributes = {\n  __proto__: null,\n  allowfullscreen: true,\n  async: true,\n  autofocus: true,\n  autoplay: true,\n  checked: true,\n  controls: true,\n  default: true,\n  defer: true,\n  disabled: true,\n  hidden: true,\n  ismap: true,\n  loop: true,\n  multiple: true,\n  muted: true,\n  open: true,\n  readonly: true,\n  required: true,\n  reversed: true,\n  scoped: true,\n  seamless: true,\n  selected: true,\n  typemustmatch: true\n};\n\nvar unencodedElements = {\n  __proto__: null,\n  style: true,\n  script: true,\n  xmp: true,\n  iframe: true,\n  noembed: true,\n  noframes: true,\n  plaintext: true,\n  noscript: true\n};\n\n/*\n  Format attributes\n*/\nfunction formatAttrs(attributes, opts) {\n  if (!attributes) return;\n\n  var output = '',\n      value;\n\n  // Loop through the attributes\n  for (var key in attributes) {\n    value = attributes[key];\n    if (output) {\n      output += ' ';\n    }\n\n    if (!value && booleanAttributes[key]) {\n      output += key;\n    } else {\n      output += key + '=\"' + (opts.decodeEntities ? entities.encodeXML(value) : value) + '\"';\n    }\n  }\n\n  return output;\n}\n\n/*\n  Self-enclosing tags (stolen from node-htmlparser)\n*/\nvar singleTag = {\n  __proto__: null,\n  area: true,\n  base: true,\n  basefont: true,\n  br: true,\n  col: true,\n  command: true,\n  embed: true,\n  frame: true,\n  hr: true,\n  img: true,\n  input: true,\n  isindex: true,\n  keygen: true,\n  link: true,\n  meta: true,\n  param: true,\n  source: true,\n  track: true,\n  wbr: true,\n};\n\n\nvar render = module.exports = function(dom, opts) {\n  if (!Array.isArray(dom) && !dom.cheerio) dom = [dom];\n  opts = opts || {};\n\n  var output = '';\n\n  for(var i = 0; i < dom.length; i++){\n    var elem = dom[i];\n\n    if (elem.type === 'root')\n      output += render(elem.children, opts);\n    else if (ElementType.isTag(elem))\n      output += renderTag(elem, opts);\n    else if (elem.type === ElementType.Directive)\n      output += renderDirective(elem);\n    else if (elem.type === ElementType.Comment)\n      output += renderComment(elem);\n    else if (elem.type === ElementType.CDATA)\n      output += renderCdata(elem);\n    else\n      output += renderText(elem, opts);\n  }\n\n  return output;\n};\n\nfunction renderTag(elem, opts) {\n  // Handle SVG\n  if (elem.name === \"svg\") opts = {decodeEntities: opts.decodeEntities, xmlMode: true};\n\n  var tag = '<' + elem.name,\n      attribs = formatAttrs(elem.attribs, opts);\n\n  if (attribs) {\n    tag += ' ' + attribs;\n  }\n\n  if (\n    opts.xmlMode\n    && (!elem.children || elem.children.length === 0)\n  ) {\n    tag += '/>';\n  } else {\n    tag += '>';\n    if (elem.children) {\n      tag += render(elem.children, opts);\n    }\n\n    if (!singleTag[elem.name] || opts.xmlMode) {\n      tag += '</' + elem.name + '>';\n    }\n  }\n\n  return tag;\n}\n\nfunction renderDirective(elem) {\n  return '<' + elem.data + '>';\n}\n\nfunction renderText(elem, opts) {\n  var data = elem.data || '';\n\n  // if entities weren't decoded, no need to encode them back\n  if (opts.decodeEntities && !(elem.parent && elem.parent.name in unencodedElements)) {\n    data = entities.encodeXML(data);\n  }\n\n  return data;\n}\n\nfunction renderCdata(elem) {\n  return '<![CDATA[' + elem.children[0].data + ']]>';\n}\n\nfunction renderComment(elem) {\n  return '<!--' + elem.data + '-->';\n}\n\n},{\"domelementtype\":8,\"entities\":20}],8:[function(require,module,exports){\n//Types of elements found in the DOM\nmodule.exports = {\n\tText: \"text\", //Text\n\tDirective: \"directive\", //<? ... ?>\n\tComment: \"comment\", //<!-- ... -->\n\tScript: \"script\", //<script> tags\n\tStyle: \"style\", //<style> tags\n\tTag: \"tag\", //Any tag\n\tCDATA: \"cdata\", //<![CDATA[ ... ]]>\n\n\tisTag: function(elem){\n\t\treturn elem.type === \"tag\" || elem.type === \"script\" || elem.type === \"style\";\n\t}\n};\n},{}],9:[function(require,module,exports){\n//Types of elements found in the DOM\nmodule.exports = {\n\tText: \"text\", //Text\n\tDirective: \"directive\", //<? ... ?>\n\tComment: \"comment\", //<!-- ... -->\n\tScript: \"script\", //<script> tags\n\tStyle: \"style\", //<style> tags\n\tTag: \"tag\", //Any tag\n\tCDATA: \"cdata\", //<![CDATA[ ... ]]>\n\tDoctype: \"doctype\",\n\n\tisTag: function(elem){\n\t\treturn elem.type === \"tag\" || elem.type === \"script\" || elem.type === \"style\";\n\t}\n};\n\n},{}],10:[function(require,module,exports){\nvar ElementType = require(\"domelementtype\");\n\nvar re_whitespace = /\\s+/g;\nvar NodePrototype = require(\"./lib/node\");\nvar ElementPrototype = require(\"./lib/element\");\n\nfunction DomHandler(callback, options, elementCB){\n\tif(typeof callback === \"object\"){\n\t\telementCB = options;\n\t\toptions = callback;\n\t\tcallback = null;\n\t} else if(typeof options === \"function\"){\n\t\telementCB = options;\n\t\toptions = defaultOpts;\n\t}\n\tthis._callback = callback;\n\tthis._options = options || defaultOpts;\n\tthis._elementCB = elementCB;\n\tthis.dom = [];\n\tthis._done = false;\n\tthis._tagStack = [];\n\tthis._parser = this._parser || null;\n}\n\n//default options\nvar defaultOpts = {\n\tnormalizeWhitespace: false, //Replace all whitespace with single spaces\n\twithStartIndices: false, //Add startIndex properties to nodes\n};\n\nDomHandler.prototype.onparserinit = function(parser){\n\tthis._parser = parser;\n};\n\n//Resets the handler back to starting state\nDomHandler.prototype.onreset = function(){\n\tDomHandler.call(this, this._callback, this._options, this._elementCB);\n};\n\n//Signals the handler that parsing is done\nDomHandler.prototype.onend = function(){\n\tif(this._done) return;\n\tthis._done = true;\n\tthis._parser = null;\n\tthis._handleCallback(null);\n};\n\nDomHandler.prototype._handleCallback =\nDomHandler.prototype.onerror = function(error){\n\tif(typeof this._callback === \"function\"){\n\t\tthis._callback(error, this.dom);\n\t} else {\n\t\tif(error) throw error;\n\t}\n};\n\nDomHandler.prototype.onclosetag = function(){\n\t//if(this._tagStack.pop().name !== name) this._handleCallback(Error(\"Tagname didn't match!\"));\n\tvar elem = this._tagStack.pop();\n\tif(this._elementCB) this._elementCB(elem);\n};\n\nDomHandler.prototype._addDomElement = function(element){\n\tvar parent = this._tagStack[this._tagStack.length - 1];\n\tvar siblings = parent ? parent.children : this.dom;\n\tvar previousSibling = siblings[siblings.length - 1];\n\n\telement.next = null;\n\n\tif(this._options.withStartIndices){\n\t\telement.startIndex = this._parser.startIndex;\n\t}\n\n\tif (this._options.withDomLvl1) {\n\t\telement.__proto__ = element.type === \"tag\" ? ElementPrototype : NodePrototype;\n\t}\n\n\tif(previousSibling){\n\t\telement.prev = previousSibling;\n\t\tpreviousSibling.next = element;\n\t} else {\n\t\telement.prev = null;\n\t}\n\n\tsiblings.push(element);\n\telement.parent = parent || null;\n};\n\nDomHandler.prototype.onopentag = function(name, attribs){\n\tvar element = {\n\t\ttype: name === \"script\" ? ElementType.Script : name === \"style\" ? ElementType.Style : ElementType.Tag,\n\t\tname: name,\n\t\tattribs: attribs,\n\t\tchildren: []\n\t};\n\n\tthis._addDomElement(element);\n\n\tthis._tagStack.push(element);\n};\n\nDomHandler.prototype.ontext = function(data){\n\t//the ignoreWhitespace is officially dropped, but for now,\n\t//it's an alias for normalizeWhitespace\n\tvar normalize = this._options.normalizeWhitespace || this._options.ignoreWhitespace;\n\n\tvar lastTag;\n\n\tif(!this._tagStack.length && this.dom.length && (lastTag = this.dom[this.dom.length-1]).type === ElementType.Text){\n\t\tif(normalize){\n\t\t\tlastTag.data = (lastTag.data + data).replace(re_whitespace, \" \");\n\t\t} else {\n\t\t\tlastTag.data += data;\n\t\t}\n\t} else {\n\t\tif(\n\t\t\tthis._tagStack.length &&\n\t\t\t(lastTag = this._tagStack[this._tagStack.length - 1]) &&\n\t\t\t(lastTag = lastTag.children[lastTag.children.length - 1]) &&\n\t\t\tlastTag.type === ElementType.Text\n\t\t){\n\t\t\tif(normalize){\n\t\t\t\tlastTag.data = (lastTag.data + data).replace(re_whitespace, \" \");\n\t\t\t} else {\n\t\t\t\tlastTag.data += data;\n\t\t\t}\n\t\t} else {\n\t\t\tif(normalize){\n\t\t\t\tdata = data.replace(re_whitespace, \" \");\n\t\t\t}\n\n\t\t\tthis._addDomElement({\n\t\t\t\tdata: data,\n\t\t\t\ttype: ElementType.Text\n\t\t\t});\n\t\t}\n\t}\n};\n\nDomHandler.prototype.oncomment = function(data){\n\tvar lastTag = this._tagStack[this._tagStack.length - 1];\n\n\tif(lastTag && lastTag.type === ElementType.Comment){\n\t\tlastTag.data += data;\n\t\treturn;\n\t}\n\n\tvar element = {\n\t\tdata: data,\n\t\ttype: ElementType.Comment\n\t};\n\n\tthis._addDomElement(element);\n\tthis._tagStack.push(element);\n};\n\nDomHandler.prototype.oncdatastart = function(){\n\tvar element = {\n\t\tchildren: [{\n\t\t\tdata: \"\",\n\t\t\ttype: ElementType.Text\n\t\t}],\n\t\ttype: ElementType.CDATA\n\t};\n\n\tthis._addDomElement(element);\n\tthis._tagStack.push(element);\n};\n\nDomHandler.prototype.oncommentend = DomHandler.prototype.oncdataend = function(){\n\tthis._tagStack.pop();\n};\n\nDomHandler.prototype.onprocessinginstruction = function(name, data){\n\tthis._addDomElement({\n\t\tname: name,\n\t\tdata: data,\n\t\ttype: ElementType.Directive\n\t});\n};\n\nmodule.exports = DomHandler;\n\n},{\"./lib/element\":11,\"./lib/node\":12,\"domelementtype\":9}],11:[function(require,module,exports){\n// DOM-Level-1-compliant structure\nvar NodePrototype = require('./node');\nvar ElementPrototype = module.exports = Object.create(NodePrototype);\n\nvar domLvl1 = {\n\ttagName: \"name\"\n};\n\nObject.keys(domLvl1).forEach(function(key) {\n\tvar shorthand = domLvl1[key];\n\tObject.defineProperty(ElementPrototype, key, {\n\t\tget: function() {\n\t\t\treturn this[shorthand] || null;\n\t\t},\n\t\tset: function(val) {\n\t\t\tthis[shorthand] = val;\n\t\t\treturn val;\n\t\t}\n\t});\n});\n\n},{\"./node\":12}],12:[function(require,module,exports){\n// This object will be used as the prototype for Nodes when creating a\n// DOM-Level-1-compliant structure.\nvar NodePrototype = module.exports = {\n\tget firstChild() {\n\t\tvar children = this.children;\n\t\treturn children && children[0] || null;\n\t},\n\tget lastChild() {\n\t\tvar children = this.children;\n\t\treturn children && children[children.length - 1] || null;\n\t},\n\tget nodeType() {\n\t\treturn nodeTypes[this.type] || nodeTypes.element;\n\t}\n};\n\nvar domLvl1 = {\n\ttagName: \"name\",\n\tchildNodes: \"children\",\n\tparentNode: \"parent\",\n\tpreviousSibling: \"prev\",\n\tnextSibling: \"next\",\n\tnodeValue: \"data\"\n};\n\nvar nodeTypes = {\n\telement: 1,\n\ttext: 3,\n\tcdata: 4,\n\tcomment: 8\n};\n\nObject.keys(domLvl1).forEach(function(key) {\n\tvar shorthand = domLvl1[key];\n\tObject.defineProperty(NodePrototype, key, {\n\t\tget: function() {\n\t\t\treturn this[shorthand] || null;\n\t\t},\n\t\tset: function(val) {\n\t\t\tthis[shorthand] = val;\n\t\t\treturn val;\n\t\t}\n\t});\n});\n\n},{}],13:[function(require,module,exports){\nvar DomUtils = module.exports;\n\n[\n\trequire(\"./lib/stringify\"),\n\trequire(\"./lib/traversal\"),\n\trequire(\"./lib/manipulation\"),\n\trequire(\"./lib/querying\"),\n\trequire(\"./lib/legacy\"),\n\trequire(\"./lib/helpers\")\n].forEach(function(ext){\n\tObject.keys(ext).forEach(function(key){\n\t\tDomUtils[key] = ext[key].bind(DomUtils);\n\t});\n});\n\n},{\"./lib/helpers\":14,\"./lib/legacy\":15,\"./lib/manipulation\":16,\"./lib/querying\":17,\"./lib/stringify\":18,\"./lib/traversal\":19}],14:[function(require,module,exports){\n// removeSubsets\n// Given an array of nodes, remove any member that is contained by another.\nexports.removeSubsets = function(nodes) {\n\tvar idx = nodes.length, node, ancestor, replace;\n\n\t// Check if each node (or one of its ancestors) is already contained in the\n\t// array.\n\twhile (--idx > -1) {\n\t\tnode = ancestor = nodes[idx];\n\n\t\t// Temporarily remove the node under consideration\n\t\tnodes[idx] = null;\n\t\treplace = true;\n\n\t\twhile (ancestor) {\n\t\t\tif (nodes.indexOf(ancestor) > -1) {\n\t\t\t\treplace = false;\n\t\t\t\tnodes.splice(idx, 1);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tancestor = ancestor.parent;\n\t\t}\n\n\t\t// If the node has been found to be unique, re-insert it.\n\t\tif (replace) {\n\t\t\tnodes[idx] = node;\n\t\t}\n\t}\n\n\treturn nodes;\n};\n\n// Source: http://dom.spec.whatwg.org/#dom-node-comparedocumentposition\nvar POSITION = {\n\tDISCONNECTED: 1,\n\tPRECEDING: 2,\n\tFOLLOWING: 4,\n\tCONTAINS: 8,\n\tCONTAINED_BY: 16\n};\n\n// Compare the position of one node against another node in any other document.\n// The return value is a bitmask with the following values:\n//\n// document order:\n// > There is an ordering, document order, defined on all the nodes in the\n// > document corresponding to the order in which the first character of the\n// > XML representation of each node occurs in the XML representation of the\n// > document after expansion of general entities. Thus, the document element\n// > node will be the first node. Element nodes occur before their children.\n// > Thus, document order orders element nodes in order of the occurrence of\n// > their start-tag in the XML (after expansion of entities). The attribute\n// > nodes of an element occur after the element and before its children. The\n// > relative order of attribute nodes is implementation-dependent./\n// Source:\n// http://www.w3.org/TR/DOM-Level-3-Core/glossary.html#dt-document-order\n//\n// @argument {Node} nodaA The first node to use in the comparison\n// @argument {Node} nodeB The second node to use in the comparison\n//\n// @return {Number} A bitmask describing the input nodes' relative position.\n//         See http://dom.spec.whatwg.org/#dom-node-comparedocumentposition for\n//         a description of these values.\nvar comparePos = exports.compareDocumentPosition = function(nodeA, nodeB) {\n\tvar aParents = [];\n\tvar bParents = [];\n\tvar current, sharedParent, siblings, aSibling, bSibling, idx;\n\n\tif (nodeA === nodeB) {\n\t\treturn 0;\n\t}\n\n\tcurrent = nodeA;\n\twhile (current) {\n\t\taParents.unshift(current);\n\t\tcurrent = current.parent;\n\t}\n\tcurrent = nodeB;\n\twhile (current) {\n\t\tbParents.unshift(current);\n\t\tcurrent = current.parent;\n\t}\n\n\tidx = 0;\n\twhile (aParents[idx] === bParents[idx]) {\n\t\tidx++;\n\t}\n\n\tif (idx === 0) {\n\t\treturn POSITION.DISCONNECTED;\n\t}\n\n\tsharedParent = aParents[idx - 1];\n\tsiblings = sharedParent.children;\n\taSibling = aParents[idx];\n\tbSibling = bParents[idx];\n\n\tif (siblings.indexOf(aSibling) > siblings.indexOf(bSibling)) {\n\t\tif (sharedParent === nodeB) {\n\t\t\treturn POSITION.FOLLOWING | POSITION.CONTAINED_BY;\n\t\t}\n\t\treturn POSITION.FOLLOWING;\n\t} else {\n\t\tif (sharedParent === nodeA) {\n\t\t\treturn POSITION.PRECEDING | POSITION.CONTAINS;\n\t\t}\n\t\treturn POSITION.PRECEDING;\n\t}\n};\n\n// Sort an array of nodes based on their relative position in the document and\n// remove any duplicate nodes. If the array contains nodes that do not belong\n// to the same document, sort order is unspecified.\n//\n// @argument {Array} nodes Array of DOM nodes\n//\n// @returns {Array} collection of unique nodes, sorted in document order\nexports.uniqueSort = function(nodes) {\n\tvar idx = nodes.length, node, position;\n\n\tnodes = nodes.slice();\n\n\twhile (--idx > -1) {\n\t\tnode = nodes[idx];\n\t\tposition = nodes.indexOf(node);\n\t\tif (position > -1 && position < idx) {\n\t\t\tnodes.splice(idx, 1);\n\t\t}\n\t}\n\tnodes.sort(function(a, b) {\n\t\tvar relative = comparePos(a, b);\n\t\tif (relative & POSITION.PRECEDING) {\n\t\t\treturn -1;\n\t\t} else if (relative & POSITION.FOLLOWING) {\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n\t});\n\n\treturn nodes;\n};\n\n},{}],15:[function(require,module,exports){\nvar ElementType = require(\"domelementtype\");\nvar isTag = exports.isTag = ElementType.isTag;\n\nexports.testElement = function(options, element){\n\tfor(var key in options){\n\t\tif(!options.hasOwnProperty(key));\n\t\telse if(key === \"tag_name\"){\n\t\t\tif(!isTag(element) || !options.tag_name(element.name)){\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} else if(key === \"tag_type\"){\n\t\t\tif(!options.tag_type(element.type)) return false;\n\t\t} else if(key === \"tag_contains\"){\n\t\t\tif(isTag(element) || !options.tag_contains(element.data)){\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} else if(!element.attribs || !options[key](element.attribs[key])){\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n};\n\nvar Checks = {\n\ttag_name: function(name){\n\t\tif(typeof name === \"function\"){\n\t\t\treturn function(elem){ return isTag(elem) && name(elem.name); };\n\t\t} else if(name === \"*\"){\n\t\t\treturn isTag;\n\t\t} else {\n\t\t\treturn function(elem){ return isTag(elem) && elem.name === name; };\n\t\t}\n\t},\n\ttag_type: function(type){\n\t\tif(typeof type === \"function\"){\n\t\t\treturn function(elem){ return type(elem.type); };\n\t\t} else {\n\t\t\treturn function(elem){ return elem.type === type; };\n\t\t}\n\t},\n\ttag_contains: function(data){\n\t\tif(typeof data === \"function\"){\n\t\t\treturn function(elem){ return !isTag(elem) && data(elem.data); };\n\t\t} else {\n\t\t\treturn function(elem){ return !isTag(elem) && elem.data === data; };\n\t\t}\n\t}\n};\n\nfunction getAttribCheck(attrib, value){\n\tif(typeof value === \"function\"){\n\t\treturn function(elem){ return elem.attribs && value(elem.attribs[attrib]); };\n\t} else {\n\t\treturn function(elem){ return elem.attribs && elem.attribs[attrib] === value; };\n\t}\n}\n\nfunction combineFuncs(a, b){\n\treturn function(elem){\n\t\treturn a(elem) || b(elem);\n\t};\n}\n\nexports.getElements = function(options, element, recurse, limit){\n\tvar funcs = Object.keys(options).map(function(key){\n\t\tvar value = options[key];\n\t\treturn key in Checks ? Checks[key](value) : getAttribCheck(key, value);\n\t});\n\n\treturn funcs.length === 0 ? [] : this.filter(\n\t\tfuncs.reduce(combineFuncs),\n\t\telement, recurse, limit\n\t);\n};\n\nexports.getElementById = function(id, element, recurse){\n\tif(!Array.isArray(element)) element = [element];\n\treturn this.findOne(getAttribCheck(\"id\", id), element, recurse !== false);\n};\n\nexports.getElementsByTagName = function(name, element, recurse, limit){\n\treturn this.filter(Checks.tag_name(name), element, recurse, limit);\n};\n\nexports.getElementsByTagType = function(type, element, recurse, limit){\n\treturn this.filter(Checks.tag_type(type), element, recurse, limit);\n};\n\n},{\"domelementtype\":9}],16:[function(require,module,exports){\nexports.removeElement = function(elem){\n\tif(elem.prev) elem.prev.next = elem.next;\n\tif(elem.next) elem.next.prev = elem.prev;\n\n\tif(elem.parent){\n\t\tvar childs = elem.parent.children;\n\t\tchilds.splice(childs.lastIndexOf(elem), 1);\n\t}\n};\n\nexports.replaceElement = function(elem, replacement){\n\tvar prev = replacement.prev = elem.prev;\n\tif(prev){\n\t\tprev.next = replacement;\n\t}\n\n\tvar next = replacement.next = elem.next;\n\tif(next){\n\t\tnext.prev = replacement;\n\t}\n\n\tvar parent = replacement.parent = elem.parent;\n\tif(parent){\n\t\tvar childs = parent.children;\n\t\tchilds[childs.lastIndexOf(elem)] = replacement;\n\t}\n};\n\nexports.appendChild = function(elem, child){\n\tchild.parent = elem;\n\n\tif(elem.children.push(child) !== 1){\n\t\tvar sibling = elem.children[elem.children.length - 2];\n\t\tsibling.next = child;\n\t\tchild.prev = sibling;\n\t\tchild.next = null;\n\t}\n};\n\nexports.append = function(elem, next){\n\tvar parent = elem.parent,\n\t\tcurrNext = elem.next;\n\n\tnext.next = currNext;\n\tnext.prev = elem;\n\telem.next = next;\n\tnext.parent = parent;\n\n\tif(currNext){\n\t\tcurrNext.prev = next;\n\t\tif(parent){\n\t\t\tvar childs = parent.children;\n\t\t\tchilds.splice(childs.lastIndexOf(currNext), 0, next);\n\t\t}\n\t} else if(parent){\n\t\tparent.children.push(next);\n\t}\n};\n\nexports.prepend = function(elem, prev){\n\tvar parent = elem.parent;\n\tif(parent){\n\t\tvar childs = parent.children;\n\t\tchilds.splice(childs.lastIndexOf(elem), 0, prev);\n\t}\n\n\tif(elem.prev){\n\t\telem.prev.next = prev;\n\t}\n\t\n\tprev.parent = parent;\n\tprev.prev = elem.prev;\n\tprev.next = elem;\n\telem.prev = prev;\n};\n\n\n\n},{}],17:[function(require,module,exports){\nvar isTag = require(\"domelementtype\").isTag;\n\nmodule.exports = {\n\tfilter: filter,\n\tfind: find,\n\tfindOneChild: findOneChild,\n\tfindOne: findOne,\n\texistsOne: existsOne,\n\tfindAll: findAll\n};\n\nfunction filter(test, element, recurse, limit){\n\tif(!Array.isArray(element)) element = [element];\n\n\tif(typeof limit !== \"number\" || !isFinite(limit)){\n\t\tlimit = Infinity;\n\t}\n\treturn find(test, element, recurse !== false, limit);\n}\n\nfunction find(test, elems, recurse, limit){\n\tvar result = [], childs;\n\n\tfor(var i = 0, j = elems.length; i < j; i++){\n\t\tif(test(elems[i])){\n\t\t\tresult.push(elems[i]);\n\t\t\tif(--limit <= 0) break;\n\t\t}\n\n\t\tchilds = elems[i].children;\n\t\tif(recurse && childs && childs.length > 0){\n\t\t\tchilds = find(test, childs, recurse, limit);\n\t\t\tresult = result.concat(childs);\n\t\t\tlimit -= childs.length;\n\t\t\tif(limit <= 0) break;\n\t\t}\n\t}\n\n\treturn result;\n}\n\nfunction findOneChild(test, elems){\n\tfor(var i = 0, l = elems.length; i < l; i++){\n\t\tif(test(elems[i])) return elems[i];\n\t}\n\n\treturn null;\n}\n\nfunction findOne(test, elems){\n\tvar elem = null;\n\n\tfor(var i = 0, l = elems.length; i < l && !elem; i++){\n\t\tif(!isTag(elems[i])){\n\t\t\tcontinue;\n\t\t} else if(test(elems[i])){\n\t\t\telem = elems[i];\n\t\t} else if(elems[i].children.length > 0){\n\t\t\telem = findOne(test, elems[i].children);\n\t\t}\n\t}\n\n\treturn elem;\n}\n\nfunction existsOne(test, elems){\n\tfor(var i = 0, l = elems.length; i < l; i++){\n\t\tif(\n\t\t\tisTag(elems[i]) && (\n\t\t\t\ttest(elems[i]) || (\n\t\t\t\t\telems[i].children.length > 0 &&\n\t\t\t\t\texistsOne(test, elems[i].children)\n\t\t\t\t)\n\t\t\t)\n\t\t){\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\nfunction findAll(test, elems){\n\tvar result = [];\n\tfor(var i = 0, j = elems.length; i < j; i++){\n\t\tif(!isTag(elems[i])) continue;\n\t\tif(test(elems[i])) result.push(elems[i]);\n\n\t\tif(elems[i].children.length > 0){\n\t\t\tresult = result.concat(findAll(test, elems[i].children));\n\t\t}\n\t}\n\treturn result;\n}\n\n},{\"domelementtype\":9}],18:[function(require,module,exports){\nvar ElementType = require(\"domelementtype\"),\n    getOuterHTML = require(\"dom-serializer\"),\n    isTag = ElementType.isTag;\n\nmodule.exports = {\n\tgetInnerHTML: getInnerHTML,\n\tgetOuterHTML: getOuterHTML,\n\tgetText: getText\n};\n\nfunction getInnerHTML(elem, opts){\n\treturn elem.children ? elem.children.map(function(elem){\n\t\treturn getOuterHTML(elem, opts);\n\t}).join(\"\") : \"\";\n}\n\nfunction getText(elem){\n\tif(Array.isArray(elem)) return elem.map(getText).join(\"\");\n\tif(isTag(elem) || elem.type === ElementType.CDATA) return getText(elem.children);\n\tif(elem.type === ElementType.Text) return elem.data;\n\treturn \"\";\n}\n\n},{\"dom-serializer\":7,\"domelementtype\":9}],19:[function(require,module,exports){\nvar getChildren = exports.getChildren = function(elem){\n\treturn elem.children;\n};\n\nvar getParent = exports.getParent = function(elem){\n\treturn elem.parent;\n};\n\nexports.getSiblings = function(elem){\n\tvar parent = getParent(elem);\n\treturn parent ? getChildren(parent) : [elem];\n};\n\nexports.getAttributeValue = function(elem, name){\n\treturn elem.attribs && elem.attribs[name];\n};\n\nexports.hasAttrib = function(elem, name){\n\treturn !!elem.attribs && hasOwnProperty.call(elem.attribs, name);\n};\n\nexports.getName = function(elem){\n\treturn elem.name;\n};\n\n},{}],20:[function(require,module,exports){\nvar encode = require(\"./lib/encode.js\"),\n    decode = require(\"./lib/decode.js\");\n\nexports.decode = function(data, level){\n\treturn (!level || level <= 0 ? decode.XML : decode.HTML)(data);\n};\n\nexports.decodeStrict = function(data, level){\n\treturn (!level || level <= 0 ? decode.XML : decode.HTMLStrict)(data);\n};\n\nexports.encode = function(data, level){\n\treturn (!level || level <= 0 ? encode.XML : encode.HTML)(data);\n};\n\nexports.encodeXML = encode.XML;\n\nexports.encodeHTML4 =\nexports.encodeHTML5 =\nexports.encodeHTML  = encode.HTML;\n\nexports.decodeXML =\nexports.decodeXMLStrict = decode.XML;\n\nexports.decodeHTML4 =\nexports.decodeHTML5 =\nexports.decodeHTML = decode.HTML;\n\nexports.decodeHTML4Strict =\nexports.decodeHTML5Strict =\nexports.decodeHTMLStrict = decode.HTMLStrict;\n\nexports.escape = encode.escape;\n\n},{\"./lib/decode.js\":21,\"./lib/encode.js\":23}],21:[function(require,module,exports){\nvar entityMap = require(\"../maps/entities.json\"),\n    legacyMap = require(\"../maps/legacy.json\"),\n    xmlMap    = require(\"../maps/xml.json\"),\n    decodeCodePoint = require(\"./decode_codepoint.js\");\n\nvar decodeXMLStrict  = getStrictDecoder(xmlMap),\n    decodeHTMLStrict = getStrictDecoder(entityMap);\n\nfunction getStrictDecoder(map){\n\tvar keys = Object.keys(map).join(\"|\"),\n\t    replace = getReplacer(map);\n\n\tkeys += \"|#[xX][\\\\da-fA-F]+|#\\\\d+\";\n\n\tvar re = new RegExp(\"&(?:\" + keys + \");\", \"g\");\n\n\treturn function(str){\n\t\treturn String(str).replace(re, replace);\n\t};\n}\n\nvar decodeHTML = (function(){\n\tvar legacy = Object.keys(legacyMap)\n\t\t.sort(sorter);\n\n\tvar keys = Object.keys(entityMap)\n\t\t.sort(sorter);\n\n\tfor(var i = 0, j = 0; i < keys.length; i++){\n\t\tif(legacy[j] === keys[i]){\n\t\t\tkeys[i] += \";?\";\n\t\t\tj++;\n\t\t} else {\n\t\t\tkeys[i] += \";\";\n\t\t}\n\t}\n\n\tvar re = new RegExp(\"&(?:\" + keys.join(\"|\") + \"|#[xX][\\\\da-fA-F]+;?|#\\\\d+;?)\", \"g\"),\n\t    replace = getReplacer(entityMap);\n\n\tfunction replacer(str){\n\t\tif(str.substr(-1) !== \";\") str += \";\";\n\t\treturn replace(str);\n\t}\n\n\t//TODO consider creating a merged map\n\treturn function(str){\n\t\treturn String(str).replace(re, replacer);\n\t};\n}());\n\nfunction sorter(a, b){\n\treturn a < b ? 1 : -1;\n}\n\nfunction getReplacer(map){\n\treturn function replace(str){\n\t\tif(str.charAt(1) === \"#\"){\n\t\t\tif(str.charAt(2) === \"X\" || str.charAt(2) === \"x\"){\n\t\t\t\treturn decodeCodePoint(parseInt(str.substr(3), 16));\n\t\t\t}\n\t\t\treturn decodeCodePoint(parseInt(str.substr(2), 10));\n\t\t}\n\t\treturn map[str.slice(1, -1)];\n\t};\n}\n\nmodule.exports = {\n\tXML: decodeXMLStrict,\n\tHTML: decodeHTML,\n\tHTMLStrict: decodeHTMLStrict\n};\n},{\"../maps/entities.json\":25,\"../maps/legacy.json\":26,\"../maps/xml.json\":27,\"./decode_codepoint.js\":22}],22:[function(require,module,exports){\nvar decodeMap = require(\"../maps/decode.json\");\n\nmodule.exports = decodeCodePoint;\n\n// modified version of https://github.com/mathiasbynens/he/blob/master/src/he.js#L94-L119\nfunction decodeCodePoint(codePoint){\n\n\tif((codePoint >= 0xD800 && codePoint <= 0xDFFF) || codePoint > 0x10FFFF){\n\t\treturn \"\\uFFFD\";\n\t}\n\n\tif(codePoint in decodeMap){\n\t\tcodePoint = decodeMap[codePoint];\n\t}\n\n\tvar output = \"\";\n\n\tif(codePoint > 0xFFFF){\n\t\tcodePoint -= 0x10000;\n\t\toutput += String.fromCharCode(codePoint >>> 10 & 0x3FF | 0xD800);\n\t\tcodePoint = 0xDC00 | codePoint & 0x3FF;\n\t}\n\n\toutput += String.fromCharCode(codePoint);\n\treturn output;\n}\n\n},{\"../maps/decode.json\":24}],23:[function(require,module,exports){\nvar inverseXML = getInverseObj(require(\"../maps/xml.json\")),\n    xmlReplacer = getInverseReplacer(inverseXML);\n\nexports.XML = getInverse(inverseXML, xmlReplacer);\n\nvar inverseHTML = getInverseObj(require(\"../maps/entities.json\")),\n    htmlReplacer = getInverseReplacer(inverseHTML);\n\nexports.HTML = getInverse(inverseHTML, htmlReplacer);\n\nfunction getInverseObj(obj){\n\treturn Object.keys(obj).sort().reduce(function(inverse, name){\n\t\tinverse[obj[name]] = \"&\" + name + \";\";\n\t\treturn inverse;\n\t}, {});\n}\n\nfunction getInverseReplacer(inverse){\n\tvar single = [],\n\t    multiple = [];\n\n\tObject.keys(inverse).forEach(function(k){\n\t\tif(k.length === 1){\n\t\t\tsingle.push(\"\\\\\" + k);\n\t\t} else {\n\t\t\tmultiple.push(k);\n\t\t}\n\t});\n\n\t//TODO add ranges\n\tmultiple.unshift(\"[\" + single.join(\"\") + \"]\");\n\n\treturn new RegExp(multiple.join(\"|\"), \"g\");\n}\n\nvar re_nonASCII = /[^\\0-\\x7F]/g,\n    re_astralSymbols = /[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]/g;\n\nfunction singleCharReplacer(c){\n\treturn \"&#x\" + c.charCodeAt(0).toString(16).toUpperCase() + \";\";\n}\n\nfunction astralReplacer(c){\n\t// http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae\n\tvar high = c.charCodeAt(0);\n\tvar low  = c.charCodeAt(1);\n\tvar codePoint = (high - 0xD800) * 0x400 + low - 0xDC00 + 0x10000;\n\treturn \"&#x\" + codePoint.toString(16).toUpperCase() + \";\";\n}\n\nfunction getInverse(inverse, re){\n\tfunction func(name){\n\t\treturn inverse[name];\n\t}\n\n\treturn function(data){\n\t\treturn data\n\t\t\t\t.replace(re, func)\n\t\t\t\t.replace(re_astralSymbols, astralReplacer)\n\t\t\t\t.replace(re_nonASCII, singleCharReplacer);\n\t};\n}\n\nvar re_xmlChars = getInverseReplacer(inverseXML);\n\nfunction escapeXML(data){\n\treturn data\n\t\t\t.replace(re_xmlChars, singleCharReplacer)\n\t\t\t.replace(re_astralSymbols, astralReplacer)\n\t\t\t.replace(re_nonASCII, singleCharReplacer);\n}\n\nexports.escape = escapeXML;\n\n},{\"../maps/entities.json\":25,\"../maps/xml.json\":27}],24:[function(require,module,exports){\nmodule.exports={\"0\":65533,\"128\":8364,\"130\":8218,\"131\":402,\"132\":8222,\"133\":8230,\"134\":8224,\"135\":8225,\"136\":710,\"137\":8240,\"138\":352,\"139\":8249,\"140\":338,\"142\":381,\"145\":8216,\"146\":8217,\"147\":8220,\"148\":8221,\"149\":8226,\"150\":8211,\"151\":8212,\"152\":732,\"153\":8482,\"154\":353,\"155\":8250,\"156\":339,\"158\":382,\"159\":376}\n},{}],25:[function(require,module,exports){\nmodule.exports={\"Aacute\":\"\\u00C1\",\"aacute\":\"\\u00E1\",\"Abreve\":\"\\u0102\",\"abreve\":\"\\u0103\",\"ac\":\"\\u223E\",\"acd\":\"\\u223F\",\"acE\":\"\\u223E\\u0333\",\"Acirc\":\"\\u00C2\",\"acirc\":\"\\u00E2\",\"acute\":\"\\u00B4\",\"Acy\":\"\\u0410\",\"acy\":\"\\u0430\",\"AElig\":\"\\u00C6\",\"aelig\":\"\\u00E6\",\"af\":\"\\u2061\",\"Afr\":\"\\uD835\\uDD04\",\"afr\":\"\\uD835\\uDD1E\",\"Agrave\":\"\\u00C0\",\"agrave\":\"\\u00E0\",\"alefsym\":\"\\u2135\",\"aleph\":\"\\u2135\",\"Alpha\":\"\\u0391\",\"alpha\":\"\\u03B1\",\"Amacr\":\"\\u0100\",\"amacr\":\"\\u0101\",\"amalg\":\"\\u2A3F\",\"amp\":\"&\",\"AMP\":\"&\",\"andand\":\"\\u2A55\",\"And\":\"\\u2A53\",\"and\":\"\\u2227\",\"andd\":\"\\u2A5C\",\"andslope\":\"\\u2A58\",\"andv\":\"\\u2A5A\",\"ang\":\"\\u2220\",\"ange\":\"\\u29A4\",\"angle\":\"\\u2220\",\"angmsdaa\":\"\\u29A8\",\"angmsdab\":\"\\u29A9\",\"angmsdac\":\"\\u29AA\",\"angmsdad\":\"\\u29AB\",\"angmsdae\":\"\\u29AC\",\"angmsdaf\":\"\\u29AD\",\"angmsdag\":\"\\u29AE\",\"angmsdah\":\"\\u29AF\",\"angmsd\":\"\\u2221\",\"angrt\":\"\\u221F\",\"angrtvb\":\"\\u22BE\",\"angrtvbd\":\"\\u299D\",\"angsph\":\"\\u2222\",\"angst\":\"\\u00C5\",\"angzarr\":\"\\u237C\",\"Aogon\":\"\\u0104\",\"aogon\":\"\\u0105\",\"Aopf\":\"\\uD835\\uDD38\",\"aopf\":\"\\uD835\\uDD52\",\"apacir\":\"\\u2A6F\",\"ap\":\"\\u2248\",\"apE\":\"\\u2A70\",\"ape\":\"\\u224A\",\"apid\":\"\\u224B\",\"apos\":\"'\",\"ApplyFunction\":\"\\u2061\",\"approx\":\"\\u2248\",\"approxeq\":\"\\u224A\",\"Aring\":\"\\u00C5\",\"aring\":\"\\u00E5\",\"Ascr\":\"\\uD835\\uDC9C\",\"ascr\":\"\\uD835\\uDCB6\",\"Assign\":\"\\u2254\",\"ast\":\"*\",\"asymp\":\"\\u2248\",\"asympeq\":\"\\u224D\",\"Atilde\":\"\\u00C3\",\"atilde\":\"\\u00E3\",\"Auml\":\"\\u00C4\",\"auml\":\"\\u00E4\",\"awconint\":\"\\u2233\",\"awint\":\"\\u2A11\",\"backcong\":\"\\u224C\",\"backepsilon\":\"\\u03F6\",\"backprime\":\"\\u2035\",\"backsim\":\"\\u223D\",\"backsimeq\":\"\\u22CD\",\"Backslash\":\"\\u2216\",\"Barv\":\"\\u2AE7\",\"barvee\":\"\\u22BD\",\"barwed\":\"\\u2305\",\"Barwed\":\"\\u2306\",\"barwedge\":\"\\u2305\",\"bbrk\":\"\\u23B5\",\"bbrktbrk\":\"\\u23B6\",\"bcong\":\"\\u224C\",\"Bcy\":\"\\u0411\",\"bcy\":\"\\u0431\",\"bdquo\":\"\\u201E\",\"becaus\":\"\\u2235\",\"because\":\"\\u2235\",\"Because\":\"\\u2235\",\"bemptyv\":\"\\u29B0\",\"bepsi\":\"\\u03F6\",\"bernou\":\"\\u212C\",\"Bernoullis\":\"\\u212C\",\"Beta\":\"\\u0392\",\"beta\":\"\\u03B2\",\"beth\":\"\\u2136\",\"between\":\"\\u226C\",\"Bfr\":\"\\uD835\\uDD05\",\"bfr\":\"\\uD835\\uDD1F\",\"bigcap\":\"\\u22C2\",\"bigcirc\":\"\\u25EF\",\"bigcup\":\"\\u22C3\",\"bigodot\":\"\\u2A00\",\"bigoplus\":\"\\u2A01\",\"bigotimes\":\"\\u2A02\",\"bigsqcup\":\"\\u2A06\",\"bigstar\":\"\\u2605\",\"bigtriangledown\":\"\\u25BD\",\"bigtriangleup\":\"\\u25B3\",\"biguplus\":\"\\u2A04\",\"bigvee\":\"\\u22C1\",\"bigwedge\":\"\\u22C0\",\"bkarow\":\"\\u290D\",\"blacklozenge\":\"\\u29EB\",\"blacksquare\":\"\\u25AA\",\"blacktriangle\":\"\\u25B4\",\"blacktriangledown\":\"\\u25BE\",\"blacktriangleleft\":\"\\u25C2\",\"blacktriangleright\":\"\\u25B8\",\"blank\":\"\\u2423\",\"blk12\":\"\\u2592\",\"blk14\":\"\\u2591\",\"blk34\":\"\\u2593\",\"block\":\"\\u2588\",\"bne\":\"=\\u20E5\",\"bnequiv\":\"\\u2261\\u20E5\",\"bNot\":\"\\u2AED\",\"bnot\":\"\\u2310\",\"Bopf\":\"\\uD835\\uDD39\",\"bopf\":\"\\uD835\\uDD53\",\"bot\":\"\\u22A5\",\"bottom\":\"\\u22A5\",\"bowtie\":\"\\u22C8\",\"boxbox\":\"\\u29C9\",\"boxdl\":\"\\u2510\",\"boxdL\":\"\\u2555\",\"boxDl\":\"\\u2556\",\"boxDL\":\"\\u2557\",\"boxdr\":\"\\u250C\",\"boxdR\":\"\\u2552\",\"boxDr\":\"\\u2553\",\"boxDR\":\"\\u2554\",\"boxh\":\"\\u2500\",\"boxH\":\"\\u2550\",\"boxhd\":\"\\u252C\",\"boxHd\":\"\\u2564\",\"boxhD\":\"\\u2565\",\"boxHD\":\"\\u2566\",\"boxhu\":\"\\u2534\",\"boxHu\":\"\\u2567\",\"boxhU\":\"\\u2568\",\"boxHU\":\"\\u2569\",\"boxminus\":\"\\u229F\",\"boxplus\":\"\\u229E\",\"boxtimes\":\"\\u22A0\",\"boxul\":\"\\u2518\",\"boxuL\":\"\\u255B\",\"boxUl\":\"\\u255C\",\"boxUL\":\"\\u255D\",\"boxur\":\"\\u2514\",\"boxuR\":\"\\u2558\",\"boxUr\":\"\\u2559\",\"boxUR\":\"\\u255A\",\"boxv\":\"\\u2502\",\"boxV\":\"\\u2551\",\"boxvh\":\"\\u253C\",\"boxvH\":\"\\u256A\",\"boxVh\":\"\\u256B\",\"boxVH\":\"\\u256C\",\"boxvl\":\"\\u2524\",\"boxvL\":\"\\u2561\",\"boxVl\":\"\\u2562\",\"boxVL\":\"\\u2563\",\"boxvr\":\"\\u251C\",\"boxvR\":\"\\u255E\",\"boxVr\":\"\\u255F\",\"boxVR\":\"\\u2560\",\"bprime\":\"\\u2035\",\"breve\":\"\\u02D8\",\"Breve\":\"\\u02D8\",\"brvbar\":\"\\u00A6\",\"bscr\":\"\\uD835\\uDCB7\",\"Bscr\":\"\\u212C\",\"bsemi\":\"\\u204F\",\"bsim\":\"\\u223D\",\"bsime\":\"\\u22CD\",\"bsolb\":\"\\u29C5\",\"bsol\":\"\\\\\",\"bsolhsub\":\"\\u27C8\",\"bull\":\"\\u2022\",\"bullet\":\"\\u2022\",\"bump\":\"\\u224E\",\"bumpE\":\"\\u2AAE\",\"bumpe\":\"\\u224F\",\"Bumpeq\":\"\\u224E\",\"bumpeq\":\"\\u224F\",\"Cacute\":\"\\u0106\",\"cacute\":\"\\u0107\",\"capand\":\"\\u2A44\",\"capbrcup\":\"\\u2A49\",\"capcap\":\"\\u2A4B\",\"cap\":\"\\u2229\",\"Cap\":\"\\u22D2\",\"capcup\":\"\\u2A47\",\"capdot\":\"\\u2A40\",\"CapitalDifferentialD\":\"\\u2145\",\"caps\":\"\\u2229\\uFE00\",\"caret\":\"\\u2041\",\"caron\":\"\\u02C7\",\"Cayleys\":\"\\u212D\",\"ccaps\":\"\\u2A4D\",\"Ccaron\":\"\\u010C\",\"ccaron\":\"\\u010D\",\"Ccedil\":\"\\u00C7\",\"ccedil\":\"\\u00E7\",\"Ccirc\":\"\\u0108\",\"ccirc\":\"\\u0109\",\"Cconint\":\"\\u2230\",\"ccups\":\"\\u2A4C\",\"ccupssm\":\"\\u2A50\",\"Cdot\":\"\\u010A\",\"cdot\":\"\\u010B\",\"cedil\":\"\\u00B8\",\"Cedilla\":\"\\u00B8\",\"cemptyv\":\"\\u29B2\",\"cent\":\"\\u00A2\",\"centerdot\":\"\\u00B7\",\"CenterDot\":\"\\u00B7\",\"cfr\":\"\\uD835\\uDD20\",\"Cfr\":\"\\u212D\",\"CHcy\":\"\\u0427\",\"chcy\":\"\\u0447\",\"check\":\"\\u2713\",\"checkmark\":\"\\u2713\",\"Chi\":\"\\u03A7\",\"chi\":\"\\u03C7\",\"circ\":\"\\u02C6\",\"circeq\":\"\\u2257\",\"circlearrowleft\":\"\\u21BA\",\"circlearrowright\":\"\\u21BB\",\"circledast\":\"\\u229B\",\"circledcirc\":\"\\u229A\",\"circleddash\":\"\\u229D\",\"CircleDot\":\"\\u2299\",\"circledR\":\"\\u00AE\",\"circledS\":\"\\u24C8\",\"CircleMinus\":\"\\u2296\",\"CirclePlus\":\"\\u2295\",\"CircleTimes\":\"\\u2297\",\"cir\":\"\\u25CB\",\"cirE\":\"\\u29C3\",\"cire\":\"\\u2257\",\"cirfnint\":\"\\u2A10\",\"cirmid\":\"\\u2AEF\",\"cirscir\":\"\\u29C2\",\"ClockwiseContourIntegral\":\"\\u2232\",\"CloseCurlyDoubleQuote\":\"\\u201D\",\"CloseCurlyQuote\":\"\\u2019\",\"clubs\":\"\\u2663\",\"clubsuit\":\"\\u2663\",\"colon\":\":\",\"Colon\":\"\\u2237\",\"Colone\":\"\\u2A74\",\"colone\":\"\\u2254\",\"coloneq\":\"\\u2254\",\"comma\":\",\",\"commat\":\"@\",\"comp\":\"\\u2201\",\"compfn\":\"\\u2218\",\"complement\":\"\\u2201\",\"complexes\":\"\\u2102\",\"cong\":\"\\u2245\",\"congdot\":\"\\u2A6D\",\"Congruent\":\"\\u2261\",\"conint\":\"\\u222E\",\"Conint\":\"\\u222F\",\"ContourIntegral\":\"\\u222E\",\"copf\":\"\\uD835\\uDD54\",\"Copf\":\"\\u2102\",\"coprod\":\"\\u2210\",\"Coproduct\":\"\\u2210\",\"copy\":\"\\u00A9\",\"COPY\":\"\\u00A9\",\"copysr\":\"\\u2117\",\"CounterClockwiseContourIntegral\":\"\\u2233\",\"crarr\":\"\\u21B5\",\"cross\":\"\\u2717\",\"Cross\":\"\\u2A2F\",\"Cscr\":\"\\uD835\\uDC9E\",\"cscr\":\"\\uD835\\uDCB8\",\"csub\":\"\\u2ACF\",\"csube\":\"\\u2AD1\",\"csup\":\"\\u2AD0\",\"csupe\":\"\\u2AD2\",\"ctdot\":\"\\u22EF\",\"cudarrl\":\"\\u2938\",\"cudarrr\":\"\\u2935\",\"cuepr\":\"\\u22DE\",\"cuesc\":\"\\u22DF\",\"cularr\":\"\\u21B6\",\"cularrp\":\"\\u293D\",\"cupbrcap\":\"\\u2A48\",\"cupcap\":\"\\u2A46\",\"CupCap\":\"\\u224D\",\"cup\":\"\\u222A\",\"Cup\":\"\\u22D3\",\"cupcup\":\"\\u2A4A\",\"cupdot\":\"\\u228D\",\"cupor\":\"\\u2A45\",\"cups\":\"\\u222A\\uFE00\",\"curarr\":\"\\u21B7\",\"curarrm\":\"\\u293C\",\"curlyeqprec\":\"\\u22DE\",\"curlyeqsucc\":\"\\u22DF\",\"curlyvee\":\"\\u22CE\",\"curlywedge\":\"\\u22CF\",\"curren\":\"\\u00A4\",\"curvearrowleft\":\"\\u21B6\",\"curvearrowright\":\"\\u21B7\",\"cuvee\":\"\\u22CE\",\"cuwed\":\"\\u22CF\",\"cwconint\":\"\\u2232\",\"cwint\":\"\\u2231\",\"cylcty\":\"\\u232D\",\"dagger\":\"\\u2020\",\"Dagger\":\"\\u2021\",\"daleth\":\"\\u2138\",\"darr\":\"\\u2193\",\"Darr\":\"\\u21A1\",\"dArr\":\"\\u21D3\",\"dash\":\"\\u2010\",\"Dashv\":\"\\u2AE4\",\"dashv\":\"\\u22A3\",\"dbkarow\":\"\\u290F\",\"dblac\":\"\\u02DD\",\"Dcaron\":\"\\u010E\",\"dcaron\":\"\\u010F\",\"Dcy\":\"\\u0414\",\"dcy\":\"\\u0434\",\"ddagger\":\"\\u2021\",\"ddarr\":\"\\u21CA\",\"DD\":\"\\u2145\",\"dd\":\"\\u2146\",\"DDotrahd\":\"\\u2911\",\"ddotseq\":\"\\u2A77\",\"deg\":\"\\u00B0\",\"Del\":\"\\u2207\",\"Delta\":\"\\u0394\",\"delta\":\"\\u03B4\",\"demptyv\":\"\\u29B1\",\"dfisht\":\"\\u297F\",\"Dfr\":\"\\uD835\\uDD07\",\"dfr\":\"\\uD835\\uDD21\",\"dHar\":\"\\u2965\",\"dharl\":\"\\u21C3\",\"dharr\":\"\\u21C2\",\"DiacriticalAcute\":\"\\u00B4\",\"DiacriticalDot\":\"\\u02D9\",\"DiacriticalDoubleAcute\":\"\\u02DD\",\"DiacriticalGrave\":\"`\",\"DiacriticalTilde\":\"\\u02DC\",\"diam\":\"\\u22C4\",\"diamond\":\"\\u22C4\",\"Diamond\":\"\\u22C4\",\"diamondsuit\":\"\\u2666\",\"diams\":\"\\u2666\",\"die\":\"\\u00A8\",\"DifferentialD\":\"\\u2146\",\"digamma\":\"\\u03DD\",\"disin\":\"\\u22F2\",\"div\":\"\\u00F7\",\"divide\":\"\\u00F7\",\"divideontimes\":\"\\u22C7\",\"divonx\":\"\\u22C7\",\"DJcy\":\"\\u0402\",\"djcy\":\"\\u0452\",\"dlcorn\":\"\\u231E\",\"dlcrop\":\"\\u230D\",\"dollar\":\"$\",\"Dopf\":\"\\uD835\\uDD3B\",\"dopf\":\"\\uD835\\uDD55\",\"Dot\":\"\\u00A8\",\"dot\":\"\\u02D9\",\"DotDot\":\"\\u20DC\",\"doteq\":\"\\u2250\",\"doteqdot\":\"\\u2251\",\"DotEqual\":\"\\u2250\",\"dotminus\":\"\\u2238\",\"dotplus\":\"\\u2214\",\"dotsquare\":\"\\u22A1\",\"doublebarwedge\":\"\\u2306\",\"DoubleContourIntegral\":\"\\u222F\",\"DoubleDot\":\"\\u00A8\",\"DoubleDownArrow\":\"\\u21D3\",\"DoubleLeftArrow\":\"\\u21D0\",\"DoubleLeftRightArrow\":\"\\u21D4\",\"DoubleLeftTee\":\"\\u2AE4\",\"DoubleLongLeftArrow\":\"\\u27F8\",\"DoubleLongLeftRightArrow\":\"\\u27FA\",\"DoubleLongRightArrow\":\"\\u27F9\",\"DoubleRightArrow\":\"\\u21D2\",\"DoubleRightTee\":\"\\u22A8\",\"DoubleUpArrow\":\"\\u21D1\",\"DoubleUpDownArrow\":\"\\u21D5\",\"DoubleVerticalBar\":\"\\u2225\",\"DownArrowBar\":\"\\u2913\",\"downarrow\":\"\\u2193\",\"DownArrow\":\"\\u2193\",\"Downarrow\":\"\\u21D3\",\"DownArrowUpArrow\":\"\\u21F5\",\"DownBreve\":\"\\u0311\",\"downdownarrows\":\"\\u21CA\",\"downharpoonleft\":\"\\u21C3\",\"downharpoonright\":\"\\u21C2\",\"DownLeftRightVector\":\"\\u2950\",\"DownLeftTeeVector\":\"\\u295E\",\"DownLeftVectorBar\":\"\\u2956\",\"DownLeftVector\":\"\\u21BD\",\"DownRightTeeVector\":\"\\u295F\",\"DownRightVectorBar\":\"\\u2957\",\"DownRightVector\":\"\\u21C1\",\"DownTeeArrow\":\"\\u21A7\",\"DownTee\":\"\\u22A4\",\"drbkarow\":\"\\u2910\",\"drcorn\":\"\\u231F\",\"drcrop\":\"\\u230C\",\"Dscr\":\"\\uD835\\uDC9F\",\"dscr\":\"\\uD835\\uDCB9\",\"DScy\":\"\\u0405\",\"dscy\":\"\\u0455\",\"dsol\":\"\\u29F6\",\"Dstrok\":\"\\u0110\",\"dstrok\":\"\\u0111\",\"dtdot\":\"\\u22F1\",\"dtri\":\"\\u25BF\",\"dtrif\":\"\\u25BE\",\"duarr\":\"\\u21F5\",\"duhar\":\"\\u296F\",\"dwangle\":\"\\u29A6\",\"DZcy\":\"\\u040F\",\"dzcy\":\"\\u045F\",\"dzigrarr\":\"\\u27FF\",\"Eacute\":\"\\u00C9\",\"eacute\":\"\\u00E9\",\"easter\":\"\\u2A6E\",\"Ecaron\":\"\\u011A\",\"ecaron\":\"\\u011B\",\"Ecirc\":\"\\u00CA\",\"ecirc\":\"\\u00EA\",\"ecir\":\"\\u2256\",\"ecolon\":\"\\u2255\",\"Ecy\":\"\\u042D\",\"ecy\":\"\\u044D\",\"eDDot\":\"\\u2A77\",\"Edot\":\"\\u0116\",\"edot\":\"\\u0117\",\"eDot\":\"\\u2251\",\"ee\":\"\\u2147\",\"efDot\":\"\\u2252\",\"Efr\":\"\\uD835\\uDD08\",\"efr\":\"\\uD835\\uDD22\",\"eg\":\"\\u2A9A\",\"Egrave\":\"\\u00C8\",\"egrave\":\"\\u00E8\",\"egs\":\"\\u2A96\",\"egsdot\":\"\\u2A98\",\"el\":\"\\u2A99\",\"Element\":\"\\u2208\",\"elinters\":\"\\u23E7\",\"ell\":\"\\u2113\",\"els\":\"\\u2A95\",\"elsdot\":\"\\u2A97\",\"Emacr\":\"\\u0112\",\"emacr\":\"\\u0113\",\"empty\":\"\\u2205\",\"emptyset\":\"\\u2205\",\"EmptySmallSquare\":\"\\u25FB\",\"emptyv\":\"\\u2205\",\"EmptyVerySmallSquare\":\"\\u25AB\",\"emsp13\":\"\\u2004\",\"emsp14\":\"\\u2005\",\"emsp\":\"\\u2003\",\"ENG\":\"\\u014A\",\"eng\":\"\\u014B\",\"ensp\":\"\\u2002\",\"Eogon\":\"\\u0118\",\"eogon\":\"\\u0119\",\"Eopf\":\"\\uD835\\uDD3C\",\"eopf\":\"\\uD835\\uDD56\",\"epar\":\"\\u22D5\",\"eparsl\":\"\\u29E3\",\"eplus\":\"\\u2A71\",\"epsi\":\"\\u03B5\",\"Epsilon\":\"\\u0395\",\"epsilon\":\"\\u03B5\",\"epsiv\":\"\\u03F5\",\"eqcirc\":\"\\u2256\",\"eqcolon\":\"\\u2255\",\"eqsim\":\"\\u2242\",\"eqslantgtr\":\"\\u2A96\",\"eqslantless\":\"\\u2A95\",\"Equal\":\"\\u2A75\",\"equals\":\"=\",\"EqualTilde\":\"\\u2242\",\"equest\":\"\\u225F\",\"Equilibrium\":\"\\u21CC\",\"equiv\":\"\\u2261\",\"equivDD\":\"\\u2A78\",\"eqvparsl\":\"\\u29E5\",\"erarr\":\"\\u2971\",\"erDot\":\"\\u2253\",\"escr\":\"\\u212F\",\"Escr\":\"\\u2130\",\"esdot\":\"\\u2250\",\"Esim\":\"\\u2A73\",\"esim\":\"\\u2242\",\"Eta\":\"\\u0397\",\"eta\":\"\\u03B7\",\"ETH\":\"\\u00D0\",\"eth\":\"\\u00F0\",\"Euml\":\"\\u00CB\",\"euml\":\"\\u00EB\",\"euro\":\"\\u20AC\",\"excl\":\"!\",\"exist\":\"\\u2203\",\"Exists\":\"\\u2203\",\"expectation\":\"\\u2130\",\"exponentiale\":\"\\u2147\",\"ExponentialE\":\"\\u2147\",\"fallingdotseq\":\"\\u2252\",\"Fcy\":\"\\u0424\",\"fcy\":\"\\u0444\",\"female\":\"\\u2640\",\"ffilig\":\"\\uFB03\",\"fflig\":\"\\uFB00\",\"ffllig\":\"\\uFB04\",\"Ffr\":\"\\uD835\\uDD09\",\"ffr\":\"\\uD835\\uDD23\",\"filig\":\"\\uFB01\",\"FilledSmallSquare\":\"\\u25FC\",\"FilledVerySmallSquare\":\"\\u25AA\",\"fjlig\":\"fj\",\"flat\":\"\\u266D\",\"fllig\":\"\\uFB02\",\"fltns\":\"\\u25B1\",\"fnof\":\"\\u0192\",\"Fopf\":\"\\uD835\\uDD3D\",\"fopf\":\"\\uD835\\uDD57\",\"forall\":\"\\u2200\",\"ForAll\":\"\\u2200\",\"fork\":\"\\u22D4\",\"forkv\":\"\\u2AD9\",\"Fouriertrf\":\"\\u2131\",\"fpartint\":\"\\u2A0D\",\"frac12\":\"\\u00BD\",\"frac13\":\"\\u2153\",\"frac14\":\"\\u00BC\",\"frac15\":\"\\u2155\",\"frac16\":\"\\u2159\",\"frac18\":\"\\u215B\",\"frac23\":\"\\u2154\",\"frac25\":\"\\u2156\",\"frac34\":\"\\u00BE\",\"frac35\":\"\\u2157\",\"frac38\":\"\\u215C\",\"frac45\":\"\\u2158\",\"frac56\":\"\\u215A\",\"frac58\":\"\\u215D\",\"frac78\":\"\\u215E\",\"frasl\":\"\\u2044\",\"frown\":\"\\u2322\",\"fscr\":\"\\uD835\\uDCBB\",\"Fscr\":\"\\u2131\",\"gacute\":\"\\u01F5\",\"Gamma\":\"\\u0393\",\"gamma\":\"\\u03B3\",\"Gammad\":\"\\u03DC\",\"gammad\":\"\\u03DD\",\"gap\":\"\\u2A86\",\"Gbreve\":\"\\u011E\",\"gbreve\":\"\\u011F\",\"Gcedil\":\"\\u0122\",\"Gcirc\":\"\\u011C\",\"gcirc\":\"\\u011D\",\"Gcy\":\"\\u0413\",\"gcy\":\"\\u0433\",\"Gdot\":\"\\u0120\",\"gdot\":\"\\u0121\",\"ge\":\"\\u2265\",\"gE\":\"\\u2267\",\"gEl\":\"\\u2A8C\",\"gel\":\"\\u22DB\",\"geq\":\"\\u2265\",\"geqq\":\"\\u2267\",\"geqslant\":\"\\u2A7E\",\"gescc\":\"\\u2AA9\",\"ges\":\"\\u2A7E\",\"gesdot\":\"\\u2A80\",\"gesdoto\":\"\\u2A82\",\"gesdotol\":\"\\u2A84\",\"gesl\":\"\\u22DB\\uFE00\",\"gesles\":\"\\u2A94\",\"Gfr\":\"\\uD835\\uDD0A\",\"gfr\":\"\\uD835\\uDD24\",\"gg\":\"\\u226B\",\"Gg\":\"\\u22D9\",\"ggg\":\"\\u22D9\",\"gimel\":\"\\u2137\",\"GJcy\":\"\\u0403\",\"gjcy\":\"\\u0453\",\"gla\":\"\\u2AA5\",\"gl\":\"\\u2277\",\"glE\":\"\\u2A92\",\"glj\":\"\\u2AA4\",\"gnap\":\"\\u2A8A\",\"gnapprox\":\"\\u2A8A\",\"gne\":\"\\u2A88\",\"gnE\":\"\\u2269\",\"gneq\":\"\\u2A88\",\"gneqq\":\"\\u2269\",\"gnsim\":\"\\u22E7\",\"Gopf\":\"\\uD835\\uDD3E\",\"gopf\":\"\\uD835\\uDD58\",\"grave\":\"`\",\"GreaterEqual\":\"\\u2265\",\"GreaterEqualLess\":\"\\u22DB\",\"GreaterFullEqual\":\"\\u2267\",\"GreaterGreater\":\"\\u2AA2\",\"GreaterLess\":\"\\u2277\",\"GreaterSlantEqual\":\"\\u2A7E\",\"GreaterTilde\":\"\\u2273\",\"Gscr\":\"\\uD835\\uDCA2\",\"gscr\":\"\\u210A\",\"gsim\":\"\\u2273\",\"gsime\":\"\\u2A8E\",\"gsiml\":\"\\u2A90\",\"gtcc\":\"\\u2AA7\",\"gtcir\":\"\\u2A7A\",\"gt\":\">\",\"GT\":\">\",\"Gt\":\"\\u226B\",\"gtdot\":\"\\u22D7\",\"gtlPar\":\"\\u2995\",\"gtquest\":\"\\u2A7C\",\"gtrapprox\":\"\\u2A86\",\"gtrarr\":\"\\u2978\",\"gtrdot\":\"\\u22D7\",\"gtreqless\":\"\\u22DB\",\"gtreqqless\":\"\\u2A8C\",\"gtrless\":\"\\u2277\",\"gtrsim\":\"\\u2273\",\"gvertneqq\":\"\\u2269\\uFE00\",\"gvnE\":\"\\u2269\\uFE00\",\"Hacek\":\"\\u02C7\",\"hairsp\":\"\\u200A\",\"half\":\"\\u00BD\",\"hamilt\":\"\\u210B\",\"HARDcy\":\"\\u042A\",\"hardcy\":\"\\u044A\",\"harrcir\":\"\\u2948\",\"harr\":\"\\u2194\",\"hArr\":\"\\u21D4\",\"harrw\":\"\\u21AD\",\"Hat\":\"^\",\"hbar\":\"\\u210F\",\"Hcirc\":\"\\u0124\",\"hcirc\":\"\\u0125\",\"hearts\":\"\\u2665\",\"heartsuit\":\"\\u2665\",\"hellip\":\"\\u2026\",\"hercon\":\"\\u22B9\",\"hfr\":\"\\uD835\\uDD25\",\"Hfr\":\"\\u210C\",\"HilbertSpace\":\"\\u210B\",\"hksearow\":\"\\u2925\",\"hkswarow\":\"\\u2926\",\"hoarr\":\"\\u21FF\",\"homtht\":\"\\u223B\",\"hookleftarrow\":\"\\u21A9\",\"hookrightarrow\":\"\\u21AA\",\"hopf\":\"\\uD835\\uDD59\",\"Hopf\":\"\\u210D\",\"horbar\":\"\\u2015\",\"HorizontalLine\":\"\\u2500\",\"hscr\":\"\\uD835\\uDCBD\",\"Hscr\":\"\\u210B\",\"hslash\":\"\\u210F\",\"Hstrok\":\"\\u0126\",\"hstrok\":\"\\u0127\",\"HumpDownHump\":\"\\u224E\",\"HumpEqual\":\"\\u224F\",\"hybull\":\"\\u2043\",\"hyphen\":\"\\u2010\",\"Iacute\":\"\\u00CD\",\"iacute\":\"\\u00ED\",\"ic\":\"\\u2063\",\"Icirc\":\"\\u00CE\",\"icirc\":\"\\u00EE\",\"Icy\":\"\\u0418\",\"icy\":\"\\u0438\",\"Idot\":\"\\u0130\",\"IEcy\":\"\\u0415\",\"iecy\":\"\\u0435\",\"iexcl\":\"\\u00A1\",\"iff\":\"\\u21D4\",\"ifr\":\"\\uD835\\uDD26\",\"Ifr\":\"\\u2111\",\"Igrave\":\"\\u00CC\",\"igrave\":\"\\u00EC\",\"ii\":\"\\u2148\",\"iiiint\":\"\\u2A0C\",\"iiint\":\"\\u222D\",\"iinfin\":\"\\u29DC\",\"iiota\":\"\\u2129\",\"IJlig\":\"\\u0132\",\"ijlig\":\"\\u0133\",\"Imacr\":\"\\u012A\",\"imacr\":\"\\u012B\",\"image\":\"\\u2111\",\"ImaginaryI\":\"\\u2148\",\"imagline\":\"\\u2110\",\"imagpart\":\"\\u2111\",\"imath\":\"\\u0131\",\"Im\":\"\\u2111\",\"imof\":\"\\u22B7\",\"imped\":\"\\u01B5\",\"Implies\":\"\\u21D2\",\"incare\":\"\\u2105\",\"in\":\"\\u2208\",\"infin\":\"\\u221E\",\"infintie\":\"\\u29DD\",\"inodot\":\"\\u0131\",\"intcal\":\"\\u22BA\",\"int\":\"\\u222B\",\"Int\":\"\\u222C\",\"integers\":\"\\u2124\",\"Integral\":\"\\u222B\",\"intercal\":\"\\u22BA\",\"Intersection\":\"\\u22C2\",\"intlarhk\":\"\\u2A17\",\"intprod\":\"\\u2A3C\",\"InvisibleComma\":\"\\u2063\",\"InvisibleTimes\":\"\\u2062\",\"IOcy\":\"\\u0401\",\"iocy\":\"\\u0451\",\"Iogon\":\"\\u012E\",\"iogon\":\"\\u012F\",\"Iopf\":\"\\uD835\\uDD40\",\"iopf\":\"\\uD835\\uDD5A\",\"Iota\":\"\\u0399\",\"iota\":\"\\u03B9\",\"iprod\":\"\\u2A3C\",\"iquest\":\"\\u00BF\",\"iscr\":\"\\uD835\\uDCBE\",\"Iscr\":\"\\u2110\",\"isin\":\"\\u2208\",\"isindot\":\"\\u22F5\",\"isinE\":\"\\u22F9\",\"isins\":\"\\u22F4\",\"isinsv\":\"\\u22F3\",\"isinv\":\"\\u2208\",\"it\":\"\\u2062\",\"Itilde\":\"\\u0128\",\"itilde\":\"\\u0129\",\"Iukcy\":\"\\u0406\",\"iukcy\":\"\\u0456\",\"Iuml\":\"\\u00CF\",\"iuml\":\"\\u00EF\",\"Jcirc\":\"\\u0134\",\"jcirc\":\"\\u0135\",\"Jcy\":\"\\u0419\",\"jcy\":\"\\u0439\",\"Jfr\":\"\\uD835\\uDD0D\",\"jfr\":\"\\uD835\\uDD27\",\"jmath\":\"\\u0237\",\"Jopf\":\"\\uD835\\uDD41\",\"jopf\":\"\\uD835\\uDD5B\",\"Jscr\":\"\\uD835\\uDCA5\",\"jscr\":\"\\uD835\\uDCBF\",\"Jsercy\":\"\\u0408\",\"jsercy\":\"\\u0458\",\"Jukcy\":\"\\u0404\",\"jukcy\":\"\\u0454\",\"Kappa\":\"\\u039A\",\"kappa\":\"\\u03BA\",\"kappav\":\"\\u03F0\",\"Kcedil\":\"\\u0136\",\"kcedil\":\"\\u0137\",\"Kcy\":\"\\u041A\",\"kcy\":\"\\u043A\",\"Kfr\":\"\\uD835\\uDD0E\",\"kfr\":\"\\uD835\\uDD28\",\"kgreen\":\"\\u0138\",\"KHcy\":\"\\u0425\",\"khcy\":\"\\u0445\",\"KJcy\":\"\\u040C\",\"kjcy\":\"\\u045C\",\"Kopf\":\"\\uD835\\uDD42\",\"kopf\":\"\\uD835\\uDD5C\",\"Kscr\":\"\\uD835\\uDCA6\",\"kscr\":\"\\uD835\\uDCC0\",\"lAarr\":\"\\u21DA\",\"Lacute\":\"\\u0139\",\"lacute\":\"\\u013A\",\"laemptyv\":\"\\u29B4\",\"lagran\":\"\\u2112\",\"Lambda\":\"\\u039B\",\"lambda\":\"\\u03BB\",\"lang\":\"\\u27E8\",\"Lang\":\"\\u27EA\",\"langd\":\"\\u2991\",\"langle\":\"\\u27E8\",\"lap\":\"\\u2A85\",\"Laplacetrf\":\"\\u2112\",\"laquo\":\"\\u00AB\",\"larrb\":\"\\u21E4\",\"larrbfs\":\"\\u291F\",\"larr\":\"\\u2190\",\"Larr\":\"\\u219E\",\"lArr\":\"\\u21D0\",\"larrfs\":\"\\u291D\",\"larrhk\":\"\\u21A9\",\"larrlp\":\"\\u21AB\",\"larrpl\":\"\\u2939\",\"larrsim\":\"\\u2973\",\"larrtl\":\"\\u21A2\",\"latail\":\"\\u2919\",\"lAtail\":\"\\u291B\",\"lat\":\"\\u2AAB\",\"late\":\"\\u2AAD\",\"lates\":\"\\u2AAD\\uFE00\",\"lbarr\":\"\\u290C\",\"lBarr\":\"\\u290E\",\"lbbrk\":\"\\u2772\",\"lbrace\":\"{\",\"lbrack\":\"[\",\"lbrke\":\"\\u298B\",\"lbrksld\":\"\\u298F\",\"lbrkslu\":\"\\u298D\",\"Lcaron\":\"\\u013D\",\"lcaron\":\"\\u013E\",\"Lcedil\":\"\\u013B\",\"lcedil\":\"\\u013C\",\"lceil\":\"\\u2308\",\"lcub\":\"{\",\"Lcy\":\"\\u041B\",\"lcy\":\"\\u043B\",\"ldca\":\"\\u2936\",\"ldquo\":\"\\u201C\",\"ldquor\":\"\\u201E\",\"ldrdhar\":\"\\u2967\",\"ldrushar\":\"\\u294B\",\"ldsh\":\"\\u21B2\",\"le\":\"\\u2264\",\"lE\":\"\\u2266\",\"LeftAngleBracket\":\"\\u27E8\",\"LeftArrowBar\":\"\\u21E4\",\"leftarrow\":\"\\u2190\",\"LeftArrow\":\"\\u2190\",\"Leftarrow\":\"\\u21D0\",\"LeftArrowRightArrow\":\"\\u21C6\",\"leftarrowtail\":\"\\u21A2\",\"LeftCeiling\":\"\\u2308\",\"LeftDoubleBracket\":\"\\u27E6\",\"LeftDownTeeVector\":\"\\u2961\",\"LeftDownVectorBar\":\"\\u2959\",\"LeftDownVector\":\"\\u21C3\",\"LeftFloor\":\"\\u230A\",\"leftharpoondown\":\"\\u21BD\",\"leftharpoonup\":\"\\u21BC\",\"leftleftarrows\":\"\\u21C7\",\"leftrightarrow\":\"\\u2194\",\"LeftRightArrow\":\"\\u2194\",\"Leftrightarrow\":\"\\u21D4\",\"leftrightarrows\":\"\\u21C6\",\"leftrightharpoons\":\"\\u21CB\",\"leftrightsquigarrow\":\"\\u21AD\",\"LeftRightVector\":\"\\u294E\",\"LeftTeeArrow\":\"\\u21A4\",\"LeftTee\":\"\\u22A3\",\"LeftTeeVector\":\"\\u295A\",\"leftthreetimes\":\"\\u22CB\",\"LeftTriangleBar\":\"\\u29CF\",\"LeftTriangle\":\"\\u22B2\",\"LeftTriangleEqual\":\"\\u22B4\",\"LeftUpDownVector\":\"\\u2951\",\"LeftUpTeeVector\":\"\\u2960\",\"LeftUpVectorBar\":\"\\u2958\",\"LeftUpVector\":\"\\u21BF\",\"LeftVectorBar\":\"\\u2952\",\"LeftVector\":\"\\u21BC\",\"lEg\":\"\\u2A8B\",\"leg\":\"\\u22DA\",\"leq\":\"\\u2264\",\"leqq\":\"\\u2266\",\"leqslant\":\"\\u2A7D\",\"lescc\":\"\\u2AA8\",\"les\":\"\\u2A7D\",\"lesdot\":\"\\u2A7F\",\"lesdoto\":\"\\u2A81\",\"lesdotor\":\"\\u2A83\",\"lesg\":\"\\u22DA\\uFE00\",\"lesges\":\"\\u2A93\",\"lessapprox\":\"\\u2A85\",\"lessdot\":\"\\u22D6\",\"lesseqgtr\":\"\\u22DA\",\"lesseqqgtr\":\"\\u2A8B\",\"LessEqualGreater\":\"\\u22DA\",\"LessFullEqual\":\"\\u2266\",\"LessGreater\":\"\\u2276\",\"lessgtr\":\"\\u2276\",\"LessLess\":\"\\u2AA1\",\"lesssim\":\"\\u2272\",\"LessSlantEqual\":\"\\u2A7D\",\"LessTilde\":\"\\u2272\",\"lfisht\":\"\\u297C\",\"lfloor\":\"\\u230A\",\"Lfr\":\"\\uD835\\uDD0F\",\"lfr\":\"\\uD835\\uDD29\",\"lg\":\"\\u2276\",\"lgE\":\"\\u2A91\",\"lHar\":\"\\u2962\",\"lhard\":\"\\u21BD\",\"lharu\":\"\\u21BC\",\"lharul\":\"\\u296A\",\"lhblk\":\"\\u2584\",\"LJcy\":\"\\u0409\",\"ljcy\":\"\\u0459\",\"llarr\":\"\\u21C7\",\"ll\":\"\\u226A\",\"Ll\":\"\\u22D8\",\"llcorner\":\"\\u231E\",\"Lleftarrow\":\"\\u21DA\",\"llhard\":\"\\u296B\",\"lltri\":\"\\u25FA\",\"Lmidot\":\"\\u013F\",\"lmidot\":\"\\u0140\",\"lmoustache\":\"\\u23B0\",\"lmoust\":\"\\u23B0\",\"lnap\":\"\\u2A89\",\"lnapprox\":\"\\u2A89\",\"lne\":\"\\u2A87\",\"lnE\":\"\\u2268\",\"lneq\":\"\\u2A87\",\"lneqq\":\"\\u2268\",\"lnsim\":\"\\u22E6\",\"loang\":\"\\u27EC\",\"loarr\":\"\\u21FD\",\"lobrk\":\"\\u27E6\",\"longleftarrow\":\"\\u27F5\",\"LongLeftArrow\":\"\\u27F5\",\"Longleftarrow\":\"\\u27F8\",\"longleftrightarrow\":\"\\u27F7\",\"LongLeftRightArrow\":\"\\u27F7\",\"Longleftrightarrow\":\"\\u27FA\",\"longmapsto\":\"\\u27FC\",\"longrightarrow\":\"\\u27F6\",\"LongRightArrow\":\"\\u27F6\",\"Longrightarrow\":\"\\u27F9\",\"looparrowleft\":\"\\u21AB\",\"looparrowright\":\"\\u21AC\",\"lopar\":\"\\u2985\",\"Lopf\":\"\\uD835\\uDD43\",\"lopf\":\"\\uD835\\uDD5D\",\"loplus\":\"\\u2A2D\",\"lotimes\":\"\\u2A34\",\"lowast\":\"\\u2217\",\"lowbar\":\"_\",\"LowerLeftArrow\":\"\\u2199\",\"LowerRightArrow\":\"\\u2198\",\"loz\":\"\\u25CA\",\"lozenge\":\"\\u25CA\",\"lozf\":\"\\u29EB\",\"lpar\":\"(\",\"lparlt\":\"\\u2993\",\"lrarr\":\"\\u21C6\",\"lrcorner\":\"\\u231F\",\"lrhar\":\"\\u21CB\",\"lrhard\":\"\\u296D\",\"lrm\":\"\\u200E\",\"lrtri\":\"\\u22BF\",\"lsaquo\":\"\\u2039\",\"lscr\":\"\\uD835\\uDCC1\",\"Lscr\":\"\\u2112\",\"lsh\":\"\\u21B0\",\"Lsh\":\"\\u21B0\",\"lsim\":\"\\u2272\",\"lsime\":\"\\u2A8D\",\"lsimg\":\"\\u2A8F\",\"lsqb\":\"[\",\"lsquo\":\"\\u2018\",\"lsquor\":\"\\u201A\",\"Lstrok\":\"\\u0141\",\"lstrok\":\"\\u0142\",\"ltcc\":\"\\u2AA6\",\"ltcir\":\"\\u2A79\",\"lt\":\"<\",\"LT\":\"<\",\"Lt\":\"\\u226A\",\"ltdot\":\"\\u22D6\",\"lthree\":\"\\u22CB\",\"ltimes\":\"\\u22C9\",\"ltlarr\":\"\\u2976\",\"ltquest\":\"\\u2A7B\",\"ltri\":\"\\u25C3\",\"ltrie\":\"\\u22B4\",\"ltrif\":\"\\u25C2\",\"ltrPar\":\"\\u2996\",\"lurdshar\":\"\\u294A\",\"luruhar\":\"\\u2966\",\"lvertneqq\":\"\\u2268\\uFE00\",\"lvnE\":\"\\u2268\\uFE00\",\"macr\":\"\\u00AF\",\"male\":\"\\u2642\",\"malt\":\"\\u2720\",\"maltese\":\"\\u2720\",\"Map\":\"\\u2905\",\"map\":\"\\u21A6\",\"mapsto\":\"\\u21A6\",\"mapstodown\":\"\\u21A7\",\"mapstoleft\":\"\\u21A4\",\"mapstoup\":\"\\u21A5\",\"marker\":\"\\u25AE\",\"mcomma\":\"\\u2A29\",\"Mcy\":\"\\u041C\",\"mcy\":\"\\u043C\",\"mdash\":\"\\u2014\",\"mDDot\":\"\\u223A\",\"measuredangle\":\"\\u2221\",\"MediumSpace\":\"\\u205F\",\"Mellintrf\":\"\\u2133\",\"Mfr\":\"\\uD835\\uDD10\",\"mfr\":\"\\uD835\\uDD2A\",\"mho\":\"\\u2127\",\"micro\":\"\\u00B5\",\"midast\":\"*\",\"midcir\":\"\\u2AF0\",\"mid\":\"\\u2223\",\"middot\":\"\\u00B7\",\"minusb\":\"\\u229F\",\"minus\":\"\\u2212\",\"minusd\":\"\\u2238\",\"minusdu\":\"\\u2A2A\",\"MinusPlus\":\"\\u2213\",\"mlcp\":\"\\u2ADB\",\"mldr\":\"\\u2026\",\"mnplus\":\"\\u2213\",\"models\":\"\\u22A7\",\"Mopf\":\"\\uD835\\uDD44\",\"mopf\":\"\\uD835\\uDD5E\",\"mp\":\"\\u2213\",\"mscr\":\"\\uD835\\uDCC2\",\"Mscr\":\"\\u2133\",\"mstpos\":\"\\u223E\",\"Mu\":\"\\u039C\",\"mu\":\"\\u03BC\",\"multimap\":\"\\u22B8\",\"mumap\":\"\\u22B8\",\"nabla\":\"\\u2207\",\"Nacute\":\"\\u0143\",\"nacute\":\"\\u0144\",\"nang\":\"\\u2220\\u20D2\",\"nap\":\"\\u2249\",\"napE\":\"\\u2A70\\u0338\",\"napid\":\"\\u224B\\u0338\",\"napos\":\"\\u0149\",\"napprox\":\"\\u2249\",\"natural\":\"\\u266E\",\"naturals\":\"\\u2115\",\"natur\":\"\\u266E\",\"nbsp\":\"\\u00A0\",\"nbump\":\"\\u224E\\u0338\",\"nbumpe\":\"\\u224F\\u0338\",\"ncap\":\"\\u2A43\",\"Ncaron\":\"\\u0147\",\"ncaron\":\"\\u0148\",\"Ncedil\":\"\\u0145\",\"ncedil\":\"\\u0146\",\"ncong\":\"\\u2247\",\"ncongdot\":\"\\u2A6D\\u0338\",\"ncup\":\"\\u2A42\",\"Ncy\":\"\\u041D\",\"ncy\":\"\\u043D\",\"ndash\":\"\\u2013\",\"nearhk\":\"\\u2924\",\"nearr\":\"\\u2197\",\"neArr\":\"\\u21D7\",\"nearrow\":\"\\u2197\",\"ne\":\"\\u2260\",\"nedot\":\"\\u2250\\u0338\",\"NegativeMediumSpace\":\"\\u200B\",\"NegativeThickSpace\":\"\\u200B\",\"NegativeThinSpace\":\"\\u200B\",\"NegativeVeryThinSpace\":\"\\u200B\",\"nequiv\":\"\\u2262\",\"nesear\":\"\\u2928\",\"nesim\":\"\\u2242\\u0338\",\"NestedGreaterGreater\":\"\\u226B\",\"NestedLessLess\":\"\\u226A\",\"NewLine\":\"\\n\",\"nexist\":\"\\u2204\",\"nexists\":\"\\u2204\",\"Nfr\":\"\\uD835\\uDD11\",\"nfr\":\"\\uD835\\uDD2B\",\"ngE\":\"\\u2267\\u0338\",\"nge\":\"\\u2271\",\"ngeq\":\"\\u2271\",\"ngeqq\":\"\\u2267\\u0338\",\"ngeqslant\":\"\\u2A7E\\u0338\",\"nges\":\"\\u2A7E\\u0338\",\"nGg\":\"\\u22D9\\u0338\",\"ngsim\":\"\\u2275\",\"nGt\":\"\\u226B\\u20D2\",\"ngt\":\"\\u226F\",\"ngtr\":\"\\u226F\",\"nGtv\":\"\\u226B\\u0338\",\"nharr\":\"\\u21AE\",\"nhArr\":\"\\u21CE\",\"nhpar\":\"\\u2AF2\",\"ni\":\"\\u220B\",\"nis\":\"\\u22FC\",\"nisd\":\"\\u22FA\",\"niv\":\"\\u220B\",\"NJcy\":\"\\u040A\",\"njcy\":\"\\u045A\",\"nlarr\":\"\\u219A\",\"nlArr\":\"\\u21CD\",\"nldr\":\"\\u2025\",\"nlE\":\"\\u2266\\u0338\",\"nle\":\"\\u2270\",\"nleftarrow\":\"\\u219A\",\"nLeftarrow\":\"\\u21CD\",\"nleftrightarrow\":\"\\u21AE\",\"nLeftrightarrow\":\"\\u21CE\",\"nleq\":\"\\u2270\",\"nleqq\":\"\\u2266\\u0338\",\"nleqslant\":\"\\u2A7D\\u0338\",\"nles\":\"\\u2A7D\\u0338\",\"nless\":\"\\u226E\",\"nLl\":\"\\u22D8\\u0338\",\"nlsim\":\"\\u2274\",\"nLt\":\"\\u226A\\u20D2\",\"nlt\":\"\\u226E\",\"nltri\":\"\\u22EA\",\"nltrie\":\"\\u22EC\",\"nLtv\":\"\\u226A\\u0338\",\"nmid\":\"\\u2224\",\"NoBreak\":\"\\u2060\",\"NonBreakingSpace\":\"\\u00A0\",\"nopf\":\"\\uD835\\uDD5F\",\"Nopf\":\"\\u2115\",\"Not\":\"\\u2AEC\",\"not\":\"\\u00AC\",\"NotCongruent\":\"\\u2262\",\"NotCupCap\":\"\\u226D\",\"NotDoubleVerticalBar\":\"\\u2226\",\"NotElement\":\"\\u2209\",\"NotEqual\":\"\\u2260\",\"NotEqualTilde\":\"\\u2242\\u0338\",\"NotExists\":\"\\u2204\",\"NotGreater\":\"\\u226F\",\"NotGreaterEqual\":\"\\u2271\",\"NotGreaterFullEqual\":\"\\u2267\\u0338\",\"NotGreaterGreater\":\"\\u226B\\u0338\",\"NotGreaterLess\":\"\\u2279\",\"NotGreaterSlantEqual\":\"\\u2A7E\\u0338\",\"NotGreaterTilde\":\"\\u2275\",\"NotHumpDownHump\":\"\\u224E\\u0338\",\"NotHumpEqual\":\"\\u224F\\u0338\",\"notin\":\"\\u2209\",\"notindot\":\"\\u22F5\\u0338\",\"notinE\":\"\\u22F9\\u0338\",\"notinva\":\"\\u2209\",\"notinvb\":\"\\u22F7\",\"notinvc\":\"\\u22F6\",\"NotLeftTriangleBar\":\"\\u29CF\\u0338\",\"NotLeftTriangle\":\"\\u22EA\",\"NotLeftTriangleEqual\":\"\\u22EC\",\"NotLess\":\"\\u226E\",\"NotLessEqual\":\"\\u2270\",\"NotLessGreater\":\"\\u2278\",\"NotLessLess\":\"\\u226A\\u0338\",\"NotLessSlantEqual\":\"\\u2A7D\\u0338\",\"NotLessTilde\":\"\\u2274\",\"NotNestedGreaterGreater\":\"\\u2AA2\\u0338\",\"NotNestedLessLess\":\"\\u2AA1\\u0338\",\"notni\":\"\\u220C\",\"notniva\":\"\\u220C\",\"notnivb\":\"\\u22FE\",\"notnivc\":\"\\u22FD\",\"NotPrecedes\":\"\\u2280\",\"NotPrecedesEqual\":\"\\u2AAF\\u0338\",\"NotPrecedesSlantEqual\":\"\\u22E0\",\"NotReverseElement\":\"\\u220C\",\"NotRightTriangleBar\":\"\\u29D0\\u0338\",\"NotRightTriangle\":\"\\u22EB\",\"NotRightTriangleEqual\":\"\\u22ED\",\"NotSquareSubset\":\"\\u228F\\u0338\",\"NotSquareSubsetEqual\":\"\\u22E2\",\"NotSquareSuperset\":\"\\u2290\\u0338\",\"NotSquareSupersetEqual\":\"\\u22E3\",\"NotSubset\":\"\\u2282\\u20D2\",\"NotSubsetEqual\":\"\\u2288\",\"NotSucceeds\":\"\\u2281\",\"NotSucceedsEqual\":\"\\u2AB0\\u0338\",\"NotSucceedsSlantEqual\":\"\\u22E1\",\"NotSucceedsTilde\":\"\\u227F\\u0338\",\"NotSuperset\":\"\\u2283\\u20D2\",\"NotSupersetEqual\":\"\\u2289\",\"NotTilde\":\"\\u2241\",\"NotTildeEqual\":\"\\u2244\",\"NotTildeFullEqual\":\"\\u2247\",\"NotTildeTilde\":\"\\u2249\",\"NotVerticalBar\":\"\\u2224\",\"nparallel\":\"\\u2226\",\"npar\":\"\\u2226\",\"nparsl\":\"\\u2AFD\\u20E5\",\"npart\":\"\\u2202\\u0338\",\"npolint\":\"\\u2A14\",\"npr\":\"\\u2280\",\"nprcue\":\"\\u22E0\",\"nprec\":\"\\u2280\",\"npreceq\":\"\\u2AAF\\u0338\",\"npre\":\"\\u2AAF\\u0338\",\"nrarrc\":\"\\u2933\\u0338\",\"nrarr\":\"\\u219B\",\"nrArr\":\"\\u21CF\",\"nrarrw\":\"\\u219D\\u0338\",\"nrightarrow\":\"\\u219B\",\"nRightarrow\":\"\\u21CF\",\"nrtri\":\"\\u22EB\",\"nrtrie\":\"\\u22ED\",\"nsc\":\"\\u2281\",\"nsccue\":\"\\u22E1\",\"nsce\":\"\\u2AB0\\u0338\",\"Nscr\":\"\\uD835\\uDCA9\",\"nscr\":\"\\uD835\\uDCC3\",\"nshortmid\":\"\\u2224\",\"nshortparallel\":\"\\u2226\",\"nsim\":\"\\u2241\",\"nsime\":\"\\u2244\",\"nsimeq\":\"\\u2244\",\"nsmid\":\"\\u2224\",\"nspar\":\"\\u2226\",\"nsqsube\":\"\\u22E2\",\"nsqsupe\":\"\\u22E3\",\"nsub\":\"\\u2284\",\"nsubE\":\"\\u2AC5\\u0338\",\"nsube\":\"\\u2288\",\"nsubset\":\"\\u2282\\u20D2\",\"nsubseteq\":\"\\u2288\",\"nsubseteqq\":\"\\u2AC5\\u0338\",\"nsucc\":\"\\u2281\",\"nsucceq\":\"\\u2AB0\\u0338\",\"nsup\":\"\\u2285\",\"nsupE\":\"\\u2AC6\\u0338\",\"nsupe\":\"\\u2289\",\"nsupset\":\"\\u2283\\u20D2\",\"nsupseteq\":\"\\u2289\",\"nsupseteqq\":\"\\u2AC6\\u0338\",\"ntgl\":\"\\u2279\",\"Ntilde\":\"\\u00D1\",\"ntilde\":\"\\u00F1\",\"ntlg\":\"\\u2278\",\"ntriangleleft\":\"\\u22EA\",\"ntrianglelefteq\":\"\\u22EC\",\"ntriangleright\":\"\\u22EB\",\"ntrianglerighteq\":\"\\u22ED\",\"Nu\":\"\\u039D\",\"nu\":\"\\u03BD\",\"num\":\"#\",\"numero\":\"\\u2116\",\"numsp\":\"\\u2007\",\"nvap\":\"\\u224D\\u20D2\",\"nvdash\":\"\\u22AC\",\"nvDash\":\"\\u22AD\",\"nVdash\":\"\\u22AE\",\"nVDash\":\"\\u22AF\",\"nvge\":\"\\u2265\\u20D2\",\"nvgt\":\">\\u20D2\",\"nvHarr\":\"\\u2904\",\"nvinfin\":\"\\u29DE\",\"nvlArr\":\"\\u2902\",\"nvle\":\"\\u2264\\u20D2\",\"nvlt\":\"<\\u20D2\",\"nvltrie\":\"\\u22B4\\u20D2\",\"nvrArr\":\"\\u2903\",\"nvrtrie\":\"\\u22B5\\u20D2\",\"nvsim\":\"\\u223C\\u20D2\",\"nwarhk\":\"\\u2923\",\"nwarr\":\"\\u2196\",\"nwArr\":\"\\u21D6\",\"nwarrow\":\"\\u2196\",\"nwnear\":\"\\u2927\",\"Oacute\":\"\\u00D3\",\"oacute\":\"\\u00F3\",\"oast\":\"\\u229B\",\"Ocirc\":\"\\u00D4\",\"ocirc\":\"\\u00F4\",\"ocir\":\"\\u229A\",\"Ocy\":\"\\u041E\",\"ocy\":\"\\u043E\",\"odash\":\"\\u229D\",\"Odblac\":\"\\u0150\",\"odblac\":\"\\u0151\",\"odiv\":\"\\u2A38\",\"odot\":\"\\u2299\",\"odsold\":\"\\u29BC\",\"OElig\":\"\\u0152\",\"oelig\":\"\\u0153\",\"ofcir\":\"\\u29BF\",\"Ofr\":\"\\uD835\\uDD12\",\"ofr\":\"\\uD835\\uDD2C\",\"ogon\":\"\\u02DB\",\"Ograve\":\"\\u00D2\",\"ograve\":\"\\u00F2\",\"ogt\":\"\\u29C1\",\"ohbar\":\"\\u29B5\",\"ohm\":\"\\u03A9\",\"oint\":\"\\u222E\",\"olarr\":\"\\u21BA\",\"olcir\":\"\\u29BE\",\"olcross\":\"\\u29BB\",\"oline\":\"\\u203E\",\"olt\":\"\\u29C0\",\"Omacr\":\"\\u014C\",\"omacr\":\"\\u014D\",\"Omega\":\"\\u03A9\",\"omega\":\"\\u03C9\",\"Omicron\":\"\\u039F\",\"omicron\":\"\\u03BF\",\"omid\":\"\\u29B6\",\"ominus\":\"\\u2296\",\"Oopf\":\"\\uD835\\uDD46\",\"oopf\":\"\\uD835\\uDD60\",\"opar\":\"\\u29B7\",\"OpenCurlyDoubleQuote\":\"\\u201C\",\"OpenCurlyQuote\":\"\\u2018\",\"operp\":\"\\u29B9\",\"oplus\":\"\\u2295\",\"orarr\":\"\\u21BB\",\"Or\":\"\\u2A54\",\"or\":\"\\u2228\",\"ord\":\"\\u2A5D\",\"order\":\"\\u2134\",\"orderof\":\"\\u2134\",\"ordf\":\"\\u00AA\",\"ordm\":\"\\u00BA\",\"origof\":\"\\u22B6\",\"oror\":\"\\u2A56\",\"orslope\":\"\\u2A57\",\"orv\":\"\\u2A5B\",\"oS\":\"\\u24C8\",\"Oscr\":\"\\uD835\\uDCAA\",\"oscr\":\"\\u2134\",\"Oslash\":\"\\u00D8\",\"oslash\":\"\\u00F8\",\"osol\":\"\\u2298\",\"Otilde\":\"\\u00D5\",\"otilde\":\"\\u00F5\",\"otimesas\":\"\\u2A36\",\"Otimes\":\"\\u2A37\",\"otimes\":\"\\u2297\",\"Ouml\":\"\\u00D6\",\"ouml\":\"\\u00F6\",\"ovbar\":\"\\u233D\",\"OverBar\":\"\\u203E\",\"OverBrace\":\"\\u23DE\",\"OverBracket\":\"\\u23B4\",\"OverParenthesis\":\"\\u23DC\",\"para\":\"\\u00B6\",\"parallel\":\"\\u2225\",\"par\":\"\\u2225\",\"parsim\":\"\\u2AF3\",\"parsl\":\"\\u2AFD\",\"part\":\"\\u2202\",\"PartialD\":\"\\u2202\",\"Pcy\":\"\\u041F\",\"pcy\":\"\\u043F\",\"percnt\":\"%\",\"period\":\".\",\"permil\":\"\\u2030\",\"perp\":\"\\u22A5\",\"pertenk\":\"\\u2031\",\"Pfr\":\"\\uD835\\uDD13\",\"pfr\":\"\\uD835\\uDD2D\",\"Phi\":\"\\u03A6\",\"phi\":\"\\u03C6\",\"phiv\":\"\\u03D5\",\"phmmat\":\"\\u2133\",\"phone\":\"\\u260E\",\"Pi\":\"\\u03A0\",\"pi\":\"\\u03C0\",\"pitchfork\":\"\\u22D4\",\"piv\":\"\\u03D6\",\"planck\":\"\\u210F\",\"planckh\":\"\\u210E\",\"plankv\":\"\\u210F\",\"plusacir\":\"\\u2A23\",\"plusb\":\"\\u229E\",\"pluscir\":\"\\u2A22\",\"plus\":\"+\",\"plusdo\":\"\\u2214\",\"plusdu\":\"\\u2A25\",\"pluse\":\"\\u2A72\",\"PlusMinus\":\"\\u00B1\",\"plusmn\":\"\\u00B1\",\"plussim\":\"\\u2A26\",\"plustwo\":\"\\u2A27\",\"pm\":\"\\u00B1\",\"Poincareplane\":\"\\u210C\",\"pointint\":\"\\u2A15\",\"popf\":\"\\uD835\\uDD61\",\"Popf\":\"\\u2119\",\"pound\":\"\\u00A3\",\"prap\":\"\\u2AB7\",\"Pr\":\"\\u2ABB\",\"pr\":\"\\u227A\",\"prcue\":\"\\u227C\",\"precapprox\":\"\\u2AB7\",\"prec\":\"\\u227A\",\"preccurlyeq\":\"\\u227C\",\"Precedes\":\"\\u227A\",\"PrecedesEqual\":\"\\u2AAF\",\"PrecedesSlantEqual\":\"\\u227C\",\"PrecedesTilde\":\"\\u227E\",\"preceq\":\"\\u2AAF\",\"precnapprox\":\"\\u2AB9\",\"precneqq\":\"\\u2AB5\",\"precnsim\":\"\\u22E8\",\"pre\":\"\\u2AAF\",\"prE\":\"\\u2AB3\",\"precsim\":\"\\u227E\",\"prime\":\"\\u2032\",\"Prime\":\"\\u2033\",\"primes\":\"\\u2119\",\"prnap\":\"\\u2AB9\",\"prnE\":\"\\u2AB5\",\"prnsim\":\"\\u22E8\",\"prod\":\"\\u220F\",\"Product\":\"\\u220F\",\"profalar\":\"\\u232E\",\"profline\":\"\\u2312\",\"profsurf\":\"\\u2313\",\"prop\":\"\\u221D\",\"Proportional\":\"\\u221D\",\"Proportion\":\"\\u2237\",\"propto\":\"\\u221D\",\"prsim\":\"\\u227E\",\"prurel\":\"\\u22B0\",\"Pscr\":\"\\uD835\\uDCAB\",\"pscr\":\"\\uD835\\uDCC5\",\"Psi\":\"\\u03A8\",\"psi\":\"\\u03C8\",\"puncsp\":\"\\u2008\",\"Qfr\":\"\\uD835\\uDD14\",\"qfr\":\"\\uD835\\uDD2E\",\"qint\":\"\\u2A0C\",\"qopf\":\"\\uD835\\uDD62\",\"Qopf\":\"\\u211A\",\"qprime\":\"\\u2057\",\"Qscr\":\"\\uD835\\uDCAC\",\"qscr\":\"\\uD835\\uDCC6\",\"quaternions\":\"\\u210D\",\"quatint\":\"\\u2A16\",\"quest\":\"?\",\"questeq\":\"\\u225F\",\"quot\":\"\\\"\",\"QUOT\":\"\\\"\",\"rAarr\":\"\\u21DB\",\"race\":\"\\u223D\\u0331\",\"Racute\":\"\\u0154\",\"racute\":\"\\u0155\",\"radic\":\"\\u221A\",\"raemptyv\":\"\\u29B3\",\"rang\":\"\\u27E9\",\"Rang\":\"\\u27EB\",\"rangd\":\"\\u2992\",\"range\":\"\\u29A5\",\"rangle\":\"\\u27E9\",\"raquo\":\"\\u00BB\",\"rarrap\":\"\\u2975\",\"rarrb\":\"\\u21E5\",\"rarrbfs\":\"\\u2920\",\"rarrc\":\"\\u2933\",\"rarr\":\"\\u2192\",\"Rarr\":\"\\u21A0\",\"rArr\":\"\\u21D2\",\"rarrfs\":\"\\u291E\",\"rarrhk\":\"\\u21AA\",\"rarrlp\":\"\\u21AC\",\"rarrpl\":\"\\u2945\",\"rarrsim\":\"\\u2974\",\"Rarrtl\":\"\\u2916\",\"rarrtl\":\"\\u21A3\",\"rarrw\":\"\\u219D\",\"ratail\":\"\\u291A\",\"rAtail\":\"\\u291C\",\"ratio\":\"\\u2236\",\"rationals\":\"\\u211A\",\"rbarr\":\"\\u290D\",\"rBarr\":\"\\u290F\",\"RBarr\":\"\\u2910\",\"rbbrk\":\"\\u2773\",\"rbrace\":\"}\",\"rbrack\":\"]\",\"rbrke\":\"\\u298C\",\"rbrksld\":\"\\u298E\",\"rbrkslu\":\"\\u2990\",\"Rcaron\":\"\\u0158\",\"rcaron\":\"\\u0159\",\"Rcedil\":\"\\u0156\",\"rcedil\":\"\\u0157\",\"rceil\":\"\\u2309\",\"rcub\":\"}\",\"Rcy\":\"\\u0420\",\"rcy\":\"\\u0440\",\"rdca\":\"\\u2937\",\"rdldhar\":\"\\u2969\",\"rdquo\":\"\\u201D\",\"rdquor\":\"\\u201D\",\"rdsh\":\"\\u21B3\",\"real\":\"\\u211C\",\"realine\":\"\\u211B\",\"realpart\":\"\\u211C\",\"reals\":\"\\u211D\",\"Re\":\"\\u211C\",\"rect\":\"\\u25AD\",\"reg\":\"\\u00AE\",\"REG\":\"\\u00AE\",\"ReverseElement\":\"\\u220B\",\"ReverseEquilibrium\":\"\\u21CB\",\"ReverseUpEquilibrium\":\"\\u296F\",\"rfisht\":\"\\u297D\",\"rfloor\":\"\\u230B\",\"rfr\":\"\\uD835\\uDD2F\",\"Rfr\":\"\\u211C\",\"rHar\":\"\\u2964\",\"rhard\":\"\\u21C1\",\"rharu\":\"\\u21C0\",\"rharul\":\"\\u296C\",\"Rho\":\"\\u03A1\",\"rho\":\"\\u03C1\",\"rhov\":\"\\u03F1\",\"RightAngleBracket\":\"\\u27E9\",\"RightArrowBar\":\"\\u21E5\",\"rightarrow\":\"\\u2192\",\"RightArrow\":\"\\u2192\",\"Rightarrow\":\"\\u21D2\",\"RightArrowLeftArrow\":\"\\u21C4\",\"rightarrowtail\":\"\\u21A3\",\"RightCeiling\":\"\\u2309\",\"RightDoubleBracket\":\"\\u27E7\",\"RightDownTeeVector\":\"\\u295D\",\"RightDownVectorBar\":\"\\u2955\",\"RightDownVector\":\"\\u21C2\",\"RightFloor\":\"\\u230B\",\"rightharpoondown\":\"\\u21C1\",\"rightharpoonup\":\"\\u21C0\",\"rightleftarrows\":\"\\u21C4\",\"rightleftharpoons\":\"\\u21CC\",\"rightrightarrows\":\"\\u21C9\",\"rightsquigarrow\":\"\\u219D\",\"RightTeeArrow\":\"\\u21A6\",\"RightTee\":\"\\u22A2\",\"RightTeeVector\":\"\\u295B\",\"rightthreetimes\":\"\\u22CC\",\"RightTriangleBar\":\"\\u29D0\",\"RightTriangle\":\"\\u22B3\",\"RightTriangleEqual\":\"\\u22B5\",\"RightUpDownVector\":\"\\u294F\",\"RightUpTeeVector\":\"\\u295C\",\"RightUpVectorBar\":\"\\u2954\",\"RightUpVector\":\"\\u21BE\",\"RightVectorBar\":\"\\u2953\",\"RightVector\":\"\\u21C0\",\"ring\":\"\\u02DA\",\"risingdotseq\":\"\\u2253\",\"rlarr\":\"\\u21C4\",\"rlhar\":\"\\u21CC\",\"rlm\":\"\\u200F\",\"rmoustache\":\"\\u23B1\",\"rmoust\":\"\\u23B1\",\"rnmid\":\"\\u2AEE\",\"roang\":\"\\u27ED\",\"roarr\":\"\\u21FE\",\"robrk\":\"\\u27E7\",\"ropar\":\"\\u2986\",\"ropf\":\"\\uD835\\uDD63\",\"Ropf\":\"\\u211D\",\"roplus\":\"\\u2A2E\",\"rotimes\":\"\\u2A35\",\"RoundImplies\":\"\\u2970\",\"rpar\":\")\",\"rpargt\":\"\\u2994\",\"rppolint\":\"\\u2A12\",\"rrarr\":\"\\u21C9\",\"Rrightarrow\":\"\\u21DB\",\"rsaquo\":\"\\u203A\",\"rscr\":\"\\uD835\\uDCC7\",\"Rscr\":\"\\u211B\",\"rsh\":\"\\u21B1\",\"Rsh\":\"\\u21B1\",\"rsqb\":\"]\",\"rsquo\":\"\\u2019\",\"rsquor\":\"\\u2019\",\"rthree\":\"\\u22CC\",\"rtimes\":\"\\u22CA\",\"rtri\":\"\\u25B9\",\"rtrie\":\"\\u22B5\",\"rtrif\":\"\\u25B8\",\"rtriltri\":\"\\u29CE\",\"RuleDelayed\":\"\\u29F4\",\"ruluhar\":\"\\u2968\",\"rx\":\"\\u211E\",\"Sacute\":\"\\u015A\",\"sacute\":\"\\u015B\",\"sbquo\":\"\\u201A\",\"scap\":\"\\u2AB8\",\"Scaron\":\"\\u0160\",\"scaron\":\"\\u0161\",\"Sc\":\"\\u2ABC\",\"sc\":\"\\u227B\",\"sccue\":\"\\u227D\",\"sce\":\"\\u2AB0\",\"scE\":\"\\u2AB4\",\"Scedil\":\"\\u015E\",\"scedil\":\"\\u015F\",\"Scirc\":\"\\u015C\",\"scirc\":\"\\u015D\",\"scnap\":\"\\u2ABA\",\"scnE\":\"\\u2AB6\",\"scnsim\":\"\\u22E9\",\"scpolint\":\"\\u2A13\",\"scsim\":\"\\u227F\",\"Scy\":\"\\u0421\",\"scy\":\"\\u0441\",\"sdotb\":\"\\u22A1\",\"sdot\":\"\\u22C5\",\"sdote\":\"\\u2A66\",\"searhk\":\"\\u2925\",\"searr\":\"\\u2198\",\"seArr\":\"\\u21D8\",\"searrow\":\"\\u2198\",\"sect\":\"\\u00A7\",\"semi\":\";\",\"seswar\":\"\\u2929\",\"setminus\":\"\\u2216\",\"setmn\":\"\\u2216\",\"sext\":\"\\u2736\",\"Sfr\":\"\\uD835\\uDD16\",\"sfr\":\"\\uD835\\uDD30\",\"sfrown\":\"\\u2322\",\"sharp\":\"\\u266F\",\"SHCHcy\":\"\\u0429\",\"shchcy\":\"\\u0449\",\"SHcy\":\"\\u0428\",\"shcy\":\"\\u0448\",\"ShortDownArrow\":\"\\u2193\",\"ShortLeftArrow\":\"\\u2190\",\"shortmid\":\"\\u2223\",\"shortparallel\":\"\\u2225\",\"ShortRightArrow\":\"\\u2192\",\"ShortUpArrow\":\"\\u2191\",\"shy\":\"\\u00AD\",\"Sigma\":\"\\u03A3\",\"sigma\":\"\\u03C3\",\"sigmaf\":\"\\u03C2\",\"sigmav\":\"\\u03C2\",\"sim\":\"\\u223C\",\"simdot\":\"\\u2A6A\",\"sime\":\"\\u2243\",\"simeq\":\"\\u2243\",\"simg\":\"\\u2A9E\",\"simgE\":\"\\u2AA0\",\"siml\":\"\\u2A9D\",\"simlE\":\"\\u2A9F\",\"simne\":\"\\u2246\",\"simplus\":\"\\u2A24\",\"simrarr\":\"\\u2972\",\"slarr\":\"\\u2190\",\"SmallCircle\":\"\\u2218\",\"smallsetminus\":\"\\u2216\",\"smashp\":\"\\u2A33\",\"smeparsl\":\"\\u29E4\",\"smid\":\"\\u2223\",\"smile\":\"\\u2323\",\"smt\":\"\\u2AAA\",\"smte\":\"\\u2AAC\",\"smtes\":\"\\u2AAC\\uFE00\",\"SOFTcy\":\"\\u042C\",\"softcy\":\"\\u044C\",\"solbar\":\"\\u233F\",\"solb\":\"\\u29C4\",\"sol\":\"/\",\"Sopf\":\"\\uD835\\uDD4A\",\"sopf\":\"\\uD835\\uDD64\",\"spades\":\"\\u2660\",\"spadesuit\":\"\\u2660\",\"spar\":\"\\u2225\",\"sqcap\":\"\\u2293\",\"sqcaps\":\"\\u2293\\uFE00\",\"sqcup\":\"\\u2294\",\"sqcups\":\"\\u2294\\uFE00\",\"Sqrt\":\"\\u221A\",\"sqsub\":\"\\u228F\",\"sqsube\":\"\\u2291\",\"sqsubset\":\"\\u228F\",\"sqsubseteq\":\"\\u2291\",\"sqsup\":\"\\u2290\",\"sqsupe\":\"\\u2292\",\"sqsupset\":\"\\u2290\",\"sqsupseteq\":\"\\u2292\",\"square\":\"\\u25A1\",\"Square\":\"\\u25A1\",\"SquareIntersection\":\"\\u2293\",\"SquareSubset\":\"\\u228F\",\"SquareSubsetEqual\":\"\\u2291\",\"SquareSuperset\":\"\\u2290\",\"SquareSupersetEqual\":\"\\u2292\",\"SquareUnion\":\"\\u2294\",\"squarf\":\"\\u25AA\",\"squ\":\"\\u25A1\",\"squf\":\"\\u25AA\",\"srarr\":\"\\u2192\",\"Sscr\":\"\\uD835\\uDCAE\",\"sscr\":\"\\uD835\\uDCC8\",\"ssetmn\":\"\\u2216\",\"ssmile\":\"\\u2323\",\"sstarf\":\"\\u22C6\",\"Star\":\"\\u22C6\",\"star\":\"\\u2606\",\"starf\":\"\\u2605\",\"straightepsilon\":\"\\u03F5\",\"straightphi\":\"\\u03D5\",\"strns\":\"\\u00AF\",\"sub\":\"\\u2282\",\"Sub\":\"\\u22D0\",\"subdot\":\"\\u2ABD\",\"subE\":\"\\u2AC5\",\"sube\":\"\\u2286\",\"subedot\":\"\\u2AC3\",\"submult\":\"\\u2AC1\",\"subnE\":\"\\u2ACB\",\"subne\":\"\\u228A\",\"subplus\":\"\\u2ABF\",\"subrarr\":\"\\u2979\",\"subset\":\"\\u2282\",\"Subset\":\"\\u22D0\",\"subseteq\":\"\\u2286\",\"subseteqq\":\"\\u2AC5\",\"SubsetEqual\":\"\\u2286\",\"subsetneq\":\"\\u228A\",\"subsetneqq\":\"\\u2ACB\",\"subsim\":\"\\u2AC7\",\"subsub\":\"\\u2AD5\",\"subsup\":\"\\u2AD3\",\"succapprox\":\"\\u2AB8\",\"succ\":\"\\u227B\",\"succcurlyeq\":\"\\u227D\",\"Succeeds\":\"\\u227B\",\"SucceedsEqual\":\"\\u2AB0\",\"SucceedsSlantEqual\":\"\\u227D\",\"SucceedsTilde\":\"\\u227F\",\"succeq\":\"\\u2AB0\",\"succnapprox\":\"\\u2ABA\",\"succneqq\":\"\\u2AB6\",\"succnsim\":\"\\u22E9\",\"succsim\":\"\\u227F\",\"SuchThat\":\"\\u220B\",\"sum\":\"\\u2211\",\"Sum\":\"\\u2211\",\"sung\":\"\\u266A\",\"sup1\":\"\\u00B9\",\"sup2\":\"\\u00B2\",\"sup3\":\"\\u00B3\",\"sup\":\"\\u2283\",\"Sup\":\"\\u22D1\",\"supdot\":\"\\u2ABE\",\"supdsub\":\"\\u2AD8\",\"supE\":\"\\u2AC6\",\"supe\":\"\\u2287\",\"supedot\":\"\\u2AC4\",\"Superset\":\"\\u2283\",\"SupersetEqual\":\"\\u2287\",\"suphsol\":\"\\u27C9\",\"suphsub\":\"\\u2AD7\",\"suplarr\":\"\\u297B\",\"supmult\":\"\\u2AC2\",\"supnE\":\"\\u2ACC\",\"supne\":\"\\u228B\",\"supplus\":\"\\u2AC0\",\"supset\":\"\\u2283\",\"Supset\":\"\\u22D1\",\"supseteq\":\"\\u2287\",\"supseteqq\":\"\\u2AC6\",\"supsetneq\":\"\\u228B\",\"supsetneqq\":\"\\u2ACC\",\"supsim\":\"\\u2AC8\",\"supsub\":\"\\u2AD4\",\"supsup\":\"\\u2AD6\",\"swarhk\":\"\\u2926\",\"swarr\":\"\\u2199\",\"swArr\":\"\\u21D9\",\"swarrow\":\"\\u2199\",\"swnwar\":\"\\u292A\",\"szlig\":\"\\u00DF\",\"Tab\":\"\\t\",\"target\":\"\\u2316\",\"Tau\":\"\\u03A4\",\"tau\":\"\\u03C4\",\"tbrk\":\"\\u23B4\",\"Tcaron\":\"\\u0164\",\"tcaron\":\"\\u0165\",\"Tcedil\":\"\\u0162\",\"tcedil\":\"\\u0163\",\"Tcy\":\"\\u0422\",\"tcy\":\"\\u0442\",\"tdot\":\"\\u20DB\",\"telrec\":\"\\u2315\",\"Tfr\":\"\\uD835\\uDD17\",\"tfr\":\"\\uD835\\uDD31\",\"there4\":\"\\u2234\",\"therefore\":\"\\u2234\",\"Therefore\":\"\\u2234\",\"Theta\":\"\\u0398\",\"theta\":\"\\u03B8\",\"thetasym\":\"\\u03D1\",\"thetav\":\"\\u03D1\",\"thickapprox\":\"\\u2248\",\"thicksim\":\"\\u223C\",\"ThickSpace\":\"\\u205F\\u200A\",\"ThinSpace\":\"\\u2009\",\"thinsp\":\"\\u2009\",\"thkap\":\"\\u2248\",\"thksim\":\"\\u223C\",\"THORN\":\"\\u00DE\",\"thorn\":\"\\u00FE\",\"tilde\":\"\\u02DC\",\"Tilde\":\"\\u223C\",\"TildeEqual\":\"\\u2243\",\"TildeFullEqual\":\"\\u2245\",\"TildeTilde\":\"\\u2248\",\"timesbar\":\"\\u2A31\",\"timesb\":\"\\u22A0\",\"times\":\"\\u00D7\",\"timesd\":\"\\u2A30\",\"tint\":\"\\u222D\",\"toea\":\"\\u2928\",\"topbot\":\"\\u2336\",\"topcir\":\"\\u2AF1\",\"top\":\"\\u22A4\",\"Topf\":\"\\uD835\\uDD4B\",\"topf\":\"\\uD835\\uDD65\",\"topfork\":\"\\u2ADA\",\"tosa\":\"\\u2929\",\"tprime\":\"\\u2034\",\"trade\":\"\\u2122\",\"TRADE\":\"\\u2122\",\"triangle\":\"\\u25B5\",\"triangledown\":\"\\u25BF\",\"triangleleft\":\"\\u25C3\",\"trianglelefteq\":\"\\u22B4\",\"triangleq\":\"\\u225C\",\"triangleright\":\"\\u25B9\",\"trianglerighteq\":\"\\u22B5\",\"tridot\":\"\\u25EC\",\"trie\":\"\\u225C\",\"triminus\":\"\\u2A3A\",\"TripleDot\":\"\\u20DB\",\"triplus\":\"\\u2A39\",\"trisb\":\"\\u29CD\",\"tritime\":\"\\u2A3B\",\"trpezium\":\"\\u23E2\",\"Tscr\":\"\\uD835\\uDCAF\",\"tscr\":\"\\uD835\\uDCC9\",\"TScy\":\"\\u0426\",\"tscy\":\"\\u0446\",\"TSHcy\":\"\\u040B\",\"tshcy\":\"\\u045B\",\"Tstrok\":\"\\u0166\",\"tstrok\":\"\\u0167\",\"twixt\":\"\\u226C\",\"twoheadleftarrow\":\"\\u219E\",\"twoheadrightarrow\":\"\\u21A0\",\"Uacute\":\"\\u00DA\",\"uacute\":\"\\u00FA\",\"uarr\":\"\\u2191\",\"Uarr\":\"\\u219F\",\"uArr\":\"\\u21D1\",\"Uarrocir\":\"\\u2949\",\"Ubrcy\":\"\\u040E\",\"ubrcy\":\"\\u045E\",\"Ubreve\":\"\\u016C\",\"ubreve\":\"\\u016D\",\"Ucirc\":\"\\u00DB\",\"ucirc\":\"\\u00FB\",\"Ucy\":\"\\u0423\",\"ucy\":\"\\u0443\",\"udarr\":\"\\u21C5\",\"Udblac\":\"\\u0170\",\"udblac\":\"\\u0171\",\"udhar\":\"\\u296E\",\"ufisht\":\"\\u297E\",\"Ufr\":\"\\uD835\\uDD18\",\"ufr\":\"\\uD835\\uDD32\",\"Ugrave\":\"\\u00D9\",\"ugrave\":\"\\u00F9\",\"uHar\":\"\\u2963\",\"uharl\":\"\\u21BF\",\"uharr\":\"\\u21BE\",\"uhblk\":\"\\u2580\",\"ulcorn\":\"\\u231C\",\"ulcorner\":\"\\u231C\",\"ulcrop\":\"\\u230F\",\"ultri\":\"\\u25F8\",\"Umacr\":\"\\u016A\",\"umacr\":\"\\u016B\",\"uml\":\"\\u00A8\",\"UnderBar\":\"_\",\"UnderBrace\":\"\\u23DF\",\"UnderBracket\":\"\\u23B5\",\"UnderParenthesis\":\"\\u23DD\",\"Union\":\"\\u22C3\",\"UnionPlus\":\"\\u228E\",\"Uogon\":\"\\u0172\",\"uogon\":\"\\u0173\",\"Uopf\":\"\\uD835\\uDD4C\",\"uopf\":\"\\uD835\\uDD66\",\"UpArrowBar\":\"\\u2912\",\"uparrow\":\"\\u2191\",\"UpArrow\":\"\\u2191\",\"Uparrow\":\"\\u21D1\",\"UpArrowDownArrow\":\"\\u21C5\",\"updownarrow\":\"\\u2195\",\"UpDownArrow\":\"\\u2195\",\"Updownarrow\":\"\\u21D5\",\"UpEquilibrium\":\"\\u296E\",\"upharpoonleft\":\"\\u21BF\",\"upharpoonright\":\"\\u21BE\",\"uplus\":\"\\u228E\",\"UpperLeftArrow\":\"\\u2196\",\"UpperRightArrow\":\"\\u2197\",\"upsi\":\"\\u03C5\",\"Upsi\":\"\\u03D2\",\"upsih\":\"\\u03D2\",\"Upsilon\":\"\\u03A5\",\"upsilon\":\"\\u03C5\",\"UpTeeArrow\":\"\\u21A5\",\"UpTee\":\"\\u22A5\",\"upuparrows\":\"\\u21C8\",\"urcorn\":\"\\u231D\",\"urcorner\":\"\\u231D\",\"urcrop\":\"\\u230E\",\"Uring\":\"\\u016E\",\"uring\":\"\\u016F\",\"urtri\":\"\\u25F9\",\"Uscr\":\"\\uD835\\uDCB0\",\"uscr\":\"\\uD835\\uDCCA\",\"utdot\":\"\\u22F0\",\"Utilde\":\"\\u0168\",\"utilde\":\"\\u0169\",\"utri\":\"\\u25B5\",\"utrif\":\"\\u25B4\",\"uuarr\":\"\\u21C8\",\"Uuml\":\"\\u00DC\",\"uuml\":\"\\u00FC\",\"uwangle\":\"\\u29A7\",\"vangrt\":\"\\u299C\",\"varepsilon\":\"\\u03F5\",\"varkappa\":\"\\u03F0\",\"varnothing\":\"\\u2205\",\"varphi\":\"\\u03D5\",\"varpi\":\"\\u03D6\",\"varpropto\":\"\\u221D\",\"varr\":\"\\u2195\",\"vArr\":\"\\u21D5\",\"varrho\":\"\\u03F1\",\"varsigma\":\"\\u03C2\",\"varsubsetneq\":\"\\u228A\\uFE00\",\"varsubsetneqq\":\"\\u2ACB\\uFE00\",\"varsupsetneq\":\"\\u228B\\uFE00\",\"varsupsetneqq\":\"\\u2ACC\\uFE00\",\"vartheta\":\"\\u03D1\",\"vartriangleleft\":\"\\u22B2\",\"vartriangleright\":\"\\u22B3\",\"vBar\":\"\\u2AE8\",\"Vbar\":\"\\u2AEB\",\"vBarv\":\"\\u2AE9\",\"Vcy\":\"\\u0412\",\"vcy\":\"\\u0432\",\"vdash\":\"\\u22A2\",\"vDash\":\"\\u22A8\",\"Vdash\":\"\\u22A9\",\"VDash\":\"\\u22AB\",\"Vdashl\":\"\\u2AE6\",\"veebar\":\"\\u22BB\",\"vee\":\"\\u2228\",\"Vee\":\"\\u22C1\",\"veeeq\":\"\\u225A\",\"vellip\":\"\\u22EE\",\"verbar\":\"|\",\"Verbar\":\"\\u2016\",\"vert\":\"|\",\"Vert\":\"\\u2016\",\"VerticalBar\":\"\\u2223\",\"VerticalLine\":\"|\",\"VerticalSeparator\":\"\\u2758\",\"VerticalTilde\":\"\\u2240\",\"VeryThinSpace\":\"\\u200A\",\"Vfr\":\"\\uD835\\uDD19\",\"vfr\":\"\\uD835\\uDD33\",\"vltri\":\"\\u22B2\",\"vnsub\":\"\\u2282\\u20D2\",\"vnsup\":\"\\u2283\\u20D2\",\"Vopf\":\"\\uD835\\uDD4D\",\"vopf\":\"\\uD835\\uDD67\",\"vprop\":\"\\u221D\",\"vrtri\":\"\\u22B3\",\"Vscr\":\"\\uD835\\uDCB1\",\"vscr\":\"\\uD835\\uDCCB\",\"vsubnE\":\"\\u2ACB\\uFE00\",\"vsubne\":\"\\u228A\\uFE00\",\"vsupnE\":\"\\u2ACC\\uFE00\",\"vsupne\":\"\\u228B\\uFE00\",\"Vvdash\":\"\\u22AA\",\"vzigzag\":\"\\u299A\",\"Wcirc\":\"\\u0174\",\"wcirc\":\"\\u0175\",\"wedbar\":\"\\u2A5F\",\"wedge\":\"\\u2227\",\"Wedge\":\"\\u22C0\",\"wedgeq\":\"\\u2259\",\"weierp\":\"\\u2118\",\"Wfr\":\"\\uD835\\uDD1A\",\"wfr\":\"\\uD835\\uDD34\",\"Wopf\":\"\\uD835\\uDD4E\",\"wopf\":\"\\uD835\\uDD68\",\"wp\":\"\\u2118\",\"wr\":\"\\u2240\",\"wreath\":\"\\u2240\",\"Wscr\":\"\\uD835\\uDCB2\",\"wscr\":\"\\uD835\\uDCCC\",\"xcap\":\"\\u22C2\",\"xcirc\":\"\\u25EF\",\"xcup\":\"\\u22C3\",\"xdtri\":\"\\u25BD\",\"Xfr\":\"\\uD835\\uDD1B\",\"xfr\":\"\\uD835\\uDD35\",\"xharr\":\"\\u27F7\",\"xhArr\":\"\\u27FA\",\"Xi\":\"\\u039E\",\"xi\":\"\\u03BE\",\"xlarr\":\"\\u27F5\",\"xlArr\":\"\\u27F8\",\"xmap\":\"\\u27FC\",\"xnis\":\"\\u22FB\",\"xodot\":\"\\u2A00\",\"Xopf\":\"\\uD835\\uDD4F\",\"xopf\":\"\\uD835\\uDD69\",\"xoplus\":\"\\u2A01\",\"xotime\":\"\\u2A02\",\"xrarr\":\"\\u27F6\",\"xrArr\":\"\\u27F9\",\"Xscr\":\"\\uD835\\uDCB3\",\"xscr\":\"\\uD835\\uDCCD\",\"xsqcup\":\"\\u2A06\",\"xuplus\":\"\\u2A04\",\"xutri\":\"\\u25B3\",\"xvee\":\"\\u22C1\",\"xwedge\":\"\\u22C0\",\"Yacute\":\"\\u00DD\",\"yacute\":\"\\u00FD\",\"YAcy\":\"\\u042F\",\"yacy\":\"\\u044F\",\"Ycirc\":\"\\u0176\",\"ycirc\":\"\\u0177\",\"Ycy\":\"\\u042B\",\"ycy\":\"\\u044B\",\"yen\":\"\\u00A5\",\"Yfr\":\"\\uD835\\uDD1C\",\"yfr\":\"\\uD835\\uDD36\",\"YIcy\":\"\\u0407\",\"yicy\":\"\\u0457\",\"Yopf\":\"\\uD835\\uDD50\",\"yopf\":\"\\uD835\\uDD6A\",\"Yscr\":\"\\uD835\\uDCB4\",\"yscr\":\"\\uD835\\uDCCE\",\"YUcy\":\"\\u042E\",\"yucy\":\"\\u044E\",\"yuml\":\"\\u00FF\",\"Yuml\":\"\\u0178\",\"Zacute\":\"\\u0179\",\"zacute\":\"\\u017A\",\"Zcaron\":\"\\u017D\",\"zcaron\":\"\\u017E\",\"Zcy\":\"\\u0417\",\"zcy\":\"\\u0437\",\"Zdot\":\"\\u017B\",\"zdot\":\"\\u017C\",\"zeetrf\":\"\\u2128\",\"ZeroWidthSpace\":\"\\u200B\",\"Zeta\":\"\\u0396\",\"zeta\":\"\\u03B6\",\"zfr\":\"\\uD835\\uDD37\",\"Zfr\":\"\\u2128\",\"ZHcy\":\"\\u0416\",\"zhcy\":\"\\u0436\",\"zigrarr\":\"\\u21DD\",\"zopf\":\"\\uD835\\uDD6B\",\"Zopf\":\"\\u2124\",\"Zscr\":\"\\uD835\\uDCB5\",\"zscr\":\"\\uD835\\uDCCF\",\"zwj\":\"\\u200D\",\"zwnj\":\"\\u200C\"}\n},{}],26:[function(require,module,exports){\nmodule.exports={\"Aacute\":\"\\u00C1\",\"aacute\":\"\\u00E1\",\"Acirc\":\"\\u00C2\",\"acirc\":\"\\u00E2\",\"acute\":\"\\u00B4\",\"AElig\":\"\\u00C6\",\"aelig\":\"\\u00E6\",\"Agrave\":\"\\u00C0\",\"agrave\":\"\\u00E0\",\"amp\":\"&\",\"AMP\":\"&\",\"Aring\":\"\\u00C5\",\"aring\":\"\\u00E5\",\"Atilde\":\"\\u00C3\",\"atilde\":\"\\u00E3\",\"Auml\":\"\\u00C4\",\"auml\":\"\\u00E4\",\"brvbar\":\"\\u00A6\",\"Ccedil\":\"\\u00C7\",\"ccedil\":\"\\u00E7\",\"cedil\":\"\\u00B8\",\"cent\":\"\\u00A2\",\"copy\":\"\\u00A9\",\"COPY\":\"\\u00A9\",\"curren\":\"\\u00A4\",\"deg\":\"\\u00B0\",\"divide\":\"\\u00F7\",\"Eacute\":\"\\u00C9\",\"eacute\":\"\\u00E9\",\"Ecirc\":\"\\u00CA\",\"ecirc\":\"\\u00EA\",\"Egrave\":\"\\u00C8\",\"egrave\":\"\\u00E8\",\"ETH\":\"\\u00D0\",\"eth\":\"\\u00F0\",\"Euml\":\"\\u00CB\",\"euml\":\"\\u00EB\",\"frac12\":\"\\u00BD\",\"frac14\":\"\\u00BC\",\"frac34\":\"\\u00BE\",\"gt\":\">\",\"GT\":\">\",\"Iacute\":\"\\u00CD\",\"iacute\":\"\\u00ED\",\"Icirc\":\"\\u00CE\",\"icirc\":\"\\u00EE\",\"iexcl\":\"\\u00A1\",\"Igrave\":\"\\u00CC\",\"igrave\":\"\\u00EC\",\"iquest\":\"\\u00BF\",\"Iuml\":\"\\u00CF\",\"iuml\":\"\\u00EF\",\"laquo\":\"\\u00AB\",\"lt\":\"<\",\"LT\":\"<\",\"macr\":\"\\u00AF\",\"micro\":\"\\u00B5\",\"middot\":\"\\u00B7\",\"nbsp\":\"\\u00A0\",\"not\":\"\\u00AC\",\"Ntilde\":\"\\u00D1\",\"ntilde\":\"\\u00F1\",\"Oacute\":\"\\u00D3\",\"oacute\":\"\\u00F3\",\"Ocirc\":\"\\u00D4\",\"ocirc\":\"\\u00F4\",\"Ograve\":\"\\u00D2\",\"ograve\":\"\\u00F2\",\"ordf\":\"\\u00AA\",\"ordm\":\"\\u00BA\",\"Oslash\":\"\\u00D8\",\"oslash\":\"\\u00F8\",\"Otilde\":\"\\u00D5\",\"otilde\":\"\\u00F5\",\"Ouml\":\"\\u00D6\",\"ouml\":\"\\u00F6\",\"para\":\"\\u00B6\",\"plusmn\":\"\\u00B1\",\"pound\":\"\\u00A3\",\"quot\":\"\\\"\",\"QUOT\":\"\\\"\",\"raquo\":\"\\u00BB\",\"reg\":\"\\u00AE\",\"REG\":\"\\u00AE\",\"sect\":\"\\u00A7\",\"shy\":\"\\u00AD\",\"sup1\":\"\\u00B9\",\"sup2\":\"\\u00B2\",\"sup3\":\"\\u00B3\",\"szlig\":\"\\u00DF\",\"THORN\":\"\\u00DE\",\"thorn\":\"\\u00FE\",\"times\":\"\\u00D7\",\"Uacute\":\"\\u00DA\",\"uacute\":\"\\u00FA\",\"Ucirc\":\"\\u00DB\",\"ucirc\":\"\\u00FB\",\"Ugrave\":\"\\u00D9\",\"ugrave\":\"\\u00F9\",\"uml\":\"\\u00A8\",\"Uuml\":\"\\u00DC\",\"uuml\":\"\\u00FC\",\"Yacute\":\"\\u00DD\",\"yacute\":\"\\u00FD\",\"yen\":\"\\u00A5\",\"yuml\":\"\\u00FF\"}\n},{}],27:[function(require,module,exports){\nmodule.exports={\"amp\":\"&\",\"apos\":\"'\",\"gt\":\">\",\"lt\":\"<\",\"quot\":\"\\\"\"}\n\n},{}],28:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nfunction EventEmitter() {\n  this._events = this._events || {};\n  this._maxListeners = this._maxListeners || undefined;\n}\nmodule.exports = EventEmitter;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nEventEmitter.defaultMaxListeners = 10;\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function(n) {\n  if (!isNumber(n) || n < 0 || isNaN(n))\n    throw TypeError('n must be a positive number');\n  this._maxListeners = n;\n  return this;\n};\n\nEventEmitter.prototype.emit = function(type) {\n  var er, handler, len, args, i, listeners;\n\n  if (!this._events)\n    this._events = {};\n\n  // If there is no 'error' event listener then throw.\n  if (type === 'error') {\n    if (!this._events.error ||\n        (isObject(this._events.error) && !this._events.error.length)) {\n      er = arguments[1];\n      if (er instanceof Error) {\n        throw er; // Unhandled 'error' event\n      } else {\n        // At least give some kind of context to the user\n        var err = new Error('Uncaught, unspecified \"error\" event. (' + er + ')');\n        err.context = er;\n        throw err;\n      }\n    }\n  }\n\n  handler = this._events[type];\n\n  if (isUndefined(handler))\n    return false;\n\n  if (isFunction(handler)) {\n    switch (arguments.length) {\n      // fast cases\n      case 1:\n        handler.call(this);\n        break;\n      case 2:\n        handler.call(this, arguments[1]);\n        break;\n      case 3:\n        handler.call(this, arguments[1], arguments[2]);\n        break;\n      // slower\n      default:\n        args = Array.prototype.slice.call(arguments, 1);\n        handler.apply(this, args);\n    }\n  } else if (isObject(handler)) {\n    args = Array.prototype.slice.call(arguments, 1);\n    listeners = handler.slice();\n    len = listeners.length;\n    for (i = 0; i < len; i++)\n      listeners[i].apply(this, args);\n  }\n\n  return true;\n};\n\nEventEmitter.prototype.addListener = function(type, listener) {\n  var m;\n\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  if (!this._events)\n    this._events = {};\n\n  // To avoid recursion in the case that type === \"newListener\"! Before\n  // adding it to the listeners, first emit \"newListener\".\n  if (this._events.newListener)\n    this.emit('newListener', type,\n              isFunction(listener.listener) ?\n              listener.listener : listener);\n\n  if (!this._events[type])\n    // Optimize the case of one listener. Don't need the extra array object.\n    this._events[type] = listener;\n  else if (isObject(this._events[type]))\n    // If we've already got an array, just append.\n    this._events[type].push(listener);\n  else\n    // Adding the second element, need to change to array.\n    this._events[type] = [this._events[type], listener];\n\n  // Check for listener leak\n  if (isObject(this._events[type]) && !this._events[type].warned) {\n    if (!isUndefined(this._maxListeners)) {\n      m = this._maxListeners;\n    } else {\n      m = EventEmitter.defaultMaxListeners;\n    }\n\n    if (m && m > 0 && this._events[type].length > m) {\n      this._events[type].warned = true;\n      console.error('(node) warning: possible EventEmitter memory ' +\n                    'leak detected. %d listeners added. ' +\n                    'Use emitter.setMaxListeners() to increase limit.',\n                    this._events[type].length);\n      if (typeof console.trace === 'function') {\n        // not supported in IE 10\n        console.trace();\n      }\n    }\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.once = function(type, listener) {\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  var fired = false;\n\n  function g() {\n    this.removeListener(type, g);\n\n    if (!fired) {\n      fired = true;\n      listener.apply(this, arguments);\n    }\n  }\n\n  g.listener = listener;\n  this.on(type, g);\n\n  return this;\n};\n\n// emits a 'removeListener' event iff the listener was removed\nEventEmitter.prototype.removeListener = function(type, listener) {\n  var list, position, length, i;\n\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  if (!this._events || !this._events[type])\n    return this;\n\n  list = this._events[type];\n  length = list.length;\n  position = -1;\n\n  if (list === listener ||\n      (isFunction(list.listener) && list.listener === listener)) {\n    delete this._events[type];\n    if (this._events.removeListener)\n      this.emit('removeListener', type, listener);\n\n  } else if (isObject(list)) {\n    for (i = length; i-- > 0;) {\n      if (list[i] === listener ||\n          (list[i].listener && list[i].listener === listener)) {\n        position = i;\n        break;\n      }\n    }\n\n    if (position < 0)\n      return this;\n\n    if (list.length === 1) {\n      list.length = 0;\n      delete this._events[type];\n    } else {\n      list.splice(position, 1);\n    }\n\n    if (this._events.removeListener)\n      this.emit('removeListener', type, listener);\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.removeAllListeners = function(type) {\n  var key, listeners;\n\n  if (!this._events)\n    return this;\n\n  // not listening for removeListener, no need to emit\n  if (!this._events.removeListener) {\n    if (arguments.length === 0)\n      this._events = {};\n    else if (this._events[type])\n      delete this._events[type];\n    return this;\n  }\n\n  // emit removeListener for all listeners on all events\n  if (arguments.length === 0) {\n    for (key in this._events) {\n      if (key === 'removeListener') continue;\n      this.removeAllListeners(key);\n    }\n    this.removeAllListeners('removeListener');\n    this._events = {};\n    return this;\n  }\n\n  listeners = this._events[type];\n\n  if (isFunction(listeners)) {\n    this.removeListener(type, listeners);\n  } else if (listeners) {\n    // LIFO order\n    while (listeners.length)\n      this.removeListener(type, listeners[listeners.length - 1]);\n  }\n  delete this._events[type];\n\n  return this;\n};\n\nEventEmitter.prototype.listeners = function(type) {\n  var ret;\n  if (!this._events || !this._events[type])\n    ret = [];\n  else if (isFunction(this._events[type]))\n    ret = [this._events[type]];\n  else\n    ret = this._events[type].slice();\n  return ret;\n};\n\nEventEmitter.prototype.listenerCount = function(type) {\n  if (this._events) {\n    var evlistener = this._events[type];\n\n    if (isFunction(evlistener))\n      return 1;\n    else if (evlistener)\n      return evlistener.length;\n  }\n  return 0;\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n  return emitter.listenerCount(type);\n};\n\nfunction isFunction(arg) {\n  return typeof arg === 'function';\n}\n\nfunction isNumber(arg) {\n  return typeof arg === 'number';\n}\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\n\nfunction isUndefined(arg) {\n  return arg === void 0;\n}\n\n},{}],29:[function(require,module,exports){\nmodule.exports = CollectingHandler;\n\nfunction CollectingHandler(cbs){\n\tthis._cbs = cbs || {};\n\tthis.events = [];\n}\n\nvar EVENTS = require(\"./\").EVENTS;\nObject.keys(EVENTS).forEach(function(name){\n\tif(EVENTS[name] === 0){\n\t\tname = \"on\" + name;\n\t\tCollectingHandler.prototype[name] = function(){\n\t\t\tthis.events.push([name]);\n\t\t\tif(this._cbs[name]) this._cbs[name]();\n\t\t};\n\t} else if(EVENTS[name] === 1){\n\t\tname = \"on\" + name;\n\t\tCollectingHandler.prototype[name] = function(a){\n\t\t\tthis.events.push([name, a]);\n\t\t\tif(this._cbs[name]) this._cbs[name](a);\n\t\t};\n\t} else if(EVENTS[name] === 2){\n\t\tname = \"on\" + name;\n\t\tCollectingHandler.prototype[name] = function(a, b){\n\t\t\tthis.events.push([name, a, b]);\n\t\t\tif(this._cbs[name]) this._cbs[name](a, b);\n\t\t};\n\t} else {\n\t\tthrow Error(\"wrong number of arguments\");\n\t}\n});\n\nCollectingHandler.prototype.onreset = function(){\n\tthis.events = [];\n\tif(this._cbs.onreset) this._cbs.onreset();\n};\n\nCollectingHandler.prototype.restart = function(){\n\tif(this._cbs.onreset) this._cbs.onreset();\n\n\tfor(var i = 0, len = this.events.length; i < len; i++){\n\t\tif(this._cbs[this.events[i][0]]){\n\n\t\t\tvar num = this.events[i].length;\n\n\t\t\tif(num === 1){\n\t\t\t\tthis._cbs[this.events[i][0]]();\n\t\t\t} else if(num === 2){\n\t\t\t\tthis._cbs[this.events[i][0]](this.events[i][1]);\n\t\t\t} else {\n\t\t\t\tthis._cbs[this.events[i][0]](this.events[i][1], this.events[i][2]);\n\t\t\t}\n\t\t}\n\t}\n};\n\n},{\"./\":36}],30:[function(require,module,exports){\nvar index = require(\"./index.js\"),\n    DomHandler = index.DomHandler,\n    DomUtils = index.DomUtils;\n\n//TODO: make this a streamable handler\nfunction FeedHandler(callback, options){\n\tthis.init(callback, options);\n}\n\nrequire(\"inherits\")(FeedHandler, DomHandler);\n\nFeedHandler.prototype.init = DomHandler;\n\nfunction getElements(what, where){\n\treturn DomUtils.getElementsByTagName(what, where, true);\n}\nfunction getOneElement(what, where){\n\treturn DomUtils.getElementsByTagName(what, where, true, 1)[0];\n}\nfunction fetch(what, where, recurse){\n\treturn DomUtils.getText(\n\t\tDomUtils.getElementsByTagName(what, where, recurse, 1)\n\t).trim();\n}\n\nfunction addConditionally(obj, prop, what, where, recurse){\n\tvar tmp = fetch(what, where, recurse);\n\tif(tmp) obj[prop] = tmp;\n}\n\nvar isValidFeed = function(value){\n\treturn value === \"rss\" || value === \"feed\" || value === \"rdf:RDF\";\n};\n\nFeedHandler.prototype.onend = function(){\n\tvar feed = {},\n\t    feedRoot = getOneElement(isValidFeed, this.dom),\n\t    tmp, childs;\n\n\tif(feedRoot){\n\t\tif(feedRoot.name === \"feed\"){\n\t\t\tchilds = feedRoot.children;\n\n\t\t\tfeed.type = \"atom\";\n\t\t\taddConditionally(feed, \"id\", \"id\", childs);\n\t\t\taddConditionally(feed, \"title\", \"title\", childs);\n\t\t\tif((tmp = getOneElement(\"link\", childs)) && (tmp = tmp.attribs) && (tmp = tmp.href)) feed.link = tmp;\n\t\t\taddConditionally(feed, \"description\", \"subtitle\", childs);\n\t\t\tif((tmp = fetch(\"updated\", childs))) feed.updated = new Date(tmp);\n\t\t\taddConditionally(feed, \"author\", \"email\", childs, true);\n\n\t\t\tfeed.items = getElements(\"entry\", childs).map(function(item){\n\t\t\t\tvar entry = {}, tmp;\n\n\t\t\t\titem = item.children;\n\n\t\t\t\taddConditionally(entry, \"id\", \"id\", item);\n\t\t\t\taddConditionally(entry, \"title\", \"title\", item);\n\t\t\t\tif((tmp = getOneElement(\"link\", item)) && (tmp = tmp.attribs) && (tmp = tmp.href)) entry.link = tmp;\n\t\t\t\tif((tmp = fetch(\"summary\", item) || fetch(\"content\", item))) entry.description = tmp;\n\t\t\t\tif((tmp = fetch(\"updated\", item))) entry.pubDate = new Date(tmp);\n\t\t\t\treturn entry;\n\t\t\t});\n\t\t} else {\n\t\t\tchilds = getOneElement(\"channel\", feedRoot.children).children;\n\n\t\t\tfeed.type = feedRoot.name.substr(0, 3);\n\t\t\tfeed.id = \"\";\n\t\t\taddConditionally(feed, \"title\", \"title\", childs);\n\t\t\taddConditionally(feed, \"link\", \"link\", childs);\n\t\t\taddConditionally(feed, \"description\", \"description\", childs);\n\t\t\tif((tmp = fetch(\"lastBuildDate\", childs))) feed.updated = new Date(tmp);\n\t\t\taddConditionally(feed, \"author\", \"managingEditor\", childs, true);\n\n\t\t\tfeed.items = getElements(\"item\", feedRoot.children).map(function(item){\n\t\t\t\tvar entry = {}, tmp;\n\n\t\t\t\titem = item.children;\n\n\t\t\t\taddConditionally(entry, \"id\", \"guid\", item);\n\t\t\t\taddConditionally(entry, \"title\", \"title\", item);\n\t\t\t\taddConditionally(entry, \"link\", \"link\", item);\n\t\t\t\taddConditionally(entry, \"description\", \"description\", item);\n\t\t\t\tif((tmp = fetch(\"pubDate\", item))) entry.pubDate = new Date(tmp);\n\t\t\t\treturn entry;\n\t\t\t});\n\t\t}\n\t}\n\tthis.dom = feed;\n\tDomHandler.prototype._handleCallback.call(\n\t\tthis, feedRoot ? null : Error(\"couldn't find root of feed\")\n\t);\n};\n\nmodule.exports = FeedHandler;\n\n},{\"./index.js\":36,\"inherits\":38}],31:[function(require,module,exports){\nvar Tokenizer = require(\"./Tokenizer.js\");\n\n/*\n\tOptions:\n\n\txmlMode: Disables the special behavior for script/style tags (false by default)\n\tlowerCaseAttributeNames: call .toLowerCase for each attribute name (true if xmlMode is `false`)\n\tlowerCaseTags: call .toLowerCase for each tag name (true if xmlMode is `false`)\n*/\n\n/*\n\tCallbacks:\n\n\toncdataend,\n\toncdatastart,\n\tonclosetag,\n\toncomment,\n\toncommentend,\n\tonerror,\n\tonopentag,\n\tonprocessinginstruction,\n\tonreset,\n\tontext\n*/\n\nvar formTags = {\n\tinput: true,\n\toption: true,\n\toptgroup: true,\n\tselect: true,\n\tbutton: true,\n\tdatalist: true,\n\ttextarea: true\n};\n\nvar openImpliesClose = {\n\ttr      : { tr:true, th:true, td:true },\n\tth      : { th:true },\n\ttd      : { thead:true, th:true, td:true },\n\tbody    : { head:true, link:true, script:true },\n\tli      : { li:true },\n\tp       : { p:true },\n\th1      : { p:true },\n\th2      : { p:true },\n\th3      : { p:true },\n\th4      : { p:true },\n\th5      : { p:true },\n\th6      : { p:true },\n\tselect  : formTags,\n\tinput   : formTags,\n\toutput  : formTags,\n\tbutton  : formTags,\n\tdatalist: formTags,\n\ttextarea: formTags,\n\toption  : { option:true },\n\toptgroup: { optgroup:true }\n};\n\nvar voidElements = {\n\t__proto__: null,\n\tarea: true,\n\tbase: true,\n\tbasefont: true,\n\tbr: true,\n\tcol: true,\n\tcommand: true,\n\tembed: true,\n\tframe: true,\n\thr: true,\n\timg: true,\n\tinput: true,\n\tisindex: true,\n\tkeygen: true,\n\tlink: true,\n\tmeta: true,\n\tparam: true,\n\tsource: true,\n\ttrack: true,\n\twbr: true,\n\n\t//common self closing svg elements\n\tpath: true,\n\tcircle: true,\n\tellipse: true,\n\tline: true,\n\trect: true,\n\tuse: true,\n\tstop: true,\n\tpolyline: true,\n\tpolygon: true\n};\n\nvar re_nameEnd = /\\s|\\//;\n\nfunction Parser(cbs, options){\n\tthis._options = options || {};\n\tthis._cbs = cbs || {};\n\n\tthis._tagname = \"\";\n\tthis._attribname = \"\";\n\tthis._attribvalue = \"\";\n\tthis._attribs = null;\n\tthis._stack = [];\n\n\tthis.startIndex = 0;\n\tthis.endIndex = null;\n\n\tthis._lowerCaseTagNames = \"lowerCaseTags\" in this._options ?\n\t\t\t\t\t\t\t\t\t!!this._options.lowerCaseTags :\n\t\t\t\t\t\t\t\t\t!this._options.xmlMode;\n\tthis._lowerCaseAttributeNames = \"lowerCaseAttributeNames\" in this._options ?\n\t\t\t\t\t\t\t\t\t!!this._options.lowerCaseAttributeNames :\n\t\t\t\t\t\t\t\t\t!this._options.xmlMode;\n\n\tif(this._options.Tokenizer) {\n\t\tTokenizer = this._options.Tokenizer;\n\t}\n\tthis._tokenizer = new Tokenizer(this._options, this);\n\n\tif(this._cbs.onparserinit) this._cbs.onparserinit(this);\n}\n\nrequire(\"inherits\")(Parser, require(\"events\").EventEmitter);\n\nParser.prototype._updatePosition = function(initialOffset){\n\tif(this.endIndex === null){\n\t\tif(this._tokenizer._sectionStart <= initialOffset){\n\t\t\tthis.startIndex = 0;\n\t\t} else {\n\t\t\tthis.startIndex = this._tokenizer._sectionStart - initialOffset;\n\t\t}\n\t}\n\telse this.startIndex = this.endIndex + 1;\n\tthis.endIndex = this._tokenizer.getAbsoluteIndex();\n};\n\n//Tokenizer event handlers\nParser.prototype.ontext = function(data){\n\tthis._updatePosition(1);\n\tthis.endIndex--;\n\n\tif(this._cbs.ontext) this._cbs.ontext(data);\n};\n\nParser.prototype.onopentagname = function(name){\n\tif(this._lowerCaseTagNames){\n\t\tname = name.toLowerCase();\n\t}\n\n\tthis._tagname = name;\n\n\tif(!this._options.xmlMode && name in openImpliesClose) {\n\t\tfor(\n\t\t\tvar el;\n\t\t\t(el = this._stack[this._stack.length - 1]) in openImpliesClose[name];\n\t\t\tthis.onclosetag(el)\n\t\t);\n\t}\n\n\tif(this._options.xmlMode || !(name in voidElements)){\n\t\tthis._stack.push(name);\n\t}\n\n\tif(this._cbs.onopentagname) this._cbs.onopentagname(name);\n\tif(this._cbs.onopentag) this._attribs = {};\n};\n\nParser.prototype.onopentagend = function(){\n\tthis._updatePosition(1);\n\n\tif(this._attribs){\n\t\tif(this._cbs.onopentag) this._cbs.onopentag(this._tagname, this._attribs);\n\t\tthis._attribs = null;\n\t}\n\n\tif(!this._options.xmlMode && this._cbs.onclosetag && this._tagname in voidElements){\n\t\tthis._cbs.onclosetag(this._tagname);\n\t}\n\n\tthis._tagname = \"\";\n};\n\nParser.prototype.onclosetag = function(name){\n\tthis._updatePosition(1);\n\n\tif(this._lowerCaseTagNames){\n\t\tname = name.toLowerCase();\n\t}\n\n\tif(this._stack.length && (!(name in voidElements) || this._options.xmlMode)){\n\t\tvar pos = this._stack.lastIndexOf(name);\n\t\tif(pos !== -1){\n\t\t\tif(this._cbs.onclosetag){\n\t\t\t\tpos = this._stack.length - pos;\n\t\t\t\twhile(pos--) this._cbs.onclosetag(this._stack.pop());\n\t\t\t}\n\t\t\telse this._stack.length = pos;\n\t\t} else if(name === \"p\" && !this._options.xmlMode){\n\t\t\tthis.onopentagname(name);\n\t\t\tthis._closeCurrentTag();\n\t\t}\n\t} else if(!this._options.xmlMode && (name === \"br\" || name === \"p\")){\n\t\tthis.onopentagname(name);\n\t\tthis._closeCurrentTag();\n\t}\n};\n\nParser.prototype.onselfclosingtag = function(){\n\tif(this._options.xmlMode || this._options.recognizeSelfClosing){\n\t\tthis._closeCurrentTag();\n\t} else {\n\t\tthis.onopentagend();\n\t}\n};\n\nParser.prototype._closeCurrentTag = function(){\n\tvar name = this._tagname;\n\n\tthis.onopentagend();\n\n\t//self-closing tags will be on the top of the stack\n\t//(cheaper check than in onclosetag)\n\tif(this._stack[this._stack.length - 1] === name){\n\t\tif(this._cbs.onclosetag){\n\t\t\tthis._cbs.onclosetag(name);\n\t\t}\n\t\tthis._stack.pop();\n\t}\n};\n\nParser.prototype.onattribname = function(name){\n\tif(this._lowerCaseAttributeNames){\n\t\tname = name.toLowerCase();\n\t}\n\tthis._attribname = name;\n};\n\nParser.prototype.onattribdata = function(value){\n\tthis._attribvalue += value;\n};\n\nParser.prototype.onattribend = function(){\n\tif(this._cbs.onattribute) this._cbs.onattribute(this._attribname, this._attribvalue);\n\tif(\n\t\tthis._attribs &&\n\t\t!Object.prototype.hasOwnProperty.call(this._attribs, this._attribname)\n\t){\n\t\tthis._attribs[this._attribname] = this._attribvalue;\n\t}\n\tthis._attribname = \"\";\n\tthis._attribvalue = \"\";\n};\n\nParser.prototype._getInstructionName = function(value){\n\tvar idx = value.search(re_nameEnd),\n\t    name = idx < 0 ? value : value.substr(0, idx);\n\n\tif(this._lowerCaseTagNames){\n\t\tname = name.toLowerCase();\n\t}\n\n\treturn name;\n};\n\nParser.prototype.ondeclaration = function(value){\n\tif(this._cbs.onprocessinginstruction){\n\t\tvar name = this._getInstructionName(value);\n\t\tthis._cbs.onprocessinginstruction(\"!\" + name, \"!\" + value);\n\t}\n};\n\nParser.prototype.onprocessinginstruction = function(value){\n\tif(this._cbs.onprocessinginstruction){\n\t\tvar name = this._getInstructionName(value);\n\t\tthis._cbs.onprocessinginstruction(\"?\" + name, \"?\" + value);\n\t}\n};\n\nParser.prototype.oncomment = function(value){\n\tthis._updatePosition(4);\n\n\tif(this._cbs.oncomment) this._cbs.oncomment(value);\n\tif(this._cbs.oncommentend) this._cbs.oncommentend();\n};\n\nParser.prototype.oncdata = function(value){\n\tthis._updatePosition(1);\n\n\tif(this._options.xmlMode || this._options.recognizeCDATA){\n\t\tif(this._cbs.oncdatastart) this._cbs.oncdatastart();\n\t\tif(this._cbs.ontext) this._cbs.ontext(value);\n\t\tif(this._cbs.oncdataend) this._cbs.oncdataend();\n\t} else {\n\t\tthis.oncomment(\"[CDATA[\" + value + \"]]\");\n\t}\n};\n\nParser.prototype.onerror = function(err){\n\tif(this._cbs.onerror) this._cbs.onerror(err);\n};\n\nParser.prototype.onend = function(){\n\tif(this._cbs.onclosetag){\n\t\tfor(\n\t\t\tvar i = this._stack.length;\n\t\t\ti > 0;\n\t\t\tthis._cbs.onclosetag(this._stack[--i])\n\t\t);\n\t}\n\tif(this._cbs.onend) this._cbs.onend();\n};\n\n\n//Resets the parser to a blank state, ready to parse a new HTML document\nParser.prototype.reset = function(){\n\tif(this._cbs.onreset) this._cbs.onreset();\n\tthis._tokenizer.reset();\n\n\tthis._tagname = \"\";\n\tthis._attribname = \"\";\n\tthis._attribs = null;\n\tthis._stack = [];\n\n\tif(this._cbs.onparserinit) this._cbs.onparserinit(this);\n};\n\n//Parses a complete HTML document and pushes it to the handler\nParser.prototype.parseComplete = function(data){\n\tthis.reset();\n\tthis.end(data);\n};\n\nParser.prototype.write = function(chunk){\n\tthis._tokenizer.write(chunk);\n};\n\nParser.prototype.end = function(chunk){\n\tthis._tokenizer.end(chunk);\n};\n\nParser.prototype.pause = function(){\n\tthis._tokenizer.pause();\n};\n\nParser.prototype.resume = function(){\n\tthis._tokenizer.resume();\n};\n\n//alias for backwards compat\nParser.prototype.parseChunk = Parser.prototype.write;\nParser.prototype.done = Parser.prototype.end;\n\nmodule.exports = Parser;\n\n},{\"./Tokenizer.js\":34,\"events\":28,\"inherits\":38}],32:[function(require,module,exports){\nmodule.exports = ProxyHandler;\n\nfunction ProxyHandler(cbs){\n\tthis._cbs = cbs || {};\n}\n\nvar EVENTS = require(\"./\").EVENTS;\nObject.keys(EVENTS).forEach(function(name){\n\tif(EVENTS[name] === 0){\n\t\tname = \"on\" + name;\n\t\tProxyHandler.prototype[name] = function(){\n\t\t\tif(this._cbs[name]) this._cbs[name]();\n\t\t};\n\t} else if(EVENTS[name] === 1){\n\t\tname = \"on\" + name;\n\t\tProxyHandler.prototype[name] = function(a){\n\t\t\tif(this._cbs[name]) this._cbs[name](a);\n\t\t};\n\t} else if(EVENTS[name] === 2){\n\t\tname = \"on\" + name;\n\t\tProxyHandler.prototype[name] = function(a, b){\n\t\t\tif(this._cbs[name]) this._cbs[name](a, b);\n\t\t};\n\t} else {\n\t\tthrow Error(\"wrong number of arguments\");\n\t}\n});\n},{\"./\":36}],33:[function(require,module,exports){\nmodule.exports = Stream;\n\nvar Parser = require(\"./WritableStream.js\");\n\nfunction Stream(options){\n\tParser.call(this, new Cbs(this), options);\n}\n\nrequire(\"inherits\")(Stream, Parser);\n\nStream.prototype.readable = true;\n\nfunction Cbs(scope){\n\tthis.scope = scope;\n}\n\nvar EVENTS = require(\"../\").EVENTS;\n\nObject.keys(EVENTS).forEach(function(name){\n\tif(EVENTS[name] === 0){\n\t\tCbs.prototype[\"on\" + name] = function(){\n\t\t\tthis.scope.emit(name);\n\t\t};\n\t} else if(EVENTS[name] === 1){\n\t\tCbs.prototype[\"on\" + name] = function(a){\n\t\t\tthis.scope.emit(name, a);\n\t\t};\n\t} else if(EVENTS[name] === 2){\n\t\tCbs.prototype[\"on\" + name] = function(a, b){\n\t\t\tthis.scope.emit(name, a, b);\n\t\t};\n\t} else {\n\t\tthrow Error(\"wrong number of arguments!\");\n\t}\n});\n},{\"../\":36,\"./WritableStream.js\":35,\"inherits\":38}],34:[function(require,module,exports){\nmodule.exports = Tokenizer;\n\nvar decodeCodePoint = require(\"entities/lib/decode_codepoint.js\"),\n    entityMap = require(\"entities/maps/entities.json\"),\n    legacyMap = require(\"entities/maps/legacy.json\"),\n    xmlMap    = require(\"entities/maps/xml.json\"),\n\n    i = 0,\n\n    TEXT                      = i++,\n    BEFORE_TAG_NAME           = i++, //after <\n    IN_TAG_NAME               = i++,\n    IN_SELF_CLOSING_TAG       = i++,\n    BEFORE_CLOSING_TAG_NAME   = i++,\n    IN_CLOSING_TAG_NAME       = i++,\n    AFTER_CLOSING_TAG_NAME    = i++,\n\n    //attributes\n    BEFORE_ATTRIBUTE_NAME     = i++,\n    IN_ATTRIBUTE_NAME         = i++,\n    AFTER_ATTRIBUTE_NAME      = i++,\n    BEFORE_ATTRIBUTE_VALUE    = i++,\n    IN_ATTRIBUTE_VALUE_DQ     = i++, // \"\n    IN_ATTRIBUTE_VALUE_SQ     = i++, // '\n    IN_ATTRIBUTE_VALUE_NQ     = i++,\n\n    //declarations\n    BEFORE_DECLARATION        = i++, // !\n    IN_DECLARATION            = i++,\n\n    //processing instructions\n    IN_PROCESSING_INSTRUCTION = i++, // ?\n\n    //comments\n    BEFORE_COMMENT            = i++,\n    IN_COMMENT                = i++,\n    AFTER_COMMENT_1           = i++,\n    AFTER_COMMENT_2           = i++,\n\n    //cdata\n    BEFORE_CDATA_1            = i++, // [\n    BEFORE_CDATA_2            = i++, // C\n    BEFORE_CDATA_3            = i++, // D\n    BEFORE_CDATA_4            = i++, // A\n    BEFORE_CDATA_5            = i++, // T\n    BEFORE_CDATA_6            = i++, // A\n    IN_CDATA                  = i++, // [\n    AFTER_CDATA_1             = i++, // ]\n    AFTER_CDATA_2             = i++, // ]\n\n    //special tags\n    BEFORE_SPECIAL            = i++, //S\n    BEFORE_SPECIAL_END        = i++,   //S\n\n    BEFORE_SCRIPT_1           = i++, //C\n    BEFORE_SCRIPT_2           = i++, //R\n    BEFORE_SCRIPT_3           = i++, //I\n    BEFORE_SCRIPT_4           = i++, //P\n    BEFORE_SCRIPT_5           = i++, //T\n    AFTER_SCRIPT_1            = i++, //C\n    AFTER_SCRIPT_2            = i++, //R\n    AFTER_SCRIPT_3            = i++, //I\n    AFTER_SCRIPT_4            = i++, //P\n    AFTER_SCRIPT_5            = i++, //T\n\n    BEFORE_STYLE_1            = i++, //T\n    BEFORE_STYLE_2            = i++, //Y\n    BEFORE_STYLE_3            = i++, //L\n    BEFORE_STYLE_4            = i++, //E\n    AFTER_STYLE_1             = i++, //T\n    AFTER_STYLE_2             = i++, //Y\n    AFTER_STYLE_3             = i++, //L\n    AFTER_STYLE_4             = i++, //E\n\n    BEFORE_ENTITY             = i++, //&\n    BEFORE_NUMERIC_ENTITY     = i++, //#\n    IN_NAMED_ENTITY           = i++,\n    IN_NUMERIC_ENTITY         = i++,\n    IN_HEX_ENTITY             = i++, //X\n\n    j = 0,\n\n    SPECIAL_NONE              = j++,\n    SPECIAL_SCRIPT            = j++,\n    SPECIAL_STYLE             = j++;\n\nfunction whitespace(c){\n\treturn c === \" \" || c === \"\\n\" || c === \"\\t\" || c === \"\\f\" || c === \"\\r\";\n}\n\nfunction characterState(char, SUCCESS){\n\treturn function(c){\n\t\tif(c === char) this._state = SUCCESS;\n\t};\n}\n\nfunction ifElseState(upper, SUCCESS, FAILURE){\n\tvar lower = upper.toLowerCase();\n\n\tif(upper === lower){\n\t\treturn function(c){\n\t\t\tif(c === lower){\n\t\t\t\tthis._state = SUCCESS;\n\t\t\t} else {\n\t\t\t\tthis._state = FAILURE;\n\t\t\t\tthis._index--;\n\t\t\t}\n\t\t};\n\t} else {\n\t\treturn function(c){\n\t\t\tif(c === lower || c === upper){\n\t\t\t\tthis._state = SUCCESS;\n\t\t\t} else {\n\t\t\t\tthis._state = FAILURE;\n\t\t\t\tthis._index--;\n\t\t\t}\n\t\t};\n\t}\n}\n\nfunction consumeSpecialNameChar(upper, NEXT_STATE){\n\tvar lower = upper.toLowerCase();\n\n\treturn function(c){\n\t\tif(c === lower || c === upper){\n\t\t\tthis._state = NEXT_STATE;\n\t\t} else {\n\t\t\tthis._state = IN_TAG_NAME;\n\t\t\tthis._index--; //consume the token again\n\t\t}\n\t};\n}\n\nfunction Tokenizer(options, cbs){\n\tthis._state = TEXT;\n\tthis._buffer = \"\";\n\tthis._sectionStart = 0;\n\tthis._index = 0;\n\tthis._bufferOffset = 0; //chars removed from _buffer\n\tthis._baseState = TEXT;\n\tthis._special = SPECIAL_NONE;\n\tthis._cbs = cbs;\n\tthis._running = true;\n\tthis._ended = false;\n\tthis._xmlMode = !!(options && options.xmlMode);\n\tthis._decodeEntities = !!(options && options.decodeEntities);\n}\n\nTokenizer.prototype._stateText = function(c){\n\tif(c === \"<\"){\n\t\tif(this._index > this._sectionStart){\n\t\t\tthis._cbs.ontext(this._getSection());\n\t\t}\n\t\tthis._state = BEFORE_TAG_NAME;\n\t\tthis._sectionStart = this._index;\n\t} else if(this._decodeEntities && this._special === SPECIAL_NONE && c === \"&\"){\n\t\tif(this._index > this._sectionStart){\n\t\t\tthis._cbs.ontext(this._getSection());\n\t\t}\n\t\tthis._baseState = TEXT;\n\t\tthis._state = BEFORE_ENTITY;\n\t\tthis._sectionStart = this._index;\n\t}\n};\n\nTokenizer.prototype._stateBeforeTagName = function(c){\n\tif(c === \"/\"){\n\t\tthis._state = BEFORE_CLOSING_TAG_NAME;\n\t} else if(c === \"<\"){\n\t\tthis._cbs.ontext(this._getSection());\n\t\tthis._sectionStart = this._index;\n\t} else if(c === \">\" || this._special !== SPECIAL_NONE || whitespace(c)) {\n\t\tthis._state = TEXT;\n\t} else if(c === \"!\"){\n\t\tthis._state = BEFORE_DECLARATION;\n\t\tthis._sectionStart = this._index + 1;\n\t} else if(c === \"?\"){\n\t\tthis._state = IN_PROCESSING_INSTRUCTION;\n\t\tthis._sectionStart = this._index + 1;\n\t} else {\n\t\tthis._state = (!this._xmlMode && (c === \"s\" || c === \"S\")) ?\n\t\t\t\t\t\tBEFORE_SPECIAL : IN_TAG_NAME;\n\t\tthis._sectionStart = this._index;\n\t}\n};\n\nTokenizer.prototype._stateInTagName = function(c){\n\tif(c === \"/\" || c === \">\" || whitespace(c)){\n\t\tthis._emitToken(\"onopentagname\");\n\t\tthis._state = BEFORE_ATTRIBUTE_NAME;\n\t\tthis._index--;\n\t}\n};\n\nTokenizer.prototype._stateBeforeCloseingTagName = function(c){\n\tif(whitespace(c));\n\telse if(c === \">\"){\n\t\tthis._state = TEXT;\n\t} else if(this._special !== SPECIAL_NONE){\n\t\tif(c === \"s\" || c === \"S\"){\n\t\t\tthis._state = BEFORE_SPECIAL_END;\n\t\t} else {\n\t\t\tthis._state = TEXT;\n\t\t\tthis._index--;\n\t\t}\n\t} else {\n\t\tthis._state = IN_CLOSING_TAG_NAME;\n\t\tthis._sectionStart = this._index;\n\t}\n};\n\nTokenizer.prototype._stateInCloseingTagName = function(c){\n\tif(c === \">\" || whitespace(c)){\n\t\tthis._emitToken(\"onclosetag\");\n\t\tthis._state = AFTER_CLOSING_TAG_NAME;\n\t\tthis._index--;\n\t}\n};\n\nTokenizer.prototype._stateAfterCloseingTagName = function(c){\n\t//skip everything until \">\"\n\tif(c === \">\"){\n\t\tthis._state = TEXT;\n\t\tthis._sectionStart = this._index + 1;\n\t}\n};\n\nTokenizer.prototype._stateBeforeAttributeName = function(c){\n\tif(c === \">\"){\n\t\tthis._cbs.onopentagend();\n\t\tthis._state = TEXT;\n\t\tthis._sectionStart = this._index + 1;\n\t} else if(c === \"/\"){\n\t\tthis._state = IN_SELF_CLOSING_TAG;\n\t} else if(!whitespace(c)){\n\t\tthis._state = IN_ATTRIBUTE_NAME;\n\t\tthis._sectionStart = this._index;\n\t}\n};\n\nTokenizer.prototype._stateInSelfClosingTag = function(c){\n\tif(c === \">\"){\n\t\tthis._cbs.onselfclosingtag();\n\t\tthis._state = TEXT;\n\t\tthis._sectionStart = this._index + 1;\n\t} else if(!whitespace(c)){\n\t\tthis._state = BEFORE_ATTRIBUTE_NAME;\n\t\tthis._index--;\n\t}\n};\n\nTokenizer.prototype._stateInAttributeName = function(c){\n\tif(c === \"=\" || c === \"/\" || c === \">\" || whitespace(c)){\n\t\tthis._cbs.onattribname(this._getSection());\n\t\tthis._sectionStart = -1;\n\t\tthis._state = AFTER_ATTRIBUTE_NAME;\n\t\tthis._index--;\n\t}\n};\n\nTokenizer.prototype._stateAfterAttributeName = function(c){\n\tif(c === \"=\"){\n\t\tthis._state = BEFORE_ATTRIBUTE_VALUE;\n\t} else if(c === \"/\" || c === \">\"){\n\t\tthis._cbs.onattribend();\n\t\tthis._state = BEFORE_ATTRIBUTE_NAME;\n\t\tthis._index--;\n\t} else if(!whitespace(c)){\n\t\tthis._cbs.onattribend();\n\t\tthis._state = IN_ATTRIBUTE_NAME;\n\t\tthis._sectionStart = this._index;\n\t}\n};\n\nTokenizer.prototype._stateBeforeAttributeValue = function(c){\n\tif(c === \"\\\"\"){\n\t\tthis._state = IN_ATTRIBUTE_VALUE_DQ;\n\t\tthis._sectionStart = this._index + 1;\n\t} else if(c === \"'\"){\n\t\tthis._state = IN_ATTRIBUTE_VALUE_SQ;\n\t\tthis._sectionStart = this._index + 1;\n\t} else if(!whitespace(c)){\n\t\tthis._state = IN_ATTRIBUTE_VALUE_NQ;\n\t\tthis._sectionStart = this._index;\n\t\tthis._index--; //reconsume token\n\t}\n};\n\nTokenizer.prototype._stateInAttributeValueDoubleQuotes = function(c){\n\tif(c === \"\\\"\"){\n\t\tthis._emitToken(\"onattribdata\");\n\t\tthis._cbs.onattribend();\n\t\tthis._state = BEFORE_ATTRIBUTE_NAME;\n\t} else if(this._decodeEntities && c === \"&\"){\n\t\tthis._emitToken(\"onattribdata\");\n\t\tthis._baseState = this._state;\n\t\tthis._state = BEFORE_ENTITY;\n\t\tthis._sectionStart = this._index;\n\t}\n};\n\nTokenizer.prototype._stateInAttributeValueSingleQuotes = function(c){\n\tif(c === \"'\"){\n\t\tthis._emitToken(\"onattribdata\");\n\t\tthis._cbs.onattribend();\n\t\tthis._state = BEFORE_ATTRIBUTE_NAME;\n\t} else if(this._decodeEntities && c === \"&\"){\n\t\tthis._emitToken(\"onattribdata\");\n\t\tthis._baseState = this._state;\n\t\tthis._state = BEFORE_ENTITY;\n\t\tthis._sectionStart = this._index;\n\t}\n};\n\nTokenizer.prototype._stateInAttributeValueNoQuotes = function(c){\n\tif(whitespace(c) || c === \">\"){\n\t\tthis._emitToken(\"onattribdata\");\n\t\tthis._cbs.onattribend();\n\t\tthis._state = BEFORE_ATTRIBUTE_NAME;\n\t\tthis._index--;\n\t} else if(this._decodeEntities && c === \"&\"){\n\t\tthis._emitToken(\"onattribdata\");\n\t\tthis._baseState = this._state;\n\t\tthis._state = BEFORE_ENTITY;\n\t\tthis._sectionStart = this._index;\n\t}\n};\n\nTokenizer.prototype._stateBeforeDeclaration = function(c){\n\tthis._state = c === \"[\" ? BEFORE_CDATA_1 :\n\t\t\t\t\tc === \"-\" ? BEFORE_COMMENT :\n\t\t\t\t\t\tIN_DECLARATION;\n};\n\nTokenizer.prototype._stateInDeclaration = function(c){\n\tif(c === \">\"){\n\t\tthis._cbs.ondeclaration(this._getSection());\n\t\tthis._state = TEXT;\n\t\tthis._sectionStart = this._index + 1;\n\t}\n};\n\nTokenizer.prototype._stateInProcessingInstruction = function(c){\n\tif(c === \">\"){\n\t\tthis._cbs.onprocessinginstruction(this._getSection());\n\t\tthis._state = TEXT;\n\t\tthis._sectionStart = this._index + 1;\n\t}\n};\n\nTokenizer.prototype._stateBeforeComment = function(c){\n\tif(c === \"-\"){\n\t\tthis._state = IN_COMMENT;\n\t\tthis._sectionStart = this._index + 1;\n\t} else {\n\t\tthis._state = IN_DECLARATION;\n\t}\n};\n\nTokenizer.prototype._stateInComment = function(c){\n\tif(c === \"-\") this._state = AFTER_COMMENT_1;\n};\n\nTokenizer.prototype._stateAfterComment1 = function(c){\n\tif(c === \"-\"){\n\t\tthis._state = AFTER_COMMENT_2;\n\t} else {\n\t\tthis._state = IN_COMMENT;\n\t}\n};\n\nTokenizer.prototype._stateAfterComment2 = function(c){\n\tif(c === \">\"){\n\t\t//remove 2 trailing chars\n\t\tthis._cbs.oncomment(this._buffer.substring(this._sectionStart, this._index - 2));\n\t\tthis._state = TEXT;\n\t\tthis._sectionStart = this._index + 1;\n\t} else if(c !== \"-\"){\n\t\tthis._state = IN_COMMENT;\n\t}\n\t// else: stay in AFTER_COMMENT_2 (`--->`)\n};\n\nTokenizer.prototype._stateBeforeCdata1 = ifElseState(\"C\", BEFORE_CDATA_2, IN_DECLARATION);\nTokenizer.prototype._stateBeforeCdata2 = ifElseState(\"D\", BEFORE_CDATA_3, IN_DECLARATION);\nTokenizer.prototype._stateBeforeCdata3 = ifElseState(\"A\", BEFORE_CDATA_4, IN_DECLARATION);\nTokenizer.prototype._stateBeforeCdata4 = ifElseState(\"T\", BEFORE_CDATA_5, IN_DECLARATION);\nTokenizer.prototype._stateBeforeCdata5 = ifElseState(\"A\", BEFORE_CDATA_6, IN_DECLARATION);\n\nTokenizer.prototype._stateBeforeCdata6 = function(c){\n\tif(c === \"[\"){\n\t\tthis._state = IN_CDATA;\n\t\tthis._sectionStart = this._index + 1;\n\t} else {\n\t\tthis._state = IN_DECLARATION;\n\t\tthis._index--;\n\t}\n};\n\nTokenizer.prototype._stateInCdata = function(c){\n\tif(c === \"]\") this._state = AFTER_CDATA_1;\n};\n\nTokenizer.prototype._stateAfterCdata1 = characterState(\"]\", AFTER_CDATA_2);\n\nTokenizer.prototype._stateAfterCdata2 = function(c){\n\tif(c === \">\"){\n\t\t//remove 2 trailing chars\n\t\tthis._cbs.oncdata(this._buffer.substring(this._sectionStart, this._index - 2));\n\t\tthis._state = TEXT;\n\t\tthis._sectionStart = this._index + 1;\n\t} else if(c !== \"]\") {\n\t\tthis._state = IN_CDATA;\n\t}\n\t//else: stay in AFTER_CDATA_2 (`]]]>`)\n};\n\nTokenizer.prototype._stateBeforeSpecial = function(c){\n\tif(c === \"c\" || c === \"C\"){\n\t\tthis._state = BEFORE_SCRIPT_1;\n\t} else if(c === \"t\" || c === \"T\"){\n\t\tthis._state = BEFORE_STYLE_1;\n\t} else {\n\t\tthis._state = IN_TAG_NAME;\n\t\tthis._index--; //consume the token again\n\t}\n};\n\nTokenizer.prototype._stateBeforeSpecialEnd = function(c){\n\tif(this._special === SPECIAL_SCRIPT && (c === \"c\" || c === \"C\")){\n\t\tthis._state = AFTER_SCRIPT_1;\n\t} else if(this._special === SPECIAL_STYLE && (c === \"t\" || c === \"T\")){\n\t\tthis._state = AFTER_STYLE_1;\n\t}\n\telse this._state = TEXT;\n};\n\nTokenizer.prototype._stateBeforeScript1 = consumeSpecialNameChar(\"R\", BEFORE_SCRIPT_2);\nTokenizer.prototype._stateBeforeScript2 = consumeSpecialNameChar(\"I\", BEFORE_SCRIPT_3);\nTokenizer.prototype._stateBeforeScript3 = consumeSpecialNameChar(\"P\", BEFORE_SCRIPT_4);\nTokenizer.prototype._stateBeforeScript4 = consumeSpecialNameChar(\"T\", BEFORE_SCRIPT_5);\n\nTokenizer.prototype._stateBeforeScript5 = function(c){\n\tif(c === \"/\" || c === \">\" || whitespace(c)){\n\t\tthis._special = SPECIAL_SCRIPT;\n\t}\n\tthis._state = IN_TAG_NAME;\n\tthis._index--; //consume the token again\n};\n\nTokenizer.prototype._stateAfterScript1 = ifElseState(\"R\", AFTER_SCRIPT_2, TEXT);\nTokenizer.prototype._stateAfterScript2 = ifElseState(\"I\", AFTER_SCRIPT_3, TEXT);\nTokenizer.prototype._stateAfterScript3 = ifElseState(\"P\", AFTER_SCRIPT_4, TEXT);\nTokenizer.prototype._stateAfterScript4 = ifElseState(\"T\", AFTER_SCRIPT_5, TEXT);\n\nTokenizer.prototype._stateAfterScript5 = function(c){\n\tif(c === \">\" || whitespace(c)){\n\t\tthis._special = SPECIAL_NONE;\n\t\tthis._state = IN_CLOSING_TAG_NAME;\n\t\tthis._sectionStart = this._index - 6;\n\t\tthis._index--; //reconsume the token\n\t}\n\telse this._state = TEXT;\n};\n\nTokenizer.prototype._stateBeforeStyle1 = consumeSpecialNameChar(\"Y\", BEFORE_STYLE_2);\nTokenizer.prototype._stateBeforeStyle2 = consumeSpecialNameChar(\"L\", BEFORE_STYLE_3);\nTokenizer.prototype._stateBeforeStyle3 = consumeSpecialNameChar(\"E\", BEFORE_STYLE_4);\n\nTokenizer.prototype._stateBeforeStyle4 = function(c){\n\tif(c === \"/\" || c === \">\" || whitespace(c)){\n\t\tthis._special = SPECIAL_STYLE;\n\t}\n\tthis._state = IN_TAG_NAME;\n\tthis._index--; //consume the token again\n};\n\nTokenizer.prototype._stateAfterStyle1 = ifElseState(\"Y\", AFTER_STYLE_2, TEXT);\nTokenizer.prototype._stateAfterStyle2 = ifElseState(\"L\", AFTER_STYLE_3, TEXT);\nTokenizer.prototype._stateAfterStyle3 = ifElseState(\"E\", AFTER_STYLE_4, TEXT);\n\nTokenizer.prototype._stateAfterStyle4 = function(c){\n\tif(c === \">\" || whitespace(c)){\n\t\tthis._special = SPECIAL_NONE;\n\t\tthis._state = IN_CLOSING_TAG_NAME;\n\t\tthis._sectionStart = this._index - 5;\n\t\tthis._index--; //reconsume the token\n\t}\n\telse this._state = TEXT;\n};\n\nTokenizer.prototype._stateBeforeEntity = ifElseState(\"#\", BEFORE_NUMERIC_ENTITY, IN_NAMED_ENTITY);\nTokenizer.prototype._stateBeforeNumericEntity = ifElseState(\"X\", IN_HEX_ENTITY, IN_NUMERIC_ENTITY);\n\n//for entities terminated with a semicolon\nTokenizer.prototype._parseNamedEntityStrict = function(){\n\t//offset = 1\n\tif(this._sectionStart + 1 < this._index){\n\t\tvar entity = this._buffer.substring(this._sectionStart + 1, this._index),\n\t\t    map = this._xmlMode ? xmlMap : entityMap;\n\n\t\tif(map.hasOwnProperty(entity)){\n\t\t\tthis._emitPartial(map[entity]);\n\t\t\tthis._sectionStart = this._index + 1;\n\t\t}\n\t}\n};\n\n\n//parses legacy entities (without trailing semicolon)\nTokenizer.prototype._parseLegacyEntity = function(){\n\tvar start = this._sectionStart + 1,\n\t    limit = this._index - start;\n\n\tif(limit > 6) limit = 6; //the max length of legacy entities is 6\n\n\twhile(limit >= 2){ //the min length of legacy entities is 2\n\t\tvar entity = this._buffer.substr(start, limit);\n\n\t\tif(legacyMap.hasOwnProperty(entity)){\n\t\t\tthis._emitPartial(legacyMap[entity]);\n\t\t\tthis._sectionStart += limit + 1;\n\t\t\treturn;\n\t\t} else {\n\t\t\tlimit--;\n\t\t}\n\t}\n};\n\nTokenizer.prototype._stateInNamedEntity = function(c){\n\tif(c === \";\"){\n\t\tthis._parseNamedEntityStrict();\n\t\tif(this._sectionStart + 1 < this._index && !this._xmlMode){\n\t\t\tthis._parseLegacyEntity();\n\t\t}\n\t\tthis._state = this._baseState;\n\t} else if((c < \"a\" || c > \"z\") && (c < \"A\" || c > \"Z\") && (c < \"0\" || c > \"9\")){\n\t\tif(this._xmlMode);\n\t\telse if(this._sectionStart + 1 === this._index);\n\t\telse if(this._baseState !== TEXT){\n\t\t\tif(c !== \"=\"){\n\t\t\t\tthis._parseNamedEntityStrict();\n\t\t\t}\n\t\t} else {\n\t\t\tthis._parseLegacyEntity();\n\t\t}\n\n\t\tthis._state = this._baseState;\n\t\tthis._index--;\n\t}\n};\n\nTokenizer.prototype._decodeNumericEntity = function(offset, base){\n\tvar sectionStart = this._sectionStart + offset;\n\n\tif(sectionStart !== this._index){\n\t\t//parse entity\n\t\tvar entity = this._buffer.substring(sectionStart, this._index);\n\t\tvar parsed = parseInt(entity, base);\n\n\t\tthis._emitPartial(decodeCodePoint(parsed));\n\t\tthis._sectionStart = this._index;\n\t} else {\n\t\tthis._sectionStart--;\n\t}\n\n\tthis._state = this._baseState;\n};\n\nTokenizer.prototype._stateInNumericEntity = function(c){\n\tif(c === \";\"){\n\t\tthis._decodeNumericEntity(2, 10);\n\t\tthis._sectionStart++;\n\t} else if(c < \"0\" || c > \"9\"){\n\t\tif(!this._xmlMode){\n\t\t\tthis._decodeNumericEntity(2, 10);\n\t\t} else {\n\t\t\tthis._state = this._baseState;\n\t\t}\n\t\tthis._index--;\n\t}\n};\n\nTokenizer.prototype._stateInHexEntity = function(c){\n\tif(c === \";\"){\n\t\tthis._decodeNumericEntity(3, 16);\n\t\tthis._sectionStart++;\n\t} else if((c < \"a\" || c > \"f\") && (c < \"A\" || c > \"F\") && (c < \"0\" || c > \"9\")){\n\t\tif(!this._xmlMode){\n\t\t\tthis._decodeNumericEntity(3, 16);\n\t\t} else {\n\t\t\tthis._state = this._baseState;\n\t\t}\n\t\tthis._index--;\n\t}\n};\n\nTokenizer.prototype._cleanup = function (){\n\tif(this._sectionStart < 0){\n\t\tthis._buffer = \"\";\n\t\tthis._index = 0;\n\t\tthis._bufferOffset += this._index;\n\t} else if(this._running){\n\t\tif(this._state === TEXT){\n\t\t\tif(this._sectionStart !== this._index){\n\t\t\t\tthis._cbs.ontext(this._buffer.substr(this._sectionStart));\n\t\t\t}\n\t\t\tthis._buffer = \"\";\n\t\t\tthis._bufferOffset += this._index;\n\t\t\tthis._index = 0;\n\t\t} else if(this._sectionStart === this._index){\n\t\t\t//the section just started\n\t\t\tthis._buffer = \"\";\n\t\t\tthis._bufferOffset += this._index;\n\t\t\tthis._index = 0;\n\t\t} else {\n\t\t\t//remove everything unnecessary\n\t\t\tthis._buffer = this._buffer.substr(this._sectionStart);\n\t\t\tthis._index -= this._sectionStart;\n\t\t\tthis._bufferOffset += this._sectionStart;\n\t\t}\n\n\t\tthis._sectionStart = 0;\n\t}\n};\n\n//TODO make events conditional\nTokenizer.prototype.write = function(chunk){\n\tif(this._ended) this._cbs.onerror(Error(\".write() after done!\"));\n\n\tthis._buffer += chunk;\n\tthis._parse();\n};\n\nTokenizer.prototype._parse = function(){\n\twhile(this._index < this._buffer.length && this._running){\n\t\tvar c = this._buffer.charAt(this._index);\n\t\tif(this._state === TEXT) {\n\t\t\tthis._stateText(c);\n\t\t} else if(this._state === BEFORE_TAG_NAME){\n\t\t\tthis._stateBeforeTagName(c);\n\t\t} else if(this._state === IN_TAG_NAME) {\n\t\t\tthis._stateInTagName(c);\n\t\t} else if(this._state === BEFORE_CLOSING_TAG_NAME){\n\t\t\tthis._stateBeforeCloseingTagName(c);\n\t\t} else if(this._state === IN_CLOSING_TAG_NAME){\n\t\t\tthis._stateInCloseingTagName(c);\n\t\t} else if(this._state === AFTER_CLOSING_TAG_NAME){\n\t\t\tthis._stateAfterCloseingTagName(c);\n\t\t} else if(this._state === IN_SELF_CLOSING_TAG){\n\t\t\tthis._stateInSelfClosingTag(c);\n\t\t}\n\n\t\t/*\n\t\t*\tattributes\n\t\t*/\n\t\telse if(this._state === BEFORE_ATTRIBUTE_NAME){\n\t\t\tthis._stateBeforeAttributeName(c);\n\t\t} else if(this._state === IN_ATTRIBUTE_NAME){\n\t\t\tthis._stateInAttributeName(c);\n\t\t} else if(this._state === AFTER_ATTRIBUTE_NAME){\n\t\t\tthis._stateAfterAttributeName(c);\n\t\t} else if(this._state === BEFORE_ATTRIBUTE_VALUE){\n\t\t\tthis._stateBeforeAttributeValue(c);\n\t\t} else if(this._state === IN_ATTRIBUTE_VALUE_DQ){\n\t\t\tthis._stateInAttributeValueDoubleQuotes(c);\n\t\t} else if(this._state === IN_ATTRIBUTE_VALUE_SQ){\n\t\t\tthis._stateInAttributeValueSingleQuotes(c);\n\t\t} else if(this._state === IN_ATTRIBUTE_VALUE_NQ){\n\t\t\tthis._stateInAttributeValueNoQuotes(c);\n\t\t}\n\n\t\t/*\n\t\t*\tdeclarations\n\t\t*/\n\t\telse if(this._state === BEFORE_DECLARATION){\n\t\t\tthis._stateBeforeDeclaration(c);\n\t\t} else if(this._state === IN_DECLARATION){\n\t\t\tthis._stateInDeclaration(c);\n\t\t}\n\n\t\t/*\n\t\t*\tprocessing instructions\n\t\t*/\n\t\telse if(this._state === IN_PROCESSING_INSTRUCTION){\n\t\t\tthis._stateInProcessingInstruction(c);\n\t\t}\n\n\t\t/*\n\t\t*\tcomments\n\t\t*/\n\t\telse if(this._state === BEFORE_COMMENT){\n\t\t\tthis._stateBeforeComment(c);\n\t\t} else if(this._state === IN_COMMENT){\n\t\t\tthis._stateInComment(c);\n\t\t} else if(this._state === AFTER_COMMENT_1){\n\t\t\tthis._stateAfterComment1(c);\n\t\t} else if(this._state === AFTER_COMMENT_2){\n\t\t\tthis._stateAfterComment2(c);\n\t\t}\n\n\t\t/*\n\t\t*\tcdata\n\t\t*/\n\t\telse if(this._state === BEFORE_CDATA_1){\n\t\t\tthis._stateBeforeCdata1(c);\n\t\t} else if(this._state === BEFORE_CDATA_2){\n\t\t\tthis._stateBeforeCdata2(c);\n\t\t} else if(this._state === BEFORE_CDATA_3){\n\t\t\tthis._stateBeforeCdata3(c);\n\t\t} else if(this._state === BEFORE_CDATA_4){\n\t\t\tthis._stateBeforeCdata4(c);\n\t\t} else if(this._state === BEFORE_CDATA_5){\n\t\t\tthis._stateBeforeCdata5(c);\n\t\t} else if(this._state === BEFORE_CDATA_6){\n\t\t\tthis._stateBeforeCdata6(c);\n\t\t} else if(this._state === IN_CDATA){\n\t\t\tthis._stateInCdata(c);\n\t\t} else if(this._state === AFTER_CDATA_1){\n\t\t\tthis._stateAfterCdata1(c);\n\t\t} else if(this._state === AFTER_CDATA_2){\n\t\t\tthis._stateAfterCdata2(c);\n\t\t}\n\n\t\t/*\n\t\t* special tags\n\t\t*/\n\t\telse if(this._state === BEFORE_SPECIAL){\n\t\t\tthis._stateBeforeSpecial(c);\n\t\t} else if(this._state === BEFORE_SPECIAL_END){\n\t\t\tthis._stateBeforeSpecialEnd(c);\n\t\t}\n\n\t\t/*\n\t\t* script\n\t\t*/\n\t\telse if(this._state === BEFORE_SCRIPT_1){\n\t\t\tthis._stateBeforeScript1(c);\n\t\t} else if(this._state === BEFORE_SCRIPT_2){\n\t\t\tthis._stateBeforeScript2(c);\n\t\t} else if(this._state === BEFORE_SCRIPT_3){\n\t\t\tthis._stateBeforeScript3(c);\n\t\t} else if(this._state === BEFORE_SCRIPT_4){\n\t\t\tthis._stateBeforeScript4(c);\n\t\t} else if(this._state === BEFORE_SCRIPT_5){\n\t\t\tthis._stateBeforeScript5(c);\n\t\t}\n\n\t\telse if(this._state === AFTER_SCRIPT_1){\n\t\t\tthis._stateAfterScript1(c);\n\t\t} else if(this._state === AFTER_SCRIPT_2){\n\t\t\tthis._stateAfterScript2(c);\n\t\t} else if(this._state === AFTER_SCRIPT_3){\n\t\t\tthis._stateAfterScript3(c);\n\t\t} else if(this._state === AFTER_SCRIPT_4){\n\t\t\tthis._stateAfterScript4(c);\n\t\t} else if(this._state === AFTER_SCRIPT_5){\n\t\t\tthis._stateAfterScript5(c);\n\t\t}\n\n\t\t/*\n\t\t* style\n\t\t*/\n\t\telse if(this._state === BEFORE_STYLE_1){\n\t\t\tthis._stateBeforeStyle1(c);\n\t\t} else if(this._state === BEFORE_STYLE_2){\n\t\t\tthis._stateBeforeStyle2(c);\n\t\t} else if(this._state === BEFORE_STYLE_3){\n\t\t\tthis._stateBeforeStyle3(c);\n\t\t} else if(this._state === BEFORE_STYLE_4){\n\t\t\tthis._stateBeforeStyle4(c);\n\t\t}\n\n\t\telse if(this._state === AFTER_STYLE_1){\n\t\t\tthis._stateAfterStyle1(c);\n\t\t} else if(this._state === AFTER_STYLE_2){\n\t\t\tthis._stateAfterStyle2(c);\n\t\t} else if(this._state === AFTER_STYLE_3){\n\t\t\tthis._stateAfterStyle3(c);\n\t\t} else if(this._state === AFTER_STYLE_4){\n\t\t\tthis._stateAfterStyle4(c);\n\t\t}\n\n\t\t/*\n\t\t* entities\n\t\t*/\n\t\telse if(this._state === BEFORE_ENTITY){\n\t\t\tthis._stateBeforeEntity(c);\n\t\t} else if(this._state === BEFORE_NUMERIC_ENTITY){\n\t\t\tthis._stateBeforeNumericEntity(c);\n\t\t} else if(this._state === IN_NAMED_ENTITY){\n\t\t\tthis._stateInNamedEntity(c);\n\t\t} else if(this._state === IN_NUMERIC_ENTITY){\n\t\t\tthis._stateInNumericEntity(c);\n\t\t} else if(this._state === IN_HEX_ENTITY){\n\t\t\tthis._stateInHexEntity(c);\n\t\t}\n\n\t\telse {\n\t\t\tthis._cbs.onerror(Error(\"unknown _state\"), this._state);\n\t\t}\n\n\t\tthis._index++;\n\t}\n\n\tthis._cleanup();\n};\n\nTokenizer.prototype.pause = function(){\n\tthis._running = false;\n};\nTokenizer.prototype.resume = function(){\n\tthis._running = true;\n\n\tif(this._index < this._buffer.length){\n\t\tthis._parse();\n\t}\n\tif(this._ended){\n\t\tthis._finish();\n\t}\n};\n\nTokenizer.prototype.end = function(chunk){\n\tif(this._ended) this._cbs.onerror(Error(\".end() after done!\"));\n\tif(chunk) this.write(chunk);\n\n\tthis._ended = true;\n\n\tif(this._running) this._finish();\n};\n\nTokenizer.prototype._finish = function(){\n\t//if there is remaining data, emit it in a reasonable way\n\tif(this._sectionStart < this._index){\n\t\tthis._handleTrailingData();\n\t}\n\n\tthis._cbs.onend();\n};\n\nTokenizer.prototype._handleTrailingData = function(){\n\tvar data = this._buffer.substr(this._sectionStart);\n\n\tif(this._state === IN_CDATA || this._state === AFTER_CDATA_1 || this._state === AFTER_CDATA_2){\n\t\tthis._cbs.oncdata(data);\n\t} else if(this._state === IN_COMMENT || this._state === AFTER_COMMENT_1 || this._state === AFTER_COMMENT_2){\n\t\tthis._cbs.oncomment(data);\n\t} else if(this._state === IN_NAMED_ENTITY && !this._xmlMode){\n\t\tthis._parseLegacyEntity();\n\t\tif(this._sectionStart < this._index){\n\t\t\tthis._state = this._baseState;\n\t\t\tthis._handleTrailingData();\n\t\t}\n\t} else if(this._state === IN_NUMERIC_ENTITY && !this._xmlMode){\n\t\tthis._decodeNumericEntity(2, 10);\n\t\tif(this._sectionStart < this._index){\n\t\t\tthis._state = this._baseState;\n\t\t\tthis._handleTrailingData();\n\t\t}\n\t} else if(this._state === IN_HEX_ENTITY && !this._xmlMode){\n\t\tthis._decodeNumericEntity(3, 16);\n\t\tif(this._sectionStart < this._index){\n\t\t\tthis._state = this._baseState;\n\t\t\tthis._handleTrailingData();\n\t\t}\n\t} else if(\n\t\tthis._state !== IN_TAG_NAME &&\n\t\tthis._state !== BEFORE_ATTRIBUTE_NAME &&\n\t\tthis._state !== BEFORE_ATTRIBUTE_VALUE &&\n\t\tthis._state !== AFTER_ATTRIBUTE_NAME &&\n\t\tthis._state !== IN_ATTRIBUTE_NAME &&\n\t\tthis._state !== IN_ATTRIBUTE_VALUE_SQ &&\n\t\tthis._state !== IN_ATTRIBUTE_VALUE_DQ &&\n\t\tthis._state !== IN_ATTRIBUTE_VALUE_NQ &&\n\t\tthis._state !== IN_CLOSING_TAG_NAME\n\t){\n\t\tthis._cbs.ontext(data);\n\t}\n\t//else, ignore remaining data\n\t//TODO add a way to remove current tag\n};\n\nTokenizer.prototype.reset = function(){\n\tTokenizer.call(this, {xmlMode: this._xmlMode, decodeEntities: this._decodeEntities}, this._cbs);\n};\n\nTokenizer.prototype.getAbsoluteIndex = function(){\n\treturn this._bufferOffset + this._index;\n};\n\nTokenizer.prototype._getSection = function(){\n\treturn this._buffer.substring(this._sectionStart, this._index);\n};\n\nTokenizer.prototype._emitToken = function(name){\n\tthis._cbs[name](this._getSection());\n\tthis._sectionStart = -1;\n};\n\nTokenizer.prototype._emitPartial = function(value){\n\tif(this._baseState !== TEXT){\n\t\tthis._cbs.onattribdata(value); //TODO implement the new event\n\t} else {\n\t\tthis._cbs.ontext(value);\n\t}\n};\n\n},{\"entities/lib/decode_codepoint.js\":22,\"entities/maps/entities.json\":25,\"entities/maps/legacy.json\":26,\"entities/maps/xml.json\":27}],35:[function(require,module,exports){\nmodule.exports = Stream;\n\nvar Parser = require(\"./Parser.js\"),\n    WritableStream = require(\"stream\").Writable || require(\"readable-stream\").Writable,\n    StringDecoder = require(\"string_decoder\").StringDecoder,\n    Buffer = require(\"buffer\").Buffer;\n\nfunction Stream(cbs, options){\n\tvar parser = this._parser = new Parser(cbs, options);\n\tvar decoder = this._decoder = new StringDecoder();\n\n\tWritableStream.call(this, {decodeStrings: false});\n\n\tthis.once(\"finish\", function(){\n\t\tparser.end(decoder.end());\n\t});\n}\n\nrequire(\"inherits\")(Stream, WritableStream);\n\nWritableStream.prototype._write = function(chunk, encoding, cb){\n\tif(chunk instanceof Buffer) chunk = this._decoder.write(chunk);\n\tthis._parser.write(chunk);\n\tcb();\n};\n},{\"./Parser.js\":31,\"buffer\":5,\"inherits\":38,\"readable-stream\":3,\"stream\":55,\"string_decoder\":56}],36:[function(require,module,exports){\nvar Parser = require(\"./Parser.js\"),\n    DomHandler = require(\"domhandler\");\n\nfunction defineProp(name, value){\n\tdelete module.exports[name];\n\tmodule.exports[name] = value;\n\treturn value;\n}\n\nmodule.exports = {\n\tParser: Parser,\n\tTokenizer: require(\"./Tokenizer.js\"),\n\tElementType: require(\"domelementtype\"),\n\tDomHandler: DomHandler,\n\tget FeedHandler(){\n\t\treturn defineProp(\"FeedHandler\", require(\"./FeedHandler.js\"));\n\t},\n\tget Stream(){\n\t\treturn defineProp(\"Stream\", require(\"./Stream.js\"));\n\t},\n\tget WritableStream(){\n\t\treturn defineProp(\"WritableStream\", require(\"./WritableStream.js\"));\n\t},\n\tget ProxyHandler(){\n\t\treturn defineProp(\"ProxyHandler\", require(\"./ProxyHandler.js\"));\n\t},\n\tget DomUtils(){\n\t\treturn defineProp(\"DomUtils\", require(\"domutils\"));\n\t},\n\tget CollectingHandler(){\n\t\treturn defineProp(\"CollectingHandler\", require(\"./CollectingHandler.js\"));\n\t},\n\t// For legacy support\n\tDefaultHandler: DomHandler,\n\tget RssHandler(){\n\t\treturn defineProp(\"RssHandler\", this.FeedHandler);\n\t},\n\t//helper methods\n\tparseDOM: function(data, options){\n\t\tvar handler = new DomHandler(options);\n\t\tnew Parser(handler, options).end(data);\n\t\treturn handler.dom;\n\t},\n\tparseFeed: function(feed, options){\n\t\tvar handler = new module.exports.FeedHandler(options);\n\t\tnew Parser(handler, options).end(feed);\n\t\treturn handler.dom;\n\t},\n\tcreateDomStream: function(cb, options, elementCb){\n\t\tvar handler = new DomHandler(cb, options, elementCb);\n\t\treturn new Parser(handler, options);\n\t},\n\t// List of all events that the parser emits\n\tEVENTS: { /* Format: eventname: number of arguments */\n\t\tattribute: 2,\n\t\tcdatastart: 0,\n\t\tcdataend: 0,\n\t\ttext: 1,\n\t\tprocessinginstruction: 2,\n\t\tcomment: 1,\n\t\tcommentend: 0,\n\t\tclosetag: 1,\n\t\topentag: 2,\n\t\topentagname: 1,\n\t\terror: 1,\n\t\tend: 0\n\t}\n};\n\n},{\"./CollectingHandler.js\":29,\"./FeedHandler.js\":30,\"./Parser.js\":31,\"./ProxyHandler.js\":32,\"./Stream.js\":33,\"./Tokenizer.js\":34,\"./WritableStream.js\":35,\"domelementtype\":9,\"domhandler\":10,\"domutils\":13}],37:[function(require,module,exports){\nexports.read = function (buffer, offset, isLE, mLen, nBytes) {\n  var e, m\n  var eLen = nBytes * 8 - mLen - 1\n  var eMax = (1 << eLen) - 1\n  var eBias = eMax >> 1\n  var nBits = -7\n  var i = isLE ? (nBytes - 1) : 0\n  var d = isLE ? -1 : 1\n  var s = buffer[offset + i]\n\n  i += d\n\n  e = s & ((1 << (-nBits)) - 1)\n  s >>= (-nBits)\n  nBits += eLen\n  for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}\n\n  m = e & ((1 << (-nBits)) - 1)\n  e >>= (-nBits)\n  nBits += mLen\n  for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}\n\n  if (e === 0) {\n    e = 1 - eBias\n  } else if (e === eMax) {\n    return m ? NaN : ((s ? -1 : 1) * Infinity)\n  } else {\n    m = m + Math.pow(2, mLen)\n    e = e - eBias\n  }\n  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)\n}\n\nexports.write = function (buffer, value, offset, isLE, mLen, nBytes) {\n  var e, m, c\n  var eLen = nBytes * 8 - mLen - 1\n  var eMax = (1 << eLen) - 1\n  var eBias = eMax >> 1\n  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)\n  var i = isLE ? 0 : (nBytes - 1)\n  var d = isLE ? 1 : -1\n  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0\n\n  value = Math.abs(value)\n\n  if (isNaN(value) || value === Infinity) {\n    m = isNaN(value) ? 1 : 0\n    e = eMax\n  } else {\n    e = Math.floor(Math.log(value) / Math.LN2)\n    if (value * (c = Math.pow(2, -e)) < 1) {\n      e--\n      c *= 2\n    }\n    if (e + eBias >= 1) {\n      value += rt / c\n    } else {\n      value += rt * Math.pow(2, 1 - eBias)\n    }\n    if (value * c >= 2) {\n      e++\n      c /= 2\n    }\n\n    if (e + eBias >= eMax) {\n      m = 0\n      e = eMax\n    } else if (e + eBias >= 1) {\n      m = (value * c - 1) * Math.pow(2, mLen)\n      e = e + eBias\n    } else {\n      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)\n      e = 0\n    }\n  }\n\n  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}\n\n  e = (e << mLen) | m\n  eLen += mLen\n  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}\n\n  buffer[offset + i - d] |= s * 128\n}\n\n},{}],38:[function(require,module,exports){\nif (typeof Object.create === 'function') {\n  // implementation from standard node.js 'util' module\n  module.exports = function inherits(ctor, superCtor) {\n    ctor.super_ = superCtor\n    ctor.prototype = Object.create(superCtor.prototype, {\n      constructor: {\n        value: ctor,\n        enumerable: false,\n        writable: true,\n        configurable: true\n      }\n    });\n  };\n} else {\n  // old school shim for old browsers\n  module.exports = function inherits(ctor, superCtor) {\n    ctor.super_ = superCtor\n    var TempCtor = function () {}\n    TempCtor.prototype = superCtor.prototype\n    ctor.prototype = new TempCtor()\n    ctor.prototype.constructor = ctor\n  }\n}\n\n},{}],39:[function(require,module,exports){\n/*!\n * Determine if an object is a Buffer\n *\n * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>\n * @license  MIT\n */\n\n// The _isBuffer check is for Safari 5-7 support, because it's missing\n// Object.prototype.constructor. Remove this eventually\nmodule.exports = function (obj) {\n  return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)\n}\n\nfunction isBuffer (obj) {\n  return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)\n}\n\n// For Node v0.10 support. Remove this eventually.\nfunction isSlowBuffer (obj) {\n  return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0))\n}\n\n},{}],40:[function(require,module,exports){\nvar toString = {}.toString;\n\nmodule.exports = Array.isArray || function (arr) {\n  return toString.call(arr) == '[object Array]';\n};\n\n},{}],41:[function(require,module,exports){\n(function (process){\n'use strict';\n\nif (!process.version ||\n    process.version.indexOf('v0.') === 0 ||\n    process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) {\n  module.exports = nextTick;\n} else {\n  module.exports = process.nextTick;\n}\n\nfunction nextTick(fn, arg1, arg2, arg3) {\n  if (typeof fn !== 'function') {\n    throw new TypeError('\"callback\" argument must be a function');\n  }\n  var len = arguments.length;\n  var args, i;\n  switch (len) {\n  case 0:\n  case 1:\n    return process.nextTick(fn);\n  case 2:\n    return process.nextTick(function afterTickOne() {\n      fn.call(null, arg1);\n    });\n  case 3:\n    return process.nextTick(function afterTickTwo() {\n      fn.call(null, arg1, arg2);\n    });\n  case 4:\n    return process.nextTick(function afterTickThree() {\n      fn.call(null, arg1, arg2, arg3);\n    });\n  default:\n    args = new Array(len - 1);\n    i = 0;\n    while (i < args.length) {\n      args[i++] = arguments[i];\n    }\n    return process.nextTick(function afterTick() {\n      fn.apply(null, args);\n    });\n  }\n}\n\n}).call(this,require('_process'))\n},{\"_process\":42}],42:[function(require,module,exports){\n// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things.  But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals.  It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n    throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n    throw new Error('clearTimeout has not been defined');\n}\n(function () {\n    try {\n        if (typeof setTimeout === 'function') {\n            cachedSetTimeout = setTimeout;\n        } else {\n            cachedSetTimeout = defaultSetTimout;\n        }\n    } catch (e) {\n        cachedSetTimeout = defaultSetTimout;\n    }\n    try {\n        if (typeof clearTimeout === 'function') {\n            cachedClearTimeout = clearTimeout;\n        } else {\n            cachedClearTimeout = defaultClearTimeout;\n        }\n    } catch (e) {\n        cachedClearTimeout = defaultClearTimeout;\n    }\n} ())\nfunction runTimeout(fun) {\n    if (cachedSetTimeout === setTimeout) {\n        //normal enviroments in sane situations\n        return setTimeout(fun, 0);\n    }\n    // if setTimeout wasn't available but was latter defined\n    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n        cachedSetTimeout = setTimeout;\n        return setTimeout(fun, 0);\n    }\n    try {\n        // when when somebody has screwed with setTimeout but no I.E. maddness\n        return cachedSetTimeout(fun, 0);\n    } catch(e){\n        try {\n            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n            return cachedSetTimeout.call(null, fun, 0);\n        } catch(e){\n            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n            return cachedSetTimeout.call(this, fun, 0);\n        }\n    }\n\n\n}\nfunction runClearTimeout(marker) {\n    if (cachedClearTimeout === clearTimeout) {\n        //normal enviroments in sane situations\n        return clearTimeout(marker);\n    }\n    // if clearTimeout wasn't available but was latter defined\n    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n        cachedClearTimeout = clearTimeout;\n        return clearTimeout(marker);\n    }\n    try {\n        // when when somebody has screwed with setTimeout but no I.E. maddness\n        return cachedClearTimeout(marker);\n    } catch (e){\n        try {\n            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally\n            return cachedClearTimeout.call(null, marker);\n        } catch (e){\n            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n            // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n            return cachedClearTimeout.call(this, marker);\n        }\n    }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n    if (!draining || !currentQueue) {\n        return;\n    }\n    draining = false;\n    if (currentQueue.length) {\n        queue = currentQueue.concat(queue);\n    } else {\n        queueIndex = -1;\n    }\n    if (queue.length) {\n        drainQueue();\n    }\n}\n\nfunction drainQueue() {\n    if (draining) {\n        return;\n    }\n    var timeout = runTimeout(cleanUpNextTick);\n    draining = true;\n\n    var len = queue.length;\n    while(len) {\n        currentQueue = queue;\n        queue = [];\n        while (++queueIndex < len) {\n            if (currentQueue) {\n                currentQueue[queueIndex].run();\n            }\n        }\n        queueIndex = -1;\n        len = queue.length;\n    }\n    currentQueue = null;\n    draining = false;\n    runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n    var args = new Array(arguments.length - 1);\n    if (arguments.length > 1) {\n        for (var i = 1; i < arguments.length; i++) {\n            args[i - 1] = arguments[i];\n        }\n    }\n    queue.push(new Item(fun, args));\n    if (queue.length === 1 && !draining) {\n        runTimeout(drainQueue);\n    }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n    this.fun = fun;\n    this.array = array;\n}\nItem.prototype.run = function () {\n    this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\n\nprocess.binding = function (name) {\n    throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n    throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n\n},{}],43:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_duplex.js\")\n\n},{\"./lib/_stream_duplex.js\":44}],44:[function(require,module,exports){\n// a duplex stream is just a stream that is both readable and writable.\n// Since JS doesn't have multiple prototypal inheritance, this class\n// prototypally inherits from Readable, and then parasitically from\n// Writable.\n\n'use strict';\n\n/*<replacement>*/\n\nvar objectKeys = Object.keys || function (obj) {\n  var keys = [];\n  for (var key in obj) {\n    keys.push(key);\n  }return keys;\n};\n/*</replacement>*/\n\nmodule.exports = Duplex;\n\n/*<replacement>*/\nvar processNextTick = require('process-nextick-args');\n/*</replacement>*/\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nvar Readable = require('./_stream_readable');\nvar Writable = require('./_stream_writable');\n\nutil.inherits(Duplex, Readable);\n\nvar keys = objectKeys(Writable.prototype);\nfor (var v = 0; v < keys.length; v++) {\n  var method = keys[v];\n  if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];\n}\n\nfunction Duplex(options) {\n  if (!(this instanceof Duplex)) return new Duplex(options);\n\n  Readable.call(this, options);\n  Writable.call(this, options);\n\n  if (options && options.readable === false) this.readable = false;\n\n  if (options && options.writable === false) this.writable = false;\n\n  this.allowHalfOpen = true;\n  if (options && options.allowHalfOpen === false) this.allowHalfOpen = false;\n\n  this.once('end', onend);\n}\n\n// the no-half-open enforcer\nfunction onend() {\n  // if we allow half-open state, or if the writable side ended,\n  // then we're ok.\n  if (this.allowHalfOpen || this._writableState.ended) return;\n\n  // no more data can be written.\n  // But allow more writes to happen in this tick.\n  processNextTick(onEndNT, this);\n}\n\nfunction onEndNT(self) {\n  self.end();\n}\n\nfunction forEach(xs, f) {\n  for (var i = 0, l = xs.length; i < l; i++) {\n    f(xs[i], i);\n  }\n}\n},{\"./_stream_readable\":46,\"./_stream_writable\":48,\"core-util-is\":6,\"inherits\":38,\"process-nextick-args\":41}],45:[function(require,module,exports){\n// a passthrough stream.\n// basically just the most minimal sort of Transform stream.\n// Every written chunk gets output as-is.\n\n'use strict';\n\nmodule.exports = PassThrough;\n\nvar Transform = require('./_stream_transform');\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nutil.inherits(PassThrough, Transform);\n\nfunction PassThrough(options) {\n  if (!(this instanceof PassThrough)) return new PassThrough(options);\n\n  Transform.call(this, options);\n}\n\nPassThrough.prototype._transform = function (chunk, encoding, cb) {\n  cb(null, chunk);\n};\n},{\"./_stream_transform\":47,\"core-util-is\":6,\"inherits\":38}],46:[function(require,module,exports){\n(function (process){\n'use strict';\n\nmodule.exports = Readable;\n\n/*<replacement>*/\nvar processNextTick = require('process-nextick-args');\n/*</replacement>*/\n\n/*<replacement>*/\nvar isArray = require('isarray');\n/*</replacement>*/\n\nReadable.ReadableState = ReadableState;\n\n/*<replacement>*/\nvar EE = require('events').EventEmitter;\n\nvar EElistenerCount = function (emitter, type) {\n  return emitter.listeners(type).length;\n};\n/*</replacement>*/\n\n/*<replacement>*/\nvar Stream;\n(function () {\n  try {\n    Stream = require('st' + 'ream');\n  } catch (_) {} finally {\n    if (!Stream) Stream = require('events').EventEmitter;\n  }\n})();\n/*</replacement>*/\n\nvar Buffer = require('buffer').Buffer;\n/*<replacement>*/\nvar bufferShim = require('buffer-shims');\n/*</replacement>*/\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\n/*<replacement>*/\nvar debugUtil = require('util');\nvar debug = void 0;\nif (debugUtil && debugUtil.debuglog) {\n  debug = debugUtil.debuglog('stream');\n} else {\n  debug = function () {};\n}\n/*</replacement>*/\n\nvar BufferList = require('./internal/streams/BufferList');\nvar StringDecoder;\n\nutil.inherits(Readable, Stream);\n\nfunction prependListener(emitter, event, fn) {\n  if (typeof emitter.prependListener === 'function') {\n    return emitter.prependListener(event, fn);\n  } else {\n    // This is a hack to make sure that our error handler is attached before any\n    // userland ones.  NEVER DO THIS. This is here only because this code needs\n    // to continue to work with older versions of Node.js that do not include\n    // the prependListener() method. The goal is to eventually remove this hack.\n    if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]];\n  }\n}\n\nvar Duplex;\nfunction ReadableState(options, stream) {\n  Duplex = Duplex || require('./_stream_duplex');\n\n  options = options || {};\n\n  // object stream flag. Used to make read(n) ignore n and to\n  // make all the buffer merging and length checks go away\n  this.objectMode = !!options.objectMode;\n\n  if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode;\n\n  // the point at which it stops calling _read() to fill the buffer\n  // Note: 0 is a valid value, means \"don't call _read preemptively ever\"\n  var hwm = options.highWaterMark;\n  var defaultHwm = this.objectMode ? 16 : 16 * 1024;\n  this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;\n\n  // cast to ints.\n  this.highWaterMark = ~ ~this.highWaterMark;\n\n  // A linked list is used to store data chunks instead of an array because the\n  // linked list can remove elements from the beginning faster than\n  // array.shift()\n  this.buffer = new BufferList();\n  this.length = 0;\n  this.pipes = null;\n  this.pipesCount = 0;\n  this.flowing = null;\n  this.ended = false;\n  this.endEmitted = false;\n  this.reading = false;\n\n  // a flag to be able to tell if the onwrite cb is called immediately,\n  // or on a later tick.  We set this to true at first, because any\n  // actions that shouldn't happen until \"later\" should generally also\n  // not happen before the first write call.\n  this.sync = true;\n\n  // whenever we return null, then we set a flag to say\n  // that we're awaiting a 'readable' event emission.\n  this.needReadable = false;\n  this.emittedReadable = false;\n  this.readableListening = false;\n  this.resumeScheduled = false;\n\n  // Crypto is kind of old and crusty.  Historically, its default string\n  // encoding is 'binary' so we have to make this configurable.\n  // Everything else in the universe uses 'utf8', though.\n  this.defaultEncoding = options.defaultEncoding || 'utf8';\n\n  // when piping, we only care about 'readable' events that happen\n  // after read()ing all the bytes and not getting any pushback.\n  this.ranOut = false;\n\n  // the number of writers that are awaiting a drain event in .pipe()s\n  this.awaitDrain = 0;\n\n  // if true, a maybeReadMore has been scheduled\n  this.readingMore = false;\n\n  this.decoder = null;\n  this.encoding = null;\n  if (options.encoding) {\n    if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;\n    this.decoder = new StringDecoder(options.encoding);\n    this.encoding = options.encoding;\n  }\n}\n\nvar Duplex;\nfunction Readable(options) {\n  Duplex = Duplex || require('./_stream_duplex');\n\n  if (!(this instanceof Readable)) return new Readable(options);\n\n  this._readableState = new ReadableState(options, this);\n\n  // legacy\n  this.readable = true;\n\n  if (options && typeof options.read === 'function') this._read = options.read;\n\n  Stream.call(this);\n}\n\n// Manually shove something into the read() buffer.\n// This returns true if the highWaterMark has not been hit yet,\n// similar to how Writable.write() returns true if you should\n// write() some more.\nReadable.prototype.push = function (chunk, encoding) {\n  var state = this._readableState;\n\n  if (!state.objectMode && typeof chunk === 'string') {\n    encoding = encoding || state.defaultEncoding;\n    if (encoding !== state.encoding) {\n      chunk = bufferShim.from(chunk, encoding);\n      encoding = '';\n    }\n  }\n\n  return readableAddChunk(this, state, chunk, encoding, false);\n};\n\n// Unshift should *always* be something directly out of read()\nReadable.prototype.unshift = function (chunk) {\n  var state = this._readableState;\n  return readableAddChunk(this, state, chunk, '', true);\n};\n\nReadable.prototype.isPaused = function () {\n  return this._readableState.flowing === false;\n};\n\nfunction readableAddChunk(stream, state, chunk, encoding, addToFront) {\n  var er = chunkInvalid(state, chunk);\n  if (er) {\n    stream.emit('error', er);\n  } else if (chunk === null) {\n    state.reading = false;\n    onEofChunk(stream, state);\n  } else if (state.objectMode || chunk && chunk.length > 0) {\n    if (state.ended && !addToFront) {\n      var e = new Error('stream.push() after EOF');\n      stream.emit('error', e);\n    } else if (state.endEmitted && addToFront) {\n      var _e = new Error('stream.unshift() after end event');\n      stream.emit('error', _e);\n    } else {\n      var skipAdd;\n      if (state.decoder && !addToFront && !encoding) {\n        chunk = state.decoder.write(chunk);\n        skipAdd = !state.objectMode && chunk.length === 0;\n      }\n\n      if (!addToFront) state.reading = false;\n\n      // Don't add to the buffer if we've decoded to an empty string chunk and\n      // we're not in object mode\n      if (!skipAdd) {\n        // if we want the data now, just emit it.\n        if (state.flowing && state.length === 0 && !state.sync) {\n          stream.emit('data', chunk);\n          stream.read(0);\n        } else {\n          // update the buffer info.\n          state.length += state.objectMode ? 1 : chunk.length;\n          if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk);\n\n          if (state.needReadable) emitReadable(stream);\n        }\n      }\n\n      maybeReadMore(stream, state);\n    }\n  } else if (!addToFront) {\n    state.reading = false;\n  }\n\n  return needMoreData(state);\n}\n\n// if it's past the high water mark, we can push in some more.\n// Also, if we have no data yet, we can stand some\n// more bytes.  This is to work around cases where hwm=0,\n// such as the repl.  Also, if the push() triggered a\n// readable event, and the user called read(largeNumber) such that\n// needReadable was set, then we ought to push more, so that another\n// 'readable' event will be triggered.\nfunction needMoreData(state) {\n  return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0);\n}\n\n// backwards compatibility.\nReadable.prototype.setEncoding = function (enc) {\n  if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;\n  this._readableState.decoder = new StringDecoder(enc);\n  this._readableState.encoding = enc;\n  return this;\n};\n\n// Don't raise the hwm > 8MB\nvar MAX_HWM = 0x800000;\nfunction computeNewHighWaterMark(n) {\n  if (n >= MAX_HWM) {\n    n = MAX_HWM;\n  } else {\n    // Get the next highest power of 2 to prevent increasing hwm excessively in\n    // tiny amounts\n    n--;\n    n |= n >>> 1;\n    n |= n >>> 2;\n    n |= n >>> 4;\n    n |= n >>> 8;\n    n |= n >>> 16;\n    n++;\n  }\n  return n;\n}\n\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction howMuchToRead(n, state) {\n  if (n <= 0 || state.length === 0 && state.ended) return 0;\n  if (state.objectMode) return 1;\n  if (n !== n) {\n    // Only flow one buffer at a time\n    if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length;\n  }\n  // If we're asking for more than the current hwm, then raise the hwm.\n  if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n);\n  if (n <= state.length) return n;\n  // Don't have enough\n  if (!state.ended) {\n    state.needReadable = true;\n    return 0;\n  }\n  return state.length;\n}\n\n// you can override either this method, or the async _read(n) below.\nReadable.prototype.read = function (n) {\n  debug('read', n);\n  n = parseInt(n, 10);\n  var state = this._readableState;\n  var nOrig = n;\n\n  if (n !== 0) state.emittedReadable = false;\n\n  // if we're doing read(0) to trigger a readable event, but we\n  // already have a bunch of data in the buffer, then just trigger\n  // the 'readable' event and move on.\n  if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) {\n    debug('read: emitReadable', state.length, state.ended);\n    if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this);\n    return null;\n  }\n\n  n = howMuchToRead(n, state);\n\n  // if we've ended, and we're now clear, then finish it up.\n  if (n === 0 && state.ended) {\n    if (state.length === 0) endReadable(this);\n    return null;\n  }\n\n  // All the actual chunk generation logic needs to be\n  // *below* the call to _read.  The reason is that in certain\n  // synthetic stream cases, such as passthrough streams, _read\n  // may be a completely synchronous operation which may change\n  // the state of the read buffer, providing enough data when\n  // before there was *not* enough.\n  //\n  // So, the steps are:\n  // 1. Figure out what the state of things will be after we do\n  // a read from the buffer.\n  //\n  // 2. If that resulting state will trigger a _read, then call _read.\n  // Note that this may be asynchronous, or synchronous.  Yes, it is\n  // deeply ugly to write APIs this way, but that still doesn't mean\n  // that the Readable class should behave improperly, as streams are\n  // designed to be sync/async agnostic.\n  // Take note if the _read call is sync or async (ie, if the read call\n  // has returned yet), so that we know whether or not it's safe to emit\n  // 'readable' etc.\n  //\n  // 3. Actually pull the requested chunks out of the buffer and return.\n\n  // if we need a readable event, then we need to do some reading.\n  var doRead = state.needReadable;\n  debug('need readable', doRead);\n\n  // if we currently have less than the highWaterMark, then also read some\n  if (state.length === 0 || state.length - n < state.highWaterMark) {\n    doRead = true;\n    debug('length less than watermark', doRead);\n  }\n\n  // however, if we've ended, then there's no point, and if we're already\n  // reading, then it's unnecessary.\n  if (state.ended || state.reading) {\n    doRead = false;\n    debug('reading or ended', doRead);\n  } else if (doRead) {\n    debug('do read');\n    state.reading = true;\n    state.sync = true;\n    // if the length is currently zero, then we *need* a readable event.\n    if (state.length === 0) state.needReadable = true;\n    // call internal read method\n    this._read(state.highWaterMark);\n    state.sync = false;\n    // If _read pushed data synchronously, then `reading` will be false,\n    // and we need to re-evaluate how much data we can return to the user.\n    if (!state.reading) n = howMuchToRead(nOrig, state);\n  }\n\n  var ret;\n  if (n > 0) ret = fromList(n, state);else ret = null;\n\n  if (ret === null) {\n    state.needReadable = true;\n    n = 0;\n  } else {\n    state.length -= n;\n  }\n\n  if (state.length === 0) {\n    // If we have nothing in the buffer, then we want to know\n    // as soon as we *do* get something into the buffer.\n    if (!state.ended) state.needReadable = true;\n\n    // If we tried to read() past the EOF, then emit end on the next tick.\n    if (nOrig !== n && state.ended) endReadable(this);\n  }\n\n  if (ret !== null) this.emit('data', ret);\n\n  return ret;\n};\n\nfunction chunkInvalid(state, chunk) {\n  var er = null;\n  if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) {\n    er = new TypeError('Invalid non-string/buffer chunk');\n  }\n  return er;\n}\n\nfunction onEofChunk(stream, state) {\n  if (state.ended) return;\n  if (state.decoder) {\n    var chunk = state.decoder.end();\n    if (chunk && chunk.length) {\n      state.buffer.push(chunk);\n      state.length += state.objectMode ? 1 : chunk.length;\n    }\n  }\n  state.ended = true;\n\n  // emit 'readable' now to make sure it gets picked up.\n  emitReadable(stream);\n}\n\n// Don't emit readable right away in sync mode, because this can trigger\n// another read() call => stack overflow.  This way, it might trigger\n// a nextTick recursion warning, but that's not so bad.\nfunction emitReadable(stream) {\n  var state = stream._readableState;\n  state.needReadable = false;\n  if (!state.emittedReadable) {\n    debug('emitReadable', state.flowing);\n    state.emittedReadable = true;\n    if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream);\n  }\n}\n\nfunction emitReadable_(stream) {\n  debug('emit readable');\n  stream.emit('readable');\n  flow(stream);\n}\n\n// at this point, the user has presumably seen the 'readable' event,\n// and called read() to consume some data.  that may have triggered\n// in turn another _read(n) call, in which case reading = true if\n// it's in progress.\n// However, if we're not ended, or reading, and the length < hwm,\n// then go ahead and try to read some more preemptively.\nfunction maybeReadMore(stream, state) {\n  if (!state.readingMore) {\n    state.readingMore = true;\n    processNextTick(maybeReadMore_, stream, state);\n  }\n}\n\nfunction maybeReadMore_(stream, state) {\n  var len = state.length;\n  while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) {\n    debug('maybeReadMore read 0');\n    stream.read(0);\n    if (len === state.length)\n      // didn't get any data, stop spinning.\n      break;else len = state.length;\n  }\n  state.readingMore = false;\n}\n\n// abstract method.  to be overridden in specific implementation classes.\n// call cb(er, data) where data is <= n in length.\n// for virtual (non-string, non-buffer) streams, \"length\" is somewhat\n// arbitrary, and perhaps not very meaningful.\nReadable.prototype._read = function (n) {\n  this.emit('error', new Error('not implemented'));\n};\n\nReadable.prototype.pipe = function (dest, pipeOpts) {\n  var src = this;\n  var state = this._readableState;\n\n  switch (state.pipesCount) {\n    case 0:\n      state.pipes = dest;\n      break;\n    case 1:\n      state.pipes = [state.pipes, dest];\n      break;\n    default:\n      state.pipes.push(dest);\n      break;\n  }\n  state.pipesCount += 1;\n  debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);\n\n  var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr;\n\n  var endFn = doEnd ? onend : cleanup;\n  if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn);\n\n  dest.on('unpipe', onunpipe);\n  function onunpipe(readable) {\n    debug('onunpipe');\n    if (readable === src) {\n      cleanup();\n    }\n  }\n\n  function onend() {\n    debug('onend');\n    dest.end();\n  }\n\n  // when the dest drains, it reduces the awaitDrain counter\n  // on the source.  This would be more elegant with a .once()\n  // handler in flow(), but adding and removing repeatedly is\n  // too slow.\n  var ondrain = pipeOnDrain(src);\n  dest.on('drain', ondrain);\n\n  var cleanedUp = false;\n  function cleanup() {\n    debug('cleanup');\n    // cleanup event handlers once the pipe is broken\n    dest.removeListener('close', onclose);\n    dest.removeListener('finish', onfinish);\n    dest.removeListener('drain', ondrain);\n    dest.removeListener('error', onerror);\n    dest.removeListener('unpipe', onunpipe);\n    src.removeListener('end', onend);\n    src.removeListener('end', cleanup);\n    src.removeListener('data', ondata);\n\n    cleanedUp = true;\n\n    // if the reader is waiting for a drain event from this\n    // specific writer, then it would cause it to never start\n    // flowing again.\n    // So, if this is awaiting a drain, then we just call it now.\n    // If we don't know, then assume that we are waiting for one.\n    if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain();\n  }\n\n  // If the user pushes more data while we're writing to dest then we'll end up\n  // in ondata again. However, we only want to increase awaitDrain once because\n  // dest will only emit one 'drain' event for the multiple writes.\n  // => Introduce a guard on increasing awaitDrain.\n  var increasedAwaitDrain = false;\n  src.on('data', ondata);\n  function ondata(chunk) {\n    debug('ondata');\n    increasedAwaitDrain = false;\n    var ret = dest.write(chunk);\n    if (false === ret && !increasedAwaitDrain) {\n      // If the user unpiped during `dest.write()`, it is possible\n      // to get stuck in a permanently paused state if that write\n      // also returned false.\n      // => Check whether `dest` is still a piping destination.\n      if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) {\n        debug('false write response, pause', src._readableState.awaitDrain);\n        src._readableState.awaitDrain++;\n        increasedAwaitDrain = true;\n      }\n      src.pause();\n    }\n  }\n\n  // if the dest has an error, then stop piping into it.\n  // however, don't suppress the throwing behavior for this.\n  function onerror(er) {\n    debug('onerror', er);\n    unpipe();\n    dest.removeListener('error', onerror);\n    if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er);\n  }\n\n  // Make sure our error handler is attached before userland ones.\n  prependListener(dest, 'error', onerror);\n\n  // Both close and finish should trigger unpipe, but only once.\n  function onclose() {\n    dest.removeListener('finish', onfinish);\n    unpipe();\n  }\n  dest.once('close', onclose);\n  function onfinish() {\n    debug('onfinish');\n    dest.removeListener('close', onclose);\n    unpipe();\n  }\n  dest.once('finish', onfinish);\n\n  function unpipe() {\n    debug('unpipe');\n    src.unpipe(dest);\n  }\n\n  // tell the dest that it's being piped to\n  dest.emit('pipe', src);\n\n  // start the flow if it hasn't been started already.\n  if (!state.flowing) {\n    debug('pipe resume');\n    src.resume();\n  }\n\n  return dest;\n};\n\nfunction pipeOnDrain(src) {\n  return function () {\n    var state = src._readableState;\n    debug('pipeOnDrain', state.awaitDrain);\n    if (state.awaitDrain) state.awaitDrain--;\n    if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {\n      state.flowing = true;\n      flow(src);\n    }\n  };\n}\n\nReadable.prototype.unpipe = function (dest) {\n  var state = this._readableState;\n\n  // if we're not piping anywhere, then do nothing.\n  if (state.pipesCount === 0) return this;\n\n  // just one destination.  most common case.\n  if (state.pipesCount === 1) {\n    // passed in one, but it's not the right one.\n    if (dest && dest !== state.pipes) return this;\n\n    if (!dest) dest = state.pipes;\n\n    // got a match.\n    state.pipes = null;\n    state.pipesCount = 0;\n    state.flowing = false;\n    if (dest) dest.emit('unpipe', this);\n    return this;\n  }\n\n  // slow case. multiple pipe destinations.\n\n  if (!dest) {\n    // remove all.\n    var dests = state.pipes;\n    var len = state.pipesCount;\n    state.pipes = null;\n    state.pipesCount = 0;\n    state.flowing = false;\n\n    for (var _i = 0; _i < len; _i++) {\n      dests[_i].emit('unpipe', this);\n    }return this;\n  }\n\n  // try to find the right one.\n  var i = indexOf(state.pipes, dest);\n  if (i === -1) return this;\n\n  state.pipes.splice(i, 1);\n  state.pipesCount -= 1;\n  if (state.pipesCount === 1) state.pipes = state.pipes[0];\n\n  dest.emit('unpipe', this);\n\n  return this;\n};\n\n// set up data events if they are asked for\n// Ensure readable listeners eventually get something\nReadable.prototype.on = function (ev, fn) {\n  var res = Stream.prototype.on.call(this, ev, fn);\n\n  if (ev === 'data') {\n    // Start flowing on next tick if stream isn't explicitly paused\n    if (this._readableState.flowing !== false) this.resume();\n  } else if (ev === 'readable') {\n    var state = this._readableState;\n    if (!state.endEmitted && !state.readableListening) {\n      state.readableListening = state.needReadable = true;\n      state.emittedReadable = false;\n      if (!state.reading) {\n        processNextTick(nReadingNextTick, this);\n      } else if (state.length) {\n        emitReadable(this, state);\n      }\n    }\n  }\n\n  return res;\n};\nReadable.prototype.addListener = Readable.prototype.on;\n\nfunction nReadingNextTick(self) {\n  debug('readable nexttick read 0');\n  self.read(0);\n}\n\n// pause() and resume() are remnants of the legacy readable stream API\n// If the user uses them, then switch into old mode.\nReadable.prototype.resume = function () {\n  var state = this._readableState;\n  if (!state.flowing) {\n    debug('resume');\n    state.flowing = true;\n    resume(this, state);\n  }\n  return this;\n};\n\nfunction resume(stream, state) {\n  if (!state.resumeScheduled) {\n    state.resumeScheduled = true;\n    processNextTick(resume_, stream, state);\n  }\n}\n\nfunction resume_(stream, state) {\n  if (!state.reading) {\n    debug('resume read 0');\n    stream.read(0);\n  }\n\n  state.resumeScheduled = false;\n  state.awaitDrain = 0;\n  stream.emit('resume');\n  flow(stream);\n  if (state.flowing && !state.reading) stream.read(0);\n}\n\nReadable.prototype.pause = function () {\n  debug('call pause flowing=%j', this._readableState.flowing);\n  if (false !== this._readableState.flowing) {\n    debug('pause');\n    this._readableState.flowing = false;\n    this.emit('pause');\n  }\n  return this;\n};\n\nfunction flow(stream) {\n  var state = stream._readableState;\n  debug('flow', state.flowing);\n  while (state.flowing && stream.read() !== null) {}\n}\n\n// wrap an old-style stream as the async data source.\n// This is *not* part of the readable stream interface.\n// It is an ugly unfortunate mess of history.\nReadable.prototype.wrap = function (stream) {\n  var state = this._readableState;\n  var paused = false;\n\n  var self = this;\n  stream.on('end', function () {\n    debug('wrapped end');\n    if (state.decoder && !state.ended) {\n      var chunk = state.decoder.end();\n      if (chunk && chunk.length) self.push(chunk);\n    }\n\n    self.push(null);\n  });\n\n  stream.on('data', function (chunk) {\n    debug('wrapped data');\n    if (state.decoder) chunk = state.decoder.write(chunk);\n\n    // don't skip over falsy values in objectMode\n    if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return;\n\n    var ret = self.push(chunk);\n    if (!ret) {\n      paused = true;\n      stream.pause();\n    }\n  });\n\n  // proxy all the other methods.\n  // important when wrapping filters and duplexes.\n  for (var i in stream) {\n    if (this[i] === undefined && typeof stream[i] === 'function') {\n      this[i] = function (method) {\n        return function () {\n          return stream[method].apply(stream, arguments);\n        };\n      }(i);\n    }\n  }\n\n  // proxy certain important events.\n  var events = ['error', 'close', 'destroy', 'pause', 'resume'];\n  forEach(events, function (ev) {\n    stream.on(ev, self.emit.bind(self, ev));\n  });\n\n  // when we try to consume some more bytes, simply unpause the\n  // underlying stream.\n  self._read = function (n) {\n    debug('wrapped _read', n);\n    if (paused) {\n      paused = false;\n      stream.resume();\n    }\n  };\n\n  return self;\n};\n\n// exposed for testing purposes only.\nReadable._fromList = fromList;\n\n// Pluck off n bytes from an array of buffers.\n// Length is the combined lengths of all the buffers in the list.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction fromList(n, state) {\n  // nothing buffered\n  if (state.length === 0) return null;\n\n  var ret;\n  if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) {\n    // read it all, truncate the list\n    if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length);\n    state.buffer.clear();\n  } else {\n    // read part of list\n    ret = fromListPartial(n, state.buffer, state.decoder);\n  }\n\n  return ret;\n}\n\n// Extracts only enough buffered data to satisfy the amount requested.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction fromListPartial(n, list, hasStrings) {\n  var ret;\n  if (n < list.head.data.length) {\n    // slice is the same for buffers and strings\n    ret = list.head.data.slice(0, n);\n    list.head.data = list.head.data.slice(n);\n  } else if (n === list.head.data.length) {\n    // first chunk is a perfect match\n    ret = list.shift();\n  } else {\n    // result spans more than one buffer\n    ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list);\n  }\n  return ret;\n}\n\n// Copies a specified amount of characters from the list of buffered data\n// chunks.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction copyFromBufferString(n, list) {\n  var p = list.head;\n  var c = 1;\n  var ret = p.data;\n  n -= ret.length;\n  while (p = p.next) {\n    var str = p.data;\n    var nb = n > str.length ? str.length : n;\n    if (nb === str.length) ret += str;else ret += str.slice(0, n);\n    n -= nb;\n    if (n === 0) {\n      if (nb === str.length) {\n        ++c;\n        if (p.next) list.head = p.next;else list.head = list.tail = null;\n      } else {\n        list.head = p;\n        p.data = str.slice(nb);\n      }\n      break;\n    }\n    ++c;\n  }\n  list.length -= c;\n  return ret;\n}\n\n// Copies a specified amount of bytes from the list of buffered data chunks.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction copyFromBuffer(n, list) {\n  var ret = bufferShim.allocUnsafe(n);\n  var p = list.head;\n  var c = 1;\n  p.data.copy(ret);\n  n -= p.data.length;\n  while (p = p.next) {\n    var buf = p.data;\n    var nb = n > buf.length ? buf.length : n;\n    buf.copy(ret, ret.length - n, 0, nb);\n    n -= nb;\n    if (n === 0) {\n      if (nb === buf.length) {\n        ++c;\n        if (p.next) list.head = p.next;else list.head = list.tail = null;\n      } else {\n        list.head = p;\n        p.data = buf.slice(nb);\n      }\n      break;\n    }\n    ++c;\n  }\n  list.length -= c;\n  return ret;\n}\n\nfunction endReadable(stream) {\n  var state = stream._readableState;\n\n  // If we get here before consuming all the bytes, then that is a\n  // bug in node.  Should never happen.\n  if (state.length > 0) throw new Error('\"endReadable()\" called on non-empty stream');\n\n  if (!state.endEmitted) {\n    state.ended = true;\n    processNextTick(endReadableNT, state, stream);\n  }\n}\n\nfunction endReadableNT(state, stream) {\n  // Check that we didn't get one last unshift.\n  if (!state.endEmitted && state.length === 0) {\n    state.endEmitted = true;\n    stream.readable = false;\n    stream.emit('end');\n  }\n}\n\nfunction forEach(xs, f) {\n  for (var i = 0, l = xs.length; i < l; i++) {\n    f(xs[i], i);\n  }\n}\n\nfunction indexOf(xs, x) {\n  for (var i = 0, l = xs.length; i < l; i++) {\n    if (xs[i] === x) return i;\n  }\n  return -1;\n}\n}).call(this,require('_process'))\n},{\"./_stream_duplex\":44,\"./internal/streams/BufferList\":49,\"_process\":42,\"buffer\":5,\"buffer-shims\":4,\"core-util-is\":6,\"events\":28,\"inherits\":38,\"isarray\":40,\"process-nextick-args\":41,\"string_decoder/\":56,\"util\":3}],47:[function(require,module,exports){\n// a transform stream is a readable/writable stream where you do\n// something with the data.  Sometimes it's called a \"filter\",\n// but that's not a great name for it, since that implies a thing where\n// some bits pass through, and others are simply ignored.  (That would\n// be a valid example of a transform, of course.)\n//\n// While the output is causally related to the input, it's not a\n// necessarily symmetric or synchronous transformation.  For example,\n// a zlib stream might take multiple plain-text writes(), and then\n// emit a single compressed chunk some time in the future.\n//\n// Here's how this works:\n//\n// The Transform stream has all the aspects of the readable and writable\n// stream classes.  When you write(chunk), that calls _write(chunk,cb)\n// internally, and returns false if there's a lot of pending writes\n// buffered up.  When you call read(), that calls _read(n) until\n// there's enough pending readable data buffered up.\n//\n// In a transform stream, the written data is placed in a buffer.  When\n// _read(n) is called, it transforms the queued up data, calling the\n// buffered _write cb's as it consumes chunks.  If consuming a single\n// written chunk would result in multiple output chunks, then the first\n// outputted bit calls the readcb, and subsequent chunks just go into\n// the read buffer, and will cause it to emit 'readable' if necessary.\n//\n// This way, back-pressure is actually determined by the reading side,\n// since _read has to be called to start processing a new chunk.  However,\n// a pathological inflate type of transform can cause excessive buffering\n// here.  For example, imagine a stream where every byte of input is\n// interpreted as an integer from 0-255, and then results in that many\n// bytes of output.  Writing the 4 bytes {ff,ff,ff,ff} would result in\n// 1kb of data being output.  In this case, you could write a very small\n// amount of input, and end up with a very large amount of output.  In\n// such a pathological inflating mechanism, there'd be no way to tell\n// the system to stop doing the transform.  A single 4MB write could\n// cause the system to run out of memory.\n//\n// However, even in such a pathological case, only a single written chunk\n// would be consumed, and then the rest would wait (un-transformed) until\n// the results of the previous transformed chunk were consumed.\n\n'use strict';\n\nmodule.exports = Transform;\n\nvar Duplex = require('./_stream_duplex');\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nutil.inherits(Transform, Duplex);\n\nfunction TransformState(stream) {\n  this.afterTransform = function (er, data) {\n    return afterTransform(stream, er, data);\n  };\n\n  this.needTransform = false;\n  this.transforming = false;\n  this.writecb = null;\n  this.writechunk = null;\n  this.writeencoding = null;\n}\n\nfunction afterTransform(stream, er, data) {\n  var ts = stream._transformState;\n  ts.transforming = false;\n\n  var cb = ts.writecb;\n\n  if (!cb) return stream.emit('error', new Error('no writecb in Transform class'));\n\n  ts.writechunk = null;\n  ts.writecb = null;\n\n  if (data !== null && data !== undefined) stream.push(data);\n\n  cb(er);\n\n  var rs = stream._readableState;\n  rs.reading = false;\n  if (rs.needReadable || rs.length < rs.highWaterMark) {\n    stream._read(rs.highWaterMark);\n  }\n}\n\nfunction Transform(options) {\n  if (!(this instanceof Transform)) return new Transform(options);\n\n  Duplex.call(this, options);\n\n  this._transformState = new TransformState(this);\n\n  // when the writable side finishes, then flush out anything remaining.\n  var stream = this;\n\n  // start out asking for a readable event once data is transformed.\n  this._readableState.needReadable = true;\n\n  // we have implemented the _read method, and done the other things\n  // that Readable wants before the first _read call, so unset the\n  // sync guard flag.\n  this._readableState.sync = false;\n\n  if (options) {\n    if (typeof options.transform === 'function') this._transform = options.transform;\n\n    if (typeof options.flush === 'function') this._flush = options.flush;\n  }\n\n  this.once('prefinish', function () {\n    if (typeof this._flush === 'function') this._flush(function (er) {\n      done(stream, er);\n    });else done(stream);\n  });\n}\n\nTransform.prototype.push = function (chunk, encoding) {\n  this._transformState.needTransform = false;\n  return Duplex.prototype.push.call(this, chunk, encoding);\n};\n\n// This is the part where you do stuff!\n// override this function in implementation classes.\n// 'chunk' is an input chunk.\n//\n// Call `push(newChunk)` to pass along transformed output\n// to the readable side.  You may call 'push' zero or more times.\n//\n// Call `cb(err)` when you are done with this chunk.  If you pass\n// an error, then that'll put the hurt on the whole operation.  If you\n// never call cb(), then you'll never get another chunk.\nTransform.prototype._transform = function (chunk, encoding, cb) {\n  throw new Error('Not implemented');\n};\n\nTransform.prototype._write = function (chunk, encoding, cb) {\n  var ts = this._transformState;\n  ts.writecb = cb;\n  ts.writechunk = chunk;\n  ts.writeencoding = encoding;\n  if (!ts.transforming) {\n    var rs = this._readableState;\n    if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark);\n  }\n};\n\n// Doesn't matter what the args are here.\n// _transform does all the work.\n// That we got here means that the readable side wants more data.\nTransform.prototype._read = function (n) {\n  var ts = this._transformState;\n\n  if (ts.writechunk !== null && ts.writecb && !ts.transforming) {\n    ts.transforming = true;\n    this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);\n  } else {\n    // mark that we need a transform, so that any data that comes in\n    // will get processed, now that we've asked for it.\n    ts.needTransform = true;\n  }\n};\n\nfunction done(stream, er) {\n  if (er) return stream.emit('error', er);\n\n  // if there's nothing in the write buffer, then that means\n  // that nothing more will ever be provided\n  var ws = stream._writableState;\n  var ts = stream._transformState;\n\n  if (ws.length) throw new Error('Calling transform done when ws.length != 0');\n\n  if (ts.transforming) throw new Error('Calling transform done when still transforming');\n\n  return stream.push(null);\n}\n},{\"./_stream_duplex\":44,\"core-util-is\":6,\"inherits\":38}],48:[function(require,module,exports){\n(function (process){\n// A bit simpler than readable streams.\n// Implement an async ._write(chunk, encoding, cb), and it'll handle all\n// the drain event emission and buffering.\n\n'use strict';\n\nmodule.exports = Writable;\n\n/*<replacement>*/\nvar processNextTick = require('process-nextick-args');\n/*</replacement>*/\n\n/*<replacement>*/\nvar asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick;\n/*</replacement>*/\n\nWritable.WritableState = WritableState;\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\n/*<replacement>*/\nvar internalUtil = {\n  deprecate: require('util-deprecate')\n};\n/*</replacement>*/\n\n/*<replacement>*/\nvar Stream;\n(function () {\n  try {\n    Stream = require('st' + 'ream');\n  } catch (_) {} finally {\n    if (!Stream) Stream = require('events').EventEmitter;\n  }\n})();\n/*</replacement>*/\n\nvar Buffer = require('buffer').Buffer;\n/*<replacement>*/\nvar bufferShim = require('buffer-shims');\n/*</replacement>*/\n\nutil.inherits(Writable, Stream);\n\nfunction nop() {}\n\nfunction WriteReq(chunk, encoding, cb) {\n  this.chunk = chunk;\n  this.encoding = encoding;\n  this.callback = cb;\n  this.next = null;\n}\n\nvar Duplex;\nfunction WritableState(options, stream) {\n  Duplex = Duplex || require('./_stream_duplex');\n\n  options = options || {};\n\n  // object stream flag to indicate whether or not this stream\n  // contains buffers or objects.\n  this.objectMode = !!options.objectMode;\n\n  if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode;\n\n  // the point at which write() starts returning false\n  // Note: 0 is a valid value, means that we always return false if\n  // the entire buffer is not flushed immediately on write()\n  var hwm = options.highWaterMark;\n  var defaultHwm = this.objectMode ? 16 : 16 * 1024;\n  this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;\n\n  // cast to ints.\n  this.highWaterMark = ~ ~this.highWaterMark;\n\n  this.needDrain = false;\n  // at the start of calling end()\n  this.ending = false;\n  // when end() has been called, and returned\n  this.ended = false;\n  // when 'finish' is emitted\n  this.finished = false;\n\n  // should we decode strings into buffers before passing to _write?\n  // this is here so that some node-core streams can optimize string\n  // handling at a lower level.\n  var noDecode = options.decodeStrings === false;\n  this.decodeStrings = !noDecode;\n\n  // Crypto is kind of old and crusty.  Historically, its default string\n  // encoding is 'binary' so we have to make this configurable.\n  // Everything else in the universe uses 'utf8', though.\n  this.defaultEncoding = options.defaultEncoding || 'utf8';\n\n  // not an actual buffer we keep track of, but a measurement\n  // of how much we're waiting to get pushed to some underlying\n  // socket or file.\n  this.length = 0;\n\n  // a flag to see when we're in the middle of a write.\n  this.writing = false;\n\n  // when true all writes will be buffered until .uncork() call\n  this.corked = 0;\n\n  // a flag to be able to tell if the onwrite cb is called immediately,\n  // or on a later tick.  We set this to true at first, because any\n  // actions that shouldn't happen until \"later\" should generally also\n  // not happen before the first write call.\n  this.sync = true;\n\n  // a flag to know if we're processing previously buffered items, which\n  // may call the _write() callback in the same tick, so that we don't\n  // end up in an overlapped onwrite situation.\n  this.bufferProcessing = false;\n\n  // the callback that's passed to _write(chunk,cb)\n  this.onwrite = function (er) {\n    onwrite(stream, er);\n  };\n\n  // the callback that the user supplies to write(chunk,encoding,cb)\n  this.writecb = null;\n\n  // the amount that is being written when _write is called.\n  this.writelen = 0;\n\n  this.bufferedRequest = null;\n  this.lastBufferedRequest = null;\n\n  // number of pending user-supplied write callbacks\n  // this must be 0 before 'finish' can be emitted\n  this.pendingcb = 0;\n\n  // emit prefinish if the only thing we're waiting for is _write cbs\n  // This is relevant for synchronous Transform streams\n  this.prefinished = false;\n\n  // True if the error was already emitted and should not be thrown again\n  this.errorEmitted = false;\n\n  // count buffered requests\n  this.bufferedRequestCount = 0;\n\n  // allocate the first CorkedRequest, there is always\n  // one allocated and free to use, and we maintain at most two\n  this.corkedRequestsFree = new CorkedRequest(this);\n}\n\nWritableState.prototype.getBuffer = function writableStateGetBuffer() {\n  var current = this.bufferedRequest;\n  var out = [];\n  while (current) {\n    out.push(current);\n    current = current.next;\n  }\n  return out;\n};\n\n(function () {\n  try {\n    Object.defineProperty(WritableState.prototype, 'buffer', {\n      get: internalUtil.deprecate(function () {\n        return this.getBuffer();\n      }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.')\n    });\n  } catch (_) {}\n})();\n\nvar Duplex;\nfunction Writable(options) {\n  Duplex = Duplex || require('./_stream_duplex');\n\n  // Writable ctor is applied to Duplexes, though they're not\n  // instanceof Writable, they're instanceof Readable.\n  if (!(this instanceof Writable) && !(this instanceof Duplex)) return new Writable(options);\n\n  this._writableState = new WritableState(options, this);\n\n  // legacy.\n  this.writable = true;\n\n  if (options) {\n    if (typeof options.write === 'function') this._write = options.write;\n\n    if (typeof options.writev === 'function') this._writev = options.writev;\n  }\n\n  Stream.call(this);\n}\n\n// Otherwise people can pipe Writable streams, which is just wrong.\nWritable.prototype.pipe = function () {\n  this.emit('error', new Error('Cannot pipe, not readable'));\n};\n\nfunction writeAfterEnd(stream, cb) {\n  var er = new Error('write after end');\n  // TODO: defer error events consistently everywhere, not just the cb\n  stream.emit('error', er);\n  processNextTick(cb, er);\n}\n\n// If we get something that is not a buffer, string, null, or undefined,\n// and we're not in objectMode, then that's an error.\n// Otherwise stream chunks are all considered to be of length=1, and the\n// watermarks determine how many objects to keep in the buffer, rather than\n// how many bytes or characters.\nfunction validChunk(stream, state, chunk, cb) {\n  var valid = true;\n  var er = false;\n  // Always throw error if a null is written\n  // if we are not in object mode then throw\n  // if it is not a buffer, string, or undefined.\n  if (chunk === null) {\n    er = new TypeError('May not write null values to stream');\n  } else if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) {\n    er = new TypeError('Invalid non-string/buffer chunk');\n  }\n  if (er) {\n    stream.emit('error', er);\n    processNextTick(cb, er);\n    valid = false;\n  }\n  return valid;\n}\n\nWritable.prototype.write = function (chunk, encoding, cb) {\n  var state = this._writableState;\n  var ret = false;\n\n  if (typeof encoding === 'function') {\n    cb = encoding;\n    encoding = null;\n  }\n\n  if (Buffer.isBuffer(chunk)) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;\n\n  if (typeof cb !== 'function') cb = nop;\n\n  if (state.ended) writeAfterEnd(this, cb);else if (validChunk(this, state, chunk, cb)) {\n    state.pendingcb++;\n    ret = writeOrBuffer(this, state, chunk, encoding, cb);\n  }\n\n  return ret;\n};\n\nWritable.prototype.cork = function () {\n  var state = this._writableState;\n\n  state.corked++;\n};\n\nWritable.prototype.uncork = function () {\n  var state = this._writableState;\n\n  if (state.corked) {\n    state.corked--;\n\n    if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);\n  }\n};\n\nWritable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {\n  // node::ParseEncoding() requires lower case.\n  if (typeof encoding === 'string') encoding = encoding.toLowerCase();\n  if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding);\n  this._writableState.defaultEncoding = encoding;\n  return this;\n};\n\nfunction decodeChunk(state, chunk, encoding) {\n  if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {\n    chunk = bufferShim.from(chunk, encoding);\n  }\n  return chunk;\n}\n\n// if we're already writing something, then just put this\n// in the queue, and wait our turn.  Otherwise, call _write\n// If we return false, then we need a drain event, so set that flag.\nfunction writeOrBuffer(stream, state, chunk, encoding, cb) {\n  chunk = decodeChunk(state, chunk, encoding);\n\n  if (Buffer.isBuffer(chunk)) encoding = 'buffer';\n  var len = state.objectMode ? 1 : chunk.length;\n\n  state.length += len;\n\n  var ret = state.length < state.highWaterMark;\n  // we must ensure that previous needDrain will not be reset to false.\n  if (!ret) state.needDrain = true;\n\n  if (state.writing || state.corked) {\n    var last = state.lastBufferedRequest;\n    state.lastBufferedRequest = new WriteReq(chunk, encoding, cb);\n    if (last) {\n      last.next = state.lastBufferedRequest;\n    } else {\n      state.bufferedRequest = state.lastBufferedRequest;\n    }\n    state.bufferedRequestCount += 1;\n  } else {\n    doWrite(stream, state, false, len, chunk, encoding, cb);\n  }\n\n  return ret;\n}\n\nfunction doWrite(stream, state, writev, len, chunk, encoding, cb) {\n  state.writelen = len;\n  state.writecb = cb;\n  state.writing = true;\n  state.sync = true;\n  if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);\n  state.sync = false;\n}\n\nfunction onwriteError(stream, state, sync, er, cb) {\n  --state.pendingcb;\n  if (sync) processNextTick(cb, er);else cb(er);\n\n  stream._writableState.errorEmitted = true;\n  stream.emit('error', er);\n}\n\nfunction onwriteStateUpdate(state) {\n  state.writing = false;\n  state.writecb = null;\n  state.length -= state.writelen;\n  state.writelen = 0;\n}\n\nfunction onwrite(stream, er) {\n  var state = stream._writableState;\n  var sync = state.sync;\n  var cb = state.writecb;\n\n  onwriteStateUpdate(state);\n\n  if (er) onwriteError(stream, state, sync, er, cb);else {\n    // Check if we're actually ready to finish, but don't emit yet\n    var finished = needFinish(state);\n\n    if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {\n      clearBuffer(stream, state);\n    }\n\n    if (sync) {\n      /*<replacement>*/\n      asyncWrite(afterWrite, stream, state, finished, cb);\n      /*</replacement>*/\n    } else {\n        afterWrite(stream, state, finished, cb);\n      }\n  }\n}\n\nfunction afterWrite(stream, state, finished, cb) {\n  if (!finished) onwriteDrain(stream, state);\n  state.pendingcb--;\n  cb();\n  finishMaybe(stream, state);\n}\n\n// Must force callback to be called on nextTick, so that we don't\n// emit 'drain' before the write() consumer gets the 'false' return\n// value, and has a chance to attach a 'drain' listener.\nfunction onwriteDrain(stream, state) {\n  if (state.length === 0 && state.needDrain) {\n    state.needDrain = false;\n    stream.emit('drain');\n  }\n}\n\n// if there's something in the buffer waiting, then process it\nfunction clearBuffer(stream, state) {\n  state.bufferProcessing = true;\n  var entry = state.bufferedRequest;\n\n  if (stream._writev && entry && entry.next) {\n    // Fast case, write everything using _writev()\n    var l = state.bufferedRequestCount;\n    var buffer = new Array(l);\n    var holder = state.corkedRequestsFree;\n    holder.entry = entry;\n\n    var count = 0;\n    while (entry) {\n      buffer[count] = entry;\n      entry = entry.next;\n      count += 1;\n    }\n\n    doWrite(stream, state, true, state.length, buffer, '', holder.finish);\n\n    // doWrite is almost always async, defer these to save a bit of time\n    // as the hot path ends with doWrite\n    state.pendingcb++;\n    state.lastBufferedRequest = null;\n    if (holder.next) {\n      state.corkedRequestsFree = holder.next;\n      holder.next = null;\n    } else {\n      state.corkedRequestsFree = new CorkedRequest(state);\n    }\n  } else {\n    // Slow case, write chunks one-by-one\n    while (entry) {\n      var chunk = entry.chunk;\n      var encoding = entry.encoding;\n      var cb = entry.callback;\n      var len = state.objectMode ? 1 : chunk.length;\n\n      doWrite(stream, state, false, len, chunk, encoding, cb);\n      entry = entry.next;\n      // if we didn't call the onwrite immediately, then\n      // it means that we need to wait until it does.\n      // also, that means that the chunk and cb are currently\n      // being processed, so move the buffer counter past them.\n      if (state.writing) {\n        break;\n      }\n    }\n\n    if (entry === null) state.lastBufferedRequest = null;\n  }\n\n  state.bufferedRequestCount = 0;\n  state.bufferedRequest = entry;\n  state.bufferProcessing = false;\n}\n\nWritable.prototype._write = function (chunk, encoding, cb) {\n  cb(new Error('not implemented'));\n};\n\nWritable.prototype._writev = null;\n\nWritable.prototype.end = function (chunk, encoding, cb) {\n  var state = this._writableState;\n\n  if (typeof chunk === 'function') {\n    cb = chunk;\n    chunk = null;\n    encoding = null;\n  } else if (typeof encoding === 'function') {\n    cb = encoding;\n    encoding = null;\n  }\n\n  if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);\n\n  // .end() fully uncorks\n  if (state.corked) {\n    state.corked = 1;\n    this.uncork();\n  }\n\n  // ignore unnecessary end() calls.\n  if (!state.ending && !state.finished) endWritable(this, state, cb);\n};\n\nfunction needFinish(state) {\n  return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;\n}\n\nfunction prefinish(stream, state) {\n  if (!state.prefinished) {\n    state.prefinished = true;\n    stream.emit('prefinish');\n  }\n}\n\nfunction finishMaybe(stream, state) {\n  var need = needFinish(state);\n  if (need) {\n    if (state.pendingcb === 0) {\n      prefinish(stream, state);\n      state.finished = true;\n      stream.emit('finish');\n    } else {\n      prefinish(stream, state);\n    }\n  }\n  return need;\n}\n\nfunction endWritable(stream, state, cb) {\n  state.ending = true;\n  finishMaybe(stream, state);\n  if (cb) {\n    if (state.finished) processNextTick(cb);else stream.once('finish', cb);\n  }\n  state.ended = true;\n  stream.writable = false;\n}\n\n// It seems a linked list but it is not\n// there will be only 2 of these for each stream\nfunction CorkedRequest(state) {\n  var _this = this;\n\n  this.next = null;\n  this.entry = null;\n\n  this.finish = function (err) {\n    var entry = _this.entry;\n    _this.entry = null;\n    while (entry) {\n      var cb = entry.callback;\n      state.pendingcb--;\n      cb(err);\n      entry = entry.next;\n    }\n    if (state.corkedRequestsFree) {\n      state.corkedRequestsFree.next = _this;\n    } else {\n      state.corkedRequestsFree = _this;\n    }\n  };\n}\n}).call(this,require('_process'))\n},{\"./_stream_duplex\":44,\"_process\":42,\"buffer\":5,\"buffer-shims\":4,\"core-util-is\":6,\"events\":28,\"inherits\":38,\"process-nextick-args\":41,\"util-deprecate\":57}],49:[function(require,module,exports){\n'use strict';\n\nvar Buffer = require('buffer').Buffer;\n/*<replacement>*/\nvar bufferShim = require('buffer-shims');\n/*</replacement>*/\n\nmodule.exports = BufferList;\n\nfunction BufferList() {\n  this.head = null;\n  this.tail = null;\n  this.length = 0;\n}\n\nBufferList.prototype.push = function (v) {\n  var entry = { data: v, next: null };\n  if (this.length > 0) this.tail.next = entry;else this.head = entry;\n  this.tail = entry;\n  ++this.length;\n};\n\nBufferList.prototype.unshift = function (v) {\n  var entry = { data: v, next: this.head };\n  if (this.length === 0) this.tail = entry;\n  this.head = entry;\n  ++this.length;\n};\n\nBufferList.prototype.shift = function () {\n  if (this.length === 0) return;\n  var ret = this.head.data;\n  if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next;\n  --this.length;\n  return ret;\n};\n\nBufferList.prototype.clear = function () {\n  this.head = this.tail = null;\n  this.length = 0;\n};\n\nBufferList.prototype.join = function (s) {\n  if (this.length === 0) return '';\n  var p = this.head;\n  var ret = '' + p.data;\n  while (p = p.next) {\n    ret += s + p.data;\n  }return ret;\n};\n\nBufferList.prototype.concat = function (n) {\n  if (this.length === 0) return bufferShim.alloc(0);\n  if (this.length === 1) return this.head.data;\n  var ret = bufferShim.allocUnsafe(n >>> 0);\n  var p = this.head;\n  var i = 0;\n  while (p) {\n    p.data.copy(ret, i);\n    i += p.data.length;\n    p = p.next;\n  }\n  return ret;\n};\n},{\"buffer\":5,\"buffer-shims\":4}],50:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_passthrough.js\")\n\n},{\"./lib/_stream_passthrough.js\":45}],51:[function(require,module,exports){\n(function (process){\nvar Stream = (function (){\n  try {\n    return require('st' + 'ream'); // hack to fix a circular dependency issue when used with browserify\n  } catch(_){}\n}());\nexports = module.exports = require('./lib/_stream_readable.js');\nexports.Stream = Stream || exports;\nexports.Readable = exports;\nexports.Writable = require('./lib/_stream_writable.js');\nexports.Duplex = require('./lib/_stream_duplex.js');\nexports.Transform = require('./lib/_stream_transform.js');\nexports.PassThrough = require('./lib/_stream_passthrough.js');\n\nif (!process.browser && process.env.READABLE_STREAM === 'disable' && Stream) {\n  module.exports = Stream;\n}\n\n}).call(this,require('_process'))\n},{\"./lib/_stream_duplex.js\":44,\"./lib/_stream_passthrough.js\":45,\"./lib/_stream_readable.js\":46,\"./lib/_stream_transform.js\":47,\"./lib/_stream_writable.js\":48,\"_process\":42}],52:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_transform.js\")\n\n},{\"./lib/_stream_transform.js\":47}],53:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_writable.js\")\n\n},{\"./lib/_stream_writable.js\":48}],54:[function(require,module,exports){\nmodule.exports = function (string) {\n  return string.replace(/[-\\\\^$*+?.()|[\\]{}]/g, \"\\\\$&\")\n}\n\n},{}],55:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nmodule.exports = Stream;\n\nvar EE = require('events').EventEmitter;\nvar inherits = require('inherits');\n\ninherits(Stream, EE);\nStream.Readable = require('readable-stream/readable.js');\nStream.Writable = require('readable-stream/writable.js');\nStream.Duplex = require('readable-stream/duplex.js');\nStream.Transform = require('readable-stream/transform.js');\nStream.PassThrough = require('readable-stream/passthrough.js');\n\n// Backwards-compat with node 0.4.x\nStream.Stream = Stream;\n\n\n\n// old-style streams.  Note that the pipe method (the only relevant\n// part of this class) is overridden in the Readable class.\n\nfunction Stream() {\n  EE.call(this);\n}\n\nStream.prototype.pipe = function(dest, options) {\n  var source = this;\n\n  function ondata(chunk) {\n    if (dest.writable) {\n      if (false === dest.write(chunk) && source.pause) {\n        source.pause();\n      }\n    }\n  }\n\n  source.on('data', ondata);\n\n  function ondrain() {\n    if (source.readable && source.resume) {\n      source.resume();\n    }\n  }\n\n  dest.on('drain', ondrain);\n\n  // If the 'end' option is not supplied, dest.end() will be called when\n  // source gets the 'end' or 'close' events.  Only dest.end() once.\n  if (!dest._isStdio && (!options || options.end !== false)) {\n    source.on('end', onend);\n    source.on('close', onclose);\n  }\n\n  var didOnEnd = false;\n  function onend() {\n    if (didOnEnd) return;\n    didOnEnd = true;\n\n    dest.end();\n  }\n\n\n  function onclose() {\n    if (didOnEnd) return;\n    didOnEnd = true;\n\n    if (typeof dest.destroy === 'function') dest.destroy();\n  }\n\n  // don't leave dangling pipes when there are errors.\n  function onerror(er) {\n    cleanup();\n    if (EE.listenerCount(this, 'error') === 0) {\n      throw er; // Unhandled stream error in pipe.\n    }\n  }\n\n  source.on('error', onerror);\n  dest.on('error', onerror);\n\n  // remove all the event listeners that were added.\n  function cleanup() {\n    source.removeListener('data', ondata);\n    dest.removeListener('drain', ondrain);\n\n    source.removeListener('end', onend);\n    source.removeListener('close', onclose);\n\n    source.removeListener('error', onerror);\n    dest.removeListener('error', onerror);\n\n    source.removeListener('end', cleanup);\n    source.removeListener('close', cleanup);\n\n    dest.removeListener('close', cleanup);\n  }\n\n  source.on('end', cleanup);\n  source.on('close', cleanup);\n\n  dest.on('close', cleanup);\n\n  dest.emit('pipe', source);\n\n  // Allow for unix-like usage: A.pipe(B).pipe(C)\n  return dest;\n};\n\n},{\"events\":28,\"inherits\":38,\"readable-stream/duplex.js\":43,\"readable-stream/passthrough.js\":50,\"readable-stream/readable.js\":51,\"readable-stream/transform.js\":52,\"readable-stream/writable.js\":53}],56:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nvar Buffer = require('buffer').Buffer;\n\nvar isBufferEncoding = Buffer.isEncoding\n  || function(encoding) {\n       switch (encoding && encoding.toLowerCase()) {\n         case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true;\n         default: return false;\n       }\n     }\n\n\nfunction assertEncoding(encoding) {\n  if (encoding && !isBufferEncoding(encoding)) {\n    throw new Error('Unknown encoding: ' + encoding);\n  }\n}\n\n// StringDecoder provides an interface for efficiently splitting a series of\n// buffers into a series of JS strings without breaking apart multi-byte\n// characters. CESU-8 is handled as part of the UTF-8 encoding.\n//\n// @TODO Handling all encodings inside a single object makes it very difficult\n// to reason about this code, so it should be split up in the future.\n// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code\n// points as used by CESU-8.\nvar StringDecoder = exports.StringDecoder = function(encoding) {\n  this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, '');\n  assertEncoding(encoding);\n  switch (this.encoding) {\n    case 'utf8':\n      // CESU-8 represents each of Surrogate Pair by 3-bytes\n      this.surrogateSize = 3;\n      break;\n    case 'ucs2':\n    case 'utf16le':\n      // UTF-16 represents each of Surrogate Pair by 2-bytes\n      this.surrogateSize = 2;\n      this.detectIncompleteChar = utf16DetectIncompleteChar;\n      break;\n    case 'base64':\n      // Base-64 stores 3 bytes in 4 chars, and pads the remainder.\n      this.surrogateSize = 3;\n      this.detectIncompleteChar = base64DetectIncompleteChar;\n      break;\n    default:\n      this.write = passThroughWrite;\n      return;\n  }\n\n  // Enough space to store all bytes of a single character. UTF-8 needs 4\n  // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate).\n  this.charBuffer = new Buffer(6);\n  // Number of bytes received for the current incomplete multi-byte character.\n  this.charReceived = 0;\n  // Number of bytes expected for the current incomplete multi-byte character.\n  this.charLength = 0;\n};\n\n\n// write decodes the given buffer and returns it as JS string that is\n// guaranteed to not contain any partial multi-byte characters. Any partial\n// character found at the end of the buffer is buffered up, and will be\n// returned when calling write again with the remaining bytes.\n//\n// Note: Converting a Buffer containing an orphan surrogate to a String\n// currently works, but converting a String to a Buffer (via `new Buffer`, or\n// Buffer#write) will replace incomplete surrogates with the unicode\n// replacement character. See https://codereview.chromium.org/121173009/ .\nStringDecoder.prototype.write = function(buffer) {\n  var charStr = '';\n  // if our last write ended with an incomplete multibyte character\n  while (this.charLength) {\n    // determine how many remaining bytes this buffer has to offer for this char\n    var available = (buffer.length >= this.charLength - this.charReceived) ?\n        this.charLength - this.charReceived :\n        buffer.length;\n\n    // add the new bytes to the char buffer\n    buffer.copy(this.charBuffer, this.charReceived, 0, available);\n    this.charReceived += available;\n\n    if (this.charReceived < this.charLength) {\n      // still not enough chars in this buffer? wait for more ...\n      return '';\n    }\n\n    // remove bytes belonging to the current character from the buffer\n    buffer = buffer.slice(available, buffer.length);\n\n    // get the character that was split\n    charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding);\n\n    // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character\n    var charCode = charStr.charCodeAt(charStr.length - 1);\n    if (charCode >= 0xD800 && charCode <= 0xDBFF) {\n      this.charLength += this.surrogateSize;\n      charStr = '';\n      continue;\n    }\n    this.charReceived = this.charLength = 0;\n\n    // if there are no more bytes in this buffer, just emit our char\n    if (buffer.length === 0) {\n      return charStr;\n    }\n    break;\n  }\n\n  // determine and set charLength / charReceived\n  this.detectIncompleteChar(buffer);\n\n  var end = buffer.length;\n  if (this.charLength) {\n    // buffer the incomplete character bytes we got\n    buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end);\n    end -= this.charReceived;\n  }\n\n  charStr += buffer.toString(this.encoding, 0, end);\n\n  var end = charStr.length - 1;\n  var charCode = charStr.charCodeAt(end);\n  // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character\n  if (charCode >= 0xD800 && charCode <= 0xDBFF) {\n    var size = this.surrogateSize;\n    this.charLength += size;\n    this.charReceived += size;\n    this.charBuffer.copy(this.charBuffer, size, 0, size);\n    buffer.copy(this.charBuffer, 0, 0, size);\n    return charStr.substring(0, end);\n  }\n\n  // or just emit the charStr\n  return charStr;\n};\n\n// detectIncompleteChar determines if there is an incomplete UTF-8 character at\n// the end of the given buffer. If so, it sets this.charLength to the byte\n// length that character, and sets this.charReceived to the number of bytes\n// that are available for this character.\nStringDecoder.prototype.detectIncompleteChar = function(buffer) {\n  // determine how many bytes we have to check at the end of this buffer\n  var i = (buffer.length >= 3) ? 3 : buffer.length;\n\n  // Figure out if one of the last i bytes of our buffer announces an\n  // incomplete char.\n  for (; i > 0; i--) {\n    var c = buffer[buffer.length - i];\n\n    // See http://en.wikipedia.org/wiki/UTF-8#Description\n\n    // 110XXXXX\n    if (i == 1 && c >> 5 == 0x06) {\n      this.charLength = 2;\n      break;\n    }\n\n    // 1110XXXX\n    if (i <= 2 && c >> 4 == 0x0E) {\n      this.charLength = 3;\n      break;\n    }\n\n    // 11110XXX\n    if (i <= 3 && c >> 3 == 0x1E) {\n      this.charLength = 4;\n      break;\n    }\n  }\n  this.charReceived = i;\n};\n\nStringDecoder.prototype.end = function(buffer) {\n  var res = '';\n  if (buffer && buffer.length)\n    res = this.write(buffer);\n\n  if (this.charReceived) {\n    var cr = this.charReceived;\n    var buf = this.charBuffer;\n    var enc = this.encoding;\n    res += buf.slice(0, cr).toString(enc);\n  }\n\n  return res;\n};\n\nfunction passThroughWrite(buffer) {\n  return buffer.toString(this.encoding);\n}\n\nfunction utf16DetectIncompleteChar(buffer) {\n  this.charReceived = buffer.length % 2;\n  this.charLength = this.charReceived ? 2 : 0;\n}\n\nfunction base64DetectIncompleteChar(buffer) {\n  this.charReceived = buffer.length % 3;\n  this.charLength = this.charReceived ? 3 : 0;\n}\n\n},{\"buffer\":5}],57:[function(require,module,exports){\n(function (global){\n\n/**\n * Module exports.\n */\n\nmodule.exports = deprecate;\n\n/**\n * Mark that a method should not be used.\n * Returns a modified function which warns once by default.\n *\n * If `localStorage.noDeprecation = true` is set, then it is a no-op.\n *\n * If `localStorage.throwDeprecation = true` is set, then deprecated functions\n * will throw an Error when invoked.\n *\n * If `localStorage.traceDeprecation = true` is set, then deprecated functions\n * will invoke `console.trace()` instead of `console.error()`.\n *\n * @param {Function} fn - the function to deprecate\n * @param {String} msg - the string to print to the console when `fn` is invoked\n * @returns {Function} a new \"deprecated\" version of `fn`\n * @api public\n */\n\nfunction deprecate (fn, msg) {\n  if (config('noDeprecation')) {\n    return fn;\n  }\n\n  var warned = false;\n  function deprecated() {\n    if (!warned) {\n      if (config('throwDeprecation')) {\n        throw new Error(msg);\n      } else if (config('traceDeprecation')) {\n        console.trace(msg);\n      } else {\n        console.warn(msg);\n      }\n      warned = true;\n    }\n    return fn.apply(this, arguments);\n  }\n\n  return deprecated;\n}\n\n/**\n * Checks `localStorage` for boolean values for the given `name`.\n *\n * @param {String} name\n * @returns {Boolean}\n * @api private\n */\n\nfunction config (name) {\n  // accessing global.localStorage can trigger a DOMException in sandboxed iframes\n  try {\n    if (!global.localStorage) return false;\n  } catch (_) {\n    return false;\n  }\n  var val = global.localStorage[name];\n  if (null == val) return false;\n  return String(val).toLowerCase() === 'true';\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],58:[function(require,module,exports){\nmodule.exports = extend\n\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n\nfunction extend() {\n    var target = {}\n\n    for (var i = 0; i < arguments.length; i++) {\n        var source = arguments[i]\n\n        for (var key in source) {\n            if (hasOwnProperty.call(source, key)) {\n                target[key] = source[key]\n            }\n        }\n    }\n\n    return target\n}\n\n},{}]},{},[1])(1)\n});"
  },
  {
    "path": "background.js",
    "content": "'use strict';\n\nchrome.runtime.onMessage.addListener(function (req, sender, sendResponse) {\n\n    var handler = {\n\n        /**\n         * Gets all the opened tabs\n         *\n         * @returns {boolean}\n         */\n        getTabs: function () {\n            chrome.tabs.query({}, function (tabs) {\n                sendResponse(tabs);\n            });\n\n            return true;\n        },\n\n        /**\n         * Switches the browser tab to the one with required tabId\n         *\n         * @param params\n         * @returns {boolean}\n         */\n        switchTab: function (params) {\n            chrome.tabs.update(params.tabId, {active: true}, function () {\n                chrome.windows.update(params.windowId, {focused: true});\n            });\n\n            return true;\n        },\n\n        /**\n         * Toggle pinned state of the the currently selected browser tab\n         */\n        togglePin: function (params) {\n            chrome.tabs.get(params.tabId, function (tab) {\n                chrome.tabs.update(params.tabId, {pinned: !tab.pinned}, function () {\n                    chrome.windows.update(params.windowId, {focused: true});\n                    return true;\n                });\n                return true;\n            });\n\n            return true;\n        },\n\n        /**\n         * Closes the tab with passed tabId\n         *\n         * @param params\n         * @returns {boolean}\n         */\n        closeTab: function (params) {\n            chrome.tabs.remove(params.tabId);\n            return true;\n        }\n\n    };\n\n    return handler[req.type](req.params);\n\n});\n\nchrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {\n\n    if (changeInfo.status !== 'loading')\n        return;\n\n    // Inject the required assets\n    chrome.tabs.executeScript(tabId, {\n        code: 'var injected = window.tabSwitcherInjected; window.tabSwitcherInjected = true; injected;',\n        runAt: 'document_start'\n    }, function (res) {\n\n        if (chrome.runtime.lastError ||  // don't continue if error\n            res[0]) // value of `injected` above: don't inject twice\n            return;\n\n        var cssFiles = [\n                'assets/css/tab-switcher.css'\n            ],\n            jsFiles = [\n                'assets/lib/sanitize-html.js',\n                'assets/lib/jquery.js',\n                'assets/lib/keymaster.js',\n                'tab-switcher.js'\n            ];\n\n        eachTask([function (cb) {\n            return eachItem(cssFiles, inject('insertCSS'), cb);\n        }, function (cb) {\n            return eachItem(jsFiles, inject('executeScript'), cb);\n        }]);\n\n        function inject(fn) {\n            return function (file, cb) {\n                chrome.tabs[fn](tabId, {file: file, runAt: 'document_start'}, cb);\n            };\n        }\n    });\n\n});\n\nfunction eachTask(tasks, done) {\n    (function next() {\n        var index = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0];\n\n        if (index === tasks.length) {\n            done && done();\n        } else {\n            tasks[index](function () {\n                return next(++index);\n            });\n        }\n    })();\n}\n\nfunction eachItem(arr, iter, done) {\n    var tasks = arr.map(function (item) {\n        return function (cb) {\n            return iter(item, cb);\n        };\n    });\n    return eachTask(tasks, done);\n}\n"
  },
  {
    "path": "manifest.json",
    "content": "{\n  \"name\": \"TabSwitcher\",\n  \"short_name\": \"TabSwitcher\",\n  \"version\": \"1.0.1\",\n  \"manifest_version\": 2,\n  \"author\": \"Kamran Ahmed\",\n  \"description\": \"Switch between the tabs with ease\",\n  \"homepage_url\": \"https://github.com/kamranahmedse/tab-switcher\",\n  \"icons\": {\n    \"16\": \"assets/icons/icon16.png\",\n    \"48\": \"assets/icons/icon48.png\",\n    \"128\": \"assets/icons/icon128.png\"\n  },\n  \"permissions\": [\n    \"tabs\",\n    \"http://*/*\",\n    \"https://*/*\",\n    \"<all_urls>\"\n  ],\n  \"background\": {\n    \"scripts\": [\n      \"background.js\"\n    ],\n    \"persistent\": false\n  },\n  \"browser_action\": {\n    \"default_title\": \"TabSwitcher\",\n    \"default_icon\": \"assets/icons/icon128.png\"\n  }\n}\n"
  },
  {
    "path": "tab-switcher.js",
    "content": "'use strict';\n\n/**\n * TabSwitcher\n *\n * This file is part of the TabSwitcher; an opensource Google Chrome extension\n * http://github.com/kamranahmedse/tab-switcher\n *\n * MIT (c) Kamran Ahmed <kamranahmed.se@gmail.com>\n */\n(function(){\n\n    /**\n     * Configuration constants for the extension\n     *\n     * @type {Object}\n     */\n    var Config = {\n\n        // Default favicon to use\n        DEFAULT_FAVICON: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAAMklEQVR4AWMgEkT9R4INWBUgKX0Q1YBXQYQCkhKEMDILogSnAhhEV4AGRqoCTEhkPAMAbO9DU+cdCDkAAAAASUVORK5CYII=',\n\n        // Templates\n        MAIN_TEMPLATE :'<div class=\"tab-switcher\" style=\"display: none;\">' +\n        '<input type=\"text\">' +\n        '<ul class=\"tabs-list\">' +\n        '</ul>' +\n        '</div>',\n\n        TAB_TEMPLATE  : '<li data-tab-id=\"{id}\" data-window-id=\"{windowId}\" class=\"tab-item\">' +\n        '<span class=\"favicon-img\">' +\n        '<img src=\"{favicon}\" onerror=\"this.src=\\'{default_favicon}\\';\">' +\n        '</span>' +\n        '<span class=\"title\">{title}</span>' +\n        '</li>',\n\n        // References to DOM elements\n        SELECTED_CLASS: 'selected-tab',\n        TAB_SELECTED  : '.selected-tab',\n        FAVICON_IMG   : '.favicon-img img',\n        TAB_SWITCHER  : '.tab-switcher',\n        TAB_LIST      : '.tab-switcher .tabs-list',\n        TAB_ITEM      : '.tab-item',\n        TAB_INPUT     : '.tab-switcher input[type=\"text\"]',\n        TAB_SWITCHER_CONTAINER: 'body',\n\n        // Shortcut for activation\n        MASTER_KEY    : '⌘+⇧+k, ⌃+⇧+k',\n\n        // Key codes for certain actions\n        DOWN_KEY      : 40,\n        UP_KEY        : 38,\n        ESCAPE_KEY    : 27,\n        ENTER_KEY     : 13,\n        SEMICOLON_KEY : 186,\n        COMMA_KEY     : 188,\n\n        // Actions\n        GOING_UP      : 'going_up',\n        GOING_DOWN    : 'going_down',\n        ESCAPING      : 'escaping',\n        SWITCHING     : 'switching',\n        CLOSING       : 'closing',\n        PINNING       : 'pinning'\n    };\n\n    /**\n     * Houses all the browser related actions\n     *\n     * @type {Object}\n     */\n    var BrowserTab = {\n\n        /**\n         * Houses all the tabs, once fetched\n         *\n         * @param array\n         */\n        allTabs: [],\n\n        /**\n         * Closes the tab whose tabId is passed\n         *\n         * @param tabId\n         * @returns {boolean}\n         */\n        close: function (tabId) {\n            chrome.extension.sendMessage({\n                type: 'closeTab',\n                params: {\n                    tabId: tabId\n                }\n            }, function(res) {});\n\n            return true;\n        },\n\n        /**\n         * Switches to the specified tab\n         *\n         * @param tabId\n         * @param windowId\n         */\n        switch: function (tabId, windowId) {\n            chrome.extension.sendMessage({\n                type: 'switchTab',\n                params: {\n                    tabId: tabId,\n                    windowId: windowId\n                }\n            }, function(res) {});\n        },\n\n        /**\n         * Toggles pin state to the specified tab\n         *\n         * @param tabId\n         * @param windowId\n         */\n        togglePin: function (tabId, windowId) {\n            chrome.extension.sendMessage({\n                type: 'togglePin',\n                params: {\n                    tabId: tabId,\n                    windowId: windowId\n                }\n            }, function(res) {});\n        },\n\n        /**\n         * Gets all the tabs that are opened\n         *\n         * @param callback Function which will be called whilst passing the tabs\n         */\n        getAll: function (callback) {\n            chrome.extension.sendMessage({ type: 'getTabs' }, function(tabs) {\n                if (!tabs) {\n                    return false;\n                }\n\n                // Cache the tabs, this is the list, we will be filtering\n                BrowserTab.allTabs = tabs;\n\n                callback(tabs);\n            });\n        }\n    };\n\n    /**\n     * Main extension class\n     *\n     * @returns {{loadExtension: loadExtension, bindUI: bindUI}}\n     * @constructor\n     */\n    function TabSwitcher() {\n\n        /**\n         * Populates the tabs\n         * @param tabs\n         */\n        function populateTabs(tabs) {\n            var tabsHtml = getTabsHtml(tabs);\n\n            $(Config.TAB_LIST).html(tabsHtml);\n            $(Config.TAB_ITEM).first().addClass(Config.SELECTED_CLASS);\n        }\n\n        /**\n         * Hides the switcher input and list\n         */\n        function hideSwitcher() {\n            $(Config.TAB_SWITCHER).hide();\n            $(Config.TAB_INPUT).val('');\n        }\n\n        /**\n         * Gets the action to be performed for the given keycode\n         *\n         * @param keyCode\n         * @returns {*}\n         */\n        function getSwitcherAction(keyCode) {\n            switch (keyCode) {\n                case Config.UP_KEY:\n                    return Config.GOING_UP;\n                case Config.DOWN_KEY:\n                    return Config.GOING_DOWN;\n                case Config.ESCAPE_KEY:\n                    return Config.ESCAPING;\n                case Config.ENTER_KEY:\n                    return Config.SWITCHING;\n                case Config.SEMICOLON_KEY:\n                    return Config.CLOSING;\n                case Config.COMMA_KEY:\n                    return Config.PINNING;\n                default:\n                    return false;\n            }\n        }\n\n        /**\n         * Moves the focus for the selected tab for the passed action\n         *\n         * @param action\n         */\n        function moveTabFocus(action) {\n\n            var $firstSelected  = $(Config.TAB_SELECTED);\n\n            // If some tab was already selected\n            if ($firstSelected.length !== 0 ) {\n\n                // Make it unselected\n                $firstSelected.removeClass(Config.SELECTED_CLASS);\n\n                var $toSelect = null;\n\n                if (action === Config.GOING_DOWN) {\n                    var $nextSelected = $firstSelected.next(Config.TAB_ITEM);\n                    $toSelect         = $nextSelected.length !== 0 ? $nextSelected : $(Config.TAB_ITEM).first();\n                } else if (action === Config.GOING_UP) {\n                    var $prevSelected = $firstSelected.prev(Config.TAB_ITEM);\n                    $toSelect = $prevSelected.length !== 0 ? $prevSelected : $(Config.TAB_ITEM).last();\n                }\n\n                $nextSelected = $toSelect.addClass(Config.SELECTED_CLASS);\n            } else {\n                $nextSelected = $(Config.TAB_ITEM).first().addClass(Config.SELECTED_CLASS);\n            }\n\n            $nextSelected.get(0).scrollIntoViewIfNeeded();\n        }\n\n        /**\n         * Closes the tab having focus\n         */\n        function closeSelectedTab() {\n            var $firstSelected = $(Config.TAB_SWITCHER).find(Config.TAB_SELECTED).first();\n\n            if (BrowserTab.close($firstSelected.data('tabId'))) {\n                $firstSelected.remove();\n                $(Config.TAB_ITEM).first().addClass(Config.SELECTED_CLASS);\n            }\n        }\n\n        /**\n         * Switches the browser to the currently focused tab\n         */\n        function switchSelectedTab() {\n            var $firstSelected = $(Config.TAB_SWITCHER).find(Config.TAB_SELECTED).first();\n            BrowserTab.switch($firstSelected.data('tabId'), $firstSelected.data('windowId'));\n        }\n\n        /**\n         * Toggles pinned state of the tab currently focused\n         */\n        function togglePinTab() {\n            var $firstSelected = $(Config.TAB_SWITCHER).find(Config.TAB_SELECTED).first();\n            BrowserTab.togglePin($firstSelected.data('tabId'), $firstSelected.data('windowId'));\n        }\n\n        /**\n         * Performs the action for the passed keypress event\n         *\n         * @param event\n         */\n        function handleKeyPress(event) {\n\n            var action = getSwitcherAction(event.keyCode);\n\n            switch (action) {\n                case Config.GOING_UP:\n                case Config.GOING_DOWN:\n                    moveTabFocus(action);\n                    break;\n                case Config.ESCAPING:\n                    $(Config.TAB_SWITCHER).hide();\n                    break;\n                case Config.CLOSING:\n                    // Because we are using `;` to close so prevent entering\n                    event.preventDefault();\n                    closeSelectedTab();\n                    break;\n                case Config.PINNING:\n                    event.preventDefault();\n                    togglePinTab();\n                    break;\n                case Config.SWITCHING:\n                    switchSelectedTab();\n                    break;\n            }\n        }\n\n        /**\n         * Generates HTML string for the passed array of objects\n         *\n         * @param tabs\n         * @returns {string}\n         */\n        function getTabsHtml(tabs) {\n            var tabsHtml = '';\n            tabs.forEach(function(tab){\n\n                var tempTabTemplate = Config.TAB_TEMPLATE,\n                    faviconUrl = tab.favIconUrl || Config.DEFAULT_FAVICON;\n\n                tempTabTemplate = tempTabTemplate.replace('{favicon}', faviconUrl);\n                tempTabTemplate = tempTabTemplate.replace('{default_favicon}', Config.DEFAULT_FAVICON);\n                tempTabTemplate = tempTabTemplate.replace('{title}', sanitizeHtml(tab.title));\n                tempTabTemplate = tempTabTemplate.replace('{id}', tab.id);\n                tempTabTemplate = tempTabTemplate.replace('{windowId}', tab.windowId);\n\n                tabsHtml += tempTabTemplate;\n            });\n\n            return tabsHtml;\n        }\n\n        /**\n         * Filters tabs by the specified keyword string\n         *\n         * @param keyword\n         */\n        function filterTabs(keyword) {\n\n            keyword = keyword.toLowerCase();\n\n            var matches   = [],\n                tempTitle = '',\n                tempUrl   = '';\n\n            BrowserTab.allTabs.map(function (tab) {\n                tempTitle = tab.title.toLowerCase();\n                tempUrl   = tab.url.toLowerCase();\n\n                if (tempTitle.match(keyword) || tempUrl.match(keyword)) {\n                    matches.push(tab);\n                }\n            });\n\n            populateTabs(matches);\n        }\n\n        /**\n         * Appends the tab switcher HTML to the $container\n         *\n         * @param $container\n         * @returns {*}\n         */\n        function appendTabSwitcherHtml($container) {\n            if (!($container instanceof jQuery)) {\n                $container = $($container);\n            }\n\n            $container.append(Config.MAIN_TEMPLATE);\n            return $container;\n        }\n\n        /**\n         * Gets the tab switcher element and makes it visible. If it cannot find the element creates it.\n         */\n        function showTabSwitcher() {\n            var $tabSwitcher = $(Config.TAB_SWITCHER);\n\n            // Some pages remove the tab switcher HTML by chance\n            // so we check if the tab switcher was found and we re append if it is not found\n            if ($tabSwitcher.length === 0) {\n                appendTabSwitcherHtml(Config.TAB_SWITCHER_CONTAINER);\n                $tabSwitcher = $(Config.TAB_SWITCHER);\n            }\n\n            $tabSwitcher.show();\n        }\n\n        return {\n\n            /**\n             * Loads the extension in specified container\n             *\n             * @param $container\n             */\n            loadExtension: function ($container) {\n                appendTabSwitcherHtml($container);\n                this.bindUI();\n            },\n\n            /**\n             * Binds the UI elements for the extension\n             */\n            bindUI: function () {\n                // mouse-down instead of click because click gets triggered after the blur event in which case tab\n                // switcher would already be hidden (@see blur event below) and click will not be performed\n                $(document).on('mousedown', Config.TAB_ITEM, function () {\n\n                    var $this = $(this),\n                        tabId = $this.data('tabId'),\n                        windowId = $this.data('windowId');\n\n                    BrowserTab.switch(tabId, windowId);\n                });\n\n                // Hide the switcher on blurring of input\n                $(document).on('blur', Config.TAB_INPUT, function () {\n                    hideSwitcher();\n                });\n\n                // Actions on tabs listing\n                $(document).on('keydown', Config.TAB_INPUT, function (e) {\n                    // Switcher was visible and either down or up key was pressed\n                    if ($(Config.TAB_SWITCHER).is(':visible')) {\n                        handleKeyPress(e);\n                    }\n                });\n\n                // Filter for tabs\n                $(document).on('keyup', Config.TAB_INPUT, function (e) {\n\n                    var keyCode = e.keyCode,\n                        action  = getSwitcherAction(keyCode);\n\n                    switch (action) {\n                        case Config.GOING_DOWN:\n                        case Config.GOING_UP:\n                        case Config.ESCAPING:\n                        case Config.SWITCHING:\n                        case Config.CLOSING:\n                        case Config.PINNING:\n                            return;\n                        default:\n                            var keyword = $(this).val();\n                            if ($.trim(keyword) !== '') {\n                                filterTabs(keyword);\n                            } else {\n                                populateTabs(BrowserTab.allTabs);\n                            }\n                    }\n                });\n\n                // Master key binding for which extension will be enabled\n                key(Config.MASTER_KEY, function () {\n                    showTabSwitcher();\n                    $(Config.TAB_INPUT).focus();\n\n                    BrowserTab.getAll(populateTabs);\n                });\n            }\n        };\n    }\n\n    $(document).ready(function () {\n        var tabSwitcher = new TabSwitcher();\n        tabSwitcher.loadExtension(Config.TAB_SWITCHER_CONTAINER);\n    });\n\n}());\n"
  }
]