{"version":3,"sources":["jsdelivr-header.js","/gh/ajaxorg/ace-builds@1.4.8/src-noconflict/ace.js"],"names":[],"mappings":"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,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,GAAG,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE,EAAE,EAAE,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE,EAAE,EAAE,GAAG,GAAG,EAAE,EAAE,GAAG,GAAG,IAAI,GAAG,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE,EAAE,GAAG,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,GAAG,EAAE,IAAI,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,GAAG,GAAG,EAAE,GAAG,KAAK,IAAI,EAAE,GAAG,EAAE,IAAI,GAAG,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,GAAG,IAAI,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,IAAI,GAAG,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,GAAG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","file":"/gh/ajaxorg/ace-builds@1.4.8/src-noconflict/ace.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v3.14.1.\n * Original file: /gh/ajaxorg/ace-builds@1.4.8/src-noconflict/ace.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","/* ***** BEGIN LICENSE BLOCK *****\n * Distributed under the BSD license:\n *\n * Copyright (c) 2010, Ajax.org B.V.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *     * Redistributions of source code must retain the above copyright\n *       notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above copyright\n *       notice, this list of conditions and the following disclaimer in the\n *       documentation and/or other materials provided with the distribution.\n *     * Neither the name of Ajax.org B.V. nor the\n *       names of its contributors may be used to endorse or promote products\n *       derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ***** END LICENSE BLOCK ***** */\n\n/**\n * Define a module along with a payload\n * @param module a name for the payload\n * @param payload a function to call with (require, exports, module) params\n */\n\n(function() {\n\nvar ACE_NAMESPACE = \"ace\";\n\nvar global = (function() { return this; })();\nif (!global && typeof window != \"undefined\") global = window; // strict mode\n\n\nif (!ACE_NAMESPACE && typeof requirejs !== \"undefined\")\n    return;\n\n\nvar define = function(module, deps, payload) {\n    if (typeof module !== \"string\") {\n        if (define.original)\n            define.original.apply(this, arguments);\n        else {\n            console.error(\"dropping module because define wasn\\'t a string.\");\n            console.trace();\n        }\n        return;\n    }\n    if (arguments.length == 2)\n        payload = deps;\n    if (!define.modules[module]) {\n        define.payloads[module] = payload;\n        define.modules[module] = null;\n    }\n};\n\ndefine.modules = {};\ndefine.payloads = {};\n\n/**\n * Get at functionality define()ed using the function above\n */\nvar _require = function(parentId, module, callback) {\n    if (typeof module === \"string\") {\n        var payload = lookup(parentId, module);\n        if (payload != undefined) {\n            callback && callback();\n            return payload;\n        }\n    } else if (Object.prototype.toString.call(module) === \"[object Array]\") {\n        var params = [];\n        for (var i = 0, l = module.length; i < l; ++i) {\n            var dep = lookup(parentId, module[i]);\n            if (dep == undefined && require.original)\n                return;\n            params.push(dep);\n        }\n        return callback && callback.apply(null, params) || true;\n    }\n};\n\nvar require = function(module, callback) {\n    var packagedModule = _require(\"\", module, callback);\n    if (packagedModule == undefined && require.original)\n        return require.original.apply(this, arguments);\n    return packagedModule;\n};\n\nvar normalizeModule = function(parentId, moduleName) {\n    // normalize plugin requires\n    if (moduleName.indexOf(\"!\") !== -1) {\n        var chunks = moduleName.split(\"!\");\n        return normalizeModule(parentId, chunks[0]) + \"!\" + normalizeModule(parentId, chunks[1]);\n    }\n    // normalize relative requires\n    if (moduleName.charAt(0) == \".\") {\n        var base = parentId.split(\"/\").slice(0, -1).join(\"/\");\n        moduleName = base + \"/\" + moduleName;\n\n        while(moduleName.indexOf(\".\") !== -1 && previous != moduleName) {\n            var previous = moduleName;\n            moduleName = moduleName.replace(/\\/\\.\\//, \"/\").replace(/[^\\/]+\\/\\.\\.\\//, \"\");\n        }\n    }\n    return moduleName;\n};\n\n/**\n * Internal function to lookup moduleNames and resolve them by calling the\n * definition function if needed.\n */\nvar lookup = function(parentId, moduleName) {\n    moduleName = normalizeModule(parentId, moduleName);\n\n    var module = define.modules[moduleName];\n    if (!module) {\n        module = define.payloads[moduleName];\n        if (typeof module === 'function') {\n            var exports = {};\n            var mod = {\n                id: moduleName,\n                uri: '',\n                exports: exports,\n                packaged: true\n            };\n\n            var req = function(module, callback) {\n                return _require(moduleName, module, callback);\n            };\n\n            var returnValue = module(req, exports, mod);\n            exports = returnValue || mod.exports;\n            define.modules[moduleName] = exports;\n            delete define.payloads[moduleName];\n        }\n        module = define.modules[moduleName] = exports || module;\n    }\n    return module;\n};\n\nfunction exportAce(ns) {\n    var root = global;\n    if (ns) {\n        if (!global[ns])\n            global[ns] = {};\n        root = global[ns];\n    }\n\n    if (!root.define || !root.define.packaged) {\n        define.original = root.define;\n        root.define = define;\n        root.define.packaged = true;\n    }\n\n    if (!root.require || !root.require.packaged) {\n        require.original = root.require;\n        root.require = require;\n        root.require.packaged = true;\n    }\n}\n\nexportAce(ACE_NAMESPACE);\n\n})();\n\nace.define(\"ace/lib/regexp\",[\"require\",\"exports\",\"module\"], function(require, exports, module) {\n\"use strict\";\n\n    var real = {\n            exec: RegExp.prototype.exec,\n            test: RegExp.prototype.test,\n            match: String.prototype.match,\n            replace: String.prototype.replace,\n            split: String.prototype.split\n        },\n        compliantExecNpcg = real.exec.call(/()??/, \"\")[1] === undefined, // check `exec` handling of nonparticipating capturing groups\n        compliantLastIndexIncrement = function () {\n            var x = /^/g;\n            real.test.call(x, \"\");\n            return !x.lastIndex;\n        }();\n\n    if (compliantLastIndexIncrement && compliantExecNpcg)\n        return;\n    RegExp.prototype.exec = function (str) {\n        var match = real.exec.apply(this, arguments),\n            name, r2;\n        if ( typeof(str) == 'string' && match) {\n            if (!compliantExecNpcg && match.length > 1 && indexOf(match, \"\") > -1) {\n                r2 = RegExp(this.source, real.replace.call(getNativeFlags(this), \"g\", \"\"));\n                real.replace.call(str.slice(match.index), r2, function () {\n                    for (var i = 1; i < arguments.length - 2; i++) {\n                        if (arguments[i] === undefined)\n                            match[i] = undefined;\n                    }\n                });\n            }\n            if (this._xregexp && this._xregexp.captureNames) {\n                for (var i = 1; i < match.length; i++) {\n                    name = this._xregexp.captureNames[i - 1];\n                    if (name)\n                       match[name] = match[i];\n                }\n            }\n            if (!compliantLastIndexIncrement && this.global && !match[0].length && (this.lastIndex > match.index))\n                this.lastIndex--;\n        }\n        return match;\n    };\n    if (!compliantLastIndexIncrement) {\n        RegExp.prototype.test = function (str) {\n            var match = real.exec.call(this, str);\n            if (match && this.global && !match[0].length && (this.lastIndex > match.index))\n                this.lastIndex--;\n            return !!match;\n        };\n    }\n\n    function getNativeFlags (regex) {\n        return (regex.global     ? \"g\" : \"\") +\n               (regex.ignoreCase ? \"i\" : \"\") +\n               (regex.multiline  ? \"m\" : \"\") +\n               (regex.extended   ? \"x\" : \"\") + // Proposed for ES4; included in AS3\n               (regex.sticky     ? \"y\" : \"\");\n    }\n\n    function indexOf (array, item, from) {\n        if (Array.prototype.indexOf) // Use the native array method if available\n            return array.indexOf(item, from);\n        for (var i = from || 0; i < array.length; i++) {\n            if (array[i] === item)\n                return i;\n        }\n        return -1;\n    }\n\n});\n\nace.define(\"ace/lib/es5-shim\",[\"require\",\"exports\",\"module\"], function(require, exports, module) {\n\nfunction Empty() {}\n\nif (!Function.prototype.bind) {\n    Function.prototype.bind = function bind(that) { // .length is 1\n        var target = this;\n        if (typeof target != \"function\") {\n            throw new TypeError(\"Function.prototype.bind called on incompatible \" + target);\n        }\n        var args = slice.call(arguments, 1); // for normal call\n        var bound = function () {\n\n            if (this instanceof bound) {\n\n                var result = target.apply(\n                    this,\n                    args.concat(slice.call(arguments))\n                );\n                if (Object(result) === result) {\n                    return result;\n                }\n                return this;\n\n            } else {\n                return target.apply(\n                    that,\n                    args.concat(slice.call(arguments))\n                );\n\n            }\n\n        };\n        if(target.prototype) {\n            Empty.prototype = target.prototype;\n            bound.prototype = new Empty();\n            Empty.prototype = null;\n        }\n        return bound;\n    };\n}\nvar call = Function.prototype.call;\nvar prototypeOfArray = Array.prototype;\nvar prototypeOfObject = Object.prototype;\nvar slice = prototypeOfArray.slice;\nvar _toString = call.bind(prototypeOfObject.toString);\nvar owns = call.bind(prototypeOfObject.hasOwnProperty);\nvar defineGetter;\nvar defineSetter;\nvar lookupGetter;\nvar lookupSetter;\nvar supportsAccessors;\nif ((supportsAccessors = owns(prototypeOfObject, \"__defineGetter__\"))) {\n    defineGetter = call.bind(prototypeOfObject.__defineGetter__);\n    defineSetter = call.bind(prototypeOfObject.__defineSetter__);\n    lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);\n    lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);\n}\nif ([1,2].splice(0).length != 2) {\n    if(function() { // test IE < 9 to splice bug - see issue #138\n        function makeArray(l) {\n            var a = new Array(l+2);\n            a[0] = a[1] = 0;\n            return a;\n        }\n        var array = [], lengthBefore;\n        \n        array.splice.apply(array, makeArray(20));\n        array.splice.apply(array, makeArray(26));\n\n        lengthBefore = array.length; //46\n        array.splice(5, 0, \"XXX\"); // add one element\n\n        lengthBefore + 1 == array.length\n\n        if (lengthBefore + 1 == array.length) {\n            return true;// has right splice implementation without bugs\n        }\n    }()) {//IE 6/7\n        var array_splice = Array.prototype.splice;\n        Array.prototype.splice = function(start, deleteCount) {\n            if (!arguments.length) {\n                return [];\n            } else {\n                return array_splice.apply(this, [\n                    start === void 0 ? 0 : start,\n                    deleteCount === void 0 ? (this.length - start) : deleteCount\n                ].concat(slice.call(arguments, 2)))\n            }\n        };\n    } else {//IE8\n        Array.prototype.splice = function(pos, removeCount){\n            var length = this.length;\n            if (pos > 0) {\n                if (pos > length)\n                    pos = length;\n            } else if (pos == void 0) {\n                pos = 0;\n            } else if (pos < 0) {\n                pos = Math.max(length + pos, 0);\n            }\n\n            if (!(pos+removeCount < length))\n                removeCount = length - pos;\n\n            var removed = this.slice(pos, pos+removeCount);\n            var insert = slice.call(arguments, 2);\n            var add = insert.length;            \n            if (pos === length) {\n                if (add) {\n                    this.push.apply(this, insert);\n                }\n            } else {\n                var remove = Math.min(removeCount, length - pos);\n                var tailOldPos = pos + remove;\n                var tailNewPos = tailOldPos + add - remove;\n                var tailCount = length - tailOldPos;\n                var lengthAfterRemove = length - remove;\n\n                if (tailNewPos < tailOldPos) { // case A\n                    for (var i = 0; i < tailCount; ++i) {\n                        this[tailNewPos+i] = this[tailOldPos+i];\n                    }\n                } else if (tailNewPos > tailOldPos) { // case B\n                    for (i = tailCount; i--; ) {\n                        this[tailNewPos+i] = this[tailOldPos+i];\n                    }\n                } // else, add == remove (nothing to do)\n\n                if (add && pos === lengthAfterRemove) {\n                    this.length = lengthAfterRemove; // truncate array\n                    this.push.apply(this, insert);\n                } else {\n                    this.length = lengthAfterRemove + add; // reserves space\n                    for (i = 0; i < add; ++i) {\n                        this[pos+i] = insert[i];\n                    }\n                }\n            }\n            return removed;\n        };\n    }\n}\nif (!Array.isArray) {\n    Array.isArray = function isArray(obj) {\n        return _toString(obj) == \"[object Array]\";\n    };\n}\nvar boxedString = Object(\"a\"),\n    splitString = boxedString[0] != \"a\" || !(0 in boxedString);\n\nif (!Array.prototype.forEach) {\n    Array.prototype.forEach = function forEach(fun /*, thisp*/) {\n        var object = toObject(this),\n            self = splitString && _toString(this) == \"[object String]\" ?\n                this.split(\"\") :\n                object,\n            thisp = arguments[1],\n            i = -1,\n            length = self.length >>> 0;\n        if (_toString(fun) != \"[object Function]\") {\n            throw new TypeError(); // TODO message\n        }\n\n        while (++i < length) {\n            if (i in self) {\n                fun.call(thisp, self[i], i, object);\n            }\n        }\n    };\n}\nif (!Array.prototype.map) {\n    Array.prototype.map = function map(fun /*, thisp*/) {\n        var object = toObject(this),\n            self = splitString && _toString(this) == \"[object String]\" ?\n                this.split(\"\") :\n                object,\n            length = self.length >>> 0,\n            result = Array(length),\n            thisp = arguments[1];\n        if (_toString(fun) != \"[object Function]\") {\n            throw new TypeError(fun + \" is not a function\");\n        }\n\n        for (var i = 0; i < length; i++) {\n            if (i in self)\n                result[i] = fun.call(thisp, self[i], i, object);\n        }\n        return result;\n    };\n}\nif (!Array.prototype.filter) {\n    Array.prototype.filter = function filter(fun /*, thisp */) {\n        var object = toObject(this),\n            self = splitString && _toString(this) == \"[object String]\" ?\n                this.split(\"\") :\n                    object,\n            length = self.length >>> 0,\n            result = [],\n            value,\n            thisp = arguments[1];\n        if (_toString(fun) != \"[object Function]\") {\n            throw new TypeError(fun + \" is not a function\");\n        }\n\n        for (var i = 0; i < length; i++) {\n            if (i in self) {\n                value = self[i];\n                if (fun.call(thisp, value, i, object)) {\n                    result.push(value);\n                }\n            }\n        }\n        return result;\n    };\n}\nif (!Array.prototype.every) {\n    Array.prototype.every = function every(fun /*, thisp */) {\n        var object = toObject(this),\n            self = splitString && _toString(this) == \"[object String]\" ?\n                this.split(\"\") :\n                object,\n            length = self.length >>> 0,\n            thisp = arguments[1];\n        if (_toString(fun) != \"[object Function]\") {\n            throw new TypeError(fun + \" is not a function\");\n        }\n\n        for (var i = 0; i < length; i++) {\n            if (i in self && !fun.call(thisp, self[i], i, object)) {\n                return false;\n            }\n        }\n        return true;\n    };\n}\nif (!Array.prototype.some) {\n    Array.prototype.some = function some(fun /*, thisp */) {\n        var object = toObject(this),\n            self = splitString && _toString(this) == \"[object String]\" ?\n                this.split(\"\") :\n                object,\n            length = self.length >>> 0,\n            thisp = arguments[1];\n        if (_toString(fun) != \"[object Function]\") {\n            throw new TypeError(fun + \" is not a function\");\n        }\n\n        for (var i = 0; i < length; i++) {\n            if (i in self && fun.call(thisp, self[i], i, object)) {\n                return true;\n            }\n        }\n        return false;\n    };\n}\nif (!Array.prototype.reduce) {\n    Array.prototype.reduce = function reduce(fun /*, initial*/) {\n        var object = toObject(this),\n            self = splitString && _toString(this) == \"[object String]\" ?\n                this.split(\"\") :\n                object,\n            length = self.length >>> 0;\n        if (_toString(fun) != \"[object Function]\") {\n            throw new TypeError(fun + \" is not a function\");\n        }\n        if (!length && arguments.length == 1) {\n            throw new TypeError(\"reduce of empty array with no initial value\");\n        }\n\n        var i = 0;\n        var result;\n        if (arguments.length >= 2) {\n            result = arguments[1];\n        } else {\n            do {\n                if (i in self) {\n                    result = self[i++];\n                    break;\n                }\n                if (++i >= length) {\n                    throw new TypeError(\"reduce of empty array with no initial value\");\n                }\n            } while (true);\n        }\n\n        for (; i < length; i++) {\n            if (i in self) {\n                result = fun.call(void 0, result, self[i], i, object);\n            }\n        }\n\n        return result;\n    };\n}\nif (!Array.prototype.reduceRight) {\n    Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) {\n        var object = toObject(this),\n            self = splitString && _toString(this) == \"[object String]\" ?\n                this.split(\"\") :\n                object,\n            length = self.length >>> 0;\n        if (_toString(fun) != \"[object Function]\") {\n            throw new TypeError(fun + \" is not a function\");\n        }\n        if (!length && arguments.length == 1) {\n            throw new TypeError(\"reduceRight of empty array with no initial value\");\n        }\n\n        var result, i = length - 1;\n        if (arguments.length >= 2) {\n            result = arguments[1];\n        } else {\n            do {\n                if (i in self) {\n                    result = self[i--];\n                    break;\n                }\n                if (--i < 0) {\n                    throw new TypeError(\"reduceRight of empty array with no initial value\");\n                }\n            } while (true);\n        }\n\n        do {\n            if (i in this) {\n                result = fun.call(void 0, result, self[i], i, object);\n            }\n        } while (i--);\n\n        return result;\n    };\n}\nif (!Array.prototype.indexOf || ([0, 1].indexOf(1, 2) != -1)) {\n    Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) {\n        var self = splitString && _toString(this) == \"[object String]\" ?\n                this.split(\"\") :\n                toObject(this),\n            length = self.length >>> 0;\n\n        if (!length) {\n            return -1;\n        }\n\n        var i = 0;\n        if (arguments.length > 1) {\n            i = toInteger(arguments[1]);\n        }\n        i = i >= 0 ? i : Math.max(0, length + i);\n        for (; i < length; i++) {\n            if (i in self && self[i] === sought) {\n                return i;\n            }\n        }\n        return -1;\n    };\n}\nif (!Array.prototype.lastIndexOf || ([0, 1].lastIndexOf(0, -3) != -1)) {\n    Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) {\n        var self = splitString && _toString(this) == \"[object String]\" ?\n                this.split(\"\") :\n                toObject(this),\n            length = self.length >>> 0;\n\n        if (!length) {\n            return -1;\n        }\n        var i = length - 1;\n        if (arguments.length > 1) {\n            i = Math.min(i, toInteger(arguments[1]));\n        }\n        i = i >= 0 ? i : length - Math.abs(i);\n        for (; i >= 0; i--) {\n            if (i in self && sought === self[i]) {\n                return i;\n            }\n        }\n        return -1;\n    };\n}\nif (!Object.getPrototypeOf) {\n    Object.getPrototypeOf = function getPrototypeOf(object) {\n        return object.__proto__ || (\n            object.constructor ?\n            object.constructor.prototype :\n            prototypeOfObject\n        );\n    };\n}\nif (!Object.getOwnPropertyDescriptor) {\n    var ERR_NON_OBJECT = \"Object.getOwnPropertyDescriptor called on a \" +\n                         \"non-object: \";\n    Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) {\n        if ((typeof object != \"object\" && typeof object != \"function\") || object === null)\n            throw new TypeError(ERR_NON_OBJECT + object);\n        if (!owns(object, property))\n            return;\n\n        var descriptor, getter, setter;\n        descriptor =  { enumerable: true, configurable: true };\n        if (supportsAccessors) {\n            var prototype = object.__proto__;\n            object.__proto__ = prototypeOfObject;\n\n            var getter = lookupGetter(object, property);\n            var setter = lookupSetter(object, property);\n            object.__proto__ = prototype;\n\n            if (getter || setter) {\n                if (getter) descriptor.get = getter;\n                if (setter) descriptor.set = setter;\n                return descriptor;\n            }\n        }\n        descriptor.value = object[property];\n        return descriptor;\n    };\n}\nif (!Object.getOwnPropertyNames) {\n    Object.getOwnPropertyNames = function getOwnPropertyNames(object) {\n        return Object.keys(object);\n    };\n}\nif (!Object.create) {\n    var createEmpty;\n    if (Object.prototype.__proto__ === null) {\n        createEmpty = function () {\n            return { \"__proto__\": null };\n        };\n    } else {\n        createEmpty = function () {\n            var empty = {};\n            for (var i in empty)\n                empty[i] = null;\n            empty.constructor =\n            empty.hasOwnProperty =\n            empty.propertyIsEnumerable =\n            empty.isPrototypeOf =\n            empty.toLocaleString =\n            empty.toString =\n            empty.valueOf =\n            empty.__proto__ = null;\n            return empty;\n        }\n    }\n\n    Object.create = function create(prototype, properties) {\n        var object;\n        if (prototype === null) {\n            object = createEmpty();\n        } else {\n            if (typeof prototype != \"object\")\n                throw new TypeError(\"typeof prototype[\"+(typeof prototype)+\"] != 'object'\");\n            var Type = function () {};\n            Type.prototype = prototype;\n            object = new Type();\n            object.__proto__ = prototype;\n        }\n        if (properties !== void 0)\n            Object.defineProperties(object, properties);\n        return object;\n    };\n}\n\nfunction doesDefinePropertyWork(object) {\n    try {\n        Object.defineProperty(object, \"sentinel\", {});\n        return \"sentinel\" in object;\n    } catch (exception) {\n    }\n}\nif (Object.defineProperty) {\n    var definePropertyWorksOnObject = doesDefinePropertyWork({});\n    var definePropertyWorksOnDom = typeof document == \"undefined\" ||\n        doesDefinePropertyWork(document.createElement(\"div\"));\n    if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) {\n        var definePropertyFallback = Object.defineProperty;\n    }\n}\n\nif (!Object.defineProperty || definePropertyFallback) {\n    var ERR_NON_OBJECT_DESCRIPTOR = \"Property description must be an object: \";\n    var ERR_NON_OBJECT_TARGET = \"Object.defineProperty called on non-object: \"\n    var ERR_ACCESSORS_NOT_SUPPORTED = \"getters & setters can not be defined \" +\n                                      \"on this javascript engine\";\n\n    Object.defineProperty = function defineProperty(object, property, descriptor) {\n        if ((typeof object != \"object\" && typeof object != \"function\") || object === null)\n            throw new TypeError(ERR_NON_OBJECT_TARGET + object);\n        if ((typeof descriptor != \"object\" && typeof descriptor != \"function\") || descriptor === null)\n            throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor);\n        if (definePropertyFallback) {\n            try {\n                return definePropertyFallback.call(Object, object, property, descriptor);\n            } catch (exception) {\n            }\n        }\n        if (owns(descriptor, \"value\")) {\n\n            if (supportsAccessors && (lookupGetter(object, property) ||\n                                      lookupSetter(object, property)))\n            {\n                var prototype = object.__proto__;\n                object.__proto__ = prototypeOfObject;\n                delete object[property];\n                object[property] = descriptor.value;\n                object.__proto__ = prototype;\n            } else {\n                object[property] = descriptor.value;\n            }\n        } else {\n            if (!supportsAccessors)\n                throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);\n            if (owns(descriptor, \"get\"))\n                defineGetter(object, property, descriptor.get);\n            if (owns(descriptor, \"set\"))\n                defineSetter(object, property, descriptor.set);\n        }\n\n        return object;\n    };\n}\nif (!Object.defineProperties) {\n    Object.defineProperties = function defineProperties(object, properties) {\n        for (var property in properties) {\n            if (owns(properties, property))\n                Object.defineProperty(object, property, properties[property]);\n        }\n        return object;\n    };\n}\nif (!Object.seal) {\n    Object.seal = function seal(object) {\n        return object;\n    };\n}\nif (!Object.freeze) {\n    Object.freeze = function freeze(object) {\n        return object;\n    };\n}\ntry {\n    Object.freeze(function () {});\n} catch (exception) {\n    Object.freeze = (function freeze(freezeObject) {\n        return function freeze(object) {\n            if (typeof object == \"function\") {\n                return object;\n            } else {\n                return freezeObject(object);\n            }\n        };\n    })(Object.freeze);\n}\nif (!Object.preventExtensions) {\n    Object.preventExtensions = function preventExtensions(object) {\n        return object;\n    };\n}\nif (!Object.isSealed) {\n    Object.isSealed = function isSealed(object) {\n        return false;\n    };\n}\nif (!Object.isFrozen) {\n    Object.isFrozen = function isFrozen(object) {\n        return false;\n    };\n}\nif (!Object.isExtensible) {\n    Object.isExtensible = function isExtensible(object) {\n        if (Object(object) === object) {\n            throw new TypeError(); // TODO message\n        }\n        var name = '';\n        while (owns(object, name)) {\n            name += '?';\n        }\n        object[name] = true;\n        var returnValue = owns(object, name);\n        delete object[name];\n        return returnValue;\n    };\n}\nif (!Object.keys) {\n    var hasDontEnumBug = true,\n        dontEnums = [\n            \"toString\",\n            \"toLocaleString\",\n            \"valueOf\",\n            \"hasOwnProperty\",\n            \"isPrototypeOf\",\n            \"propertyIsEnumerable\",\n            \"constructor\"\n        ],\n        dontEnumsLength = dontEnums.length;\n\n    for (var key in {\"toString\": null}) {\n        hasDontEnumBug = false;\n    }\n\n    Object.keys = function keys(object) {\n\n        if (\n            (typeof object != \"object\" && typeof object != \"function\") ||\n            object === null\n        ) {\n            throw new TypeError(\"Object.keys called on a non-object\");\n        }\n\n        var keys = [];\n        for (var name in object) {\n            if (owns(object, name)) {\n                keys.push(name);\n            }\n        }\n\n        if (hasDontEnumBug) {\n            for (var i = 0, ii = dontEnumsLength; i < ii; i++) {\n                var dontEnum = dontEnums[i];\n                if (owns(object, dontEnum)) {\n                    keys.push(dontEnum);\n                }\n            }\n        }\n        return keys;\n    };\n\n}\nif (!Date.now) {\n    Date.now = function now() {\n        return new Date().getTime();\n    };\n}\nvar ws = \"\\x09\\x0A\\x0B\\x0C\\x0D\\x20\\xA0\\u1680\\u2000\\u2001\\u2002\\u2003\" +\n    \"\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\u2028\" +\n    \"\\u2029\\uFEFF\";\nif (!String.prototype.trim) {\n    ws = \"[\" + ws + \"]\";\n    var trimBeginRegexp = new RegExp(\"^\" + ws + ws + \"*\"),\n        trimEndRegexp = new RegExp(ws + ws + \"*$\");\n    String.prototype.trim = function trim() {\n        return String(this).replace(trimBeginRegexp, \"\").replace(trimEndRegexp, \"\");\n    };\n}\n\nfunction toInteger(n) {\n    n = +n;\n    if (n !== n) { // isNaN\n        n = 0;\n    } else if (n !== 0 && n !== (1/0) && n !== -(1/0)) {\n        n = (n > 0 || -1) * Math.floor(Math.abs(n));\n    }\n    return n;\n}\n\nfunction isPrimitive(input) {\n    var type = typeof input;\n    return (\n        input === null ||\n        type === \"undefined\" ||\n        type === \"boolean\" ||\n        type === \"number\" ||\n        type === \"string\"\n    );\n}\n\nfunction toPrimitive(input) {\n    var val, valueOf, toString;\n    if (isPrimitive(input)) {\n        return input;\n    }\n    valueOf = input.valueOf;\n    if (typeof valueOf === \"function\") {\n        val = valueOf.call(input);\n        if (isPrimitive(val)) {\n            return val;\n        }\n    }\n    toString = input.toString;\n    if (typeof toString === \"function\") {\n        val = toString.call(input);\n        if (isPrimitive(val)) {\n            return val;\n        }\n    }\n    throw new TypeError();\n}\nvar toObject = function (o) {\n    if (o == null) { // this matches both null and undefined\n        throw new TypeError(\"can't convert \"+o+\" to object\");\n    }\n    return Object(o);\n};\n\n});\n\nace.define(\"ace/lib/fixoldbrowsers\",[\"require\",\"exports\",\"module\",\"ace/lib/regexp\",\"ace/lib/es5-shim\"], function(require, exports, module) {\n\"use strict\";\n\nrequire(\"./regexp\");\nrequire(\"./es5-shim\");\nif (typeof Element != \"undefined\" && !Element.prototype.remove) {\n    Object.defineProperty(Element.prototype, \"remove\", {\n        enumerable: false,\n        writable: true,\n        configurable: true,\n        value: function() { this.parentNode && this.parentNode.removeChild(this); }\n    });\n}\n\n\n});\n\nace.define(\"ace/lib/useragent\",[\"require\",\"exports\",\"module\"], function(require, exports, module) {\n\"use strict\";\nexports.OS = {\n    LINUX: \"LINUX\",\n    MAC: \"MAC\",\n    WINDOWS: \"WINDOWS\"\n};\nexports.getOS = function() {\n    if (exports.isMac) {\n        return exports.OS.MAC;\n    } else if (exports.isLinux) {\n        return exports.OS.LINUX;\n    } else {\n        return exports.OS.WINDOWS;\n    }\n};\nvar _navigator = typeof navigator == \"object\" ? navigator : {};\n\nvar os = (/mac|win|linux/i.exec(_navigator.platform) || [\"other\"])[0].toLowerCase();\nvar ua = _navigator.userAgent || \"\";\nvar appName = _navigator.appName || \"\";\nexports.isWin = (os == \"win\");\nexports.isMac = (os == \"mac\");\nexports.isLinux = (os == \"linux\");\nexports.isIE = \n    (appName == \"Microsoft Internet Explorer\" || appName.indexOf(\"MSAppHost\") >= 0)\n    ? parseFloat((ua.match(/(?:MSIE |Trident\\/[0-9]+[\\.0-9]+;.*rv:)([0-9]+[\\.0-9]+)/)||[])[1])\n    : parseFloat((ua.match(/(?:Trident\\/[0-9]+[\\.0-9]+;.*rv:)([0-9]+[\\.0-9]+)/)||[])[1]); // for ie\n    \nexports.isOldIE = exports.isIE && exports.isIE < 9;\nexports.isGecko = exports.isMozilla = ua.match(/ Gecko\\/\\d+/);\nexports.isOpera = typeof opera == \"object\" && Object.prototype.toString.call(window.opera) == \"[object Opera]\";\nexports.isWebKit = parseFloat(ua.split(\"WebKit/\")[1]) || undefined;\n\nexports.isChrome = parseFloat(ua.split(\" Chrome/\")[1]) || undefined;\n\nexports.isEdge = parseFloat(ua.split(\" Edge/\")[1]) || undefined;\n\nexports.isAIR = ua.indexOf(\"AdobeAIR\") >= 0;\n\nexports.isAndroid = ua.indexOf(\"Android\") >= 0;\n\nexports.isChromeOS = ua.indexOf(\" CrOS \") >= 0;\n\nexports.isIOS = /iPad|iPhone|iPod/.test(ua) && !window.MSStream;\n\nif (exports.isIOS) exports.isMac = true;\n\nexports.isMobile = exports.isIOS || exports.isAndroid;\n\n});\n\nace.define(\"ace/lib/dom\",[\"require\",\"exports\",\"module\",\"ace/lib/useragent\"], function(require, exports, module) {\n\"use strict\";\n\nvar useragent = require(\"./useragent\"); \nvar XHTML_NS = \"http://www.w3.org/1999/xhtml\";\n\nexports.buildDom = function buildDom(arr, parent, refs) {\n    if (typeof arr == \"string\" && arr) {\n        var txt = document.createTextNode(arr);\n        if (parent)\n            parent.appendChild(txt);\n        return txt;\n    }\n    \n    if (!Array.isArray(arr))\n        return arr;\n    if (typeof arr[0] != \"string\" || !arr[0]) {\n        var els = [];\n        for (var i = 0; i < arr.length; i++) {\n            var ch = buildDom(arr[i], parent, refs);\n            ch && els.push(ch);\n        }\n        return els;\n    }\n    \n    var el = document.createElement(arr[0]);\n    var options = arr[1];\n    var childIndex = 1;\n    if (options && typeof options == \"object\" && !Array.isArray(options))\n        childIndex = 2;\n    for (var i = childIndex; i < arr.length; i++)\n        buildDom(arr[i], el, refs);\n    if (childIndex == 2) {\n        Object.keys(options).forEach(function(n) {\n            var val = options[n];\n            if (n === \"class\") {\n                el.className = Array.isArray(val) ? val.join(\" \") : val;\n            } else if (typeof val == \"function\" || n == \"value\") {\n                el[n] = val;\n            } else if (n === \"ref\") {\n                if (refs) refs[val] = el;\n            } else if (val != null) {\n                el.setAttribute(n, val);\n            }\n        });\n    }\n    if (parent)\n        parent.appendChild(el);\n    return el;\n};\n\nexports.getDocumentHead = function(doc) {\n    if (!doc)\n        doc = document;\n    return doc.head || doc.getElementsByTagName(\"head\")[0] || doc.documentElement;\n};\n\nexports.createElement = function(tag, ns) {\n    return document.createElementNS ?\n           document.createElementNS(ns || XHTML_NS, tag) :\n           document.createElement(tag);\n};\n\nexports.removeChildren = function(element) {\n    element.innerHTML = \"\";\n};\n\nexports.createTextNode = function(textContent, element) {\n    var doc = element ? element.ownerDocument : document;\n    return doc.createTextNode(textContent);\n};\n\nexports.createFragment = function(element) {\n    var doc = element ? element.ownerDocument : document;\n    return doc.createDocumentFragment();\n};\n\nexports.hasCssClass = function(el, name) {\n    var classes = (el.className + \"\").split(/\\s+/g);\n    return classes.indexOf(name) !== -1;\n};\nexports.addCssClass = function(el, name) {\n    if (!exports.hasCssClass(el, name)) {\n        el.className += \" \" + name;\n    }\n};\nexports.removeCssClass = function(el, name) {\n    var classes = el.className.split(/\\s+/g);\n    while (true) {\n        var index = classes.indexOf(name);\n        if (index == -1) {\n            break;\n        }\n        classes.splice(index, 1);\n    }\n    el.className = classes.join(\" \");\n};\n\nexports.toggleCssClass = function(el, name) {\n    var classes = el.className.split(/\\s+/g), add = true;\n    while (true) {\n        var index = classes.indexOf(name);\n        if (index == -1) {\n            break;\n        }\n        add = false;\n        classes.splice(index, 1);\n    }\n    if (add)\n        classes.push(name);\n\n    el.className = classes.join(\" \");\n    return add;\n};\nexports.setCssClass = function(node, className, include) {\n    if (include) {\n        exports.addCssClass(node, className);\n    } else {\n        exports.removeCssClass(node, className);\n    }\n};\n\nexports.hasCssString = function(id, doc) {\n    var index = 0, sheets;\n    doc = doc || document;\n    if ((sheets = doc.querySelectorAll(\"style\"))) {\n        while (index < sheets.length)\n            if (sheets[index++].id === id)\n                return true;\n    }\n};\n\nexports.importCssString = function importCssString(cssText, id, target) {\n    var container = target;\n    if (!target || !target.getRootNode) {\n        container = document;\n    } else {\n        container = target.getRootNode();\n        if (!container || container == target)\n            container = document;\n    }\n    \n    var doc = container.ownerDocument || container;\n    if (id && exports.hasCssString(id, container))\n        return null;\n    \n    if (id)\n        cssText += \"\\n/*# sourceURL=ace/css/\" + id + \" */\";\n    \n    var style = exports.createElement(\"style\");\n    style.appendChild(doc.createTextNode(cssText));\n    if (id)\n        style.id = id;\n\n    if (container == doc)\n        container = exports.getDocumentHead(doc);\n    container.insertBefore(style, container.firstChild);\n};\n\nexports.importCssStylsheet = function(uri, doc) {\n    exports.buildDom([\"link\", {rel: \"stylesheet\", href: uri}], exports.getDocumentHead(doc));\n};\nexports.scrollbarWidth = function(document) {\n    var inner = exports.createElement(\"ace_inner\");\n    inner.style.width = \"100%\";\n    inner.style.minWidth = \"0px\";\n    inner.style.height = \"200px\";\n    inner.style.display = \"block\";\n\n    var outer = exports.createElement(\"ace_outer\");\n    var style = outer.style;\n\n    style.position = \"absolute\";\n    style.left = \"-10000px\";\n    style.overflow = \"hidden\";\n    style.width = \"200px\";\n    style.minWidth = \"0px\";\n    style.height = \"150px\";\n    style.display = \"block\";\n\n    outer.appendChild(inner);\n\n    var body = document.documentElement;\n    body.appendChild(outer);\n\n    var noScrollbar = inner.offsetWidth;\n\n    style.overflow = \"scroll\";\n    var withScrollbar = inner.offsetWidth;\n\n    if (noScrollbar == withScrollbar) {\n        withScrollbar = outer.clientWidth;\n    }\n\n    body.removeChild(outer);\n\n    return noScrollbar-withScrollbar;\n};\n\nif (typeof document == \"undefined\") {\n    exports.importCssString = function() {};\n}\n\nexports.computedStyle = function(element, style) {\n    return window.getComputedStyle(element, \"\") || {};\n};\n\nexports.setStyle = function(styles, property, value) {\n    if (styles[property] !== value) {\n        styles[property] = value;\n    }\n};\n\nexports.HAS_CSS_ANIMATION = false;\nexports.HAS_CSS_TRANSFORMS = false;\nexports.HI_DPI = useragent.isWin\n    ? typeof window !== \"undefined\" && window.devicePixelRatio >= 1.5\n    : true;\n\nif (typeof document !== \"undefined\") {\n    var div = document.createElement(\"div\");\n    if (exports.HI_DPI && div.style.transform  !== undefined)\n        exports.HAS_CSS_TRANSFORMS = true;\n    if (!useragent.isEdge && typeof div.style.animationName !== \"undefined\")\n        exports.HAS_CSS_ANIMATION = true;\n    div = null;\n}\n\nif (exports.HAS_CSS_TRANSFORMS) {\n    exports.translate = function(element, tx, ty) {\n        element.style.transform = \"translate(\" + Math.round(tx) + \"px, \" + Math.round(ty) +\"px)\";\n    };\n} else {\n    exports.translate = function(element, tx, ty) {\n        element.style.top = Math.round(ty) + \"px\";\n        element.style.left = Math.round(tx) + \"px\";\n    };\n}\n\n});\n\nace.define(\"ace/lib/oop\",[\"require\",\"exports\",\"module\"], function(require, exports, module) {\n\"use strict\";\n\nexports.inherits = function(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\nexports.mixin = function(obj, mixin) {\n    for (var key in mixin) {\n        obj[key] = mixin[key];\n    }\n    return obj;\n};\n\nexports.implement = function(proto, mixin) {\n    exports.mixin(proto, mixin);\n};\n\n});\n\nace.define(\"ace/lib/keys\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\"], function(require, exports, module) {\n\"use strict\";\n\nvar oop = require(\"./oop\");\nvar Keys = (function() {\n    var ret = {\n        MODIFIER_KEYS: {\n            16: 'Shift', 17: 'Ctrl', 18: 'Alt', 224: 'Meta',\n            91: 'MetaLeft', 92: 'MetaRight', 93: 'ContextMenu'\n        },\n\n        KEY_MODS: {\n            \"ctrl\": 1, \"alt\": 2, \"option\" : 2, \"shift\": 4,\n            \"super\": 8, \"meta\": 8, \"command\": 8, \"cmd\": 8\n        },\n\n        FUNCTION_KEYS : {\n            8  : \"Backspace\",\n            9  : \"Tab\",\n            13 : \"Return\",\n            19 : \"Pause\",\n            27 : \"Esc\",\n            32 : \"Space\",\n            33 : \"PageUp\",\n            34 : \"PageDown\",\n            35 : \"End\",\n            36 : \"Home\",\n            37 : \"Left\",\n            38 : \"Up\",\n            39 : \"Right\",\n            40 : \"Down\",\n            44 : \"Print\",\n            45 : \"Insert\",\n            46 : \"Delete\",\n            96 : \"Numpad0\",\n            97 : \"Numpad1\",\n            98 : \"Numpad2\",\n            99 : \"Numpad3\",\n            100: \"Numpad4\",\n            101: \"Numpad5\",\n            102: \"Numpad6\",\n            103: \"Numpad7\",\n            104: \"Numpad8\",\n            105: \"Numpad9\",\n            '-13': \"NumpadEnter\",\n            112: \"F1\",\n            113: \"F2\",\n            114: \"F3\",\n            115: \"F4\",\n            116: \"F5\",\n            117: \"F6\",\n            118: \"F7\",\n            119: \"F8\",\n            120: \"F9\",\n            121: \"F10\",\n            122: \"F11\",\n            123: \"F12\",\n            144: \"Numlock\",\n            145: \"Scrolllock\"\n        },\n\n        PRINTABLE_KEYS: {\n           32: ' ',  48: '0',  49: '1',  50: '2',  51: '3',  52: '4', 53:  '5',\n           54: '6',  55: '7',  56: '8',  57: '9',  59: ';',  61: '=', 65:  'a',\n           66: 'b',  67: 'c',  68: 'd',  69: 'e',  70: 'f',  71: 'g', 72:  'h',\n           73: 'i',  74: 'j',  75: 'k',  76: 'l',  77: 'm',  78: 'n', 79:  'o',\n           80: 'p',  81: 'q',  82: 'r',  83: 's',  84: 't',  85: 'u', 86:  'v',\n           87: 'w',  88: 'x',  89: 'y',  90: 'z', 107: '+', 109: '-', 110: '.',\n          186: ';', 187: '=', 188: ',', 189: '-', 190: '.', 191: '/', 192: '`',\n          219: '[', 220: '\\\\',221: ']', 222: \"'\", 111: '/', 106: '*'\n        }\n    };\n    var name, i;\n    for (i in ret.FUNCTION_KEYS) {\n        name = ret.FUNCTION_KEYS[i].toLowerCase();\n        ret[name] = parseInt(i, 10);\n    }\n    for (i in ret.PRINTABLE_KEYS) {\n        name = ret.PRINTABLE_KEYS[i].toLowerCase();\n        ret[name] = parseInt(i, 10);\n    }\n    oop.mixin(ret, ret.MODIFIER_KEYS);\n    oop.mixin(ret, ret.PRINTABLE_KEYS);\n    oop.mixin(ret, ret.FUNCTION_KEYS);\n    ret.enter = ret[\"return\"];\n    ret.escape = ret.esc;\n    ret.del = ret[\"delete\"];\n    ret[173] = '-';\n    \n    (function() {\n        var mods = [\"cmd\", \"ctrl\", \"alt\", \"shift\"];\n        for (var i = Math.pow(2, mods.length); i--;) {            \n            ret.KEY_MODS[i] = mods.filter(function(x) {\n                return i & ret.KEY_MODS[x];\n            }).join(\"-\") + \"-\";\n        }\n    })();\n\n    ret.KEY_MODS[0] = \"\";\n    ret.KEY_MODS[-1] = \"input-\";\n\n    return ret;\n})();\noop.mixin(exports, Keys);\n\nexports.keyCodeToString = function(keyCode) {\n    var keyString = Keys[keyCode];\n    if (typeof keyString != \"string\")\n        keyString = String.fromCharCode(keyCode);\n    return keyString.toLowerCase();\n};\n\n});\n\nace.define(\"ace/lib/event\",[\"require\",\"exports\",\"module\",\"ace/lib/keys\",\"ace/lib/useragent\"], function(require, exports, module) {\n\"use strict\";\n\nvar keys = require(\"./keys\");\nvar useragent = require(\"./useragent\");\n\nvar pressedKeys = null;\nvar ts = 0;\n\nvar activeListenerOptions;\nfunction detectListenerOptionsSupport() {\n    activeListenerOptions = false;\n    try {\n        document.createComment(\"\").addEventListener(\"test\", function() {}, { \n            get passive() { \n                activeListenerOptions = {passive: false};\n            }\n        });\n    } catch(e) {}\n}\n\nfunction getListenerOptions() {\n    if (activeListenerOptions == undefined)\n        detectListenerOptionsSupport();\n    return activeListenerOptions;\n}\n\nexports.addListener = function(elem, type, callback) {\n    return elem.addEventListener(type, callback, getListenerOptions());\n};\n\nexports.removeListener = function(elem, type, callback) {\n    return elem.removeEventListener(type, callback, getListenerOptions());\n};\nexports.stopEvent = function(e) {\n    exports.stopPropagation(e);\n    exports.preventDefault(e);\n    return false;\n};\n\nexports.stopPropagation = function(e) {\n    if (e.stopPropagation)\n        e.stopPropagation();\n};\n\nexports.preventDefault = function(e) {\n    if (e.preventDefault)\n        e.preventDefault();\n};\nexports.getButton = function(e) {\n    if (e.type == \"dblclick\")\n        return 0;\n    if (e.type == \"contextmenu\" || (useragent.isMac && (e.ctrlKey && !e.altKey && !e.shiftKey)))\n        return 2;\n    return e.button;\n};\n\nexports.capture = function(el, eventHandler, releaseCaptureHandler) {\n    function onMouseUp(e) {\n        eventHandler && eventHandler(e);\n        releaseCaptureHandler && releaseCaptureHandler(e);\n\n        exports.removeListener(document, \"mousemove\", eventHandler, true);\n        exports.removeListener(document, \"mouseup\", onMouseUp, true);\n        exports.removeListener(document, \"dragstart\", onMouseUp, true);\n    }\n\n    exports.addListener(document, \"mousemove\", eventHandler, true);\n    exports.addListener(document, \"mouseup\", onMouseUp, true);\n    exports.addListener(document, \"dragstart\", onMouseUp, true);\n    \n    return onMouseUp;\n};\n\nexports.addMouseWheelListener = function(el, callback) {\n    if (\"onmousewheel\" in el) {\n        exports.addListener(el, \"mousewheel\", function(e) {\n            var factor = 8;\n            if (e.wheelDeltaX !== undefined) {\n                e.wheelX = -e.wheelDeltaX / factor;\n                e.wheelY = -e.wheelDeltaY / factor;\n            } else {\n                e.wheelX = 0;\n                e.wheelY = -e.wheelDelta / factor;\n            }\n            callback(e);\n        });\n    } else if (\"onwheel\" in el) {\n        exports.addListener(el, \"wheel\",  function(e) {\n            var factor = 0.35;\n            switch (e.deltaMode) {\n                case e.DOM_DELTA_PIXEL:\n                    e.wheelX = e.deltaX * factor || 0;\n                    e.wheelY = e.deltaY * factor || 0;\n                    break;\n                case e.DOM_DELTA_LINE:\n                case e.DOM_DELTA_PAGE:\n                    e.wheelX = (e.deltaX || 0) * 5;\n                    e.wheelY = (e.deltaY || 0) * 5;\n                    break;\n            }\n            \n            callback(e);\n        });\n    } else {\n        exports.addListener(el, \"DOMMouseScroll\", function(e) {\n            if (e.axis && e.axis == e.HORIZONTAL_AXIS) {\n                e.wheelX = (e.detail || 0) * 5;\n                e.wheelY = 0;\n            } else {\n                e.wheelX = 0;\n                e.wheelY = (e.detail || 0) * 5;\n            }\n            callback(e);\n        });\n    }\n};\n\nexports.addMultiMouseDownListener = function(elements, timeouts, eventHandler, callbackName) {\n    var clicks = 0;\n    var startX, startY, timer; \n    var eventNames = {\n        2: \"dblclick\",\n        3: \"tripleclick\",\n        4: \"quadclick\"\n    };\n\n    function onMousedown(e) {\n        if (exports.getButton(e) !== 0) {\n            clicks = 0;\n        } else if (e.detail > 1) {\n            clicks++;\n            if (clicks > 4)\n                clicks = 1;\n        } else {\n            clicks = 1;\n        }\n        if (useragent.isIE) {\n            var isNewClick = Math.abs(e.clientX - startX) > 5 || Math.abs(e.clientY - startY) > 5;\n            if (!timer || isNewClick)\n                clicks = 1;\n            if (timer)\n                clearTimeout(timer);\n            timer = setTimeout(function() {timer = null;}, timeouts[clicks - 1] || 600);\n\n            if (clicks == 1) {\n                startX = e.clientX;\n                startY = e.clientY;\n            }\n        }\n        \n        e._clicks = clicks;\n\n        eventHandler[callbackName](\"mousedown\", e);\n\n        if (clicks > 4)\n            clicks = 0;\n        else if (clicks > 1)\n            return eventHandler[callbackName](eventNames[clicks], e);\n    }\n    if (!Array.isArray(elements))\n        elements = [elements];\n    elements.forEach(function(el) {\n        exports.addListener(el, \"mousedown\", onMousedown);\n    });\n};\n\nvar getModifierHash = function(e) {\n    return 0 | (e.ctrlKey ? 1 : 0) | (e.altKey ? 2 : 0) | (e.shiftKey ? 4 : 0) | (e.metaKey ? 8 : 0);\n};\n\nexports.getModifierString = function(e) {\n    return keys.KEY_MODS[getModifierHash(e)];\n};\n\nfunction normalizeCommandKeys(callback, e, keyCode) {\n    var hashId = getModifierHash(e);\n\n    if (!useragent.isMac && pressedKeys) {\n        if (e.getModifierState && (e.getModifierState(\"OS\") || e.getModifierState(\"Win\")))\n            hashId |= 8;\n        if (pressedKeys.altGr) {\n            if ((3 & hashId) != 3)\n                pressedKeys.altGr = 0;\n            else\n                return;\n        }\n        if (keyCode === 18 || keyCode === 17) {\n            var location = \"location\" in e ? e.location : e.keyLocation;\n            if (keyCode === 17 && location === 1) {\n                if (pressedKeys[keyCode] == 1)\n                    ts = e.timeStamp;\n            } else if (keyCode === 18 && hashId === 3 && location === 2) {\n                var dt = e.timeStamp - ts;\n                if (dt < 50)\n                    pressedKeys.altGr = true;\n            }\n        }\n    }\n    \n    if (keyCode in keys.MODIFIER_KEYS) {\n        keyCode = -1;\n    }\n    \n    if (!hashId && keyCode === 13) {\n        var location = \"location\" in e ? e.location : e.keyLocation;\n        if (location === 3) {\n            callback(e, hashId, -keyCode);\n            if (e.defaultPrevented)\n                return;\n        }\n    }\n    \n    if (useragent.isChromeOS && hashId & 8) {\n        callback(e, hashId, keyCode);\n        if (e.defaultPrevented)\n            return;\n        else\n            hashId &= ~8;\n    }\n    if (!hashId && !(keyCode in keys.FUNCTION_KEYS) && !(keyCode in keys.PRINTABLE_KEYS)) {\n        return false;\n    }\n    \n    return callback(e, hashId, keyCode);\n}\n\n\nexports.addCommandKeyListener = function(el, callback) {\n    var addListener = exports.addListener;\n    if (useragent.isOldGecko || (useragent.isOpera && !(\"KeyboardEvent\" in window))) {\n        var lastKeyDownKeyCode = null;\n        addListener(el, \"keydown\", function(e) {\n            lastKeyDownKeyCode = e.keyCode;\n        });\n        addListener(el, \"keypress\", function(e) {\n            return normalizeCommandKeys(callback, e, lastKeyDownKeyCode);\n        });\n    } else {\n        var lastDefaultPrevented = null;\n\n        addListener(el, \"keydown\", function(e) {\n            pressedKeys[e.keyCode] = (pressedKeys[e.keyCode] || 0) + 1;\n            var result = normalizeCommandKeys(callback, e, e.keyCode);\n            lastDefaultPrevented = e.defaultPrevented;\n            return result;\n        });\n\n        addListener(el, \"keypress\", function(e) {\n            if (lastDefaultPrevented && (e.ctrlKey || e.altKey || e.shiftKey || e.metaKey)) {\n                exports.stopEvent(e);\n                lastDefaultPrevented = null;\n            }\n        });\n\n        addListener(el, \"keyup\", function(e) {\n            pressedKeys[e.keyCode] = null;\n        });\n\n        if (!pressedKeys) {\n            resetPressedKeys();\n            addListener(window, \"focus\", resetPressedKeys);\n        }\n    }\n};\nfunction resetPressedKeys() {\n    pressedKeys = Object.create(null);\n}\n\nif (typeof window == \"object\" && window.postMessage && !useragent.isOldIE) {\n    var postMessageId = 1;\n    exports.nextTick = function(callback, win) {\n        win = win || window;\n        var messageName = \"zero-timeout-message-\" + (postMessageId++);\n        \n        var listener = function(e) {\n            if (e.data == messageName) {\n                exports.stopPropagation(e);\n                exports.removeListener(win, \"message\", listener);\n                callback();\n            }\n        };\n        \n        exports.addListener(win, \"message\", listener);\n        win.postMessage(messageName, \"*\");\n    };\n}\n\nexports.$idleBlocked = false;\nexports.onIdle = function(cb, timeout) {\n    return setTimeout(function handler() {\n        if (!exports.$idleBlocked) {\n            cb();\n        } else {\n            setTimeout(handler, 100);\n        }\n    }, timeout);\n};\n\nexports.$idleBlockId = null;\nexports.blockIdle = function(delay) {\n    if (exports.$idleBlockId)\n        clearTimeout(exports.$idleBlockId);\n        \n    exports.$idleBlocked = true;\n    exports.$idleBlockId = setTimeout(function() {\n        exports.$idleBlocked = false;\n    }, delay || 100);\n};\n\nexports.nextFrame = typeof window == \"object\" && (window.requestAnimationFrame\n    || window.mozRequestAnimationFrame\n    || window.webkitRequestAnimationFrame\n    || window.msRequestAnimationFrame\n    || window.oRequestAnimationFrame);\n\nif (exports.nextFrame)\n    exports.nextFrame = exports.nextFrame.bind(window);\nelse\n    exports.nextFrame = function(callback) {\n        setTimeout(callback, 17);\n    };\n});\n\nace.define(\"ace/range\",[\"require\",\"exports\",\"module\"], function(require, exports, module) {\n\"use strict\";\nvar comparePoints = function(p1, p2) {\n    return p1.row - p2.row || p1.column - p2.column;\n};\nvar Range = function(startRow, startColumn, endRow, endColumn) {\n    this.start = {\n        row: startRow,\n        column: startColumn\n    };\n\n    this.end = {\n        row: endRow,\n        column: endColumn\n    };\n};\n\n(function() {\n    this.isEqual = function(range) {\n        return this.start.row === range.start.row &&\n            this.end.row === range.end.row &&\n            this.start.column === range.start.column &&\n            this.end.column === range.end.column;\n    };\n    this.toString = function() {\n        return (\"Range: [\" + this.start.row + \"/\" + this.start.column +\n            \"] -> [\" + this.end.row + \"/\" + this.end.column + \"]\");\n    };\n\n    this.contains = function(row, column) {\n        return this.compare(row, column) == 0;\n    };\n    this.compareRange = function(range) {\n        var cmp,\n            end = range.end,\n            start = range.start;\n\n        cmp = this.compare(end.row, end.column);\n        if (cmp == 1) {\n            cmp = this.compare(start.row, start.column);\n            if (cmp == 1) {\n                return 2;\n            } else if (cmp == 0) {\n                return 1;\n            } else {\n                return 0;\n            }\n        } else if (cmp == -1) {\n            return -2;\n        } else {\n            cmp = this.compare(start.row, start.column);\n            if (cmp == -1) {\n                return -1;\n            } else if (cmp == 1) {\n                return 42;\n            } else {\n                return 0;\n            }\n        }\n    };\n    this.comparePoint = function(p) {\n        return this.compare(p.row, p.column);\n    };\n    this.containsRange = function(range) {\n        return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0;\n    };\n    this.intersects = function(range) {\n        var cmp = this.compareRange(range);\n        return (cmp == -1 || cmp == 0 || cmp == 1);\n    };\n    this.isEnd = function(row, column) {\n        return this.end.row == row && this.end.column == column;\n    };\n    this.isStart = function(row, column) {\n        return this.start.row == row && this.start.column == column;\n    };\n    this.setStart = function(row, column) {\n        if (typeof row == \"object\") {\n            this.start.column = row.column;\n            this.start.row = row.row;\n        } else {\n            this.start.row = row;\n            this.start.column = column;\n        }\n    };\n    this.setEnd = function(row, column) {\n        if (typeof row == \"object\") {\n            this.end.column = row.column;\n            this.end.row = row.row;\n        } else {\n            this.end.row = row;\n            this.end.column = column;\n        }\n    };\n    this.inside = function(row, column) {\n        if (this.compare(row, column) == 0) {\n            if (this.isEnd(row, column) || this.isStart(row, column)) {\n                return false;\n            } else {\n                return true;\n            }\n        }\n        return false;\n    };\n    this.insideStart = function(row, column) {\n        if (this.compare(row, column) == 0) {\n            if (this.isEnd(row, column)) {\n                return false;\n            } else {\n                return true;\n            }\n        }\n        return false;\n    };\n    this.insideEnd = function(row, column) {\n        if (this.compare(row, column) == 0) {\n            if (this.isStart(row, column)) {\n                return false;\n            } else {\n                return true;\n            }\n        }\n        return false;\n    };\n    this.compare = function(row, column) {\n        if (!this.isMultiLine()) {\n            if (row === this.start.row) {\n                return column < this.start.column ? -1 : (column > this.end.column ? 1 : 0);\n            }\n        }\n\n        if (row < this.start.row)\n            return -1;\n\n        if (row > this.end.row)\n            return 1;\n\n        if (this.start.row === row)\n            return column >= this.start.column ? 0 : -1;\n\n        if (this.end.row === row)\n            return column <= this.end.column ? 0 : 1;\n\n        return 0;\n    };\n    this.compareStart = function(row, column) {\n        if (this.start.row == row && this.start.column == column) {\n            return -1;\n        } else {\n            return this.compare(row, column);\n        }\n    };\n    this.compareEnd = function(row, column) {\n        if (this.end.row == row && this.end.column == column) {\n            return 1;\n        } else {\n            return this.compare(row, column);\n        }\n    };\n    this.compareInside = function(row, column) {\n        if (this.end.row == row && this.end.column == column) {\n            return 1;\n        } else if (this.start.row == row && this.start.column == column) {\n            return -1;\n        } else {\n            return this.compare(row, column);\n        }\n    };\n    this.clipRows = function(firstRow, lastRow) {\n        if (this.end.row > lastRow)\n            var end = {row: lastRow + 1, column: 0};\n        else if (this.end.row < firstRow)\n            var end = {row: firstRow, column: 0};\n\n        if (this.start.row > lastRow)\n            var start = {row: lastRow + 1, column: 0};\n        else if (this.start.row < firstRow)\n            var start = {row: firstRow, column: 0};\n\n        return Range.fromPoints(start || this.start, end || this.end);\n    };\n    this.extend = function(row, column) {\n        var cmp = this.compare(row, column);\n\n        if (cmp == 0)\n            return this;\n        else if (cmp == -1)\n            var start = {row: row, column: column};\n        else\n            var end = {row: row, column: column};\n\n        return Range.fromPoints(start || this.start, end || this.end);\n    };\n\n    this.isEmpty = function() {\n        return (this.start.row === this.end.row && this.start.column === this.end.column);\n    };\n    this.isMultiLine = function() {\n        return (this.start.row !== this.end.row);\n    };\n    this.clone = function() {\n        return Range.fromPoints(this.start, this.end);\n    };\n    this.collapseRows = function() {\n        if (this.end.column == 0)\n            return new Range(this.start.row, 0, Math.max(this.start.row, this.end.row-1), 0);\n        else\n            return new Range(this.start.row, 0, this.end.row, 0);\n    };\n    this.toScreenRange = function(session) {\n        var screenPosStart = session.documentToScreenPosition(this.start);\n        var screenPosEnd = session.documentToScreenPosition(this.end);\n\n        return new Range(\n            screenPosStart.row, screenPosStart.column,\n            screenPosEnd.row, screenPosEnd.column\n        );\n    };\n    this.moveBy = function(row, column) {\n        this.start.row += row;\n        this.start.column += column;\n        this.end.row += row;\n        this.end.column += column;\n    };\n\n}).call(Range.prototype);\nRange.fromPoints = function(start, end) {\n    return new Range(start.row, start.column, end.row, end.column);\n};\nRange.comparePoints = comparePoints;\n\nRange.comparePoints = function(p1, p2) {\n    return p1.row - p2.row || p1.column - p2.column;\n};\n\n\nexports.Range = Range;\n});\n\nace.define(\"ace/lib/lang\",[\"require\",\"exports\",\"module\"], function(require, exports, module) {\n\"use strict\";\n\nexports.last = function(a) {\n    return a[a.length - 1];\n};\n\nexports.stringReverse = function(string) {\n    return string.split(\"\").reverse().join(\"\");\n};\n\nexports.stringRepeat = function (string, count) {\n    var result = '';\n    while (count > 0) {\n        if (count & 1)\n            result += string;\n\n        if (count >>= 1)\n            string += string;\n    }\n    return result;\n};\n\nvar trimBeginRegexp = /^\\s\\s*/;\nvar trimEndRegexp = /\\s\\s*$/;\n\nexports.stringTrimLeft = function (string) {\n    return string.replace(trimBeginRegexp, '');\n};\n\nexports.stringTrimRight = function (string) {\n    return string.replace(trimEndRegexp, '');\n};\n\nexports.copyObject = function(obj) {\n    var copy = {};\n    for (var key in obj) {\n        copy[key] = obj[key];\n    }\n    return copy;\n};\n\nexports.copyArray = function(array){\n    var copy = [];\n    for (var i=0, l=array.length; i<l; i++) {\n        if (array[i] && typeof array[i] == \"object\")\n            copy[i] = this.copyObject(array[i]);\n        else \n            copy[i] = array[i];\n    }\n    return copy;\n};\n\nexports.deepCopy = function deepCopy(obj) {\n    if (typeof obj !== \"object\" || !obj)\n        return obj;\n    var copy;\n    if (Array.isArray(obj)) {\n        copy = [];\n        for (var key = 0; key < obj.length; key++) {\n            copy[key] = deepCopy(obj[key]);\n        }\n        return copy;\n    }\n    if (Object.prototype.toString.call(obj) !== \"[object Object]\")\n        return obj;\n    \n    copy = {};\n    for (var key in obj)\n        copy[key] = deepCopy(obj[key]);\n    return copy;\n};\n\nexports.arrayToMap = function(arr) {\n    var map = {};\n    for (var i=0; i<arr.length; i++) {\n        map[arr[i]] = 1;\n    }\n    return map;\n\n};\n\nexports.createMap = function(props) {\n    var map = Object.create(null);\n    for (var i in props) {\n        map[i] = props[i];\n    }\n    return map;\n};\nexports.arrayRemove = function(array, value) {\n  for (var i = 0; i <= array.length; i++) {\n    if (value === array[i]) {\n      array.splice(i, 1);\n    }\n  }\n};\n\nexports.escapeRegExp = function(str) {\n    return str.replace(/([.*+?^${}()|[\\]\\/\\\\])/g, '\\\\$1');\n};\n\nexports.escapeHTML = function(str) {\n    return (\"\" + str).replace(/&/g, \"&#38;\").replace(/\"/g, \"&#34;\").replace(/'/g, \"&#39;\").replace(/</g, \"&#60;\");\n};\n\nexports.getMatchOffsets = function(string, regExp) {\n    var matches = [];\n\n    string.replace(regExp, function(str) {\n        matches.push({\n            offset: arguments[arguments.length-2],\n            length: str.length\n        });\n    });\n\n    return matches;\n};\nexports.deferredCall = function(fcn) {\n    var timer = null;\n    var callback = function() {\n        timer = null;\n        fcn();\n    };\n\n    var deferred = function(timeout) {\n        deferred.cancel();\n        timer = setTimeout(callback, timeout || 0);\n        return deferred;\n    };\n\n    deferred.schedule = deferred;\n\n    deferred.call = function() {\n        this.cancel();\n        fcn();\n        return deferred;\n    };\n\n    deferred.cancel = function() {\n        clearTimeout(timer);\n        timer = null;\n        return deferred;\n    };\n    \n    deferred.isPending = function() {\n        return timer;\n    };\n\n    return deferred;\n};\n\n\nexports.delayedCall = function(fcn, defaultTimeout) {\n    var timer = null;\n    var callback = function() {\n        timer = null;\n        fcn();\n    };\n\n    var _self = function(timeout) {\n        if (timer == null)\n            timer = setTimeout(callback, timeout || defaultTimeout);\n    };\n\n    _self.delay = function(timeout) {\n        timer && clearTimeout(timer);\n        timer = setTimeout(callback, timeout || defaultTimeout);\n    };\n    _self.schedule = _self;\n\n    _self.call = function() {\n        this.cancel();\n        fcn();\n    };\n\n    _self.cancel = function() {\n        timer && clearTimeout(timer);\n        timer = null;\n    };\n\n    _self.isPending = function() {\n        return timer;\n    };\n\n    return _self;\n};\n});\n\nace.define(\"ace/clipboard\",[\"require\",\"exports\",\"module\"], function(require, exports, module) {\n\"use strict\";\n\nvar $cancelT;\nmodule.exports = { \n    lineMode: false,\n    pasteCancelled: function() {\n        if ($cancelT && $cancelT > Date.now() - 50)\n            return true;\n        return $cancelT = false;\n    },\n    cancel: function() {\n        $cancelT = Date.now();\n    }\n};\n\n});\n\nace.define(\"ace/keyboard/textinput\",[\"require\",\"exports\",\"module\",\"ace/lib/event\",\"ace/lib/useragent\",\"ace/lib/dom\",\"ace/lib/lang\",\"ace/clipboard\",\"ace/lib/keys\"], function(require, exports, module) {\n\"use strict\";\n\nvar event = require(\"../lib/event\");\nvar useragent = require(\"../lib/useragent\");\nvar dom = require(\"../lib/dom\");\nvar lang = require(\"../lib/lang\");\nvar clipboard = require(\"../clipboard\");\nvar BROKEN_SETDATA = useragent.isChrome < 18;\nvar USE_IE_MIME_TYPE =  useragent.isIE;\nvar HAS_FOCUS_ARGS = useragent.isChrome > 63;\nvar MAX_LINE_LENGTH = 400;\n\nvar KEYS = require(\"../lib/keys\");\nvar MODS = KEYS.KEY_MODS;\nvar isIOS = useragent.isIOS;\nvar valueResetRegex = isIOS ? /\\s/ : /\\n/;\n\nvar TextInput = function(parentNode, host) {\n    var text = dom.createElement(\"textarea\");\n    text.className = \"ace_text-input\";\n\n    text.setAttribute(\"wrap\", \"off\");\n    text.setAttribute(\"autocorrect\", \"off\");\n    text.setAttribute(\"autocapitalize\", \"off\");\n    text.setAttribute(\"spellcheck\", false);\n\n    text.style.opacity = \"0\";\n    parentNode.insertBefore(text, parentNode.firstChild);\n\n    var copied = false;\n    var pasted = false;\n    var inComposition = false;\n    var sendingText = false;\n    var tempStyle = '';\n    \n    if (!useragent.isMobile)\n        text.style.fontSize = \"1px\";\n\n    var commandMode = false;\n    var ignoreFocusEvents = false;\n    \n    var lastValue = \"\";\n    var lastSelectionStart = 0;\n    var lastSelectionEnd = 0;\n    var lastRestoreEnd = 0;\n    try { var isFocused = document.activeElement === text; } catch(e) {}\n    \n    event.addListener(text, \"blur\", function(e) {\n        if (ignoreFocusEvents) return;\n        host.onBlur(e);\n        isFocused = false;\n    });\n    event.addListener(text, \"focus\", function(e) {\n        if (ignoreFocusEvents) return;\n        isFocused = true;\n        if (useragent.isEdge) {\n            try {\n                if (!document.hasFocus())\n                    return;\n            } catch(e) {}\n        }\n        host.onFocus(e);\n        if (useragent.isEdge)\n            setTimeout(resetSelection);\n        else\n            resetSelection();\n    });\n    this.$focusScroll = false;\n    this.focus = function() {\n        if (tempStyle || HAS_FOCUS_ARGS || this.$focusScroll == \"browser\")\n            return text.focus({ preventScroll: true });\n\n        var top = text.style.top;\n        text.style.position = \"fixed\";\n        text.style.top = \"0px\";\n        try {\n            var isTransformed = text.getBoundingClientRect().top != 0;\n        } catch(e) {\n            return;\n        }\n        var ancestors = [];\n        if (isTransformed) {\n            var t = text.parentElement;\n            while (t && t.nodeType == 1) {\n                ancestors.push(t);\n                t.setAttribute(\"ace_nocontext\", true);\n                if (!t.parentElement && t.getRootNode)\n                    t = t.getRootNode().host;\n                else\n                    t = t.parentElement;\n            }\n        }\n        text.focus({ preventScroll: true });\n        if (isTransformed) {\n            ancestors.forEach(function(p) {\n                p.removeAttribute(\"ace_nocontext\");\n            });\n        }\n        setTimeout(function() {\n            text.style.position = \"\";\n            if (text.style.top == \"0px\")\n                text.style.top = top;\n        }, 0);\n    };\n    this.blur = function() {\n        text.blur();\n    };\n    this.isFocused = function() {\n        return isFocused;\n    };\n    \n    host.on(\"beforeEndOperation\", function() {\n        if (host.curOp && host.curOp.command.name == \"insertstring\")\n            return;\n        if (inComposition) {\n            lastValue = text.value = \"\";\n            onCompositionEnd();\n        }\n        resetSelection();\n    });\n    \n    var resetSelection = isIOS\n    ? function(value) {\n        if (!isFocused || (copied && !value) || sendingText) return;\n        if (!value) \n            value = \"\";\n        var newValue = \"\\n ab\" + value + \"cde fg\\n\";\n        if (newValue != text.value)\n            text.value = lastValue = newValue;\n        \n        var selectionStart = 4;\n        var selectionEnd = 4 + (value.length || (host.selection.isEmpty() ? 0 : 1));\n\n        if (lastSelectionStart != selectionStart || lastSelectionEnd != selectionEnd) {\n            text.setSelectionRange(selectionStart, selectionEnd);\n        }\n        lastSelectionStart = selectionStart;\n        lastSelectionEnd = selectionEnd;\n    }\n    : function() {\n        if (inComposition || sendingText)\n            return;\n        if (!isFocused && !afterContextMenu)\n            return;\n        inComposition = true;\n        \n        var selection = host.selection;\n        var range = selection.getRange();\n        var row = selection.cursor.row;\n        var selectionStart = range.start.column;\n        var selectionEnd = range.end.column;\n        var line = host.session.getLine(row);\n\n        if (range.start.row != row) {\n            var prevLine = host.session.getLine(row - 1);\n            selectionStart = range.start.row < row - 1 ? 0 : selectionStart;\n            selectionEnd += prevLine.length + 1;\n            line = prevLine + \"\\n\" + line;\n        }\n        else if (range.end.row != row) {\n            var nextLine = host.session.getLine(row + 1);\n            selectionEnd = range.end.row > row  + 1 ? nextLine.length : selectionEnd;\n            selectionEnd += line.length + 1;\n            line = line + \"\\n\" + nextLine;\n        }\n\n        if (line.length > MAX_LINE_LENGTH) {\n            if (selectionStart < MAX_LINE_LENGTH && selectionEnd < MAX_LINE_LENGTH) {\n                line = line.slice(0, MAX_LINE_LENGTH);\n            } else {\n                line = \"\\n\";\n                selectionStart = 0;\n                selectionEnd = 1;\n            }\n        }\n\n        var newValue = line + \"\\n\\n\";\n        if (newValue != lastValue) {\n            text.value = lastValue = newValue;\n            lastSelectionStart = lastSelectionEnd = newValue.length;\n        }\n        if (afterContextMenu) {\n            lastSelectionStart = text.selectionStart;\n            lastSelectionEnd = text.selectionEnd;\n        }\n        if (\n            lastSelectionEnd != selectionEnd \n            || lastSelectionStart != selectionStart \n            || text.selectionEnd != lastSelectionEnd // on ie edge selectionEnd changes silently after the initialization\n        ) {\n            try {\n                text.setSelectionRange(selectionStart, selectionEnd);\n                lastSelectionStart = selectionStart;\n                lastSelectionEnd = selectionEnd;\n            } catch(e){}\n        }\n        inComposition = false;\n    };\n\n    if (isFocused)\n        host.onFocus();\n\n\n    var isAllSelected = function(text) {\n        return text.selectionStart === 0 && text.selectionEnd >= lastValue.length\n            && text.value === lastValue && lastValue\n            && text.selectionEnd !== lastSelectionEnd;\n    };\n\n    var onSelect = function(e) {\n        if (inComposition)\n            return;\n        if (copied) {\n            copied = false;\n        } else if (isAllSelected(text)) {\n            host.selectAll();\n            resetSelection();\n        }\n    };\n\n    var inputHandler = null;\n    this.setInputHandler = function(cb) {inputHandler = cb;};\n    this.getInputHandler = function() {return inputHandler;};\n    var afterContextMenu = false;\n    \n    var sendText = function(value, fromInput) {\n        if (afterContextMenu)\n            afterContextMenu = false;\n        if (pasted) {\n            resetSelection();\n            if (value)\n                host.onPaste(value);\n            pasted = false;\n            return \"\";\n        } else {\n            var selectionStart = text.selectionStart;\n            var selectionEnd = text.selectionEnd;\n        \n            var extendLeft = lastSelectionStart;\n            var extendRight = lastValue.length - lastSelectionEnd;\n            \n            var inserted = value;\n            var restoreStart = value.length - selectionStart;\n            var restoreEnd = value.length - selectionEnd;\n        \n            var i = 0;\n            while (extendLeft > 0 && lastValue[i] == value[i]) {\n                i++;\n                extendLeft--;\n            }\n            inserted = inserted.slice(i);\n            i = 1;\n            while (extendRight > 0 && lastValue.length - i > lastSelectionStart - 1  && lastValue[lastValue.length - i] == value[value.length - i]) {\n                i++;\n                extendRight--;\n            }\n            restoreStart -= i-1;\n            restoreEnd -= i-1;\n            var endIndex = inserted.length - i + 1;\n            if (endIndex < 0) {\n                extendLeft = -endIndex;\n                endIndex = 0;\n            } \n            inserted = inserted.slice(0, endIndex);\n            if (!fromInput && !inserted && !restoreStart && !extendLeft && !extendRight && !restoreEnd)\n                return \"\";\n            sendingText = true;\n            if (inserted && !extendLeft && !extendRight && !restoreStart && !restoreEnd || commandMode) {\n                host.onTextInput(inserted);\n            } else {\n                host.onTextInput(inserted, {\n                    extendLeft: extendLeft,\n                    extendRight: extendRight,\n                    restoreStart: restoreStart,\n                    restoreEnd: restoreEnd\n                });\n            }\n            sendingText = false;\n            \n            lastValue = value;\n            lastSelectionStart = selectionStart;\n            lastSelectionEnd = selectionEnd;\n            lastRestoreEnd = restoreEnd;\n            return inserted;\n        }\n    };\n    var onInput = function(e) {\n        if (inComposition)\n            return onCompositionUpdate();\n        if (e && e.inputType) {\n            if (e.inputType == \"historyUndo\") return host.execCommand(\"undo\");\n            if (e.inputType == \"historyRedo\") return host.execCommand(\"redo\");\n        }\n        var data = text.value;\n        var inserted = sendText(data, true);\n        if (data.length > MAX_LINE_LENGTH + 100 || valueResetRegex.test(inserted))\n            resetSelection();\n    };\n    \n    var handleClipboardData = function(e, data, forceIEMime) {\n        var clipboardData = e.clipboardData || window.clipboardData;\n        if (!clipboardData || BROKEN_SETDATA)\n            return;\n        var mime = USE_IE_MIME_TYPE || forceIEMime ? \"Text\" : \"text/plain\";\n        try {\n            if (data) {\n                return clipboardData.setData(mime, data) !== false;\n            } else {\n                return clipboardData.getData(mime);\n            }\n        } catch(e) {\n            if (!forceIEMime)\n                return handleClipboardData(e, data, true);\n        }\n    };\n\n    var doCopy = function(e, isCut) {\n        var data = host.getCopyText();\n        if (!data)\n            return event.preventDefault(e);\n\n        if (handleClipboardData(e, data)) {\n            if (isIOS) {\n                resetSelection(data);\n                copied = data;\n                setTimeout(function () {\n                    copied = false;\n                }, 10);\n            }\n            isCut ? host.onCut() : host.onCopy();\n            event.preventDefault(e);\n        } else {\n            copied = true;\n            text.value = data;\n            text.select();\n            setTimeout(function(){\n                copied = false;\n                resetSelection();\n                isCut ? host.onCut() : host.onCopy();\n            });\n        }\n    };\n    \n    var onCut = function(e) {\n        doCopy(e, true);\n    };\n    \n    var onCopy = function(e) {\n        doCopy(e, false);\n    };\n    \n    var onPaste = function(e) {\n        var data = handleClipboardData(e);\n        if (clipboard.pasteCancelled())\n            return;\n        if (typeof data == \"string\") {\n            if (data)\n                host.onPaste(data, e);\n            if (useragent.isIE)\n                setTimeout(resetSelection);\n            event.preventDefault(e);\n        }\n        else {\n            text.value = \"\";\n            pasted = true;\n        }\n    };\n\n    event.addCommandKeyListener(text, host.onCommandKey.bind(host));\n\n    event.addListener(text, \"select\", onSelect);\n    event.addListener(text, \"input\", onInput);\n\n    event.addListener(text, \"cut\", onCut);\n    event.addListener(text, \"copy\", onCopy);\n    event.addListener(text, \"paste\", onPaste);\n    if (!('oncut' in text) || !('oncopy' in text) || !('onpaste' in text)) {\n        event.addListener(parentNode, \"keydown\", function(e) {\n            if ((useragent.isMac && !e.metaKey) || !e.ctrlKey)\n                return;\n\n            switch (e.keyCode) {\n                case 67:\n                    onCopy(e);\n                    break;\n                case 86:\n                    onPaste(e);\n                    break;\n                case 88:\n                    onCut(e);\n                    break;\n            }\n        });\n    }\n    var onCompositionStart = function(e) {\n        if (inComposition || !host.onCompositionStart || host.$readOnly) \n            return;\n        \n        inComposition = {};\n\n        if (commandMode)\n            return;\n        \n        setTimeout(onCompositionUpdate, 0);\n        host.on(\"mousedown\", cancelComposition);\n        \n        var range = host.getSelectionRange();\n        range.end.row = range.start.row;\n        range.end.column = range.start.column;\n        inComposition.markerRange = range;\n        inComposition.selectionStart = lastSelectionStart;\n        host.onCompositionStart(inComposition);\n        \n        if (inComposition.useTextareaForIME) {\n            text.value = \"\";\n            lastValue = \"\";\n            lastSelectionStart = 0;\n            lastSelectionEnd = 0;\n        }\n        else {\n            if (text.msGetInputContext)\n                inComposition.context = text.msGetInputContext();\n            if (text.getInputContext)\n                inComposition.context = text.getInputContext();\n        }\n    };\n\n    var onCompositionUpdate = function() {\n        if (!inComposition || !host.onCompositionUpdate || host.$readOnly)\n            return;\n        if (commandMode)\n            return cancelComposition();\n        \n        if (inComposition.useTextareaForIME) {\n            host.onCompositionUpdate(text.value);\n        }\n        else {\n            var data = text.value;\n            sendText(data);\n            if (inComposition.markerRange) {\n                if (inComposition.context) {\n                    inComposition.markerRange.start.column = inComposition.selectionStart\n                        = inComposition.context.compositionStartOffset;\n                }\n                inComposition.markerRange.end.column = inComposition.markerRange.start.column\n                    + lastSelectionEnd - inComposition.selectionStart + lastRestoreEnd;\n            }\n        }\n    };\n\n    var onCompositionEnd = function(e) {\n        if (!host.onCompositionEnd || host.$readOnly) return;\n        inComposition = false;\n        host.onCompositionEnd();\n        host.off(\"mousedown\", cancelComposition);\n        if (e) onInput();\n    };\n    \n\n    function cancelComposition() {\n        ignoreFocusEvents = true;\n        text.blur();\n        text.focus();\n        ignoreFocusEvents = false;\n    }\n\n    var syncComposition = lang.delayedCall(onCompositionUpdate, 50).schedule.bind(null, null);\n    \n    function onKeyup(e) {\n        if (e.keyCode == 27 && text.value.length < text.selectionStart) {\n            if (!inComposition)\n                lastValue = text.value;\n            lastSelectionStart = lastSelectionEnd = -1;\n            resetSelection();\n        }\n        syncComposition();\n    }\n\n    event.addListener(text, \"compositionstart\", onCompositionStart);\n    event.addListener(text, \"compositionupdate\", onCompositionUpdate);\n    event.addListener(text, \"keyup\", onKeyup);\n    event.addListener(text, \"keydown\", syncComposition);\n    event.addListener(text, \"compositionend\", onCompositionEnd);\n\n    this.getElement = function() {\n        return text;\n    };\n    this.setCommandMode = function(value) {\n       commandMode = value;\n       text.readOnly = false;\n    };\n    \n    this.setReadOnly = function(readOnly) {\n        if (!commandMode)\n            text.readOnly = readOnly;\n    };\n\n    this.setCopyWithEmptySelection = function(value) {\n    };\n\n    this.onContextMenu = function(e) {\n        afterContextMenu = true;\n        resetSelection();\n        host._emit(\"nativecontextmenu\", {target: host, domEvent: e});\n        this.moveToMouse(e, true);\n    };\n    \n    this.moveToMouse = function(e, bringToFront) {\n        if (!tempStyle)\n            tempStyle = text.style.cssText;\n        text.style.cssText = (bringToFront ? \"z-index:100000;\" : \"\")\n            + (useragent.isIE ? \"opacity:0.1;\" : \"\")\n            + \"text-indent: -\" + (lastSelectionStart + lastSelectionEnd) * host.renderer.characterWidth * 0.5 + \"px;\";\n\n        var rect = host.container.getBoundingClientRect();\n        var style = dom.computedStyle(host.container);\n        var top = rect.top + (parseInt(style.borderTopWidth) || 0);\n        var left = rect.left + (parseInt(rect.borderLeftWidth) || 0);\n        var maxTop = rect.bottom - top - text.clientHeight -2;\n        var move = function(e) {\n            dom.translate(text, e.clientX - left - 2, Math.min(e.clientY - top - 2, maxTop));\n        }; \n        move(e);\n\n        if (e.type != \"mousedown\")\n            return;\n\n        host.renderer.$isMousePressed = true;\n\n        clearTimeout(closeTimeout);\n        if (useragent.isWin)\n            event.capture(host.container, move, onContextMenuClose);\n    };\n\n    this.onContextMenuClose = onContextMenuClose;\n    var closeTimeout;\n    function onContextMenuClose() {\n        clearTimeout(closeTimeout);\n        closeTimeout = setTimeout(function () {\n            if (tempStyle) {\n                text.style.cssText = tempStyle;\n                tempStyle = '';\n            }\n            host.renderer.$isMousePressed = false;\n            if (host.renderer.$keepTextAreaAtCursor)\n                host.renderer.$moveTextAreaToCursor();\n        }, 0);\n    }\n\n    var onContextMenu = function(e) {\n        host.textInput.onContextMenu(e);\n        onContextMenuClose();\n    };\n    event.addListener(text, \"mouseup\", onContextMenu);\n    event.addListener(text, \"mousedown\", function(e) {\n        e.preventDefault();\n        onContextMenuClose();\n    });\n    event.addListener(host.renderer.scroller, \"contextmenu\", onContextMenu);\n    event.addListener(text, \"contextmenu\", onContextMenu);\n    \n    if (isIOS)\n        addIosSelectionHandler(parentNode, host, text);\n\n    function addIosSelectionHandler(parentNode, host, text) {\n        var typingResetTimeout = null;\n        var typing = false;\n \n        text.addEventListener(\"keydown\", function (e) {\n            if (typingResetTimeout) clearTimeout(typingResetTimeout);\n            typing = true;\n        }, true);\n\n        text.addEventListener(\"keyup\", function (e) {\n            typingResetTimeout = setTimeout(function () {\n                typing = false;\n            }, 100);\n        }, true);\n        var detectArrowKeys = function(e) {\n            if (document.activeElement !== text) return;\n            if (typing || inComposition || host.$mouseHandler.isMousePressed) return;\n\n            if (copied) {\n                return;\n            }\n            var selectionStart = text.selectionStart;\n            var selectionEnd = text.selectionEnd;\n            \n            var key = null;\n            var modifier = 0;\n            if (selectionStart == 0) {\n                key = KEYS.up;\n            } else if (selectionStart == 1) {\n                key = KEYS.home;\n            } else if (selectionEnd > lastSelectionEnd && lastValue[selectionEnd] == \"\\n\") {\n                key = KEYS.end;\n            } else if (selectionStart < lastSelectionStart && lastValue[selectionStart - 1] == \" \") {\n                key = KEYS.left;\n                modifier = MODS.option;\n            } else if (\n                selectionStart < lastSelectionStart\n                || (\n                    selectionStart == lastSelectionStart \n                    && lastSelectionEnd != lastSelectionStart\n                    && selectionStart == selectionEnd\n                )\n            ) {\n                key = KEYS.left;\n            } else if (selectionEnd > lastSelectionEnd && lastValue.slice(0, selectionEnd).split(\"\\n\").length > 2) {\n                key = KEYS.down;\n            } else if (selectionEnd > lastSelectionEnd && lastValue[selectionEnd - 1] == \" \") {\n                key = KEYS.right;\n                modifier = MODS.option;\n            } else if (\n                selectionEnd > lastSelectionEnd\n                || (\n                    selectionEnd == lastSelectionEnd \n                    && lastSelectionEnd != lastSelectionStart\n                    && selectionStart == selectionEnd\n                )\n            ) {\n                key = KEYS.right;\n            }\n            \n            if (selectionStart !== selectionEnd)\n                modifier |= MODS.shift;\n\n            if (key) {\n                var result = host.onCommandKey({}, modifier, key);\n                if (!result && host.commands) {\n                    key = KEYS.keyCodeToString(key);\n                    var command = host.commands.findKeyCommand(modifier, key);\n                    if (command)\n                        host.execCommand(command);\n                }\n                lastSelectionStart = selectionStart;\n                lastSelectionEnd = selectionEnd;\n                resetSelection(\"\");\n            }\n        };\n        document.addEventListener(\"selectionchange\", detectArrowKeys);\n        host.on(\"destroy\", function() {\n            document.removeEventListener(\"selectionchange\", detectArrowKeys);\n        });\n    }\n\n};\n\nexports.TextInput = TextInput;\n});\n\nace.define(\"ace/mouse/default_handlers\",[\"require\",\"exports\",\"module\",\"ace/lib/useragent\"], function(require, exports, module) {\n\"use strict\";\n\nvar useragent = require(\"../lib/useragent\");\n\nvar DRAG_OFFSET = 0; // pixels\nvar SCROLL_COOLDOWN_T = 550; // milliseconds\n\nfunction DefaultHandlers(mouseHandler) {\n    mouseHandler.$clickSelection = null;\n\n    var editor = mouseHandler.editor;\n    editor.setDefaultHandler(\"mousedown\", this.onMouseDown.bind(mouseHandler));\n    editor.setDefaultHandler(\"dblclick\", this.onDoubleClick.bind(mouseHandler));\n    editor.setDefaultHandler(\"tripleclick\", this.onTripleClick.bind(mouseHandler));\n    editor.setDefaultHandler(\"quadclick\", this.onQuadClick.bind(mouseHandler));\n    editor.setDefaultHandler(\"mousewheel\", this.onMouseWheel.bind(mouseHandler));\n\n    var exports = [\"select\", \"startSelect\", \"selectEnd\", \"selectAllEnd\", \"selectByWordsEnd\",\n        \"selectByLinesEnd\", \"dragWait\", \"dragWaitEnd\", \"focusWait\"];\n\n    exports.forEach(function(x) {\n        mouseHandler[x] = this[x];\n    }, this);\n\n    mouseHandler.selectByLines = this.extendSelectionBy.bind(mouseHandler, \"getLineRange\");\n    mouseHandler.selectByWords = this.extendSelectionBy.bind(mouseHandler, \"getWordRange\");\n}\n\n(function() {\n\n    this.onMouseDown = function(ev) {\n        var inSelection = ev.inSelection();\n        var pos = ev.getDocumentPosition();\n        this.mousedownEvent = ev;\n        var editor = this.editor;\n\n        var button = ev.getButton();\n        if (button !== 0) {\n            var selectionRange = editor.getSelectionRange();\n            var selectionEmpty = selectionRange.isEmpty();\n            if (selectionEmpty || button == 1)\n                editor.selection.moveToPosition(pos);\n            if (button == 2) {\n                editor.textInput.onContextMenu(ev.domEvent);\n                if (!useragent.isMozilla)\n                    ev.preventDefault();\n            }\n            return;\n        }\n\n        this.mousedownEvent.time = Date.now();\n        if (inSelection && !editor.isFocused()) {\n            editor.focus();\n            if (this.$focusTimeout && !this.$clickSelection && !editor.inMultiSelectMode) {\n                this.setState(\"focusWait\");\n                this.captureMouse(ev);\n                return;\n            }\n        }\n\n        this.captureMouse(ev);\n        this.startSelect(pos, ev.domEvent._clicks > 1);\n        return ev.preventDefault();\n    };\n\n    this.startSelect = function(pos, waitForClickSelection) {\n        pos = pos || this.editor.renderer.screenToTextCoordinates(this.x, this.y);\n        var editor = this.editor;\n        if (!this.mousedownEvent) return;\n        if (this.mousedownEvent.getShiftKey())\n            editor.selection.selectToPosition(pos);\n        else if (!waitForClickSelection)\n            editor.selection.moveToPosition(pos);\n        if (!waitForClickSelection)\n            this.select();\n        if (editor.renderer.scroller.setCapture) {\n            editor.renderer.scroller.setCapture();\n        }\n        editor.setStyle(\"ace_selecting\");\n        this.setState(\"select\");\n    };\n\n    this.select = function() {\n        var anchor, editor = this.editor;\n        var cursor = editor.renderer.screenToTextCoordinates(this.x, this.y);\n        if (this.$clickSelection) {\n            var cmp = this.$clickSelection.comparePoint(cursor);\n\n            if (cmp == -1) {\n                anchor = this.$clickSelection.end;\n            } else if (cmp == 1) {\n                anchor = this.$clickSelection.start;\n            } else {\n                var orientedRange = calcRangeOrientation(this.$clickSelection, cursor);\n                cursor = orientedRange.cursor;\n                anchor = orientedRange.anchor;\n            }\n            editor.selection.setSelectionAnchor(anchor.row, anchor.column);\n        }\n        editor.selection.selectToPosition(cursor);\n        editor.renderer.scrollCursorIntoView();\n    };\n\n    this.extendSelectionBy = function(unitName) {\n        var anchor, editor = this.editor;\n        var cursor = editor.renderer.screenToTextCoordinates(this.x, this.y);\n        var range = editor.selection[unitName](cursor.row, cursor.column);\n        if (this.$clickSelection) {\n            var cmpStart = this.$clickSelection.comparePoint(range.start);\n            var cmpEnd = this.$clickSelection.comparePoint(range.end);\n\n            if (cmpStart == -1 && cmpEnd <= 0) {\n                anchor = this.$clickSelection.end;\n                if (range.end.row != cursor.row || range.end.column != cursor.column)\n                    cursor = range.start;\n            } else if (cmpEnd == 1 && cmpStart >= 0) {\n                anchor = this.$clickSelection.start;\n                if (range.start.row != cursor.row || range.start.column != cursor.column)\n                    cursor = range.end;\n            } else if (cmpStart == -1 && cmpEnd == 1) {\n                cursor = range.end;\n                anchor = range.start;\n            } else {\n                var orientedRange = calcRangeOrientation(this.$clickSelection, cursor);\n                cursor = orientedRange.cursor;\n                anchor = orientedRange.anchor;\n            }\n            editor.selection.setSelectionAnchor(anchor.row, anchor.column);\n        }\n        editor.selection.selectToPosition(cursor);\n        editor.renderer.scrollCursorIntoView();\n    };\n\n    this.selectEnd =\n    this.selectAllEnd =\n    this.selectByWordsEnd =\n    this.selectByLinesEnd = function() {\n        this.$clickSelection = null;\n        this.editor.unsetStyle(\"ace_selecting\");\n        if (this.editor.renderer.scroller.releaseCapture) {\n            this.editor.renderer.scroller.releaseCapture();\n        }\n    };\n\n    this.focusWait = function() {\n        var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y);\n        var time = Date.now();\n\n        if (distance > DRAG_OFFSET || time - this.mousedownEvent.time > this.$focusTimeout)\n            this.startSelect(this.mousedownEvent.getDocumentPosition());\n    };\n\n    this.onDoubleClick = function(ev) {\n        var pos = ev.getDocumentPosition();\n        var editor = this.editor;\n        var session = editor.session;\n\n        var range = session.getBracketRange(pos);\n        if (range) {\n            if (range.isEmpty()) {\n                range.start.column--;\n                range.end.column++;\n            }\n            this.setState(\"select\");\n        } else {\n            range = editor.selection.getWordRange(pos.row, pos.column);\n            this.setState(\"selectByWords\");\n        }\n        this.$clickSelection = range;\n        this.select();\n    };\n\n    this.onTripleClick = function(ev) {\n        var pos = ev.getDocumentPosition();\n        var editor = this.editor;\n\n        this.setState(\"selectByLines\");\n        var range = editor.getSelectionRange();\n        if (range.isMultiLine() && range.contains(pos.row, pos.column)) {\n            this.$clickSelection = editor.selection.getLineRange(range.start.row);\n            this.$clickSelection.end = editor.selection.getLineRange(range.end.row).end;\n        } else {\n            this.$clickSelection = editor.selection.getLineRange(pos.row);\n        }\n        this.select();\n    };\n\n    this.onQuadClick = function(ev) {\n        var editor = this.editor;\n\n        editor.selectAll();\n        this.$clickSelection = editor.getSelectionRange();\n        this.setState(\"selectAll\");\n    };\n\n    this.onMouseWheel = function(ev) {\n        if (ev.getAccelKey())\n            return;\n        if (ev.getShiftKey() && ev.wheelY && !ev.wheelX) {\n            ev.wheelX = ev.wheelY;\n            ev.wheelY = 0;\n        }\n        \n        var editor = this.editor;\n        \n        if (!this.$lastScroll)\n            this.$lastScroll = { t: 0, vx: 0, vy: 0, allowed: 0 };\n        \n        var prevScroll = this.$lastScroll;\n        var t = ev.domEvent.timeStamp;\n        var dt = t - prevScroll.t;\n        var vx = dt ? ev.wheelX / dt : prevScroll.vx;\n        var vy = dt ? ev.wheelY / dt : prevScroll.vy;\n        if (dt < SCROLL_COOLDOWN_T) {\n            vx = (vx + prevScroll.vx) / 2;\n            vy = (vy + prevScroll.vy) / 2;\n        }\n        \n        var direction = Math.abs(vx / vy);\n        \n        var canScroll = false;\n        if (direction >= 1 && editor.renderer.isScrollableBy(ev.wheelX * ev.speed, 0))\n            canScroll = true;\n        if (direction <= 1 && editor.renderer.isScrollableBy(0, ev.wheelY * ev.speed))\n            canScroll = true;\n            \n        if (canScroll) {\n            prevScroll.allowed = t;\n        } else if (t - prevScroll.allowed < SCROLL_COOLDOWN_T) {\n            var isSlower = Math.abs(vx) <= 1.5 * Math.abs(prevScroll.vx)\n                && Math.abs(vy) <= 1.5 * Math.abs(prevScroll.vy);\n            if (isSlower) {\n                canScroll = true;\n                prevScroll.allowed = t;\n            }\n            else {\n                prevScroll.allowed = 0;\n            }\n        }\n        \n        prevScroll.t = t;\n        prevScroll.vx = vx;\n        prevScroll.vy = vy;\n\n        if (canScroll) {\n            editor.renderer.scrollBy(ev.wheelX * ev.speed, ev.wheelY * ev.speed);\n            return ev.stop();\n        }\n    };\n\n}).call(DefaultHandlers.prototype);\n\nexports.DefaultHandlers = DefaultHandlers;\n\nfunction calcDistance(ax, ay, bx, by) {\n    return Math.sqrt(Math.pow(bx - ax, 2) + Math.pow(by - ay, 2));\n}\n\nfunction calcRangeOrientation(range, cursor) {\n    if (range.start.row == range.end.row)\n        var cmp = 2 * cursor.column - range.start.column - range.end.column;\n    else if (range.start.row == range.end.row - 1 && !range.start.column && !range.end.column)\n        var cmp = cursor.column - 4;\n    else\n        var cmp = 2 * cursor.row - range.start.row - range.end.row;\n\n    if (cmp < 0)\n        return {cursor: range.start, anchor: range.end};\n    else\n        return {cursor: range.end, anchor: range.start};\n}\n\n});\n\nace.define(\"ace/tooltip\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/dom\"], function(require, exports, module) {\n\"use strict\";\n\nvar oop = require(\"./lib/oop\");\nvar dom = require(\"./lib/dom\");\nfunction Tooltip (parentNode) {\n    this.isOpen = false;\n    this.$element = null;\n    this.$parentNode = parentNode;\n}\n\n(function() {\n    this.$init = function() {\n        this.$element = dom.createElement(\"div\");\n        this.$element.className = \"ace_tooltip\";\n        this.$element.style.display = \"none\";\n        this.$parentNode.appendChild(this.$element);\n        return this.$element;\n    };\n    this.getElement = function() {\n        return this.$element || this.$init();\n    };\n    this.setText = function(text) {\n        this.getElement().textContent = text;\n    };\n    this.setHtml = function(html) {\n        this.getElement().innerHTML = html;\n    };\n    this.setPosition = function(x, y) {\n        this.getElement().style.left = x + \"px\";\n        this.getElement().style.top = y + \"px\";\n    };\n    this.setClassName = function(className) {\n        dom.addCssClass(this.getElement(), className);\n    };\n    this.show = function(text, x, y) {\n        if (text != null)\n            this.setText(text);\n        if (x != null && y != null)\n            this.setPosition(x, y);\n        if (!this.isOpen) {\n            this.getElement().style.display = \"block\";\n            this.isOpen = true;\n        }\n    };\n\n    this.hide = function() {\n        if (this.isOpen) {\n            this.getElement().style.display = \"none\";\n            this.isOpen = false;\n        }\n    };\n    this.getHeight = function() {\n        return this.getElement().offsetHeight;\n    };\n    this.getWidth = function() {\n        return this.getElement().offsetWidth;\n    };\n    \n    this.destroy = function() {\n        this.isOpen = false;\n        if (this.$element && this.$element.parentNode) {\n            this.$element.parentNode.removeChild(this.$element);\n        }\n    };\n\n}).call(Tooltip.prototype);\n\nexports.Tooltip = Tooltip;\n});\n\nace.define(\"ace/mouse/default_gutter_handler\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\",\"ace/lib/oop\",\"ace/lib/event\",\"ace/tooltip\"], function(require, exports, module) {\n\"use strict\";\nvar dom = require(\"../lib/dom\");\nvar oop = require(\"../lib/oop\");\nvar event = require(\"../lib/event\");\nvar Tooltip = require(\"../tooltip\").Tooltip;\n\nfunction GutterHandler(mouseHandler) {\n    var editor = mouseHandler.editor;\n    var gutter = editor.renderer.$gutterLayer;\n    var tooltip = new GutterTooltip(editor.container);\n\n    mouseHandler.editor.setDefaultHandler(\"guttermousedown\", function(e) {\n        if (!editor.isFocused() || e.getButton() != 0)\n            return;\n        var gutterRegion = gutter.getRegion(e);\n\n        if (gutterRegion == \"foldWidgets\")\n            return;\n\n        var row = e.getDocumentPosition().row;\n        var selection = editor.session.selection;\n\n        if (e.getShiftKey())\n            selection.selectTo(row, 0);\n        else {\n            if (e.domEvent.detail == 2) {\n                editor.selectAll();\n                return e.preventDefault();\n            }\n            mouseHandler.$clickSelection = editor.selection.getLineRange(row);\n        }\n        mouseHandler.setState(\"selectByLines\");\n        mouseHandler.captureMouse(e);\n        return e.preventDefault();\n    });\n\n\n    var tooltipTimeout, mouseEvent, tooltipAnnotation;\n\n    function showTooltip() {\n        var row = mouseEvent.getDocumentPosition().row;\n        var annotation = gutter.$annotations[row];\n        if (!annotation)\n            return hideTooltip();\n\n        var maxRow = editor.session.getLength();\n        if (row == maxRow) {\n            var screenRow = editor.renderer.pixelToScreenCoordinates(0, mouseEvent.y).row;\n            var pos = mouseEvent.$pos;\n            if (screenRow > editor.session.documentToScreenRow(pos.row, pos.column))\n                return hideTooltip();\n        }\n\n        if (tooltipAnnotation == annotation)\n            return;\n        tooltipAnnotation = annotation.text.join(\"<br/>\");\n\n        tooltip.setHtml(tooltipAnnotation);\n        tooltip.show();\n        editor._signal(\"showGutterTooltip\", tooltip);\n        editor.on(\"mousewheel\", hideTooltip);\n\n        if (mouseHandler.$tooltipFollowsMouse) {\n            moveTooltip(mouseEvent);\n        } else {\n            var gutterElement = mouseEvent.domEvent.target;\n            var rect = gutterElement.getBoundingClientRect();\n            var style = tooltip.getElement().style;\n            style.left = rect.right + \"px\";\n            style.top = rect.bottom + \"px\";\n        }\n    }\n\n    function hideTooltip() {\n        if (tooltipTimeout)\n            tooltipTimeout = clearTimeout(tooltipTimeout);\n        if (tooltipAnnotation) {\n            tooltip.hide();\n            tooltipAnnotation = null;\n            editor._signal(\"hideGutterTooltip\", tooltip);\n            editor.removeEventListener(\"mousewheel\", hideTooltip);\n        }\n    }\n\n    function moveTooltip(e) {\n        tooltip.setPosition(e.x, e.y);\n    }\n\n    mouseHandler.editor.setDefaultHandler(\"guttermousemove\", function(e) {\n        var target = e.domEvent.target || e.domEvent.srcElement;\n        if (dom.hasCssClass(target, \"ace_fold-widget\"))\n            return hideTooltip();\n\n        if (tooltipAnnotation && mouseHandler.$tooltipFollowsMouse)\n            moveTooltip(e);\n\n        mouseEvent = e;\n        if (tooltipTimeout)\n            return;\n        tooltipTimeout = setTimeout(function() {\n            tooltipTimeout = null;\n            if (mouseEvent && !mouseHandler.isMousePressed)\n                showTooltip();\n            else\n                hideTooltip();\n        }, 50);\n    });\n\n    event.addListener(editor.renderer.$gutter, \"mouseout\", function(e) {\n        mouseEvent = null;\n        if (!tooltipAnnotation || tooltipTimeout)\n            return;\n\n        tooltipTimeout = setTimeout(function() {\n            tooltipTimeout = null;\n            hideTooltip();\n        }, 50);\n    });\n    \n    editor.on(\"changeSession\", hideTooltip);\n}\n\nfunction GutterTooltip(parentNode) {\n    Tooltip.call(this, parentNode);\n}\n\noop.inherits(GutterTooltip, Tooltip);\n\n(function(){\n    this.setPosition = function(x, y) {\n        var windowWidth = window.innerWidth || document.documentElement.clientWidth;\n        var windowHeight = window.innerHeight || document.documentElement.clientHeight;\n        var width = this.getWidth();\n        var height = this.getHeight();\n        x += 15;\n        y += 15;\n        if (x + width > windowWidth) {\n            x -= (x + width) - windowWidth;\n        }\n        if (y + height > windowHeight) {\n            y -= 20 + height;\n        }\n        Tooltip.prototype.setPosition.call(this, x, y);\n    };\n\n}).call(GutterTooltip.prototype);\n\n\n\nexports.GutterHandler = GutterHandler;\n\n});\n\nace.define(\"ace/mouse/mouse_event\",[\"require\",\"exports\",\"module\",\"ace/lib/event\",\"ace/lib/useragent\"], function(require, exports, module) {\n\"use strict\";\n\nvar event = require(\"../lib/event\");\nvar useragent = require(\"../lib/useragent\");\nvar MouseEvent = exports.MouseEvent = function(domEvent, editor) {\n    this.domEvent = domEvent;\n    this.editor = editor;\n    \n    this.x = this.clientX = domEvent.clientX;\n    this.y = this.clientY = domEvent.clientY;\n\n    this.$pos = null;\n    this.$inSelection = null;\n    \n    this.propagationStopped = false;\n    this.defaultPrevented = false;\n};\n\n(function() {  \n    \n    this.stopPropagation = function() {\n        event.stopPropagation(this.domEvent);\n        this.propagationStopped = true;\n    };\n    \n    this.preventDefault = function() {\n        event.preventDefault(this.domEvent);\n        this.defaultPrevented = true;\n    };\n    \n    this.stop = function() {\n        this.stopPropagation();\n        this.preventDefault();\n    };\n    this.getDocumentPosition = function() {\n        if (this.$pos)\n            return this.$pos;\n        \n        this.$pos = this.editor.renderer.screenToTextCoordinates(this.clientX, this.clientY);\n        return this.$pos;\n    };\n    this.inSelection = function() {\n        if (this.$inSelection !== null)\n            return this.$inSelection;\n            \n        var editor = this.editor;\n        \n\n        var selectionRange = editor.getSelectionRange();\n        if (selectionRange.isEmpty())\n            this.$inSelection = false;\n        else {\n            var pos = this.getDocumentPosition();\n            this.$inSelection = selectionRange.contains(pos.row, pos.column);\n        }\n\n        return this.$inSelection;\n    };\n    this.getButton = function() {\n        return event.getButton(this.domEvent);\n    };\n    this.getShiftKey = function() {\n        return this.domEvent.shiftKey;\n    };\n    \n    this.getAccelKey = useragent.isMac\n        ? function() { return this.domEvent.metaKey; }\n        : function() { return this.domEvent.ctrlKey; };\n    \n}).call(MouseEvent.prototype);\n\n});\n\nace.define(\"ace/mouse/dragdrop_handler\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\",\"ace/lib/event\",\"ace/lib/useragent\"], function(require, exports, module) {\n\"use strict\";\n\nvar dom = require(\"../lib/dom\");\nvar event = require(\"../lib/event\");\nvar useragent = require(\"../lib/useragent\");\n\nvar AUTOSCROLL_DELAY = 200;\nvar SCROLL_CURSOR_DELAY = 200;\nvar SCROLL_CURSOR_HYSTERESIS = 5;\n\nfunction DragdropHandler(mouseHandler) {\n\n    var editor = mouseHandler.editor;\n\n    var blankImage = dom.createElement(\"img\");\n    blankImage.src = \"data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\";\n    if (useragent.isOpera)\n        blankImage.style.cssText = \"width:1px;height:1px;position:fixed;top:0;left:0;z-index:2147483647;opacity:0;\";\n\n    var exports = [\"dragWait\", \"dragWaitEnd\", \"startDrag\", \"dragReadyEnd\", \"onMouseDrag\"];\n\n     exports.forEach(function(x) {\n         mouseHandler[x] = this[x];\n    }, this);\n    editor.addEventListener(\"mousedown\", this.onMouseDown.bind(mouseHandler));\n\n\n    var mouseTarget = editor.container;\n    var dragSelectionMarker, x, y;\n    var timerId, range;\n    var dragCursor, counter = 0;\n    var dragOperation;\n    var isInternal;\n    var autoScrollStartTime;\n    var cursorMovedTime;\n    var cursorPointOnCaretMoved;\n\n    this.onDragStart = function(e) {\n        if (this.cancelDrag || !mouseTarget.draggable) {\n            var self = this;\n            setTimeout(function(){\n                self.startSelect();\n                self.captureMouse(e);\n            }, 0);\n            return e.preventDefault();\n        }\n        range = editor.getSelectionRange();\n\n        var dataTransfer = e.dataTransfer;\n        dataTransfer.effectAllowed = editor.getReadOnly() ? \"copy\" : \"copyMove\";\n        if (useragent.isOpera) {\n            editor.container.appendChild(blankImage);\n            blankImage.scrollTop = 0;\n        }\n        dataTransfer.setDragImage && dataTransfer.setDragImage(blankImage, 0, 0);\n        if (useragent.isOpera) {\n            editor.container.removeChild(blankImage);\n        }\n        dataTransfer.clearData();\n        dataTransfer.setData(\"Text\", editor.session.getTextRange());\n\n        isInternal = true;\n        this.setState(\"drag\");\n    };\n\n    this.onDragEnd = function(e) {\n        mouseTarget.draggable = false;\n        isInternal = false;\n        this.setState(null);\n        if (!editor.getReadOnly()) {\n            var dropEffect = e.dataTransfer.dropEffect;\n            if (!dragOperation && dropEffect == \"move\")\n                editor.session.remove(editor.getSelectionRange());\n            editor.$resetCursorStyle();\n        }\n        this.editor.unsetStyle(\"ace_dragging\");\n        this.editor.renderer.setCursorStyle(\"\");\n    };\n\n    this.onDragEnter = function(e) {\n        if (editor.getReadOnly() || !canAccept(e.dataTransfer))\n            return;\n        x = e.clientX;\n        y = e.clientY;\n        if (!dragSelectionMarker)\n            addDragMarker();\n        counter++;\n        e.dataTransfer.dropEffect = dragOperation = getDropEffect(e);\n        return event.preventDefault(e);\n    };\n\n    this.onDragOver = function(e) {\n        if (editor.getReadOnly() || !canAccept(e.dataTransfer))\n            return;\n        x = e.clientX;\n        y = e.clientY;\n        if (!dragSelectionMarker) {\n            addDragMarker();\n            counter++;\n        }\n        if (onMouseMoveTimer !== null)\n            onMouseMoveTimer = null;\n\n        e.dataTransfer.dropEffect = dragOperation = getDropEffect(e);\n        return event.preventDefault(e);\n    };\n\n    this.onDragLeave = function(e) {\n        counter--;\n        if (counter <= 0 && dragSelectionMarker) {\n            clearDragMarker();\n            dragOperation = null;\n            return event.preventDefault(e);\n        }\n    };\n\n    this.onDrop = function(e) {\n        if (!dragCursor)\n            return;\n        var dataTransfer = e.dataTransfer;\n        if (isInternal) {\n            switch (dragOperation) {\n                case \"move\":\n                    if (range.contains(dragCursor.row, dragCursor.column)) {\n                        range = {\n                            start: dragCursor,\n                            end: dragCursor\n                        };\n                    } else {\n                        range = editor.moveText(range, dragCursor);\n                    }\n                    break;\n                case \"copy\":\n                    range = editor.moveText(range, dragCursor, true);\n                    break;\n            }\n        } else {\n            var dropData = dataTransfer.getData('Text');\n            range = {\n                start: dragCursor,\n                end: editor.session.insert(dragCursor, dropData)\n            };\n            editor.focus();\n            dragOperation = null;\n        }\n        clearDragMarker();\n        return event.preventDefault(e);\n    };\n\n    event.addListener(mouseTarget, \"dragstart\", this.onDragStart.bind(mouseHandler));\n    event.addListener(mouseTarget, \"dragend\", this.onDragEnd.bind(mouseHandler));\n    event.addListener(mouseTarget, \"dragenter\", this.onDragEnter.bind(mouseHandler));\n    event.addListener(mouseTarget, \"dragover\", this.onDragOver.bind(mouseHandler));\n    event.addListener(mouseTarget, \"dragleave\", this.onDragLeave.bind(mouseHandler));\n    event.addListener(mouseTarget, \"drop\", this.onDrop.bind(mouseHandler));\n\n    function scrollCursorIntoView(cursor, prevCursor) {\n        var now = Date.now();\n        var vMovement = !prevCursor || cursor.row != prevCursor.row;\n        var hMovement = !prevCursor || cursor.column != prevCursor.column;\n        if (!cursorMovedTime || vMovement || hMovement) {\n            editor.moveCursorToPosition(cursor);\n            cursorMovedTime = now;\n            cursorPointOnCaretMoved = {x: x, y: y};\n        } else {\n            var distance = calcDistance(cursorPointOnCaretMoved.x, cursorPointOnCaretMoved.y, x, y);\n            if (distance > SCROLL_CURSOR_HYSTERESIS) {\n                cursorMovedTime = null;\n            } else if (now - cursorMovedTime >= SCROLL_CURSOR_DELAY) {\n                editor.renderer.scrollCursorIntoView();\n                cursorMovedTime = null;\n            }\n        }\n    }\n\n    function autoScroll(cursor, prevCursor) {\n        var now = Date.now();\n        var lineHeight = editor.renderer.layerConfig.lineHeight;\n        var characterWidth = editor.renderer.layerConfig.characterWidth;\n        var editorRect = editor.renderer.scroller.getBoundingClientRect();\n        var offsets = {\n           x: {\n               left: x - editorRect.left,\n               right: editorRect.right - x\n           },\n           y: {\n               top: y - editorRect.top,\n               bottom: editorRect.bottom - y\n           }\n        };\n        var nearestXOffset = Math.min(offsets.x.left, offsets.x.right);\n        var nearestYOffset = Math.min(offsets.y.top, offsets.y.bottom);\n        var scrollCursor = {row: cursor.row, column: cursor.column};\n        if (nearestXOffset / characterWidth <= 2) {\n            scrollCursor.column += (offsets.x.left < offsets.x.right ? -3 : +2);\n        }\n        if (nearestYOffset / lineHeight <= 1) {\n            scrollCursor.row += (offsets.y.top < offsets.y.bottom ? -1 : +1);\n        }\n        var vScroll = cursor.row != scrollCursor.row;\n        var hScroll = cursor.column != scrollCursor.column;\n        var vMovement = !prevCursor || cursor.row != prevCursor.row;\n        if (vScroll || (hScroll && !vMovement)) {\n            if (!autoScrollStartTime)\n                autoScrollStartTime = now;\n            else if (now - autoScrollStartTime >= AUTOSCROLL_DELAY)\n                editor.renderer.scrollCursorIntoView(scrollCursor);\n        } else {\n            autoScrollStartTime = null;\n        }\n    }\n\n    function onDragInterval() {\n        var prevCursor = dragCursor;\n        dragCursor = editor.renderer.screenToTextCoordinates(x, y);\n        scrollCursorIntoView(dragCursor, prevCursor);\n        autoScroll(dragCursor, prevCursor);\n    }\n\n    function addDragMarker() {\n        range = editor.selection.toOrientedRange();\n        dragSelectionMarker = editor.session.addMarker(range, \"ace_selection\", editor.getSelectionStyle());\n        editor.clearSelection();\n        if (editor.isFocused())\n            editor.renderer.$cursorLayer.setBlinking(false);\n        clearInterval(timerId);\n        onDragInterval();\n        timerId = setInterval(onDragInterval, 20);\n        counter = 0;\n        event.addListener(document, \"mousemove\", onMouseMove);\n    }\n\n    function clearDragMarker() {\n        clearInterval(timerId);\n        editor.session.removeMarker(dragSelectionMarker);\n        dragSelectionMarker = null;\n        editor.selection.fromOrientedRange(range);\n        if (editor.isFocused() && !isInternal)\n            editor.$resetCursorStyle();\n        range = null;\n        dragCursor = null;\n        counter = 0;\n        autoScrollStartTime = null;\n        cursorMovedTime = null;\n        event.removeListener(document, \"mousemove\", onMouseMove);\n    }\n    var onMouseMoveTimer = null;\n    function onMouseMove() {\n        if (onMouseMoveTimer == null) {\n            onMouseMoveTimer = setTimeout(function() {\n                if (onMouseMoveTimer != null && dragSelectionMarker)\n                    clearDragMarker();\n            }, 20);\n        }\n    }\n\n    function canAccept(dataTransfer) {\n        var types = dataTransfer.types;\n        return !types || Array.prototype.some.call(types, function(type) {\n            return type == 'text/plain' || type == 'Text';\n        });\n    }\n\n    function getDropEffect(e) {\n        var copyAllowed = ['copy', 'copymove', 'all', 'uninitialized'];\n        var moveAllowed = ['move', 'copymove', 'linkmove', 'all', 'uninitialized'];\n\n        var copyModifierState = useragent.isMac ? e.altKey : e.ctrlKey;\n        var effectAllowed = \"uninitialized\";\n        try {\n            effectAllowed = e.dataTransfer.effectAllowed.toLowerCase();\n        } catch (e) {}\n        var dropEffect = \"none\";\n\n        if (copyModifierState && copyAllowed.indexOf(effectAllowed) >= 0)\n            dropEffect = \"copy\";\n        else if (moveAllowed.indexOf(effectAllowed) >= 0)\n            dropEffect = \"move\";\n        else if (copyAllowed.indexOf(effectAllowed) >= 0)\n            dropEffect = \"copy\";\n\n        return dropEffect;\n    }\n}\n\n(function() {\n\n    this.dragWait = function() {\n        var interval = Date.now() - this.mousedownEvent.time;\n        if (interval > this.editor.getDragDelay())\n            this.startDrag();\n    };\n\n    this.dragWaitEnd = function() {\n        var target = this.editor.container;\n        target.draggable = false;\n        this.startSelect(this.mousedownEvent.getDocumentPosition());\n        this.selectEnd();\n    };\n\n    this.dragReadyEnd = function(e) {\n        this.editor.$resetCursorStyle();\n        this.editor.unsetStyle(\"ace_dragging\");\n        this.editor.renderer.setCursorStyle(\"\");\n        this.dragWaitEnd();\n    };\n\n    this.startDrag = function(){\n        this.cancelDrag = false;\n        var editor = this.editor;\n        var target = editor.container;\n        target.draggable = true;\n        editor.renderer.$cursorLayer.setBlinking(false);\n        editor.setStyle(\"ace_dragging\");\n        var cursorStyle = useragent.isWin ? \"default\" : \"move\";\n        editor.renderer.setCursorStyle(cursorStyle);\n        this.setState(\"dragReady\");\n    };\n\n    this.onMouseDrag = function(e) {\n        var target = this.editor.container;\n        if (useragent.isIE && this.state == \"dragReady\") {\n            var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y);\n            if (distance > 3)\n                target.dragDrop();\n        }\n        if (this.state === \"dragWait\") {\n            var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y);\n            if (distance > 0) {\n                target.draggable = false;\n                this.startSelect(this.mousedownEvent.getDocumentPosition());\n            }\n        }\n    };\n\n    this.onMouseDown = function(e) {\n        if (!this.$dragEnabled)\n            return;\n        this.mousedownEvent = e;\n        var editor = this.editor;\n\n        var inSelection = e.inSelection();\n        var button = e.getButton();\n        var clickCount = e.domEvent.detail || 1;\n        if (clickCount === 1 && button === 0 && inSelection) {\n            if (e.editor.inMultiSelectMode && (e.getAccelKey() || e.getShiftKey()))\n                return;\n            this.mousedownEvent.time = Date.now();\n            var eventTarget = e.domEvent.target || e.domEvent.srcElement;\n            if (\"unselectable\" in eventTarget)\n                eventTarget.unselectable = \"on\";\n            if (editor.getDragDelay()) {\n                if (useragent.isWebKit) {\n                    this.cancelDrag = true;\n                    var mouseTarget = editor.container;\n                    mouseTarget.draggable = true;\n                }\n                this.setState(\"dragWait\");\n            } else {\n                this.startDrag();\n            }\n            this.captureMouse(e, this.onMouseDrag.bind(this));\n            e.defaultPrevented = true;\n        }\n    };\n\n}).call(DragdropHandler.prototype);\n\n\nfunction calcDistance(ax, ay, bx, by) {\n    return Math.sqrt(Math.pow(bx - ax, 2) + Math.pow(by - ay, 2));\n}\n\nexports.DragdropHandler = DragdropHandler;\n\n});\n\nace.define(\"ace/mouse/touch_handler\",[\"require\",\"exports\",\"module\",\"ace/mouse/mouse_event\",\"ace/lib/event\",\"ace/lib/dom\"], function(require, exports, module) {\n\"use strict\";\n\nvar MouseEvent = require(\"./mouse_event\").MouseEvent;\nvar event = require(\"../lib/event\");\nvar dom = require(\"../lib/dom\");\n\nexports.addTouchListeners = function(el, editor) {\n    var mode = \"scroll\";\n    var startX;\n    var startY;\n    var touchStartT;\n    var lastT;\n    var longTouchTimer;\n    var animationTimer;\n    var animationSteps = 0;\n    var pos;\n    var clickCount = 0;\n    var vX = 0;\n    var vY = 0;\n    var pressed;\n    var contextMenu;\n    \n    function createContextMenu() {\n        var clipboard = window.navigator && window.navigator.clipboard;\n        var isOpen = false;\n        var updateMenu = function() {\n            var selected = editor.getCopyText();\n            var hasUndo = editor.session.getUndoManager().hasUndo();\n            contextMenu.replaceChild(\n                dom.buildDom(isOpen ? [\"span\",\n                    !selected && [\"span\", { class: \"ace_mobile-button\", action: \"selectall\" }, \"Select All\"],\n                    selected && [\"span\", { class: \"ace_mobile-button\", action: \"copy\" }, \"Copy\"],\n                    selected && [\"span\", { class: \"ace_mobile-button\", action: \"cut\" }, \"Cut\"],\n                    clipboard && [\"span\", { class: \"ace_mobile-button\", action: \"paste\" }, \"Paste\"],\n                    hasUndo && [\"span\", { class: \"ace_mobile-button\", action: \"undo\" }, \"Undo\"],\n                    [\"span\", { class: \"ace_mobile-button\", action: \"find\" }, \"Find\"],\n                    [\"span\", { class: \"ace_mobile-button\", action: \"openCommandPallete\" }, \"Pallete\"]\n                ] : [\"span\"]),\n                contextMenu.firstChild\n            );\n        };\n        var handleClick = function(e) {\n            var action = e.target.getAttribute(\"action\");\n\n            if (action == \"more\" || !isOpen) {\n                isOpen = !isOpen;\n                return updateMenu();\n            }\n            if (action == \"paste\") {\n                clipboard.readText().then(function (text) {\n                    editor.execCommand(action, text);\n                });\n            }\n            else if (action) {\n                if (action == \"cut\" || action == \"copy\") {\n                    if (clipboard)\n                        clipboard.writeText(editor.getCopyText());\n                    else\n                        document.execCommand(\"copy\");\n                }\n                editor.execCommand(action);\n            }\n            contextMenu.firstChild.style.display = \"none\";\n            isOpen = false;\n            if (action != \"openCommandPallete\")\n                editor.focus();\n        };\n        contextMenu = dom.buildDom([\"div\",\n            {\n                class: \"ace_mobile-menu\",\n                ontouchstart: function(e) {\n                    mode = \"menu\";\n                    e.stopPropagation();\n                    e.preventDefault();\n                    editor.textInput.focus();\n                },\n                ontouchend: function(e) {\n                    e.stopPropagation();\n                    e.preventDefault();\n                    handleClick(e);\n                },\n                onclick: handleClick\n            },\n            [\"span\"],\n            [\"span\", { class: \"ace_mobile-button\", action: \"more\" }, \"...\"]\n        ], editor.container);\n    }\n    function showContextMenu() {\n        if (!contextMenu) createContextMenu();\n        var cursor = editor.selection.cursor;\n        var pagePos = editor.renderer.textToScreenCoordinates(cursor.row, cursor.column);\n        var rect = editor.container.getBoundingClientRect();\n        contextMenu.style.top = pagePos.pageY - rect.top - 3 + \"px\";\n        contextMenu.style.right = \"10px\";\n        contextMenu.style.display = \"\";\n        contextMenu.firstChild.style.display = \"none\";\n        editor.on(\"input\", hideContextMenu);\n    }\n    function hideContextMenu(e) {\n        if (contextMenu)\n            contextMenu.style.display = \"none\";\n        editor.off(\"input\", hideContextMenu);\n    }\n\n    function handleLongTap() {\n        longTouchTimer = null;\n        clearTimeout(longTouchTimer);\n        var range = editor.selection.getRange();\n        var inSelection = range.contains(pos.row, pos.column);\n        if (range.isEmpty() || !inSelection) {\n            editor.selection.moveToPosition(pos);\n            editor.selection.selectWord();\n        }\n        mode = \"wait\";\n        showContextMenu();\n    }\n    function switchToSelectionMode() {\n        longTouchTimer = null;\n        clearTimeout(longTouchTimer);\n        editor.selection.moveToPosition(pos);\n        var range = clickCount >= 2\n            ? editor.selection.getLineRange(pos.row)\n            : editor.session.getBracketRange(pos);\n        if (range && !range.isEmpty()) {\n            editor.selection.setRange(range);\n        } else {\n            editor.selection.selectWord();\n        }\n        mode = \"wait\";\n    }\n    event.addListener(el, \"contextmenu\", function(e) {\n        if (!pressed) return;\n        var textarea = editor.textInput.getElement();\n        textarea.focus();\n    });\n    event.addListener(el, \"touchstart\", function (e) {\n        var touches = e.touches;\n        if (longTouchTimer || touches.length > 1) {\n            clearTimeout(longTouchTimer);\n            longTouchTimer = null;\n            touchStartT = -1;\n            mode = \"zoom\";\n            return;\n        }\n        \n        pressed = editor.$mouseHandler.isMousePressed = true;\n        var h = editor.renderer.layerConfig.lineHeight;\n        var w = editor.renderer.layerConfig.lineHeight;\n        var t = e.timeStamp;\n        lastT = t;\n        var touchObj = touches[0];\n        var x = touchObj.clientX;\n        var y = touchObj.clientY;\n        if (Math.abs(startX - x) + Math.abs(startY - y) > h)\n            touchStartT = -1;\n        \n        startX = e.clientX = x;\n        startY = e.clientY = y;\n        vX = vY = 0;\n        \n        var ev = new MouseEvent(e, editor);\n        pos = ev.getDocumentPosition();\n\n        if (t - touchStartT < 500 && touches.length == 1 && !animationSteps) {\n            clickCount++;\n            e.preventDefault();\n            e.button = 0;\n            switchToSelectionMode();\n        } else {\n            clickCount = 0;\n            var cursor = editor.selection.cursor;\n            var anchor = editor.selection.isEmpty() ? cursor : editor.selection.anchor;\n            \n            var cursorPos = editor.renderer.$cursorLayer.getPixelPosition(cursor, true);\n            var anchorPos = editor.renderer.$cursorLayer.getPixelPosition(anchor, true);\n            var rect = editor.renderer.scroller.getBoundingClientRect();\n            var weightedDistance = function(x, y) {\n                x = x / w;\n                y = y / h - 0.75;\n                return x * x + y * y;\n            };\n            \n            if (e.clientX < rect.left) {\n                mode = \"zoom\";\n                return;\n            }\n            \n            var diff1 = weightedDistance(\n                e.clientX - rect.left - cursorPos.left,\n                e.clientY - rect.top - cursorPos.top\n            );\n            var diff2 = weightedDistance(\n                e.clientX - rect.left - anchorPos.left,\n                e.clientY - rect.top - anchorPos.top\n            );\n            if (diff1 < 3.5 && diff2 < 3.5)\n                mode = diff1 > diff2 ? \"cursor\" : \"anchor\";\n                \n            if (diff2 < 3.5)\n                mode = \"anchor\";\n            else if (diff1 < 3.5)\n                mode = \"cursor\";\n            else\n                mode = \"scroll\";\n            longTouchTimer = setTimeout(handleLongTap, 450);\n        }\n        touchStartT = t;\n    });\n\n    event.addListener(el, \"touchend\", function (e) {\n        pressed = editor.$mouseHandler.isMousePressed = false;\n        if (animationTimer) clearInterval(animationTimer);\n        if (mode == \"zoom\") {\n            mode = \"\";\n            animationSteps = 0;\n        } else if (longTouchTimer) {\n            editor.selection.moveToPosition(pos);\n            animationSteps = 0;\n            showContextMenu();\n        } else if (mode == \"scroll\") {\n            animate();\n            e.preventDefault();\n            hideContextMenu();\n        } else {\n            showContextMenu();\n        }\n        clearTimeout(longTouchTimer);\n        longTouchTimer = null;\n    });\n    event.addListener(el, \"touchmove\", function (e) {\n        if (longTouchTimer) {\n            clearTimeout(longTouchTimer);\n            longTouchTimer = null;\n        }\n        var touches = e.touches;\n        if (touches.length > 1 || mode == \"zoom\") return;\n\n        var touchObj = touches[0];\n\n        var wheelX = startX - touchObj.clientX;\n        var wheelY = startY - touchObj.clientY;\n\n        if (mode == \"wait\") {\n            if (wheelX * wheelX + wheelY * wheelY > 4)\n                mode = \"cursor\";\n            else\n                return e.preventDefault();\n        }\n\n        startX = touchObj.clientX;\n        startY = touchObj.clientY;\n\n        e.clientX = touchObj.clientX;\n        e.clientY = touchObj.clientY;\n\n        var t = e.timeStamp;\n        var dt = t - lastT;\n        lastT = t;\n        if (mode == \"scroll\") {\n            var mouseEvent = new MouseEvent(e, editor);\n            mouseEvent.speed = 1;\n            mouseEvent.wheelX = wheelX;\n            mouseEvent.wheelY = wheelY;\n            if (10 * Math.abs(wheelX) < Math.abs(wheelY)) wheelX = 0;\n            if (10 * Math.abs(wheelY) < Math.abs(wheelX)) wheelY = 0;\n            if (dt != 0) {\n                vX = wheelX / dt;\n                vY = wheelY / dt;\n            }\n            editor._emit(\"mousewheel\", mouseEvent);\n            if (!mouseEvent.propagationStopped) {\n                vX = vY = 0;\n            }\n        }\n        else {\n            var ev = new MouseEvent(e, editor);\n            var pos = ev.getDocumentPosition();\n            if (mode == \"cursor\")\n                editor.selection.moveCursorToPosition(pos);\n            else if (mode == \"anchor\")\n                editor.selection.setSelectionAnchor(pos.row, pos.column);\n            editor.renderer.scrollCursorIntoView(pos);\n            e.preventDefault();\n        }\n    });\n\n    function animate() {\n        animationSteps += 60;\n        animationTimer = setInterval(function() {\n            if (animationSteps-- <= 0) {\n                clearInterval(animationTimer);\n                animationTimer = null;\n            }\n            if (Math.abs(vX) < 0.01) vX = 0;\n            if (Math.abs(vY) < 0.01) vY = 0;\n            if (animationSteps < 20) vX = 0.9 * vX;\n            if (animationSteps < 20) vY = 0.9 * vY;\n            var oldScrollTop = editor.session.getScrollTop();\n            editor.renderer.scrollBy(10 * vX, 10 * vY);\n            if (oldScrollTop == editor.session.getScrollTop())\n                animationSteps = 0;\n        }, 10);\n    }\n};\n\n});\n\nace.define(\"ace/lib/net\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\"], function(require, exports, module) {\n\"use strict\";\nvar dom = require(\"./dom\");\n\nexports.get = function (url, callback) {\n    var xhr = new XMLHttpRequest();\n    xhr.open('GET', url, true);\n    xhr.onreadystatechange = function () {\n        if (xhr.readyState === 4) {\n            callback(xhr.responseText);\n        }\n    };\n    xhr.send(null);\n};\n\nexports.loadScript = function(path, callback) {\n    var head = dom.getDocumentHead();\n    var s = document.createElement('script');\n\n    s.src = path;\n    head.appendChild(s);\n\n    s.onload = s.onreadystatechange = function(_, isAbort) {\n        if (isAbort || !s.readyState || s.readyState == \"loaded\" || s.readyState == \"complete\") {\n            s = s.onload = s.onreadystatechange = null;\n            if (!isAbort)\n                callback();\n        }\n    };\n};\nexports.qualifyURL = function(url) {\n    var a = document.createElement('a');\n    a.href = url;\n    return a.href;\n};\n\n});\n\nace.define(\"ace/lib/event_emitter\",[\"require\",\"exports\",\"module\"], function(require, exports, module) {\n\"use strict\";\n\nvar EventEmitter = {};\nvar stopPropagation = function() { this.propagationStopped = true; };\nvar preventDefault = function() { this.defaultPrevented = true; };\n\nEventEmitter._emit =\nEventEmitter._dispatchEvent = function(eventName, e) {\n    this._eventRegistry || (this._eventRegistry = {});\n    this._defaultHandlers || (this._defaultHandlers = {});\n\n    var listeners = this._eventRegistry[eventName] || [];\n    var defaultHandler = this._defaultHandlers[eventName];\n    if (!listeners.length && !defaultHandler)\n        return;\n\n    if (typeof e != \"object\" || !e)\n        e = {};\n\n    if (!e.type)\n        e.type = eventName;\n    if (!e.stopPropagation)\n        e.stopPropagation = stopPropagation;\n    if (!e.preventDefault)\n        e.preventDefault = preventDefault;\n\n    listeners = listeners.slice();\n    for (var i=0; i<listeners.length; i++) {\n        listeners[i](e, this);\n        if (e.propagationStopped)\n            break;\n    }\n    \n    if (defaultHandler && !e.defaultPrevented)\n        return defaultHandler(e, this);\n};\n\n\nEventEmitter._signal = function(eventName, e) {\n    var listeners = (this._eventRegistry || {})[eventName];\n    if (!listeners)\n        return;\n    listeners = listeners.slice();\n    for (var i=0; i<listeners.length; i++)\n        listeners[i](e, this);\n};\n\nEventEmitter.once = function(eventName, callback) {\n    var _self = this;\n    this.addEventListener(eventName, function newCallback() {\n        _self.removeEventListener(eventName, newCallback);\n        callback.apply(null, arguments);\n    });\n    if (!callback) {\n        return new Promise(function(resolve) {\n            callback = resolve;\n        });\n    }\n};\n\n\nEventEmitter.setDefaultHandler = function(eventName, callback) {\n    var handlers = this._defaultHandlers;\n    if (!handlers)\n        handlers = this._defaultHandlers = {_disabled_: {}};\n    \n    if (handlers[eventName]) {\n        var old = handlers[eventName];\n        var disabled = handlers._disabled_[eventName];\n        if (!disabled)\n            handlers._disabled_[eventName] = disabled = [];\n        disabled.push(old);\n        var i = disabled.indexOf(callback);\n        if (i != -1) \n            disabled.splice(i, 1);\n    }\n    handlers[eventName] = callback;\n};\nEventEmitter.removeDefaultHandler = function(eventName, callback) {\n    var handlers = this._defaultHandlers;\n    if (!handlers)\n        return;\n    var disabled = handlers._disabled_[eventName];\n    \n    if (handlers[eventName] == callback) {\n        if (disabled)\n            this.setDefaultHandler(eventName, disabled.pop());\n    } else if (disabled) {\n        var i = disabled.indexOf(callback);\n        if (i != -1)\n            disabled.splice(i, 1);\n    }\n};\n\nEventEmitter.on =\nEventEmitter.addEventListener = function(eventName, callback, capturing) {\n    this._eventRegistry = this._eventRegistry || {};\n\n    var listeners = this._eventRegistry[eventName];\n    if (!listeners)\n        listeners = this._eventRegistry[eventName] = [];\n\n    if (listeners.indexOf(callback) == -1)\n        listeners[capturing ? \"unshift\" : \"push\"](callback);\n    return callback;\n};\n\nEventEmitter.off =\nEventEmitter.removeListener =\nEventEmitter.removeEventListener = function(eventName, callback) {\n    this._eventRegistry = this._eventRegistry || {};\n\n    var listeners = this._eventRegistry[eventName];\n    if (!listeners)\n        return;\n\n    var index = listeners.indexOf(callback);\n    if (index !== -1)\n        listeners.splice(index, 1);\n};\n\nEventEmitter.removeAllListeners = function(eventName) {\n    if (this._eventRegistry) this._eventRegistry[eventName] = [];\n};\n\nexports.EventEmitter = EventEmitter;\n\n});\n\nace.define(\"ace/lib/app_config\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/event_emitter\"], function(require, exports, module) {\n\"no use strict\";\n\nvar oop = require(\"./oop\");\nvar EventEmitter = require(\"./event_emitter\").EventEmitter;\n\nvar optionsProvider = {\n    setOptions: function(optList) {\n        Object.keys(optList).forEach(function(key) {\n            this.setOption(key, optList[key]);\n        }, this);\n    },\n    getOptions: function(optionNames) {\n        var result = {};\n        if (!optionNames) {\n            var options = this.$options;\n            optionNames = Object.keys(options).filter(function(key) {\n                return !options[key].hidden;\n            });\n        } else if (!Array.isArray(optionNames)) {\n            result = optionNames;\n            optionNames = Object.keys(result);\n        }\n        optionNames.forEach(function(key) {\n            result[key] = this.getOption(key);\n        }, this);\n        return result;\n    },\n    setOption: function(name, value) {\n        if (this[\"$\" + name] === value)\n            return;\n        var opt = this.$options[name];\n        if (!opt) {\n            return warn('misspelled option \"' + name + '\"');\n        }\n        if (opt.forwardTo)\n            return this[opt.forwardTo] && this[opt.forwardTo].setOption(name, value);\n\n        if (!opt.handlesSet)\n            this[\"$\" + name] = value;\n        if (opt && opt.set)\n            opt.set.call(this, value);\n    },\n    getOption: function(name) {\n        var opt = this.$options[name];\n        if (!opt) {\n            return warn('misspelled option \"' + name + '\"');\n        }\n        if (opt.forwardTo)\n            return this[opt.forwardTo] && this[opt.forwardTo].getOption(name);\n        return opt && opt.get ? opt.get.call(this) : this[\"$\" + name];\n    }\n};\n\nfunction warn(message) {\n    if (typeof console != \"undefined\" && console.warn)\n        console.warn.apply(console, arguments);\n}\n\nfunction reportError(msg, data) {\n    var e = new Error(msg);\n    e.data = data;\n    if (typeof console == \"object\" && console.error)\n        console.error(e);\n    setTimeout(function() { throw e; });\n}\n\nvar AppConfig = function() {\n    this.$defaultOptions = {};\n};\n\n(function() {\n    oop.implement(this, EventEmitter);\n    this.defineOptions = function(obj, path, options) {\n        if (!obj.$options)\n            this.$defaultOptions[path] = obj.$options = {};\n\n        Object.keys(options).forEach(function(key) {\n            var opt = options[key];\n            if (typeof opt == \"string\")\n                opt = {forwardTo: opt};\n\n            opt.name || (opt.name = key);\n            obj.$options[opt.name] = opt;\n            if (\"initialValue\" in opt)\n                obj[\"$\" + opt.name] = opt.initialValue;\n        });\n        oop.implement(obj, optionsProvider);\n\n        return this;\n    };\n\n    this.resetOptions = function(obj) {\n        Object.keys(obj.$options).forEach(function(key) {\n            var opt = obj.$options[key];\n            if (\"value\" in opt)\n                obj.setOption(key, opt.value);\n        });\n    };\n\n    this.setDefaultValue = function(path, name, value) {\n        if (!path) {\n            for (path in this.$defaultOptions)\n                if (this.$defaultOptions[path][name])\n                    break;\n            if (!this.$defaultOptions[path][name])\n                return false;\n        }\n        var opts = this.$defaultOptions[path] || (this.$defaultOptions[path] = {});\n        if (opts[name]) {\n            if (opts.forwardTo)\n                this.setDefaultValue(opts.forwardTo, name, value);\n            else\n                opts[name].value = value;\n        }\n    };\n\n    this.setDefaultValues = function(path, optionHash) {\n        Object.keys(optionHash).forEach(function(key) {\n            this.setDefaultValue(path, key, optionHash[key]);\n        }, this);\n    };\n    \n    this.warn = warn;\n    this.reportError = reportError;\n    \n}).call(AppConfig.prototype);\n\nexports.AppConfig = AppConfig;\n\n});\n\nace.define(\"ace/config\",[\"require\",\"exports\",\"module\",\"ace/lib/lang\",\"ace/lib/oop\",\"ace/lib/net\",\"ace/lib/app_config\"], function(require, exports, module) {\n\"no use strict\";\n\nvar lang = require(\"./lib/lang\");\nvar oop = require(\"./lib/oop\");\nvar net = require(\"./lib/net\");\nvar AppConfig = require(\"./lib/app_config\").AppConfig;\n\nmodule.exports = exports = new AppConfig();\n\nvar global = (function() {\n    return this || typeof window != \"undefined\" && window;\n})();\n\nvar options = {\n    packaged: false,\n    workerPath: null,\n    modePath: null,\n    themePath: null,\n    basePath: \"\",\n    suffix: \".js\",\n    $moduleUrls: {},\n    loadWorkerFromBlob: true,\n    sharedPopups: false\n};\n\nexports.get = function(key) {\n    if (!options.hasOwnProperty(key))\n        throw new Error(\"Unknown config key: \" + key);\n\n    return options[key];\n};\n\nexports.set = function(key, value) {\n    if (options.hasOwnProperty(key))\n        options[key] = value;\n    else if (this.setDefaultValue(\"\", key, value) == false)\n        throw new Error(\"Unknown config key: \" + key);\n};\n\nexports.all = function() {\n    return lang.copyObject(options);\n};\n\nexports.$modes = {};\nexports.moduleUrl = function(name, component) {\n    if (options.$moduleUrls[name])\n        return options.$moduleUrls[name];\n\n    var parts = name.split(\"/\");\n    component = component || parts[parts.length - 2] || \"\";\n    var sep = component == \"snippets\" ? \"/\" : \"-\";\n    var base = parts[parts.length - 1];\n    if (component == \"worker\" && sep == \"-\") {\n        var re = new RegExp(\"^\" + component + \"[\\\\-_]|[\\\\-_]\" + component + \"$\", \"g\");\n        base = base.replace(re, \"\");\n    }\n\n    if ((!base || base == component) && parts.length > 1)\n        base = parts[parts.length - 2];\n    var path = options[component + \"Path\"];\n    if (path == null) {\n        path = options.basePath;\n    } else if (sep == \"/\") {\n        component = sep = \"\";\n    }\n    if (path && path.slice(-1) != \"/\")\n        path += \"/\";\n    return path + component + sep + base + this.get(\"suffix\");\n};\n\nexports.setModuleUrl = function(name, subst) {\n    return options.$moduleUrls[name] = subst;\n};\n\nexports.$loading = {};\nexports.loadModule = function(moduleName, onLoad) {\n    var module, moduleType;\n    if (Array.isArray(moduleName)) {\n        moduleType = moduleName[0];\n        moduleName = moduleName[1];\n    }\n\n    try {\n        module = require(moduleName);\n    } catch (e) {}\n    if (module && !exports.$loading[moduleName])\n        return onLoad && onLoad(module);\n\n    if (!exports.$loading[moduleName])\n        exports.$loading[moduleName] = [];\n\n    exports.$loading[moduleName].push(onLoad);\n\n    if (exports.$loading[moduleName].length > 1)\n        return;\n\n    var afterLoad = function() {\n        require([moduleName], function(module) {\n            exports._emit(\"load.module\", {name: moduleName, module: module});\n            var listeners = exports.$loading[moduleName];\n            exports.$loading[moduleName] = null;\n            listeners.forEach(function(onLoad) {\n                onLoad && onLoad(module);\n            });\n        });\n    };\n\n    if (!exports.get(\"packaged\"))\n        return afterLoad();\n    \n    net.loadScript(exports.moduleUrl(moduleName, moduleType), afterLoad);\n    reportErrorIfPathIsNotConfigured();\n};\n\nvar reportErrorIfPathIsNotConfigured = function() {\n    if (\n        !options.basePath && !options.workerPath \n        && !options.modePath && !options.themePath\n        && !Object.keys(options.$moduleUrls).length\n    ) {\n        console.error(\n            \"Unable to infer path to ace from script src,\",\n            \"use ace.config.set('basePath', 'path') to enable dynamic loading of modes and themes\",\n            \"or with webpack use ace/webpack-resolver\"\n        );\n        reportErrorIfPathIsNotConfigured = function() {};\n    }\n};\ninit(true);function init(packaged) {\n\n    if (!global || !global.document)\n        return;\n    \n    options.packaged = packaged || require.packaged || module.packaged || (global.define && define.packaged);\n\n    var scriptOptions = {};\n    var scriptUrl = \"\";\n    var currentScript = (document.currentScript || document._currentScript ); // native or polyfill\n    var currentDocument = currentScript && currentScript.ownerDocument || document;\n    \n    var scripts = currentDocument.getElementsByTagName(\"script\");\n    for (var i=0; i<scripts.length; i++) {\n        var script = scripts[i];\n\n        var src = script.src || script.getAttribute(\"src\");\n        if (!src)\n            continue;\n\n        var attributes = script.attributes;\n        for (var j=0, l=attributes.length; j < l; j++) {\n            var attr = attributes[j];\n            if (attr.name.indexOf(\"data-ace-\") === 0) {\n                scriptOptions[deHyphenate(attr.name.replace(/^data-ace-/, \"\"))] = attr.value;\n            }\n        }\n\n        var m = src.match(/^(.*)\\/ace(\\-\\w+)?\\.js(\\?|$)/);\n        if (m)\n            scriptUrl = m[1];\n    }\n\n    if (scriptUrl) {\n        scriptOptions.base = scriptOptions.base || scriptUrl;\n        scriptOptions.packaged = true;\n    }\n\n    scriptOptions.basePath = scriptOptions.base;\n    scriptOptions.workerPath = scriptOptions.workerPath || scriptOptions.base;\n    scriptOptions.modePath = scriptOptions.modePath || scriptOptions.base;\n    scriptOptions.themePath = scriptOptions.themePath || scriptOptions.base;\n    delete scriptOptions.base;\n\n    for (var key in scriptOptions)\n        if (typeof scriptOptions[key] !== \"undefined\")\n            exports.set(key, scriptOptions[key]);\n}\n\nexports.init = init;\n\nfunction deHyphenate(str) {\n    return str.replace(/-(.)/g, function(m, m1) { return m1.toUpperCase(); });\n}\n\nexports.version = \"1.4.8\";\n\n});\n\nace.define(\"ace/mouse/mouse_handler\",[\"require\",\"exports\",\"module\",\"ace/lib/event\",\"ace/lib/useragent\",\"ace/mouse/default_handlers\",\"ace/mouse/default_gutter_handler\",\"ace/mouse/mouse_event\",\"ace/mouse/dragdrop_handler\",\"ace/mouse/touch_handler\",\"ace/config\"], function(require, exports, module) {\n\"use strict\";\n\nvar event = require(\"../lib/event\");\nvar useragent = require(\"../lib/useragent\");\nvar DefaultHandlers = require(\"./default_handlers\").DefaultHandlers;\nvar DefaultGutterHandler = require(\"./default_gutter_handler\").GutterHandler;\nvar MouseEvent = require(\"./mouse_event\").MouseEvent;\nvar DragdropHandler = require(\"./dragdrop_handler\").DragdropHandler;\nvar addTouchListeners = require(\"./touch_handler\").addTouchListeners;\nvar config = require(\"../config\");\n\nvar MouseHandler = function(editor) {\n    var _self = this;\n    this.editor = editor;\n\n    new DefaultHandlers(this);\n    new DefaultGutterHandler(this);\n    new DragdropHandler(this);\n\n    var focusEditor = function(e) {\n        var windowBlurred = !document.hasFocus || !document.hasFocus()\n            || !editor.isFocused() && document.activeElement == (editor.textInput && editor.textInput.getElement());\n        if (windowBlurred)\n            window.focus();\n        editor.focus();\n    };\n\n    var mouseTarget = editor.renderer.getMouseEventTarget();\n    event.addListener(mouseTarget, \"click\", this.onMouseEvent.bind(this, \"click\"));\n    event.addListener(mouseTarget, \"mousemove\", this.onMouseMove.bind(this, \"mousemove\"));\n    event.addMultiMouseDownListener([\n        mouseTarget,\n        editor.renderer.scrollBarV && editor.renderer.scrollBarV.inner,\n        editor.renderer.scrollBarH && editor.renderer.scrollBarH.inner,\n        editor.textInput && editor.textInput.getElement()\n    ].filter(Boolean), [400, 300, 250], this, \"onMouseEvent\");\n    event.addMouseWheelListener(editor.container, this.onMouseWheel.bind(this, \"mousewheel\"));\n    addTouchListeners(editor.container, editor);\n\n    var gutterEl = editor.renderer.$gutter;\n    event.addListener(gutterEl, \"mousedown\", this.onMouseEvent.bind(this, \"guttermousedown\"));\n    event.addListener(gutterEl, \"click\", this.onMouseEvent.bind(this, \"gutterclick\"));\n    event.addListener(gutterEl, \"dblclick\", this.onMouseEvent.bind(this, \"gutterdblclick\"));\n    event.addListener(gutterEl, \"mousemove\", this.onMouseEvent.bind(this, \"guttermousemove\"));\n\n    event.addListener(mouseTarget, \"mousedown\", focusEditor);\n    event.addListener(gutterEl, \"mousedown\", focusEditor);\n    if (useragent.isIE && editor.renderer.scrollBarV) {\n        event.addListener(editor.renderer.scrollBarV.element, \"mousedown\", focusEditor);\n        event.addListener(editor.renderer.scrollBarH.element, \"mousedown\", focusEditor);\n    }\n\n    editor.on(\"mousemove\", function(e){\n        if (_self.state || _self.$dragDelay || !_self.$dragEnabled)\n            return;\n\n        var character = editor.renderer.screenToTextCoordinates(e.x, e.y);\n        var range = editor.session.selection.getRange();\n        var renderer = editor.renderer;\n\n        if (!range.isEmpty() && range.insideStart(character.row, character.column)) {\n            renderer.setCursorStyle(\"default\");\n        } else {\n            renderer.setCursorStyle(\"\");\n        }\n    });\n};\n\n(function() {\n    this.onMouseEvent = function(name, e) {\n        this.editor._emit(name, new MouseEvent(e, this.editor));\n    };\n\n    this.onMouseMove = function(name, e) {\n        var listeners = this.editor._eventRegistry && this.editor._eventRegistry.mousemove;\n        if (!listeners || !listeners.length)\n            return;\n\n        this.editor._emit(name, new MouseEvent(e, this.editor));\n    };\n\n    this.onMouseWheel = function(name, e) {\n        var mouseEvent = new MouseEvent(e, this.editor);\n        mouseEvent.speed = this.$scrollSpeed * 2;\n        mouseEvent.wheelX = e.wheelX;\n        mouseEvent.wheelY = e.wheelY;\n\n        this.editor._emit(name, mouseEvent);\n    };\n    \n    this.setState = function(state) {\n        this.state = state;\n    };\n\n    this.captureMouse = function(ev, mouseMoveHandler) {\n        this.x = ev.x;\n        this.y = ev.y;\n\n        this.isMousePressed = true;\n        var editor = this.editor;\n        var renderer = this.editor.renderer;\n        renderer.$isMousePressed = true;\n\n        var self = this;\n        var onMouseMove = function(e) {\n            if (!e) return;\n            if (useragent.isWebKit && !e.which && self.releaseMouse)\n                return self.releaseMouse();\n\n            self.x = e.clientX;\n            self.y = e.clientY;\n            mouseMoveHandler && mouseMoveHandler(e);\n            self.mouseEvent = new MouseEvent(e, self.editor);\n            self.$mouseMoved = true;\n        };\n\n        var onCaptureEnd = function(e) {\n            editor.off(\"beforeEndOperation\", onOperationEnd);\n            clearInterval(timerId);\n            onCaptureInterval();\n            self[self.state + \"End\"] && self[self.state + \"End\"](e);\n            self.state = \"\";\n            self.isMousePressed = renderer.$isMousePressed = false;\n            if (renderer.$keepTextAreaAtCursor)\n                renderer.$moveTextAreaToCursor();\n            self.$onCaptureMouseMove = self.releaseMouse = null;\n            e && self.onMouseEvent(\"mouseup\", e);\n            editor.endOperation();\n        };\n\n        var onCaptureInterval = function() {\n            self[self.state] && self[self.state]();\n            self.$mouseMoved = false;\n        };\n\n        if (useragent.isOldIE && ev.domEvent.type == \"dblclick\") {\n            return setTimeout(function() {onCaptureEnd(ev);});\n        }\n\n        var onOperationEnd = function(e) {\n            if (!self.releaseMouse) return;\n            if (editor.curOp.command.name && editor.curOp.selectionChanged) {\n                self[self.state + \"End\"] && self[self.state + \"End\"]();\n                self.state = \"\";\n                self.releaseMouse();\n            }\n        };\n\n        editor.on(\"beforeEndOperation\", onOperationEnd);\n        editor.startOperation({command: {name: \"mouse\"}});\n\n        self.$onCaptureMouseMove = onMouseMove;\n        self.releaseMouse = event.capture(this.editor.container, onMouseMove, onCaptureEnd);\n        var timerId = setInterval(onCaptureInterval, 20);\n    };\n    this.releaseMouse = null;\n    this.cancelContextMenu = function() {\n        var stop = function(e) {\n            if (e && e.domEvent && e.domEvent.type != \"contextmenu\")\n                return;\n            this.editor.off(\"nativecontextmenu\", stop);\n            if (e && e.domEvent)\n                event.stopEvent(e.domEvent);\n        }.bind(this);\n        setTimeout(stop, 10);\n        this.editor.on(\"nativecontextmenu\", stop);\n    };\n}).call(MouseHandler.prototype);\n\nconfig.defineOptions(MouseHandler.prototype, \"mouseHandler\", {\n    scrollSpeed: {initialValue: 2},\n    dragDelay: {initialValue: (useragent.isMac ? 150 : 0)},\n    dragEnabled: {initialValue: true},\n    focusTimeout: {initialValue: 0},\n    tooltipFollowsMouse: {initialValue: true}\n});\n\n\nexports.MouseHandler = MouseHandler;\n});\n\nace.define(\"ace/mouse/fold_handler\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\"], function(require, exports, module) {\n\"use strict\";\nvar dom = require(\"../lib/dom\");\n\nfunction FoldHandler(editor) {\n\n    editor.on(\"click\", function(e) {\n        var position = e.getDocumentPosition();\n        var session = editor.session;\n        var fold = session.getFoldAt(position.row, position.column, 1);\n        if (fold) {\n            if (e.getAccelKey())\n                session.removeFold(fold);\n            else\n                session.expandFold(fold);\n\n            e.stop();\n        }\n        \n        var target = e.domEvent && e.domEvent.target;\n        if (target && dom.hasCssClass(target, \"ace_inline_button\")) {\n            if (dom.hasCssClass(target, \"ace_toggle_wrap\")) {\n                session.setOption(\"wrap\", !session.getUseWrapMode());\n                editor.renderer.scrollCursorIntoView();\n            }\n        }\n    });\n\n    editor.on(\"gutterclick\", function(e) {\n        var gutterRegion = editor.renderer.$gutterLayer.getRegion(e);\n\n        if (gutterRegion == \"foldWidgets\") {\n            var row = e.getDocumentPosition().row;\n            var session = editor.session;\n            if (session.foldWidgets && session.foldWidgets[row])\n                editor.session.onFoldWidgetClick(row, e);\n            if (!editor.isFocused())\n                editor.focus();\n            e.stop();\n        }\n    });\n\n    editor.on(\"gutterdblclick\", function(e) {\n        var gutterRegion = editor.renderer.$gutterLayer.getRegion(e);\n\n        if (gutterRegion == \"foldWidgets\") {\n            var row = e.getDocumentPosition().row;\n            var session = editor.session;\n            var data = session.getParentFoldRangeData(row, true);\n            var range = data.range || data.firstRange;\n\n            if (range) {\n                row = range.start.row;\n                var fold = session.getFoldAt(row, session.getLine(row).length, 1);\n\n                if (fold) {\n                    session.removeFold(fold);\n                } else {\n                    session.addFold(\"...\", range);\n                    editor.renderer.scrollCursorIntoView({row: range.start.row, column: 0});\n                }\n            }\n            e.stop();\n        }\n    });\n}\n\nexports.FoldHandler = FoldHandler;\n\n});\n\nace.define(\"ace/keyboard/keybinding\",[\"require\",\"exports\",\"module\",\"ace/lib/keys\",\"ace/lib/event\"], function(require, exports, module) {\n\"use strict\";\n\nvar keyUtil  = require(\"../lib/keys\");\nvar event = require(\"../lib/event\");\n\nvar KeyBinding = function(editor) {\n    this.$editor = editor;\n    this.$data = {editor: editor};\n    this.$handlers = [];\n    this.setDefaultHandler(editor.commands);\n};\n\n(function() {\n    this.setDefaultHandler = function(kb) {\n        this.removeKeyboardHandler(this.$defaultHandler);\n        this.$defaultHandler = kb;\n        this.addKeyboardHandler(kb, 0);\n    };\n\n    this.setKeyboardHandler = function(kb) {\n        var h = this.$handlers;\n        if (h[h.length - 1] == kb)\n            return;\n\n        while (h[h.length - 1] && h[h.length - 1] != this.$defaultHandler)\n            this.removeKeyboardHandler(h[h.length - 1]);\n\n        this.addKeyboardHandler(kb, 1);\n    };\n\n    this.addKeyboardHandler = function(kb, pos) {\n        if (!kb)\n            return;\n        if (typeof kb == \"function\" && !kb.handleKeyboard)\n            kb.handleKeyboard = kb;\n        var i = this.$handlers.indexOf(kb);\n        if (i != -1)\n            this.$handlers.splice(i, 1);\n\n        if (pos == undefined)\n            this.$handlers.push(kb);\n        else\n            this.$handlers.splice(pos, 0, kb);\n\n        if (i == -1 && kb.attach)\n            kb.attach(this.$editor);\n    };\n\n    this.removeKeyboardHandler = function(kb) {\n        var i = this.$handlers.indexOf(kb);\n        if (i == -1)\n            return false;\n        this.$handlers.splice(i, 1);\n        kb.detach && kb.detach(this.$editor);\n        return true;\n    };\n\n    this.getKeyboardHandler = function() {\n        return this.$handlers[this.$handlers.length - 1];\n    };\n    \n    this.getStatusText = function() {\n        var data = this.$data;\n        var editor = data.editor;\n        return this.$handlers.map(function(h) {\n            return h.getStatusText && h.getStatusText(editor, data) || \"\";\n        }).filter(Boolean).join(\" \");\n    };\n\n    this.$callKeyboardHandlers = function(hashId, keyString, keyCode, e) {\n        var toExecute;\n        var success = false;\n        var commands = this.$editor.commands;\n\n        for (var i = this.$handlers.length; i--;) {\n            toExecute = this.$handlers[i].handleKeyboard(\n                this.$data, hashId, keyString, keyCode, e\n            );\n            if (!toExecute || !toExecute.command)\n                continue;\n            if (toExecute.command == \"null\") {\n                success = true;\n            } else {\n                success = commands.exec(toExecute.command, this.$editor, toExecute.args, e);\n            }\n            if (success && e && hashId != -1 && \n                toExecute.passEvent != true && toExecute.command.passEvent != true\n            ) {\n                event.stopEvent(e);\n            }\n            if (success)\n                break;\n        }\n        \n        if (!success && hashId == -1) {\n            toExecute = {command: \"insertstring\"};\n            success = commands.exec(\"insertstring\", this.$editor, keyString);\n        }\n        \n        if (success && this.$editor._signal)\n            this.$editor._signal(\"keyboardActivity\", toExecute);\n        \n        return success;\n    };\n\n    this.onCommandKey = function(e, hashId, keyCode) {\n        var keyString = keyUtil.keyCodeToString(keyCode);\n        return this.$callKeyboardHandlers(hashId, keyString, keyCode, e);\n    };\n\n    this.onTextInput = function(text) {\n        return this.$callKeyboardHandlers(-1, text);\n    };\n\n}).call(KeyBinding.prototype);\n\nexports.KeyBinding = KeyBinding;\n});\n\nace.define(\"ace/lib/bidiutil\",[\"require\",\"exports\",\"module\"], function(require, exports, module) {\n\"use strict\";\n\nvar ArabicAlefBetIntervalsBegine = ['\\u0621', '\\u0641'];\nvar ArabicAlefBetIntervalsEnd = ['\\u063A', '\\u064a'];\nvar dir = 0, hiLevel = 0;\nvar lastArabic = false, hasUBAT_AL = false,  hasUBAT_B = false,  hasUBAT_S = false, hasBlockSep = false, hasSegSep = false;\n\nvar impTab_LTR = [\t[\t0,\t\t3,\t\t0,\t\t1,\t\t0,\t\t0,\t\t0\t],\t[\t0,\t\t3,\t\t0,\t\t1,\t\t2,\t\t2,\t\t0\t],\t[\t0,\t\t3,\t\t0,\t\t0x11,\t\t2,\t\t0,\t\t1\t],\t[\t0,\t\t3,\t\t5,\t\t5,\t\t4,\t\t1,\t\t0\t],\t[\t0,\t\t3,\t\t0x15,\t\t0x15,\t\t4,\t\t0,\t\t1\t],\t[\t0,\t\t3,\t\t5,\t\t5,\t\t4,\t\t2,\t\t0\t]\n];\n\nvar impTab_RTL = [\t[\t2,\t\t0,\t\t1,\t\t1,\t\t0,\t\t1,\t\t0\t],\t[\t2,\t\t0,\t\t1,\t\t1,\t\t0,\t\t2,\t\t0\t],\t[\t2,\t\t0,\t\t2,\t\t1,\t\t3,\t\t2,\t\t0\t],\t[\t2,\t\t0,\t\t2,\t\t0x21,\t\t3,\t\t1,\t\t1\t]\n];\n\nvar LTR = 0, RTL = 1;\n\nvar L = 0;\nvar R = 1;\nvar EN = 2;\nvar AN = 3;\nvar ON = 4;\nvar B = 5;\nvar S = 6;\nvar AL = 7;\nvar WS = 8;\nvar CS = 9;\nvar ES = 10;\nvar ET = 11;\nvar NSM = 12;\nvar LRE = 13;\nvar RLE = 14;\nvar PDF = 15;\nvar LRO = 16;\nvar RLO = 17;\nvar BN = 18;\n\nvar UnicodeTBL00 = [\nBN,BN,BN,BN,BN,BN,BN,BN,BN,S,B,S,WS,B,BN,BN,\nBN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,B,B,B,S,\nWS,ON,ON,ET,ET,ET,ON,ON,ON,ON,ON,ES,CS,ES,CS,CS,\nEN,EN,EN,EN,EN,EN,EN,EN,EN,EN,CS,ON,ON,ON,ON,ON,\nON,L,L,L,L,L,L,L,L,L,L,L,L,L,L,L,\nL,L,L,L,L,L,L,L,L,L,L,ON,ON,ON,ON,ON,\nON,L,L,L,L,L,L,L,L,L,L,L,L,L,L,L,\nL,L,L,L,L,L,L,L,L,L,L,ON,ON,ON,ON,BN,\nBN,BN,BN,BN,BN,B,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,\nBN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,\nCS,ON,ET,ET,ET,ET,ON,ON,ON,ON,L,ON,ON,BN,ON,ON,\nET,ET,EN,EN,ON,L,ON,ON,ON,EN,L,ON,ON,ON,ON,ON\n];\n\nvar UnicodeTBL20 = [\nWS,WS,WS,WS,WS,WS,WS,WS,WS,WS,WS,BN,BN,BN,L,R\t,\nON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,\nON,ON,ON,ON,ON,ON,ON,ON,WS,B,LRE,RLE,PDF,LRO,RLO,CS,\nET,ET,ET,ET,ET,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,\nON,ON,ON,ON,CS,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,\nON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,WS\n];\n\nfunction _computeLevels(chars, levels, len, charTypes) {\n\tvar impTab = dir ? impTab_RTL : impTab_LTR\n\t\t, prevState = null, newClass = null, newLevel = null, newState = 0\n\t\t, action = null, cond = null, condPos = -1, i = null, ix = null, classes = [];\n\n\tif (!charTypes) {\n\t\tfor (i = 0, charTypes = []; i < len; i++) {\n\t\t\tcharTypes[i] = _getCharacterType(chars[i]);\n\t\t}\n\t}\n\thiLevel = dir;\n\tlastArabic = false;\n\thasUBAT_AL = false;\n\thasUBAT_B = false;\n\thasUBAT_S = false;\n\tfor (ix = 0; ix < len; ix++){\n\t\tprevState = newState;\n\t\tclasses[ix] = newClass = _getCharClass(chars, charTypes, classes, ix);\n\t\tnewState = impTab[prevState][newClass];\n\t\taction = newState & 0xF0;\n\t\tnewState &= 0x0F;\n\t\tlevels[ix] = newLevel = impTab[newState][5];\n\t\tif (action > 0){\n\t\t\tif (action == 0x10){\n\t\t\t\tfor(i = condPos; i < ix; i++){\n\t\t\t\t\tlevels[i] = 1;\n\t\t\t\t}\n\t\t\t\tcondPos = -1;\n\t\t\t} else {\n\t\t\t\tcondPos = -1;\n\t\t\t}\n\t\t}\n\t\tcond = impTab[newState][6];\n\t\tif (cond){\n\t\t\tif(condPos == -1){\n\t\t\t\tcondPos = ix;\n\t\t\t}\n\t\t}else{\n\t\t\tif (condPos > -1){\n\t\t\t\tfor(i = condPos; i < ix; i++){\n\t\t\t\t\tlevels[i] = newLevel;\n\t\t\t\t}\n\t\t\t\tcondPos = -1;\n\t\t\t}\n\t\t}\n\t\tif (charTypes[ix] == B){\n\t\t\tlevels[ix] = 0;\n\t\t}\n\t\thiLevel |= newLevel;\n\t}\n\tif (hasUBAT_S){\n\t\tfor(i = 0; i < len; i++){\n\t\t\tif(charTypes[i] == S){\n\t\t\t\tlevels[i] = dir;\n\t\t\t\tfor(var j = i - 1; j >= 0; j--){\n\t\t\t\t\tif(charTypes[j] == WS){\n\t\t\t\t\t\tlevels[j] = dir;\n\t\t\t\t\t}else{\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction _invertLevel(lev, levels, _array) {\n\tif (hiLevel < lev){\n\t\treturn;\n\t}\n\tif (lev == 1 && dir == RTL && !hasUBAT_B){\n\t\t_array.reverse();\n\t\treturn;\n\t}\n\tvar len = _array.length, start = 0, end, lo, hi, tmp;\n\twhile(start < len){\n\t\tif (levels[start] >= lev){\n\t\t\tend = start + 1;\n\t\twhile(end < len && levels[end] >= lev){\n\t\t\tend++;\n\t\t}\n\t\tfor(lo = start, hi = end - 1 ; lo < hi; lo++, hi--){\n\t\t\ttmp = _array[lo];\n\t\t\t_array[lo] = _array[hi];\n\t\t\t_array[hi] = tmp;\n\t\t}\n\t\tstart = end;\n\t}\n\tstart++;\n\t}\n}\n\nfunction _getCharClass(chars, types, classes, ix) {\t\t\t\n\tvar cType = types[ix], wType, nType, len, i;\n\tswitch(cType){\n\t\tcase L:\n\t\tcase R:\n\t\t\tlastArabic = false;\n\t\tcase ON:\n\t\tcase AN:\n\t\t\treturn cType;\n\t\tcase EN:\n\t\t\treturn lastArabic ? AN : EN;\n\t\tcase AL:\n\t\t\tlastArabic = true;\n\t\t\thasUBAT_AL = true;\n\t\t\treturn R;\n\t\tcase WS:\n\t\t\treturn ON;\n\t\tcase CS:\n\t\t\tif (ix < 1 || (ix + 1) >= types.length ||\n\t\t\t\t((wType = classes[ix - 1]) != EN && wType != AN) ||\n\t\t\t\t((nType = types[ix + 1]) != EN && nType != AN)){\n\t\t\t\treturn ON;\n\t\t\t}\n\t\t\tif (lastArabic){nType = AN;}\n\t\t\treturn nType == wType ? nType : ON;\n\t\tcase ES:\n\t\t\twType = ix > 0 ? classes[ix - 1] : B;\n\t\t\tif (wType == EN && (ix + 1) < types.length && types[ix + 1] == EN){\n\t\t\t\treturn EN;\n\t\t\t}\n\t\t\treturn ON;\n\t\tcase ET:\n\t\t\tif (ix > 0 && classes[ix - 1] == EN){\n\t\t\t\treturn EN;\n\t\t\t}\n\t\t\tif (lastArabic){\n\t\t\t\treturn ON;\n\t\t\t}\n\t\t\ti = ix + 1;\n\t\t\tlen = types.length;\n\t\t\twhile (i < len && types[i] == ET){\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tif (i < len && types[i] == EN){\n\t\t\t\treturn EN;\n\t\t\t}\n\t\t\treturn ON;\n\t\tcase NSM:\n\t\t\tlen = types.length;\n\t\t\ti = ix + 1;\n\t\t\twhile (i < len && types[i] == NSM){\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tif (i < len){\n\t\t\t\tvar c = chars[ix], rtlCandidate = (c >= 0x0591 && c <= 0x08FF) || c == 0xFB1E;\n\t\t\t\t\n\t\t\t\twType = types[i];\n\t\t\t\tif (rtlCandidate && (wType == R || wType == AL)){\n\t\t\t\t\treturn R;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (ix < 1 || (wType = types[ix - 1]) == B){\n\t\t\t\treturn ON;\n\t\t\t}\n\t\t\treturn classes[ix - 1];\n\t\tcase B:\n\t\t\tlastArabic = false;\n\t\t\thasUBAT_B = true;\n\t\t\treturn dir;\n\t\tcase S:\n\t\t\thasUBAT_S = true;\n\t\t\treturn ON;\n\t\tcase LRE:\n\t\tcase RLE:\n\t\tcase LRO:\n\t\tcase RLO:\n\t\tcase PDF:\n\t\t\tlastArabic = false;\n\t\tcase BN:\n\t\t\treturn ON;\n\t}\n}\n\nfunction _getCharacterType( ch ) {\t\t\n\tvar uc = ch.charCodeAt(0), hi = uc >> 8;\n\t\n\tif (hi == 0) {\t\t\n\t\treturn ((uc > 0x00BF) ? L : UnicodeTBL00[uc]);\n\t} else if (hi == 5) {\n\t\treturn (/[\\u0591-\\u05f4]/.test(ch) ? R : L);\n\t} else if (hi == 6) {\n\t\tif (/[\\u0610-\\u061a\\u064b-\\u065f\\u06d6-\\u06e4\\u06e7-\\u06ed]/.test(ch))\n\t\t\treturn NSM;\n\t\telse if (/[\\u0660-\\u0669\\u066b-\\u066c]/.test(ch))\n\t\t\treturn AN;\n\t\telse if (uc == 0x066A)\n\t\t\treturn ET;\n\t\telse if (/[\\u06f0-\\u06f9]/.test(ch))\n\t\t\treturn EN;\t\t\t\n\t\telse\n\t\t\treturn AL;\n\t} else if (hi == 0x20 && uc <= 0x205F) {\n\t\treturn UnicodeTBL20[uc & 0xFF];\n\t} else if (hi == 0xFE) {\n\t\treturn (uc >= 0xFE70 ? AL : ON);\n\t}\t\t\n\treturn ON;\t\n}\n\nfunction _isArabicDiacritics( ch ) {\n\treturn (ch >= '\\u064b' && ch <= '\\u0655');\n}\nexports.L = L;\nexports.R = R;\nexports.EN = EN;\nexports.ON_R = 3;\nexports.AN = 4;\nexports.R_H = 5;\nexports.B = 6;\nexports.RLE = 7;\n\nexports.DOT = \"\\xB7\";\nexports.doBidiReorder = function(text, textCharTypes, isRtl) {\n\tif (text.length < 2)\n\t\treturn {};\n\t\t\n\tvar chars = text.split(\"\"), logicalFromVisual = new Array(chars.length),\n\t\tbidiLevels = new Array(chars.length), levels = []; \n\n\tdir = isRtl ? RTL : LTR;\n\n\t_computeLevels(chars, levels, chars.length, textCharTypes);\n\n\tfor (var i = 0; i < logicalFromVisual.length; logicalFromVisual[i] = i, i++);\n\n\t_invertLevel(2, levels, logicalFromVisual);\n\t_invertLevel(1, levels, logicalFromVisual);\n\n\tfor (var i = 0; i < logicalFromVisual.length - 1; i++) { //fix levels to reflect character width\n\t\tif (textCharTypes[i] === AN) {\n\t\t\tlevels[i] = exports.AN;\n\t\t} else if (levels[i] === R && ((textCharTypes[i] > AL && textCharTypes[i] < LRE) \n\t\t\t|| textCharTypes[i] === ON || textCharTypes[i] === BN)) {\n\t\t\tlevels[i] = exports.ON_R;\n\t\t} else if ((i > 0 && chars[i - 1] === '\\u0644') && /\\u0622|\\u0623|\\u0625|\\u0627/.test(chars[i])) {\n\t\t\tlevels[i - 1] = levels[i] = exports.R_H;\n\t\t\ti++;\n\t\t}\n\t}\n\tif (chars[chars.length - 1] === exports.DOT)\n\t\tlevels[chars.length - 1] = exports.B;\n\t\t\t\t\n\tif (chars[0] === '\\u202B')\n\t\tlevels[0] = exports.RLE;\n\t\t\t\t\n\tfor (var i = 0; i < logicalFromVisual.length; i++) {\n\t\tbidiLevels[i] = levels[logicalFromVisual[i]];\n\t}\n\n\treturn {'logicalFromVisual': logicalFromVisual, 'bidiLevels': bidiLevels};\n};\nexports.hasBidiCharacters = function(text, textCharTypes){\n\tvar ret = false;\n\tfor (var i = 0; i < text.length; i++){\n\t\ttextCharTypes[i] = _getCharacterType(text.charAt(i));\n\t\tif (!ret && (textCharTypes[i] == R || textCharTypes[i] == AL || textCharTypes[i] == AN))\n\t\t\tret = true;\n\t}\n\treturn ret;\n};\t\nexports.getVisualFromLogicalIdx = function(logIdx, rowMap) {\n\tfor (var i = 0; i < rowMap.logicalFromVisual.length; i++) {\n\t\tif (rowMap.logicalFromVisual[i] == logIdx)\n\t\t\treturn i;\n\t}\n\treturn 0;\n};\n\n});\n\nace.define(\"ace/bidihandler\",[\"require\",\"exports\",\"module\",\"ace/lib/bidiutil\",\"ace/lib/lang\"], function(require, exports, module) {\n\"use strict\";\n\nvar bidiUtil = require(\"./lib/bidiutil\");\nvar lang = require(\"./lib/lang\");\nvar bidiRE = /[\\u0590-\\u05f4\\u0600-\\u06ff\\u0700-\\u08ac\\u202B]/;\nvar BidiHandler = function(session) {\n    this.session = session;\n    this.bidiMap = {};\n    this.currentRow = null;\n    this.bidiUtil = bidiUtil;\n    this.charWidths = [];\n    this.EOL = \"\\xAC\";\n    this.showInvisibles = true;\n    this.isRtlDir = false;\n    this.$isRtl = false;\n    this.line = \"\";\n    this.wrapIndent = 0;\n    this.EOF = \"\\xB6\";\n    this.RLE = \"\\u202B\";\n    this.contentWidth = 0;\n    this.fontMetrics = null;\n    this.rtlLineOffset = 0;\n    this.wrapOffset = 0;\n    this.isMoveLeftOperation = false;\n    this.seenBidi = bidiRE.test(session.getValue());\n};\n\n(function() {\n    this.isBidiRow = function(screenRow, docRow, splitIndex) {\n        if (!this.seenBidi)\n            return false;\n        if (screenRow !== this.currentRow) {\n            this.currentRow = screenRow;\n            this.updateRowLine(docRow, splitIndex);\n            this.updateBidiMap();\n        }\n        return this.bidiMap.bidiLevels;\n    };\n\n    this.onChange = function(delta) {\n        if (!this.seenBidi) {\n            if (delta.action == \"insert\" && bidiRE.test(delta.lines.join(\"\\n\"))) {\n                this.seenBidi = true;\n                this.currentRow = null;\n            }\n        } \n        else {\n            this.currentRow = null;\n        }\n    };\n\n    this.getDocumentRow = function() {\n        var docRow = 0;\n        var rowCache = this.session.$screenRowCache;\n        if (rowCache.length) {\n            var index = this.session.$getRowCacheIndex(rowCache, this.currentRow);\n            if (index >= 0)\n                docRow = this.session.$docRowCache[index];\n        }\n\n        return docRow;\n    };\n\n    this.getSplitIndex = function() {\n        var splitIndex = 0;\n        var rowCache = this.session.$screenRowCache;\n        if (rowCache.length) {\n            var currentIndex, prevIndex = this.session.$getRowCacheIndex(rowCache, this.currentRow);\n            while (this.currentRow - splitIndex > 0) {\n                currentIndex = this.session.$getRowCacheIndex(rowCache, this.currentRow - splitIndex - 1);\n                if (currentIndex !== prevIndex)\n                    break;\n\n                prevIndex = currentIndex;\n                splitIndex++;\n            }\n        } else {\n            splitIndex = this.currentRow;\n        }\n\n        return splitIndex;\n    };\n\n    this.updateRowLine = function(docRow, splitIndex) {\n        if (docRow === undefined)\n            docRow = this.getDocumentRow();\n            \n        var isLastRow = (docRow === this.session.getLength() - 1),\n            endOfLine = isLastRow ? this.EOF : this.EOL;\n\n        this.wrapIndent = 0;\n        this.line = this.session.getLine(docRow);\n        this.isRtlDir = this.$isRtl || this.line.charAt(0) === this.RLE;\n        if (this.session.$useWrapMode) {\n            var splits = this.session.$wrapData[docRow];\n            if (splits) {\n                if (splitIndex === undefined)\n                    splitIndex = this.getSplitIndex();\n\n                if(splitIndex > 0 && splits.length) {\n                    this.wrapIndent = splits.indent;\n                    this.wrapOffset = this.wrapIndent * this.charWidths[bidiUtil.L];\n                    this.line = (splitIndex < splits.length) ?\n                        this.line.substring(splits[splitIndex - 1], splits[splitIndex]) :\n                            this.line.substring(splits[splits.length - 1]);\n                } else {\n                    this.line = this.line.substring(0, splits[splitIndex]);\n                }\n            }\n            if (splitIndex == splits.length)\n                this.line += (this.showInvisibles) ? endOfLine : bidiUtil.DOT;\n        } else {\n            this.line += this.showInvisibles ? endOfLine : bidiUtil.DOT;\n        }\n        var session = this.session, shift = 0, size;\n        this.line = this.line.replace(/\\t|[\\u1100-\\u2029, \\u202F-\\uFFE6]/g, function(ch, i){\n            if (ch === '\\t' || session.isFullWidth(ch.charCodeAt(0))) {\n                size = (ch === '\\t') ? session.getScreenTabSize(i + shift) : 2;\n                shift += size - 1;\n                return lang.stringRepeat(bidiUtil.DOT, size);\n            }\n            return ch;\n        });\n\n        if (this.isRtlDir) {\n            this.fontMetrics.$main.textContent = (this.line.charAt(this.line.length - 1) == bidiUtil.DOT) ? this.line.substr(0, this.line.length - 1) : this.line;\n            this.rtlLineOffset = this.contentWidth - this.fontMetrics.$main.getBoundingClientRect().width;\n        }\n    };\n    \n    this.updateBidiMap = function() {\n        var textCharTypes = [];\n        if (bidiUtil.hasBidiCharacters(this.line, textCharTypes) || this.isRtlDir) {\n             this.bidiMap = bidiUtil.doBidiReorder(this.line, textCharTypes, this.isRtlDir);\n        } else {\n            this.bidiMap = {};\n        }\n    };\n    this.markAsDirty = function() {\n        this.currentRow = null;\n    };\n    this.updateCharacterWidths = function(fontMetrics) {\n        if (this.characterWidth === fontMetrics.$characterSize.width)\n            return;\n\n        this.fontMetrics = fontMetrics;\n        var characterWidth = this.characterWidth = fontMetrics.$characterSize.width;\n        var bidiCharWidth = fontMetrics.$measureCharWidth(\"\\u05d4\");\n\n        this.charWidths[bidiUtil.L] = this.charWidths[bidiUtil.EN] = this.charWidths[bidiUtil.ON_R] = characterWidth;\n        this.charWidths[bidiUtil.R] = this.charWidths[bidiUtil.AN] = bidiCharWidth;\n        this.charWidths[bidiUtil.R_H] = bidiCharWidth * 0.45;\n        this.charWidths[bidiUtil.B] = this.charWidths[bidiUtil.RLE] = 0;\n\n        this.currentRow = null;\n    };\n\n    this.setShowInvisibles = function(showInvisibles) {\n        this.showInvisibles = showInvisibles;\n        this.currentRow = null;\n    };\n\n    this.setEolChar = function(eolChar) {\n        this.EOL = eolChar; \n    };\n\n    this.setContentWidth = function(width) {\n        this.contentWidth = width;\n    };\n\n    this.isRtlLine = function(row) {\n        if (this.$isRtl) return true;\n        if (row != undefined)\n            return (this.session.getLine(row).charAt(0) == this.RLE);\n        else\n            return this.isRtlDir; \n    };\n\n    this.setRtlDirection = function(editor, isRtlDir) {\n        var cursor = editor.getCursorPosition(); \n        for (var row = editor.selection.getSelectionAnchor().row; row <= cursor.row; row++) {\n            if (!isRtlDir && editor.session.getLine(row).charAt(0) === editor.session.$bidiHandler.RLE)\n                editor.session.doc.removeInLine(row, 0, 1);\n            else if (isRtlDir && editor.session.getLine(row).charAt(0) !== editor.session.$bidiHandler.RLE)\n                editor.session.doc.insert({column: 0, row: row}, editor.session.$bidiHandler.RLE);\n        }\n    };\n    this.getPosLeft = function(col) {\n        col -= this.wrapIndent;\n        var leftBoundary = (this.line.charAt(0) === this.RLE) ? 1 : 0;\n        var logicalIdx = (col > leftBoundary) ? (this.session.getOverwrite() ? col : col - 1) : leftBoundary;\n        var visualIdx = bidiUtil.getVisualFromLogicalIdx(logicalIdx, this.bidiMap),\n            levels = this.bidiMap.bidiLevels, left = 0;\n\n        if (!this.session.getOverwrite() && col <= leftBoundary && levels[visualIdx] % 2 !== 0)\n            visualIdx++;\n            \n        for (var i = 0; i < visualIdx; i++) {\n            left += this.charWidths[levels[i]];\n        }\n\n        if (!this.session.getOverwrite() && (col > leftBoundary) && (levels[visualIdx] % 2 === 0))\n            left += this.charWidths[levels[visualIdx]];\n\n        if (this.wrapIndent)\n            left += this.isRtlDir ? (-1 * this.wrapOffset) : this.wrapOffset;\n\n        if (this.isRtlDir)\n            left += this.rtlLineOffset;\n\n        return left;\n    };\n    this.getSelections = function(startCol, endCol) {\n        var map = this.bidiMap, levels = map.bidiLevels, level, selections = [], offset = 0,\n            selColMin = Math.min(startCol, endCol) - this.wrapIndent, selColMax = Math.max(startCol, endCol) - this.wrapIndent,\n                isSelected = false, isSelectedPrev = false, selectionStart = 0;\n            \n        if (this.wrapIndent)\n            offset += this.isRtlDir ? (-1 * this.wrapOffset) : this.wrapOffset;\n\n        for (var logIdx, visIdx = 0; visIdx < levels.length; visIdx++) {\n            logIdx = map.logicalFromVisual[visIdx];\n            level = levels[visIdx];\n            isSelected = (logIdx >= selColMin) && (logIdx < selColMax);\n            if (isSelected && !isSelectedPrev) {\n                selectionStart = offset;\n            } else if (!isSelected && isSelectedPrev) {\n                selections.push({left: selectionStart, width: offset - selectionStart});\n            }\n            offset += this.charWidths[level];\n            isSelectedPrev = isSelected;\n        }\n\n        if (isSelected && (visIdx === levels.length)) {\n            selections.push({left: selectionStart, width: offset - selectionStart});\n        }\n\n        if(this.isRtlDir) {\n            for (var i = 0; i < selections.length; i++) {\n                selections[i].left += this.rtlLineOffset;\n            }\n        }\n        return selections;\n    };\n    this.offsetToCol = function(posX) {\n        if(this.isRtlDir)\n            posX -= this.rtlLineOffset;\n\n        var logicalIdx = 0, posX = Math.max(posX, 0),\n            offset = 0, visualIdx = 0, levels = this.bidiMap.bidiLevels,\n                charWidth = this.charWidths[levels[visualIdx]];\n\n        if (this.wrapIndent)\n           posX -= this.isRtlDir ? (-1 * this.wrapOffset) : this.wrapOffset;\n    \n        while(posX > offset + charWidth/2) {\n            offset += charWidth;\n            if(visualIdx === levels.length - 1) {\n                charWidth = 0;\n                break;\n            }\n            charWidth = this.charWidths[levels[++visualIdx]];\n        }\n    \n        if (visualIdx > 0 && (levels[visualIdx - 1] % 2 !== 0) && (levels[visualIdx] % 2 === 0)){\n            if(posX < offset)\n                visualIdx--;\n            logicalIdx = this.bidiMap.logicalFromVisual[visualIdx];\n\n        } else if (visualIdx > 0 && (levels[visualIdx - 1] % 2 === 0) && (levels[visualIdx] % 2 !== 0)){\n            logicalIdx = 1 + ((posX > offset) ? this.bidiMap.logicalFromVisual[visualIdx]\n                    : this.bidiMap.logicalFromVisual[visualIdx - 1]);\n\n        } else if ((this.isRtlDir && visualIdx === levels.length - 1 && charWidth === 0 && (levels[visualIdx - 1] % 2 === 0))\n                || (!this.isRtlDir && visualIdx === 0 && (levels[visualIdx] % 2 !== 0))){\n            logicalIdx = 1 + this.bidiMap.logicalFromVisual[visualIdx];\n        } else {\n            if (visualIdx > 0 && (levels[visualIdx - 1] % 2 !== 0) && charWidth !== 0)\n                visualIdx--;\n            logicalIdx = this.bidiMap.logicalFromVisual[visualIdx];\n        }\n\n        if (logicalIdx === 0 && this.isRtlDir)\n            logicalIdx++;\n\n        return (logicalIdx + this.wrapIndent);\n    };\n\n}).call(BidiHandler.prototype);\n\nexports.BidiHandler = BidiHandler;\n});\n\nace.define(\"ace/selection\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/lang\",\"ace/lib/event_emitter\",\"ace/range\"], function(require, exports, module) {\n\"use strict\";\n\nvar oop = require(\"./lib/oop\");\nvar lang = require(\"./lib/lang\");\nvar EventEmitter = require(\"./lib/event_emitter\").EventEmitter;\nvar Range = require(\"./range\").Range;\nvar Selection = function(session) {\n    this.session = session;\n    this.doc = session.getDocument();\n\n    this.clearSelection();\n    this.cursor = this.lead = this.doc.createAnchor(0, 0);\n    this.anchor = this.doc.createAnchor(0, 0);\n    this.$silent = false;\n\n    var self = this;\n    this.cursor.on(\"change\", function(e) {\n        self.$cursorChanged = true;\n        if (!self.$silent)\n            self._emit(\"changeCursor\");\n        if (!self.$isEmpty && !self.$silent)\n            self._emit(\"changeSelection\");\n        if (!self.$keepDesiredColumnOnChange && e.old.column != e.value.column)\n            self.$desiredColumn = null;\n    });\n\n    this.anchor.on(\"change\", function() {\n        self.$anchorChanged = true;\n        if (!self.$isEmpty && !self.$silent)\n            self._emit(\"changeSelection\");\n    });\n};\n\n(function() {\n\n    oop.implement(this, EventEmitter);\n    this.isEmpty = function() {\n        return this.$isEmpty || (\n            this.anchor.row == this.lead.row &&\n            this.anchor.column == this.lead.column\n        );\n    };\n    this.isMultiLine = function() {\n        return !this.$isEmpty && this.anchor.row != this.cursor.row;\n    };\n    this.getCursor = function() {\n        return this.lead.getPosition();\n    };\n    this.setSelectionAnchor = function(row, column) {\n        this.$isEmpty = false;\n        this.anchor.setPosition(row, column);\n    };\n    this.getAnchor = \n    this.getSelectionAnchor = function() {\n        if (this.$isEmpty)\n            return this.getSelectionLead();\n        \n        return this.anchor.getPosition();\n    };\n    this.getSelectionLead = function() {\n        return this.lead.getPosition();\n    };\n    this.isBackwards = function() {\n        var anchor = this.anchor;\n        var lead = this.lead;\n        return (anchor.row > lead.row || (anchor.row == lead.row && anchor.column > lead.column));\n    };\n    this.getRange = function() {\n        var anchor = this.anchor;\n        var lead = this.lead;\n\n        if (this.$isEmpty)\n            return Range.fromPoints(lead, lead);\n\n        return this.isBackwards()\n            ? Range.fromPoints(lead, anchor)\n            : Range.fromPoints(anchor, lead);\n    };\n    this.clearSelection = function() {\n        if (!this.$isEmpty) {\n            this.$isEmpty = true;\n            this._emit(\"changeSelection\");\n        }\n    };\n    this.selectAll = function() {\n        this.$setSelection(0, 0, Number.MAX_VALUE, Number.MAX_VALUE);\n    };\n    this.setRange =\n    this.setSelectionRange = function(range, reverse) {\n        var start = reverse ? range.end : range.start;\n        var end = reverse ? range.start : range.end;\n        this.$setSelection(start.row, start.column, end.row, end.column);\n    };\n\n    this.$setSelection = function(anchorRow, anchorColumn, cursorRow, cursorColumn) {\n        if (this.$silent)\n            return;\n        var wasEmpty = this.$isEmpty;\n        var wasMultiselect = this.inMultiSelectMode;\n        this.$silent = true;\n        this.$cursorChanged = this.$anchorChanged = false;\n        this.anchor.setPosition(anchorRow, anchorColumn);\n        this.cursor.setPosition(cursorRow, cursorColumn);\n        this.$isEmpty = !Range.comparePoints(this.anchor, this.cursor);\n        this.$silent = false;\n        if (this.$cursorChanged)\n            this._emit(\"changeCursor\");\n        if (this.$cursorChanged || this.$anchorChanged || wasEmpty != this.$isEmpty || wasMultiselect)\n            this._emit(\"changeSelection\");\n    };\n\n    this.$moveSelection = function(mover) {\n        var lead = this.lead;\n        if (this.$isEmpty)\n            this.setSelectionAnchor(lead.row, lead.column);\n\n        mover.call(this);\n    };\n    this.selectTo = function(row, column) {\n        this.$moveSelection(function() {\n            this.moveCursorTo(row, column);\n        });\n    };\n    this.selectToPosition = function(pos) {\n        this.$moveSelection(function() {\n            this.moveCursorToPosition(pos);\n        });\n    };\n    this.moveTo = function(row, column) {\n        this.clearSelection();\n        this.moveCursorTo(row, column);\n    };\n    this.moveToPosition = function(pos) {\n        this.clearSelection();\n        this.moveCursorToPosition(pos);\n    };\n    this.selectUp = function() {\n        this.$moveSelection(this.moveCursorUp);\n    };\n    this.selectDown = function() {\n        this.$moveSelection(this.moveCursorDown);\n    };\n    this.selectRight = function() {\n        this.$moveSelection(this.moveCursorRight);\n    };\n    this.selectLeft = function() {\n        this.$moveSelection(this.moveCursorLeft);\n    };\n    this.selectLineStart = function() {\n        this.$moveSelection(this.moveCursorLineStart);\n    };\n    this.selectLineEnd = function() {\n        this.$moveSelection(this.moveCursorLineEnd);\n    };\n    this.selectFileEnd = function() {\n        this.$moveSelection(this.moveCursorFileEnd);\n    };\n    this.selectFileStart = function() {\n        this.$moveSelection(this.moveCursorFileStart);\n    };\n    this.selectWordRight = function() {\n        this.$moveSelection(this.moveCursorWordRight);\n    };\n    this.selectWordLeft = function() {\n        this.$moveSelection(this.moveCursorWordLeft);\n    };\n    this.getWordRange = function(row, column) {\n        if (typeof column == \"undefined\") {\n            var cursor = row || this.lead;\n            row = cursor.row;\n            column = cursor.column;\n        }\n        return this.session.getWordRange(row, column);\n    };\n    this.selectWord = function() {\n        this.setSelectionRange(this.getWordRange());\n    };\n    this.selectAWord = function() {\n        var cursor = this.getCursor();\n        var range = this.session.getAWordRange(cursor.row, cursor.column);\n        this.setSelectionRange(range);\n    };\n\n    this.getLineRange = function(row, excludeLastChar) {\n        var rowStart = typeof row == \"number\" ? row : this.lead.row;\n        var rowEnd;\n\n        var foldLine = this.session.getFoldLine(rowStart);\n        if (foldLine) {\n            rowStart = foldLine.start.row;\n            rowEnd = foldLine.end.row;\n        } else {\n            rowEnd = rowStart;\n        }\n        if (excludeLastChar === true)\n            return new Range(rowStart, 0, rowEnd, this.session.getLine(rowEnd).length);\n        else\n            return new Range(rowStart, 0, rowEnd + 1, 0);\n    };\n    this.selectLine = function() {\n        this.setSelectionRange(this.getLineRange());\n    };\n    this.moveCursorUp = function() {\n        this.moveCursorBy(-1, 0);\n    };\n    this.moveCursorDown = function() {\n        this.moveCursorBy(1, 0);\n    };\n    this.wouldMoveIntoSoftTab = function(cursor, tabSize, direction) {\n        var start = cursor.column;\n        var end = cursor.column + tabSize;\n\n        if (direction < 0) {\n            start = cursor.column - tabSize;\n            end = cursor.column;\n        }\n        return this.session.isTabStop(cursor) && this.doc.getLine(cursor.row).slice(start, end).split(\" \").length-1 == tabSize;\n    };\n    this.moveCursorLeft = function() {\n        var cursor = this.lead.getPosition(),\n            fold;\n\n        if (fold = this.session.getFoldAt(cursor.row, cursor.column, -1)) {\n            this.moveCursorTo(fold.start.row, fold.start.column);\n        } else if (cursor.column === 0) {\n            if (cursor.row > 0) {\n                this.moveCursorTo(cursor.row - 1, this.doc.getLine(cursor.row - 1).length);\n            }\n        }\n        else {\n            var tabSize = this.session.getTabSize();\n            if (this.wouldMoveIntoSoftTab(cursor, tabSize, -1) && !this.session.getNavigateWithinSoftTabs()) {\n                this.moveCursorBy(0, -tabSize);\n            } else {\n                this.moveCursorBy(0, -1);\n            }\n        }\n    };\n    this.moveCursorRight = function() {\n        var cursor = this.lead.getPosition(),\n            fold;\n        if (fold = this.session.getFoldAt(cursor.row, cursor.column, 1)) {\n            this.moveCursorTo(fold.end.row, fold.end.column);\n        }\n        else if (this.lead.column == this.doc.getLine(this.lead.row).length) {\n            if (this.lead.row < this.doc.getLength() - 1) {\n                this.moveCursorTo(this.lead.row + 1, 0);\n            }\n        }\n        else {\n            var tabSize = this.session.getTabSize();\n            var cursor = this.lead;\n            if (this.wouldMoveIntoSoftTab(cursor, tabSize, 1) && !this.session.getNavigateWithinSoftTabs()) {\n                this.moveCursorBy(0, tabSize);\n            } else {\n                this.moveCursorBy(0, 1);\n            }\n        }\n    };\n    this.moveCursorLineStart = function() {\n        var row = this.lead.row;\n        var column = this.lead.column;\n        var screenRow = this.session.documentToScreenRow(row, column);\n        var firstColumnPosition = this.session.screenToDocumentPosition(screenRow, 0);\n        var beforeCursor = this.session.getDisplayLine(\n            row, null, firstColumnPosition.row,\n            firstColumnPosition.column\n        );\n\n        var leadingSpace = beforeCursor.match(/^\\s*/);\n        if (leadingSpace[0].length != column && !this.session.$useEmacsStyleLineStart)\n            firstColumnPosition.column += leadingSpace[0].length;\n        this.moveCursorToPosition(firstColumnPosition);\n    };\n    this.moveCursorLineEnd = function() {\n        var lead = this.lead;\n        var lineEnd = this.session.getDocumentLastRowColumnPosition(lead.row, lead.column);\n        if (this.lead.column == lineEnd.column) {\n            var line = this.session.getLine(lineEnd.row);\n            if (lineEnd.column == line.length) {\n                var textEnd = line.search(/\\s+$/);\n                if (textEnd > 0)\n                    lineEnd.column = textEnd;\n            }\n        }\n\n        this.moveCursorTo(lineEnd.row, lineEnd.column);\n    };\n    this.moveCursorFileEnd = function() {\n        var row = this.doc.getLength() - 1;\n        var column = this.doc.getLine(row).length;\n        this.moveCursorTo(row, column);\n    };\n    this.moveCursorFileStart = function() {\n        this.moveCursorTo(0, 0);\n    };\n    this.moveCursorLongWordRight = function() {\n        var row = this.lead.row;\n        var column = this.lead.column;\n        var line = this.doc.getLine(row);\n        var rightOfCursor = line.substring(column);\n\n        this.session.nonTokenRe.lastIndex = 0;\n        this.session.tokenRe.lastIndex = 0;\n        var fold = this.session.getFoldAt(row, column, 1);\n        if (fold) {\n            this.moveCursorTo(fold.end.row, fold.end.column);\n            return;\n        }\n        if (this.session.nonTokenRe.exec(rightOfCursor)) {\n            column += this.session.nonTokenRe.lastIndex;\n            this.session.nonTokenRe.lastIndex = 0;\n            rightOfCursor = line.substring(column);\n        }\n        if (column >= line.length) {\n            this.moveCursorTo(row, line.length);\n            this.moveCursorRight();\n            if (row < this.doc.getLength() - 1)\n                this.moveCursorWordRight();\n            return;\n        }\n        if (this.session.tokenRe.exec(rightOfCursor)) {\n            column += this.session.tokenRe.lastIndex;\n            this.session.tokenRe.lastIndex = 0;\n        }\n\n        this.moveCursorTo(row, column);\n    };\n    this.moveCursorLongWordLeft = function() {\n        var row = this.lead.row;\n        var column = this.lead.column;\n        var fold;\n        if (fold = this.session.getFoldAt(row, column, -1)) {\n            this.moveCursorTo(fold.start.row, fold.start.column);\n            return;\n        }\n\n        var str = this.session.getFoldStringAt(row, column, -1);\n        if (str == null) {\n            str = this.doc.getLine(row).substring(0, column);\n        }\n\n        var leftOfCursor = lang.stringReverse(str);\n        this.session.nonTokenRe.lastIndex = 0;\n        this.session.tokenRe.lastIndex = 0;\n        if (this.session.nonTokenRe.exec(leftOfCursor)) {\n            column -= this.session.nonTokenRe.lastIndex;\n            leftOfCursor = leftOfCursor.slice(this.session.nonTokenRe.lastIndex);\n            this.session.nonTokenRe.lastIndex = 0;\n        }\n        if (column <= 0) {\n            this.moveCursorTo(row, 0);\n            this.moveCursorLeft();\n            if (row > 0)\n                this.moveCursorWordLeft();\n            return;\n        }\n        if (this.session.tokenRe.exec(leftOfCursor)) {\n            column -= this.session.tokenRe.lastIndex;\n            this.session.tokenRe.lastIndex = 0;\n        }\n\n        this.moveCursorTo(row, column);\n    };\n\n    this.$shortWordEndIndex = function(rightOfCursor) {\n        var index = 0, ch;\n        var whitespaceRe = /\\s/;\n        var tokenRe = this.session.tokenRe;\n\n        tokenRe.lastIndex = 0;\n        if (this.session.tokenRe.exec(rightOfCursor)) {\n            index = this.session.tokenRe.lastIndex;\n        } else {\n            while ((ch = rightOfCursor[index]) && whitespaceRe.test(ch))\n                index ++;\n\n            if (index < 1) {\n                tokenRe.lastIndex = 0;\n                 while ((ch = rightOfCursor[index]) && !tokenRe.test(ch)) {\n                    tokenRe.lastIndex = 0;\n                    index ++;\n                    if (whitespaceRe.test(ch)) {\n                        if (index > 2) {\n                            index--;\n                            break;\n                        } else {\n                            while ((ch = rightOfCursor[index]) && whitespaceRe.test(ch))\n                                index ++;\n                            if (index > 2)\n                                break;\n                        }\n                    }\n                }\n            }\n        }\n        tokenRe.lastIndex = 0;\n\n        return index;\n    };\n\n    this.moveCursorShortWordRight = function() {\n        var row = this.lead.row;\n        var column = this.lead.column;\n        var line = this.doc.getLine(row);\n        var rightOfCursor = line.substring(column);\n\n        var fold = this.session.getFoldAt(row, column, 1);\n        if (fold)\n            return this.moveCursorTo(fold.end.row, fold.end.column);\n\n        if (column == line.length) {\n            var l = this.doc.getLength();\n            do {\n                row++;\n                rightOfCursor = this.doc.getLine(row);\n            } while (row < l && /^\\s*$/.test(rightOfCursor));\n\n            if (!/^\\s+/.test(rightOfCursor))\n                rightOfCursor = \"\";\n            column = 0;\n        }\n\n        var index = this.$shortWordEndIndex(rightOfCursor);\n\n        this.moveCursorTo(row, column + index);\n    };\n\n    this.moveCursorShortWordLeft = function() {\n        var row = this.lead.row;\n        var column = this.lead.column;\n\n        var fold;\n        if (fold = this.session.getFoldAt(row, column, -1))\n            return this.moveCursorTo(fold.start.row, fold.start.column);\n\n        var line = this.session.getLine(row).substring(0, column);\n        if (column === 0) {\n            do {\n                row--;\n                line = this.doc.getLine(row);\n            } while (row > 0 && /^\\s*$/.test(line));\n\n            column = line.length;\n            if (!/\\s+$/.test(line))\n                line = \"\";\n        }\n\n        var leftOfCursor = lang.stringReverse(line);\n        var index = this.$shortWordEndIndex(leftOfCursor);\n\n        return this.moveCursorTo(row, column - index);\n    };\n\n    this.moveCursorWordRight = function() {\n        if (this.session.$selectLongWords)\n            this.moveCursorLongWordRight();\n        else\n            this.moveCursorShortWordRight();\n    };\n\n    this.moveCursorWordLeft = function() {\n        if (this.session.$selectLongWords)\n            this.moveCursorLongWordLeft();\n        else\n            this.moveCursorShortWordLeft();\n    };\n    this.moveCursorBy = function(rows, chars) {\n        var screenPos = this.session.documentToScreenPosition(\n            this.lead.row,\n            this.lead.column\n        );\n\n        var offsetX;\n\n        if (chars === 0) {\n            if (rows !== 0) {\n                if (this.session.$bidiHandler.isBidiRow(screenPos.row, this.lead.row)) {\n                    offsetX = this.session.$bidiHandler.getPosLeft(screenPos.column);\n                    screenPos.column = Math.round(offsetX / this.session.$bidiHandler.charWidths[0]);\n                } else {\n                    offsetX = screenPos.column * this.session.$bidiHandler.charWidths[0];\n                }\n            }\n\n            if (this.$desiredColumn)\n                screenPos.column = this.$desiredColumn;\n            else\n                this.$desiredColumn = screenPos.column;\n        }\n        \n        if (rows != 0 && this.session.lineWidgets && this.session.lineWidgets[this.lead.row]) {\n            var widget = this.session.lineWidgets[this.lead.row];\n            if (rows < 0)\n                rows -= widget.rowsAbove || 0;\n            else if (rows > 0)\n                rows += widget.rowCount - (widget.rowsAbove || 0);\n        }\n        \n        var docPos = this.session.screenToDocumentPosition(screenPos.row + rows, screenPos.column, offsetX);\n        \n        if (rows !== 0 && chars === 0 && docPos.row === this.lead.row && docPos.column === this.lead.column) {\n            \n        }\n        this.moveCursorTo(docPos.row, docPos.column + chars, chars === 0);\n    };\n    this.moveCursorToPosition = function(position) {\n        this.moveCursorTo(position.row, position.column);\n    };\n    this.moveCursorTo = function(row, column, keepDesiredColumn) {\n        var fold = this.session.getFoldAt(row, column, 1);\n        if (fold) {\n            row = fold.start.row;\n            column = fold.start.column;\n        }\n\n        this.$keepDesiredColumnOnChange = true;\n        var line = this.session.getLine(row);\n        if (/[\\uDC00-\\uDFFF]/.test(line.charAt(column)) && line.charAt(column - 1)) {\n            if (this.lead.row == row && this.lead.column == column + 1)\n                column = column - 1;\n            else\n                column = column + 1;\n        }\n        this.lead.setPosition(row, column);\n        this.$keepDesiredColumnOnChange = false;\n\n        if (!keepDesiredColumn)\n            this.$desiredColumn = null;\n    };\n    this.moveCursorToScreen = function(row, column, keepDesiredColumn) {\n        var pos = this.session.screenToDocumentPosition(row, column);\n        this.moveCursorTo(pos.row, pos.column, keepDesiredColumn);\n    };\n    this.detach = function() {\n        this.lead.detach();\n        this.anchor.detach();\n        this.session = this.doc = null;\n    };\n\n    this.fromOrientedRange = function(range) {\n        this.setSelectionRange(range, range.cursor == range.start);\n        this.$desiredColumn = range.desiredColumn || this.$desiredColumn;\n    };\n\n    this.toOrientedRange = function(range) {\n        var r = this.getRange();\n        if (range) {\n            range.start.column = r.start.column;\n            range.start.row = r.start.row;\n            range.end.column = r.end.column;\n            range.end.row = r.end.row;\n        } else {\n            range = r;\n        }\n\n        range.cursor = this.isBackwards() ? range.start : range.end;\n        range.desiredColumn = this.$desiredColumn;\n        return range;\n    };\n    this.getRangeOfMovements = function(func) {\n        var start = this.getCursor();\n        try {\n            func(this);\n            var end = this.getCursor();\n            return Range.fromPoints(start, end);\n        } catch(e) {\n            return Range.fromPoints(start, start);\n        } finally {\n            this.moveCursorToPosition(start);\n        }\n    };\n\n    this.toJSON = function() {\n        if (this.rangeCount) {\n            var data = this.ranges.map(function(r) {\n                var r1 = r.clone();\n                r1.isBackwards = r.cursor == r.start;\n                return r1;\n            });\n        } else {\n            var data = this.getRange();\n            data.isBackwards = this.isBackwards();\n        }\n        return data;\n    };\n\n    this.fromJSON = function(data) {\n        if (data.start == undefined) {\n            if (this.rangeList && data.length > 1) {\n                this.toSingleRange(data[0]);\n                for (var i = data.length; i--; ) {\n                    var r = Range.fromPoints(data[i].start, data[i].end);\n                    if (data[i].isBackwards)\n                        r.cursor = r.start;\n                    this.addRange(r, true);\n                }\n                return;\n            } else {\n                data = data[0];\n            }\n        }\n        if (this.rangeList)\n            this.toSingleRange(data);\n        this.setSelectionRange(data, data.isBackwards);\n    };\n\n    this.isEqual = function(data) {\n        if ((data.length || this.rangeCount) && data.length != this.rangeCount)\n            return false;\n        if (!data.length || !this.ranges)\n            return this.getRange().isEqual(data);\n\n        for (var i = this.ranges.length; i--; ) {\n            if (!this.ranges[i].isEqual(data[i]))\n                return false;\n        }\n        return true;\n    };\n\n}).call(Selection.prototype);\n\nexports.Selection = Selection;\n});\n\nace.define(\"ace/tokenizer\",[\"require\",\"exports\",\"module\",\"ace/config\"], function(require, exports, module) {\n\"use strict\";\n\nvar config = require(\"./config\");\nvar MAX_TOKEN_COUNT = 2000;\nvar Tokenizer = function(rules) {\n    this.states = rules;\n\n    this.regExps = {};\n    this.matchMappings = {};\n    for (var key in this.states) {\n        var state = this.states[key];\n        var ruleRegExps = [];\n        var matchTotal = 0;\n        var mapping = this.matchMappings[key] = {defaultToken: \"text\"};\n        var flag = \"g\";\n\n        var splitterRurles = [];\n        for (var i = 0; i < state.length; i++) {\n            var rule = state[i];\n            if (rule.defaultToken)\n                mapping.defaultToken = rule.defaultToken;\n            if (rule.caseInsensitive)\n                flag = \"gi\";\n            if (rule.regex == null)\n                continue;\n\n            if (rule.regex instanceof RegExp)\n                rule.regex = rule.regex.toString().slice(1, -1);\n            var adjustedregex = rule.regex;\n            var matchcount = new RegExp(\"(?:(\" + adjustedregex + \")|(.))\").exec(\"a\").length - 2;\n            if (Array.isArray(rule.token)) {\n                if (rule.token.length == 1 || matchcount == 1) {\n                    rule.token = rule.token[0];\n                } else if (matchcount - 1 != rule.token.length) {\n                    this.reportError(\"number of classes and regexp groups doesn't match\", { \n                        rule: rule,\n                        groupCount: matchcount - 1\n                    });\n                    rule.token = rule.token[0];\n                } else {\n                    rule.tokenArray = rule.token;\n                    rule.token = null;\n                    rule.onMatch = this.$arrayTokens;\n                }\n            } else if (typeof rule.token == \"function\" && !rule.onMatch) {\n                if (matchcount > 1)\n                    rule.onMatch = this.$applyToken;\n                else\n                    rule.onMatch = rule.token;\n            }\n\n            if (matchcount > 1) {\n                if (/\\\\\\d/.test(rule.regex)) {\n                    adjustedregex = rule.regex.replace(/\\\\([0-9]+)/g, function(match, digit) {\n                        return \"\\\\\" + (parseInt(digit, 10) + matchTotal + 1);\n                    });\n                } else {\n                    matchcount = 1;\n                    adjustedregex = this.removeCapturingGroups(rule.regex);\n                }\n                if (!rule.splitRegex && typeof rule.token != \"string\")\n                    splitterRurles.push(rule); // flag will be known only at the very end\n            }\n\n            mapping[matchTotal] = i;\n            matchTotal += matchcount;\n\n            ruleRegExps.push(adjustedregex);\n            if (!rule.onMatch)\n                rule.onMatch = null;\n        }\n        \n        if (!ruleRegExps.length) {\n            mapping[0] = 0;\n            ruleRegExps.push(\"$\");\n        }\n        \n        splitterRurles.forEach(function(rule) {\n            rule.splitRegex = this.createSplitterRegexp(rule.regex, flag);\n        }, this);\n\n        this.regExps[key] = new RegExp(\"(\" + ruleRegExps.join(\")|(\") + \")|($)\", flag);\n    }\n};\n\n(function() {\n    this.$setMaxTokenCount = function(m) {\n        MAX_TOKEN_COUNT = m | 0;\n    };\n    \n    this.$applyToken = function(str) {\n        var values = this.splitRegex.exec(str).slice(1);\n        var types = this.token.apply(this, values);\n        if (typeof types === \"string\")\n            return [{type: types, value: str}];\n\n        var tokens = [];\n        for (var i = 0, l = types.length; i < l; i++) {\n            if (values[i])\n                tokens[tokens.length] = {\n                    type: types[i],\n                    value: values[i]\n                };\n        }\n        return tokens;\n    };\n\n    this.$arrayTokens = function(str) {\n        if (!str)\n            return [];\n        var values = this.splitRegex.exec(str);\n        if (!values)\n            return \"text\";\n        var tokens = [];\n        var types = this.tokenArray;\n        for (var i = 0, l = types.length; i < l; i++) {\n            if (values[i + 1])\n                tokens[tokens.length] = {\n                    type: types[i],\n                    value: values[i + 1]\n                };\n        }\n        return tokens;\n    };\n\n    this.removeCapturingGroups = function(src) {\n        var r = src.replace(\n            /\\\\.|\\[(?:\\\\.|[^\\\\\\]])*|\\(\\?[:=!]|(\\()/g,\n            function(x, y) {return y ? \"(?:\" : x;}\n        );\n        return r;\n    };\n\n    this.createSplitterRegexp = function(src, flag) {\n        if (src.indexOf(\"(?=\") != -1) {\n            var stack = 0;\n            var inChClass = false;\n            var lastCapture = {};\n            src.replace(/(\\\\.)|(\\((?:\\?[=!])?)|(\\))|([\\[\\]])/g, function(\n                m, esc, parenOpen, parenClose, square, index\n            ) {\n                if (inChClass) {\n                    inChClass = square != \"]\";\n                } else if (square) {\n                    inChClass = true;\n                } else if (parenClose) {\n                    if (stack == lastCapture.stack) {\n                        lastCapture.end = index+1;\n                        lastCapture.stack = -1;\n                    }\n                    stack--;\n                } else if (parenOpen) {\n                    stack++;\n                    if (parenOpen.length != 1) {\n                        lastCapture.stack = stack;\n                        lastCapture.start = index;\n                    }\n                }\n                return m;\n            });\n\n            if (lastCapture.end != null && /^\\)*$/.test(src.substr(lastCapture.end)))\n                src = src.substring(0, lastCapture.start) + src.substr(lastCapture.end);\n        }\n        if (src.charAt(0) != \"^\") src = \"^\" + src;\n        if (src.charAt(src.length - 1) != \"$\") src += \"$\";\n        \n        return new RegExp(src, (flag||\"\").replace(\"g\", \"\"));\n    };\n    this.getLineTokens = function(line, startState) {\n        if (startState && typeof startState != \"string\") {\n            var stack = startState.slice(0);\n            startState = stack[0];\n            if (startState === \"#tmp\") {\n                stack.shift();\n                startState = stack.shift();\n            }\n        } else\n            var stack = [];\n\n        var currentState = startState || \"start\";\n        var state = this.states[currentState];\n        if (!state) {\n            currentState = \"start\";\n            state = this.states[currentState];\n        }\n        var mapping = this.matchMappings[currentState];\n        var re = this.regExps[currentState];\n        re.lastIndex = 0;\n\n        var match, tokens = [];\n        var lastIndex = 0;\n        var matchAttempts = 0;\n\n        var token = {type: null, value: \"\"};\n\n        while (match = re.exec(line)) {\n            var type = mapping.defaultToken;\n            var rule = null;\n            var value = match[0];\n            var index = re.lastIndex;\n\n            if (index - value.length > lastIndex) {\n                var skipped = line.substring(lastIndex, index - value.length);\n                if (token.type == type) {\n                    token.value += skipped;\n                } else {\n                    if (token.type)\n                        tokens.push(token);\n                    token = {type: type, value: skipped};\n                }\n            }\n\n            for (var i = 0; i < match.length-2; i++) {\n                if (match[i + 1] === undefined)\n                    continue;\n\n                rule = state[mapping[i]];\n\n                if (rule.onMatch)\n                    type = rule.onMatch(value, currentState, stack, line);\n                else\n                    type = rule.token;\n\n                if (rule.next) {\n                    if (typeof rule.next == \"string\") {\n                        currentState = rule.next;\n                    } else {\n                        currentState = rule.next(currentState, stack);\n                    }\n                    \n                    state = this.states[currentState];\n                    if (!state) {\n                        this.reportError(\"state doesn't exist\", currentState);\n                        currentState = \"start\";\n                        state = this.states[currentState];\n                    }\n                    mapping = this.matchMappings[currentState];\n                    lastIndex = index;\n                    re = this.regExps[currentState];\n                    re.lastIndex = index;\n                }\n                if (rule.consumeLineEnd)\n                    lastIndex = index;\n                break;\n            }\n\n            if (value) {\n                if (typeof type === \"string\") {\n                    if ((!rule || rule.merge !== false) && token.type === type) {\n                        token.value += value;\n                    } else {\n                        if (token.type)\n                            tokens.push(token);\n                        token = {type: type, value: value};\n                    }\n                } else if (type) {\n                    if (token.type)\n                        tokens.push(token);\n                    token = {type: null, value: \"\"};\n                    for (var i = 0; i < type.length; i++)\n                        tokens.push(type[i]);\n                }\n            }\n\n            if (lastIndex == line.length)\n                break;\n\n            lastIndex = index;\n\n            if (matchAttempts++ > MAX_TOKEN_COUNT) {\n                if (matchAttempts > 2 * line.length) {\n                    this.reportError(\"infinite loop with in ace tokenizer\", {\n                        startState: startState,\n                        line: line\n                    });\n                }\n                while (lastIndex < line.length) {\n                    if (token.type)\n                        tokens.push(token);\n                    token = {\n                        value: line.substring(lastIndex, lastIndex += 500),\n                        type: \"overflow\"\n                    };\n                }\n                currentState = \"start\";\n                stack = [];\n                break;\n            }\n        }\n\n        if (token.type)\n            tokens.push(token);\n        \n        if (stack.length > 1) {\n            if (stack[0] !== currentState)\n                stack.unshift(\"#tmp\", currentState);\n        }\n        return {\n            tokens : tokens,\n            state : stack.length ? stack : currentState\n        };\n    };\n    \n    this.reportError = config.reportError;\n    \n}).call(Tokenizer.prototype);\n\nexports.Tokenizer = Tokenizer;\n});\n\nace.define(\"ace/mode/text_highlight_rules\",[\"require\",\"exports\",\"module\",\"ace/lib/lang\"], function(require, exports, module) {\n\"use strict\";\n\nvar lang = require(\"../lib/lang\");\n\nvar TextHighlightRules = function() {\n\n    this.$rules = {\n        \"start\" : [{\n            token : \"empty_line\",\n            regex : '^$'\n        }, {\n            defaultToken : \"text\"\n        }]\n    };\n};\n\n(function() {\n\n    this.addRules = function(rules, prefix) {\n        if (!prefix) {\n            for (var key in rules)\n                this.$rules[key] = rules[key];\n            return;\n        }\n        for (var key in rules) {\n            var state = rules[key];\n            for (var i = 0; i < state.length; i++) {\n                var rule = state[i];\n                if (rule.next || rule.onMatch) {\n                    if (typeof rule.next == \"string\") {\n                        if (rule.next.indexOf(prefix) !== 0)\n                            rule.next = prefix + rule.next;\n                    }\n                    if (rule.nextState && rule.nextState.indexOf(prefix) !== 0)\n                        rule.nextState = prefix + rule.nextState;\n                }\n            }\n            this.$rules[prefix + key] = state;\n        }\n    };\n\n    this.getRules = function() {\n        return this.$rules;\n    };\n\n    this.embedRules = function (HighlightRules, prefix, escapeRules, states, append) {\n        var embedRules = typeof HighlightRules == \"function\"\n            ? new HighlightRules().getRules()\n            : HighlightRules;\n        if (states) {\n            for (var i = 0; i < states.length; i++)\n                states[i] = prefix + states[i];\n        } else {\n            states = [];\n            for (var key in embedRules)\n                states.push(prefix + key);\n        }\n\n        this.addRules(embedRules, prefix);\n\n        if (escapeRules) {\n            var addRules = Array.prototype[append ? \"push\" : \"unshift\"];\n            for (var i = 0; i < states.length; i++)\n                addRules.apply(this.$rules[states[i]], lang.deepCopy(escapeRules));\n        }\n\n        if (!this.$embeds)\n            this.$embeds = [];\n        this.$embeds.push(prefix);\n    };\n\n    this.getEmbeds = function() {\n        return this.$embeds;\n    };\n\n    var pushState = function(currentState, stack) {\n        if (currentState != \"start\" || stack.length)\n            stack.unshift(this.nextState, currentState);\n        return this.nextState;\n    };\n    var popState = function(currentState, stack) {\n        stack.shift();\n        return stack.shift() || \"start\";\n    };\n\n    this.normalizeRules = function() {\n        var id = 0;\n        var rules = this.$rules;\n        function processState(key) {\n            var state = rules[key];\n            state.processed = true;\n            for (var i = 0; i < state.length; i++) {\n                var rule = state[i];\n                var toInsert = null;\n                if (Array.isArray(rule)) {\n                    toInsert = rule;\n                    rule = {};\n                }\n                if (!rule.regex && rule.start) {\n                    rule.regex = rule.start;\n                    if (!rule.next)\n                        rule.next = [];\n                    rule.next.push({\n                        defaultToken: rule.token\n                    }, {\n                        token: rule.token + \".end\",\n                        regex: rule.end || rule.start,\n                        next: \"pop\"\n                    });\n                    rule.token = rule.token + \".start\";\n                    rule.push = true;\n                }\n                var next = rule.next || rule.push;\n                if (next && Array.isArray(next)) {\n                    var stateName = rule.stateName;\n                    if (!stateName)  {\n                        stateName = rule.token;\n                        if (typeof stateName != \"string\")\n                            stateName = stateName[0] || \"\";\n                        if (rules[stateName])\n                            stateName += id++;\n                    }\n                    rules[stateName] = next;\n                    rule.next = stateName;\n                    processState(stateName);\n                } else if (next == \"pop\") {\n                    rule.next = popState;\n                }\n\n                if (rule.push) {\n                    rule.nextState = rule.next || rule.push;\n                    rule.next = pushState;\n                    delete rule.push;\n                }\n\n                if (rule.rules) {\n                    for (var r in rule.rules) {\n                        if (rules[r]) {\n                            if (rules[r].push)\n                                rules[r].push.apply(rules[r], rule.rules[r]);\n                        } else {\n                            rules[r] = rule.rules[r];\n                        }\n                    }\n                }\n                var includeName = typeof rule == \"string\" ? rule : rule.include;\n                if (includeName) {\n                    if (Array.isArray(includeName))\n                        toInsert = includeName.map(function(x) { return rules[x]; });\n                    else\n                        toInsert = rules[includeName];\n                }\n\n                if (toInsert) {\n                    var args = [i, 1].concat(toInsert);\n                    if (rule.noEscape)\n                        args = args.filter(function(x) {return !x.next;});\n                    state.splice.apply(state, args);\n                    i--;\n                }\n                \n                if (rule.keywordMap) {\n                    rule.token = this.createKeywordMapper(\n                        rule.keywordMap, rule.defaultToken || \"text\", rule.caseInsensitive\n                    );\n                    delete rule.defaultToken;\n                }\n            }\n        }\n        Object.keys(rules).forEach(processState, this);\n    };\n\n    this.createKeywordMapper = function(map, defaultToken, ignoreCase, splitChar) {\n        var keywords = Object.create(null);\n        Object.keys(map).forEach(function(className) {\n            var a = map[className];\n            if (ignoreCase)\n                a = a.toLowerCase();\n            var list = a.split(splitChar || \"|\");\n            for (var i = list.length; i--; )\n                keywords[list[i]] = className;\n        });\n        if (Object.getPrototypeOf(keywords)) {\n            keywords.__proto__ = null;\n        }\n        this.$keywordList = Object.keys(keywords);\n        map = null;\n        return ignoreCase\n            ? function(value) {return keywords[value.toLowerCase()] || defaultToken; }\n            : function(value) {return keywords[value] || defaultToken; };\n    };\n\n    this.getKeywords = function() {\n        return this.$keywords;\n    };\n\n}).call(TextHighlightRules.prototype);\n\nexports.TextHighlightRules = TextHighlightRules;\n});\n\nace.define(\"ace/mode/behaviour\",[\"require\",\"exports\",\"module\"], function(require, exports, module) {\n\"use strict\";\n\nvar Behaviour = function() {\n   this.$behaviours = {};\n};\n\n(function () {\n\n    this.add = function (name, action, callback) {\n        switch (undefined) {\n          case this.$behaviours:\n              this.$behaviours = {};\n          case this.$behaviours[name]:\n              this.$behaviours[name] = {};\n        }\n        this.$behaviours[name][action] = callback;\n    };\n    \n    this.addBehaviours = function (behaviours) {\n        for (var key in behaviours) {\n            for (var action in behaviours[key]) {\n                this.add(key, action, behaviours[key][action]);\n            }\n        }\n    };\n    \n    this.remove = function (name) {\n        if (this.$behaviours && this.$behaviours[name]) {\n            delete this.$behaviours[name];\n        }\n    };\n    \n    this.inherit = function (mode, filter) {\n        if (typeof mode === \"function\") {\n            var behaviours = new mode().getBehaviours(filter);\n        } else {\n            var behaviours = mode.getBehaviours(filter);\n        }\n        this.addBehaviours(behaviours);\n    };\n    \n    this.getBehaviours = function (filter) {\n        if (!filter) {\n            return this.$behaviours;\n        } else {\n            var ret = {};\n            for (var i = 0; i < filter.length; i++) {\n                if (this.$behaviours[filter[i]]) {\n                    ret[filter[i]] = this.$behaviours[filter[i]];\n                }\n            }\n            return ret;\n        }\n    };\n\n}).call(Behaviour.prototype);\n\nexports.Behaviour = Behaviour;\n});\n\nace.define(\"ace/token_iterator\",[\"require\",\"exports\",\"module\",\"ace/range\"], function(require, exports, module) {\n\"use strict\";\n\nvar Range = require(\"./range\").Range;\nvar TokenIterator = function(session, initialRow, initialColumn) {\n    this.$session = session;\n    this.$row = initialRow;\n    this.$rowTokens = session.getTokens(initialRow);\n\n    var token = session.getTokenAt(initialRow, initialColumn);\n    this.$tokenIndex = token ? token.index : -1;\n};\n\n(function() { \n    this.stepBackward = function() {\n        this.$tokenIndex -= 1;\n        \n        while (this.$tokenIndex < 0) {\n            this.$row -= 1;\n            if (this.$row < 0) {\n                this.$row = 0;\n                return null;\n            }\n                \n            this.$rowTokens = this.$session.getTokens(this.$row);\n            this.$tokenIndex = this.$rowTokens.length - 1;\n        }\n            \n        return this.$rowTokens[this.$tokenIndex];\n    };   \n    this.stepForward = function() {\n        this.$tokenIndex += 1;\n        var rowCount;\n        while (this.$tokenIndex >= this.$rowTokens.length) {\n            this.$row += 1;\n            if (!rowCount)\n                rowCount = this.$session.getLength();\n            if (this.$row >= rowCount) {\n                this.$row = rowCount - 1;\n                return null;\n            }\n\n            this.$rowTokens = this.$session.getTokens(this.$row);\n            this.$tokenIndex = 0;\n        }\n            \n        return this.$rowTokens[this.$tokenIndex];\n    };      \n    this.getCurrentToken = function () {\n        return this.$rowTokens[this.$tokenIndex];\n    };      \n    this.getCurrentTokenRow = function () {\n        return this.$row;\n    };     \n    this.getCurrentTokenColumn = function() {\n        var rowTokens = this.$rowTokens;\n        var tokenIndex = this.$tokenIndex;\n        var column = rowTokens[tokenIndex].start;\n        if (column !== undefined)\n            return column;\n            \n        column = 0;\n        while (tokenIndex > 0) {\n            tokenIndex -= 1;\n            column += rowTokens[tokenIndex].value.length;\n        }\n        \n        return column;  \n    };\n    this.getCurrentTokenPosition = function() {\n        return {row: this.$row, column: this.getCurrentTokenColumn()};\n    };\n    this.getCurrentTokenRange = function() {\n        var token = this.$rowTokens[this.$tokenIndex];\n        var column = this.getCurrentTokenColumn();\n        return new Range(this.$row, column, this.$row, column + token.value.length);\n    };\n    \n}).call(TokenIterator.prototype);\n\nexports.TokenIterator = TokenIterator;\n});\n\nace.define(\"ace/mode/behaviour/cstyle\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/behaviour\",\"ace/token_iterator\",\"ace/lib/lang\"], function(require, exports, module) {\n\"use strict\";\n\nvar oop = require(\"../../lib/oop\");\nvar Behaviour = require(\"../behaviour\").Behaviour;\nvar TokenIterator = require(\"../../token_iterator\").TokenIterator;\nvar lang = require(\"../../lib/lang\");\n\nvar SAFE_INSERT_IN_TOKENS =\n    [\"text\", \"paren.rparen\", \"rparen\", \"paren\", \"punctuation.operator\"];\nvar SAFE_INSERT_BEFORE_TOKENS =\n    [\"text\", \"paren.rparen\", \"rparen\", \"paren\", \"punctuation.operator\", \"comment\"];\n\nvar context;\nvar contextCache = {};\nvar defaultQuotes = {'\"' : '\"', \"'\" : \"'\"};\n\nvar initContext = function(editor) {\n    var id = -1;\n    if (editor.multiSelect) {\n        id = editor.selection.index;\n        if (contextCache.rangeCount != editor.multiSelect.rangeCount)\n            contextCache = {rangeCount: editor.multiSelect.rangeCount};\n    }\n    if (contextCache[id])\n        return context = contextCache[id];\n    context = contextCache[id] = {\n        autoInsertedBrackets: 0,\n        autoInsertedRow: -1,\n        autoInsertedLineEnd: \"\",\n        maybeInsertedBrackets: 0,\n        maybeInsertedRow: -1,\n        maybeInsertedLineStart: \"\",\n        maybeInsertedLineEnd: \"\"\n    };\n};\n\nvar getWrapped = function(selection, selected, opening, closing) {\n    var rowDiff = selection.end.row - selection.start.row;\n    return {\n        text: opening + selected + closing,\n        selection: [\n                0,\n                selection.start.column + 1,\n                rowDiff,\n                selection.end.column + (rowDiff ? 0 : 1)\n            ]\n    };\n};\n\nvar CstyleBehaviour = function(options) {\n    this.add(\"braces\", \"insertion\", function(state, action, editor, session, text) {\n        var cursor = editor.getCursorPosition();\n        var line = session.doc.getLine(cursor.row);\n        if (text == '{') {\n            initContext(editor);\n            var selection = editor.getSelectionRange();\n            var selected = session.doc.getTextRange(selection);\n            if (selected !== \"\" && selected !== \"{\" && editor.getWrapBehavioursEnabled()) {\n                return getWrapped(selection, selected, '{', '}');\n            } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {\n                if (/[\\]\\}\\)]/.test(line[cursor.column]) || editor.inMultiSelectMode || options && options.braces) {\n                    CstyleBehaviour.recordAutoInsert(editor, session, \"}\");\n                    return {\n                        text: '{}',\n                        selection: [1, 1]\n                    };\n                } else {\n                    CstyleBehaviour.recordMaybeInsert(editor, session, \"{\");\n                    return {\n                        text: '{',\n                        selection: [1, 1]\n                    };\n                }\n            }\n        } else if (text == '}') {\n            initContext(editor);\n            var rightChar = line.substring(cursor.column, cursor.column + 1);\n            if (rightChar == '}') {\n                var matching = session.$findOpeningBracket('}', {column: cursor.column + 1, row: cursor.row});\n                if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {\n                    CstyleBehaviour.popAutoInsertedClosing();\n                    return {\n                        text: '',\n                        selection: [1, 1]\n                    };\n                }\n            }\n        } else if (text == \"\\n\" || text == \"\\r\\n\") {\n            initContext(editor);\n            var closing = \"\";\n            if (CstyleBehaviour.isMaybeInsertedClosing(cursor, line)) {\n                closing = lang.stringRepeat(\"}\", context.maybeInsertedBrackets);\n                CstyleBehaviour.clearMaybeInsertedClosing();\n            }\n            var rightChar = line.substring(cursor.column, cursor.column + 1);\n            if (rightChar === '}') {\n                var openBracePos = session.findMatchingBracket({row: cursor.row, column: cursor.column+1}, '}');\n                if (!openBracePos)\n                     return null;\n                var next_indent = this.$getIndent(session.getLine(openBracePos.row));\n            } else if (closing) {\n                var next_indent = this.$getIndent(line);\n            } else {\n                CstyleBehaviour.clearMaybeInsertedClosing();\n                return;\n            }\n            var indent = next_indent + session.getTabString();\n\n            return {\n                text: '\\n' + indent + '\\n' + next_indent + closing,\n                selection: [1, indent.length, 1, indent.length]\n            };\n        } else {\n            CstyleBehaviour.clearMaybeInsertedClosing();\n        }\n    });\n\n    this.add(\"braces\", \"deletion\", function(state, action, editor, session, range) {\n        var selected = session.doc.getTextRange(range);\n        if (!range.isMultiLine() && selected == '{') {\n            initContext(editor);\n            var line = session.doc.getLine(range.start.row);\n            var rightChar = line.substring(range.end.column, range.end.column + 1);\n            if (rightChar == '}') {\n                range.end.column++;\n                return range;\n            } else {\n                context.maybeInsertedBrackets--;\n            }\n        }\n    });\n\n    this.add(\"parens\", \"insertion\", function(state, action, editor, session, text) {\n        if (text == '(') {\n            initContext(editor);\n            var selection = editor.getSelectionRange();\n            var selected = session.doc.getTextRange(selection);\n            if (selected !== \"\" && editor.getWrapBehavioursEnabled()) {\n                return getWrapped(selection, selected, '(', ')');\n            } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {\n                CstyleBehaviour.recordAutoInsert(editor, session, \")\");\n                return {\n                    text: '()',\n                    selection: [1, 1]\n                };\n            }\n        } else if (text == ')') {\n            initContext(editor);\n            var cursor = editor.getCursorPosition();\n            var line = session.doc.getLine(cursor.row);\n            var rightChar = line.substring(cursor.column, cursor.column + 1);\n            if (rightChar == ')') {\n                var matching = session.$findOpeningBracket(')', {column: cursor.column + 1, row: cursor.row});\n                if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {\n                    CstyleBehaviour.popAutoInsertedClosing();\n                    return {\n                        text: '',\n                        selection: [1, 1]\n                    };\n                }\n            }\n        }\n    });\n\n    this.add(\"parens\", \"deletion\", function(state, action, editor, session, range) {\n        var selected = session.doc.getTextRange(range);\n        if (!range.isMultiLine() && selected == '(') {\n            initContext(editor);\n            var line = session.doc.getLine(range.start.row);\n            var rightChar = line.substring(range.start.column + 1, range.start.column + 2);\n            if (rightChar == ')') {\n                range.end.column++;\n                return range;\n            }\n        }\n    });\n\n    this.add(\"brackets\", \"insertion\", function(state, action, editor, session, text) {\n        if (text == '[') {\n            initContext(editor);\n            var selection = editor.getSelectionRange();\n            var selected = session.doc.getTextRange(selection);\n            if (selected !== \"\" && editor.getWrapBehavioursEnabled()) {\n                return getWrapped(selection, selected, '[', ']');\n            } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {\n                CstyleBehaviour.recordAutoInsert(editor, session, \"]\");\n                return {\n                    text: '[]',\n                    selection: [1, 1]\n                };\n            }\n        } else if (text == ']') {\n            initContext(editor);\n            var cursor = editor.getCursorPosition();\n            var line = session.doc.getLine(cursor.row);\n            var rightChar = line.substring(cursor.column, cursor.column + 1);\n            if (rightChar == ']') {\n                var matching = session.$findOpeningBracket(']', {column: cursor.column + 1, row: cursor.row});\n                if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {\n                    CstyleBehaviour.popAutoInsertedClosing();\n                    return {\n                        text: '',\n                        selection: [1, 1]\n                    };\n                }\n            }\n        }\n    });\n\n    this.add(\"brackets\", \"deletion\", function(state, action, editor, session, range) {\n        var selected = session.doc.getTextRange(range);\n        if (!range.isMultiLine() && selected == '[') {\n            initContext(editor);\n            var line = session.doc.getLine(range.start.row);\n            var rightChar = line.substring(range.start.column + 1, range.start.column + 2);\n            if (rightChar == ']') {\n                range.end.column++;\n                return range;\n            }\n        }\n    });\n\n    this.add(\"string_dquotes\", \"insertion\", function(state, action, editor, session, text) {\n        var quotes = session.$mode.$quotes || defaultQuotes;\n        if (text.length == 1 && quotes[text]) {\n            if (this.lineCommentStart && this.lineCommentStart.indexOf(text) != -1) \n                return;\n            initContext(editor);\n            var quote = text;\n            var selection = editor.getSelectionRange();\n            var selected = session.doc.getTextRange(selection);\n            if (selected !== \"\" && (selected.length != 1 || !quotes[selected]) && editor.getWrapBehavioursEnabled()) {\n                return getWrapped(selection, selected, quote, quote);\n            } else if (!selected) {\n                var cursor = editor.getCursorPosition();\n                var line = session.doc.getLine(cursor.row);\n                var leftChar = line.substring(cursor.column-1, cursor.column);\n                var rightChar = line.substring(cursor.column, cursor.column + 1);\n                \n                var token = session.getTokenAt(cursor.row, cursor.column);\n                var rightToken = session.getTokenAt(cursor.row, cursor.column + 1);\n                if (leftChar == \"\\\\\" && token && /escape/.test(token.type))\n                    return null;\n                \n                var stringBefore = token && /string|escape/.test(token.type);\n                var stringAfter = !rightToken || /string|escape/.test(rightToken.type);\n                \n                var pair;\n                if (rightChar == quote) {\n                    pair = stringBefore !== stringAfter;\n                    if (pair && /string\\.end/.test(rightToken.type))\n                        pair = false;\n                } else {\n                    if (stringBefore && !stringAfter)\n                        return null; // wrap string with different quote\n                    if (stringBefore && stringAfter)\n                        return null; // do not pair quotes inside strings\n                    var wordRe = session.$mode.tokenRe;\n                    wordRe.lastIndex = 0;\n                    var isWordBefore = wordRe.test(leftChar);\n                    wordRe.lastIndex = 0;\n                    var isWordAfter = wordRe.test(leftChar);\n                    if (isWordBefore || isWordAfter)\n                        return null; // before or after alphanumeric\n                    if (rightChar && !/[\\s;,.})\\]\\\\]/.test(rightChar))\n                        return null; // there is rightChar and it isn't closing\n                    var charBefore = line[cursor.column - 2];\n                    if (leftChar == quote &&  (charBefore == quote || wordRe.test(charBefore)))\n                        return null;\n                    pair = true;\n                }\n                return {\n                    text: pair ? quote + quote : \"\",\n                    selection: [1,1]\n                };\n            }\n        }\n    });\n\n    this.add(\"string_dquotes\", \"deletion\", function(state, action, editor, session, range) {\n        var quotes = session.$mode.$quotes || defaultQuotes;\n\n        var selected = session.doc.getTextRange(range);\n        if (!range.isMultiLine() && quotes.hasOwnProperty(selected)) {\n            initContext(editor);\n            var line = session.doc.getLine(range.start.row);\n            var rightChar = line.substring(range.start.column + 1, range.start.column + 2);\n            if (rightChar == selected) {\n                range.end.column++;\n                return range;\n            }\n        }\n    });\n\n};\n\n    \nCstyleBehaviour.isSaneInsertion = function(editor, session) {\n    var cursor = editor.getCursorPosition();\n    var iterator = new TokenIterator(session, cursor.row, cursor.column);\n    if (!this.$matchTokenType(iterator.getCurrentToken() || \"text\", SAFE_INSERT_IN_TOKENS)) {\n        if (/[)}\\]]/.test(editor.session.getLine(cursor.row)[cursor.column]))\n            return true;\n        var iterator2 = new TokenIterator(session, cursor.row, cursor.column + 1);\n        if (!this.$matchTokenType(iterator2.getCurrentToken() || \"text\", SAFE_INSERT_IN_TOKENS))\n            return false;\n    }\n    iterator.stepForward();\n    return iterator.getCurrentTokenRow() !== cursor.row ||\n        this.$matchTokenType(iterator.getCurrentToken() || \"text\", SAFE_INSERT_BEFORE_TOKENS);\n};\n\nCstyleBehaviour.$matchTokenType = function(token, types) {\n    return types.indexOf(token.type || token) > -1;\n};\n\nCstyleBehaviour.recordAutoInsert = function(editor, session, bracket) {\n    var cursor = editor.getCursorPosition();\n    var line = session.doc.getLine(cursor.row);\n    if (!this.isAutoInsertedClosing(cursor, line, context.autoInsertedLineEnd[0]))\n        context.autoInsertedBrackets = 0;\n    context.autoInsertedRow = cursor.row;\n    context.autoInsertedLineEnd = bracket + line.substr(cursor.column);\n    context.autoInsertedBrackets++;\n};\n\nCstyleBehaviour.recordMaybeInsert = function(editor, session, bracket) {\n    var cursor = editor.getCursorPosition();\n    var line = session.doc.getLine(cursor.row);\n    if (!this.isMaybeInsertedClosing(cursor, line))\n        context.maybeInsertedBrackets = 0;\n    context.maybeInsertedRow = cursor.row;\n    context.maybeInsertedLineStart = line.substr(0, cursor.column) + bracket;\n    context.maybeInsertedLineEnd = line.substr(cursor.column);\n    context.maybeInsertedBrackets++;\n};\n\nCstyleBehaviour.isAutoInsertedClosing = function(cursor, line, bracket) {\n    return context.autoInsertedBrackets > 0 &&\n        cursor.row === context.autoInsertedRow &&\n        bracket === context.autoInsertedLineEnd[0] &&\n        line.substr(cursor.column) === context.autoInsertedLineEnd;\n};\n\nCstyleBehaviour.isMaybeInsertedClosing = function(cursor, line) {\n    return context.maybeInsertedBrackets > 0 &&\n        cursor.row === context.maybeInsertedRow &&\n        line.substr(cursor.column) === context.maybeInsertedLineEnd &&\n        line.substr(0, cursor.column) == context.maybeInsertedLineStart;\n};\n\nCstyleBehaviour.popAutoInsertedClosing = function() {\n    context.autoInsertedLineEnd = context.autoInsertedLineEnd.substr(1);\n    context.autoInsertedBrackets--;\n};\n\nCstyleBehaviour.clearMaybeInsertedClosing = function() {\n    if (context) {\n        context.maybeInsertedBrackets = 0;\n        context.maybeInsertedRow = -1;\n    }\n};\n\n\n\noop.inherits(CstyleBehaviour, Behaviour);\n\nexports.CstyleBehaviour = CstyleBehaviour;\n});\n\nace.define(\"ace/unicode\",[\"require\",\"exports\",\"module\"], function(require, exports, module) {\n\"use strict\";\nvar wordChars = [48,9,8,25,5,0,2,25,48,0,11,0,5,0,6,22,2,30,2,457,5,11,15,4,8,0,2,0,18,116,2,1,3,3,9,0,2,2,2,0,2,19,2,82,2,138,2,4,3,155,12,37,3,0,8,38,10,44,2,0,2,1,2,1,2,0,9,26,6,2,30,10,7,61,2,9,5,101,2,7,3,9,2,18,3,0,17,58,3,100,15,53,5,0,6,45,211,57,3,18,2,5,3,11,3,9,2,1,7,6,2,2,2,7,3,1,3,21,2,6,2,0,4,3,3,8,3,1,3,3,9,0,5,1,2,4,3,11,16,2,2,5,5,1,3,21,2,6,2,1,2,1,2,1,3,0,2,4,5,1,3,2,4,0,8,3,2,0,8,15,12,2,2,8,2,2,2,21,2,6,2,1,2,4,3,9,2,2,2,2,3,0,16,3,3,9,18,2,2,7,3,1,3,21,2,6,2,1,2,4,3,8,3,1,3,2,9,1,5,1,2,4,3,9,2,0,17,1,2,5,4,2,2,3,4,1,2,0,2,1,4,1,4,2,4,11,5,4,4,2,2,3,3,0,7,0,15,9,18,2,2,7,2,2,2,22,2,9,2,4,4,7,2,2,2,3,8,1,2,1,7,3,3,9,19,1,2,7,2,2,2,22,2,9,2,4,3,8,2,2,2,3,8,1,8,0,2,3,3,9,19,1,2,7,2,2,2,22,2,15,4,7,2,2,2,3,10,0,9,3,3,9,11,5,3,1,2,17,4,23,2,8,2,0,3,6,4,0,5,5,2,0,2,7,19,1,14,57,6,14,2,9,40,1,2,0,3,1,2,0,3,0,7,3,2,6,2,2,2,0,2,0,3,1,2,12,2,2,3,4,2,0,2,5,3,9,3,1,35,0,24,1,7,9,12,0,2,0,2,0,5,9,2,35,5,19,2,5,5,7,2,35,10,0,58,73,7,77,3,37,11,42,2,0,4,328,2,3,3,6,2,0,2,3,3,40,2,3,3,32,2,3,3,6,2,0,2,3,3,14,2,56,2,3,3,66,5,0,33,15,17,84,13,619,3,16,2,25,6,74,22,12,2,6,12,20,12,19,13,12,2,2,2,1,13,51,3,29,4,0,5,1,3,9,34,2,3,9,7,87,9,42,6,69,11,28,4,11,5,11,11,39,3,4,12,43,5,25,7,10,38,27,5,62,2,28,3,10,7,9,14,0,89,75,5,9,18,8,13,42,4,11,71,55,9,9,4,48,83,2,2,30,14,230,23,280,3,5,3,37,3,5,3,7,2,0,2,0,2,0,2,30,3,52,2,6,2,0,4,2,2,6,4,3,3,5,5,12,6,2,2,6,67,1,20,0,29,0,14,0,17,4,60,12,5,0,4,11,18,0,5,0,3,9,2,0,4,4,7,0,2,0,2,0,2,3,2,10,3,3,6,4,5,0,53,1,2684,46,2,46,2,132,7,6,15,37,11,53,10,0,17,22,10,6,2,6,2,6,2,6,2,6,2,6,2,6,2,6,2,31,48,0,470,1,36,5,2,4,6,1,5,85,3,1,3,2,2,89,2,3,6,40,4,93,18,23,57,15,513,6581,75,20939,53,1164,68,45,3,268,4,27,21,31,3,13,13,1,2,24,9,69,11,1,38,8,3,102,3,1,111,44,25,51,13,68,12,9,7,23,4,0,5,45,3,35,13,28,4,64,15,10,39,54,10,13,3,9,7,22,4,1,5,66,25,2,227,42,2,1,3,9,7,11171,13,22,5,48,8453,301,3,61,3,105,39,6,13,4,6,11,2,12,2,4,2,0,2,1,2,1,2,107,34,362,19,63,3,53,41,11,5,15,17,6,13,1,25,2,33,4,2,134,20,9,8,25,5,0,2,25,12,88,4,5,3,5,3,5,3,2];\n\nvar code = 0;\nvar str = [];\nfor (var i = 0; i < wordChars.length; i += 2) {\n    str.push(code += wordChars[i]);\n    if (wordChars[i + 1])\n        str.push(45, code += wordChars[i + 1]);\n}\n\nexports.wordChars = String.fromCharCode.apply(null, str);\n\n});\n\nace.define(\"ace/mode/text\",[\"require\",\"exports\",\"module\",\"ace/config\",\"ace/tokenizer\",\"ace/mode/text_highlight_rules\",\"ace/mode/behaviour/cstyle\",\"ace/unicode\",\"ace/lib/lang\",\"ace/token_iterator\",\"ace/range\"], function(require, exports, module) {\n\"use strict\";\nvar config = require(\"../config\");\n\nvar Tokenizer = require(\"../tokenizer\").Tokenizer;\nvar TextHighlightRules = require(\"./text_highlight_rules\").TextHighlightRules;\nvar CstyleBehaviour = require(\"./behaviour/cstyle\").CstyleBehaviour;\nvar unicode = require(\"../unicode\");\nvar lang = require(\"../lib/lang\");\nvar TokenIterator = require(\"../token_iterator\").TokenIterator;\nvar Range = require(\"../range\").Range;\n\nvar Mode = function() {\n    this.HighlightRules = TextHighlightRules;\n};\n\n(function() {\n    this.$defaultBehaviour = new CstyleBehaviour();\n\n    this.tokenRe = new RegExp(\"^[\" + unicode.wordChars + \"\\\\$_]+\", \"g\");\n\n    this.nonTokenRe = new RegExp(\"^(?:[^\" + unicode.wordChars + \"\\\\$_]|\\\\s])+\", \"g\");\n\n    this.getTokenizer = function() {\n        if (!this.$tokenizer) {\n            this.$highlightRules = this.$highlightRules || new this.HighlightRules(this.$highlightRuleConfig);\n            this.$tokenizer = new Tokenizer(this.$highlightRules.getRules());\n        }\n        return this.$tokenizer;\n    };\n\n    this.lineCommentStart = \"\";\n    this.blockComment = \"\";\n\n    this.toggleCommentLines = function(state, session, startRow, endRow) {\n        var doc = session.doc;\n\n        var ignoreBlankLines = true;\n        var shouldRemove = true;\n        var minIndent = Infinity;\n        var tabSize = session.getTabSize();\n        var insertAtTabStop = false;\n\n        if (!this.lineCommentStart) {\n            if (!this.blockComment)\n                return false;\n            var lineCommentStart = this.blockComment.start;\n            var lineCommentEnd = this.blockComment.end;\n            var regexpStart = new RegExp(\"^(\\\\s*)(?:\" + lang.escapeRegExp(lineCommentStart) + \")\");\n            var regexpEnd = new RegExp(\"(?:\" + lang.escapeRegExp(lineCommentEnd) + \")\\\\s*$\");\n\n            var comment = function(line, i) {\n                if (testRemove(line, i))\n                    return;\n                if (!ignoreBlankLines || /\\S/.test(line)) {\n                    doc.insertInLine({row: i, column: line.length}, lineCommentEnd);\n                    doc.insertInLine({row: i, column: minIndent}, lineCommentStart);\n                }\n            };\n\n            var uncomment = function(line, i) {\n                var m;\n                if (m = line.match(regexpEnd))\n                    doc.removeInLine(i, line.length - m[0].length, line.length);\n                if (m = line.match(regexpStart))\n                    doc.removeInLine(i, m[1].length, m[0].length);\n            };\n\n            var testRemove = function(line, row) {\n                if (regexpStart.test(line))\n                    return true;\n                var tokens = session.getTokens(row);\n                for (var i = 0; i < tokens.length; i++) {\n                    if (tokens[i].type === \"comment\")\n                        return true;\n                }\n            };\n        } else {\n            if (Array.isArray(this.lineCommentStart)) {\n                var regexpStart = this.lineCommentStart.map(lang.escapeRegExp).join(\"|\");\n                var lineCommentStart = this.lineCommentStart[0];\n            } else {\n                var regexpStart = lang.escapeRegExp(this.lineCommentStart);\n                var lineCommentStart = this.lineCommentStart;\n            }\n            regexpStart = new RegExp(\"^(\\\\s*)(?:\" + regexpStart + \") ?\");\n            \n            insertAtTabStop = session.getUseSoftTabs();\n\n            var uncomment = function(line, i) {\n                var m = line.match(regexpStart);\n                if (!m) return;\n                var start = m[1].length, end = m[0].length;\n                if (!shouldInsertSpace(line, start, end) && m[0][end - 1] == \" \")\n                    end--;\n                doc.removeInLine(i, start, end);\n            };\n            var commentWithSpace = lineCommentStart + \" \";\n            var comment = function(line, i) {\n                if (!ignoreBlankLines || /\\S/.test(line)) {\n                    if (shouldInsertSpace(line, minIndent, minIndent))\n                        doc.insertInLine({row: i, column: minIndent}, commentWithSpace);\n                    else\n                        doc.insertInLine({row: i, column: minIndent}, lineCommentStart);\n                }\n            };\n            var testRemove = function(line, i) {\n                return regexpStart.test(line);\n            };\n            \n            var shouldInsertSpace = function(line, before, after) {\n                var spaces = 0;\n                while (before-- && line.charAt(before) == \" \")\n                    spaces++;\n                if (spaces % tabSize != 0)\n                    return false;\n                var spaces = 0;\n                while (line.charAt(after++) == \" \")\n                    spaces++;\n                if (tabSize > 2)\n                    return spaces % tabSize != tabSize - 1;\n                else\n                    return spaces % tabSize == 0;\n            };\n        }\n\n        function iter(fun) {\n            for (var i = startRow; i <= endRow; i++)\n                fun(doc.getLine(i), i);\n        }\n\n\n        var minEmptyLength = Infinity;\n        iter(function(line, i) {\n            var indent = line.search(/\\S/);\n            if (indent !== -1) {\n                if (indent < minIndent)\n                    minIndent = indent;\n                if (shouldRemove && !testRemove(line, i))\n                    shouldRemove = false;\n            } else if (minEmptyLength > line.length) {\n                minEmptyLength = line.length;\n            }\n        });\n\n        if (minIndent == Infinity) {\n            minIndent = minEmptyLength;\n            ignoreBlankLines = false;\n            shouldRemove = false;\n        }\n\n        if (insertAtTabStop && minIndent % tabSize != 0)\n            minIndent = Math.floor(minIndent / tabSize) * tabSize;\n\n        iter(shouldRemove ? uncomment : comment);\n    };\n\n    this.toggleBlockComment = function(state, session, range, cursor) {\n        var comment = this.blockComment;\n        if (!comment)\n            return;\n        if (!comment.start && comment[0])\n            comment = comment[0];\n\n        var iterator = new TokenIterator(session, cursor.row, cursor.column);\n        var token = iterator.getCurrentToken();\n\n        var sel = session.selection;\n        var initialRange = session.selection.toOrientedRange();\n        var startRow, colDiff;\n\n        if (token && /comment/.test(token.type)) {\n            var startRange, endRange;\n            while (token && /comment/.test(token.type)) {\n                var i = token.value.indexOf(comment.start);\n                if (i != -1) {\n                    var row = iterator.getCurrentTokenRow();\n                    var column = iterator.getCurrentTokenColumn() + i;\n                    startRange = new Range(row, column, row, column + comment.start.length);\n                    break;\n                }\n                token = iterator.stepBackward();\n            }\n\n            var iterator = new TokenIterator(session, cursor.row, cursor.column);\n            var token = iterator.getCurrentToken();\n            while (token && /comment/.test(token.type)) {\n                var i = token.value.indexOf(comment.end);\n                if (i != -1) {\n                    var row = iterator.getCurrentTokenRow();\n                    var column = iterator.getCurrentTokenColumn() + i;\n                    endRange = new Range(row, column, row, column + comment.end.length);\n                    break;\n                }\n                token = iterator.stepForward();\n            }\n            if (endRange)\n                session.remove(endRange);\n            if (startRange) {\n                session.remove(startRange);\n                startRow = startRange.start.row;\n                colDiff = -comment.start.length;\n            }\n        } else {\n            colDiff = comment.start.length;\n            startRow = range.start.row;\n            session.insert(range.end, comment.end);\n            session.insert(range.start, comment.start);\n        }\n        if (initialRange.start.row == startRow)\n            initialRange.start.column += colDiff;\n        if (initialRange.end.row == startRow)\n            initialRange.end.column += colDiff;\n        session.selection.fromOrientedRange(initialRange);\n    };\n\n    this.getNextLineIndent = function(state, line, tab) {\n        return this.$getIndent(line);\n    };\n\n    this.checkOutdent = function(state, line, input) {\n        return false;\n    };\n\n    this.autoOutdent = function(state, doc, row) {\n    };\n\n    this.$getIndent = function(line) {\n        return line.match(/^\\s*/)[0];\n    };\n\n    this.createWorker = function(session) {\n        return null;\n    };\n\n    this.createModeDelegates = function (mapping) {\n        this.$embeds = [];\n        this.$modes = {};\n        for (var i in mapping) {\n            if (mapping[i]) {\n                var Mode = mapping[i];\n                var id = Mode.prototype.$id;\n                var mode = config.$modes[id];\n                if (!mode)\n                    config.$modes[id] = mode = new Mode();\n                if (!config.$modes[i])\n                    config.$modes[i] = mode;\n                this.$embeds.push(i);\n                this.$modes[i] = mode;\n            }\n        }\n\n        var delegations = [\"toggleBlockComment\", \"toggleCommentLines\", \"getNextLineIndent\", \n            \"checkOutdent\", \"autoOutdent\", \"transformAction\", \"getCompletions\"];\n\n        for (var i = 0; i < delegations.length; i++) {\n            (function(scope) {\n              var functionName = delegations[i];\n              var defaultHandler = scope[functionName];\n              scope[delegations[i]] = function() {\n                  return this.$delegator(functionName, arguments, defaultHandler);\n              };\n            }(this));\n        }\n    };\n\n    this.$delegator = function(method, args, defaultHandler) {\n        var state = args[0] || \"start\";\n        if (typeof state != \"string\") {\n            if (Array.isArray(state[2])) {\n                var language = state[2][state[2].length - 1];\n                var mode = this.$modes[language];\n                if (mode)\n                    return mode[method].apply(mode, [state[1]].concat([].slice.call(args, 1)));\n            }\n            state = state[0] || \"start\";\n        }\n            \n        for (var i = 0; i < this.$embeds.length; i++) {\n            if (!this.$modes[this.$embeds[i]]) continue;\n\n            var split = state.split(this.$embeds[i]);\n            if (!split[0] && split[1]) {\n                args[0] = split[1];\n                var mode = this.$modes[this.$embeds[i]];\n                return mode[method].apply(mode, args);\n            }\n        }\n        var ret = defaultHandler.apply(this, args);\n        return defaultHandler ? ret : undefined;\n    };\n\n    this.transformAction = function(state, action, editor, session, param) {\n        if (this.$behaviour) {\n            var behaviours = this.$behaviour.getBehaviours();\n            for (var key in behaviours) {\n                if (behaviours[key][action]) {\n                    var ret = behaviours[key][action].apply(this, arguments);\n                    if (ret) {\n                        return ret;\n                    }\n                }\n            }\n        }\n    };\n    \n    this.getKeywords = function(append) {\n        if (!this.completionKeywords) {\n            var rules = this.$tokenizer.rules;\n            var completionKeywords = [];\n            for (var rule in rules) {\n                var ruleItr = rules[rule];\n                for (var r = 0, l = ruleItr.length; r < l; r++) {\n                    if (typeof ruleItr[r].token === \"string\") {\n                        if (/keyword|support|storage/.test(ruleItr[r].token))\n                            completionKeywords.push(ruleItr[r].regex);\n                    }\n                    else if (typeof ruleItr[r].token === \"object\") {\n                        for (var a = 0, aLength = ruleItr[r].token.length; a < aLength; a++) {    \n                            if (/keyword|support|storage/.test(ruleItr[r].token[a])) {\n                                var rule = ruleItr[r].regex.match(/\\(.+?\\)/g)[a];\n                                completionKeywords.push(rule.substr(1, rule.length - 2));\n                            }\n                        }\n                    }\n                }\n            }\n            this.completionKeywords = completionKeywords;\n        }\n        if (!append)\n            return this.$keywordList;\n        return completionKeywords.concat(this.$keywordList || []);\n    };\n    \n    this.$createKeywordList = function() {\n        if (!this.$highlightRules)\n            this.getTokenizer();\n        return this.$keywordList = this.$highlightRules.$keywordList || [];\n    };\n\n    this.getCompletions = function(state, session, pos, prefix) {\n        var keywords = this.$keywordList || this.$createKeywordList();\n        return keywords.map(function(word) {\n            return {\n                name: word,\n                value: word,\n                score: 0,\n                meta: \"keyword\"\n            };\n        });\n    };\n\n    this.$id = \"ace/mode/text\";\n}).call(Mode.prototype);\n\nexports.Mode = Mode;\n});\n\nace.define(\"ace/apply_delta\",[\"require\",\"exports\",\"module\"], function(require, exports, module) {\n\"use strict\";\n\nfunction throwDeltaError(delta, errorText){\n    console.log(\"Invalid Delta:\", delta);\n    throw \"Invalid Delta: \" + errorText;\n}\n\nfunction positionInDocument(docLines, position) {\n    return position.row    >= 0 && position.row    <  docLines.length &&\n           position.column >= 0 && position.column <= docLines[position.row].length;\n}\n\nfunction validateDelta(docLines, delta) {\n    if (delta.action != \"insert\" && delta.action != \"remove\")\n        throwDeltaError(delta, \"delta.action must be 'insert' or 'remove'\");\n    if (!(delta.lines instanceof Array))\n        throwDeltaError(delta, \"delta.lines must be an Array\");\n    if (!delta.start || !delta.end)\n       throwDeltaError(delta, \"delta.start/end must be an present\");\n    var start = delta.start;\n    if (!positionInDocument(docLines, delta.start))\n        throwDeltaError(delta, \"delta.start must be contained in document\");\n    var end = delta.end;\n    if (delta.action == \"remove\" && !positionInDocument(docLines, end))\n        throwDeltaError(delta, \"delta.end must contained in document for 'remove' actions\");\n    var numRangeRows = end.row - start.row;\n    var numRangeLastLineChars = (end.column - (numRangeRows == 0 ? start.column : 0));\n    if (numRangeRows != delta.lines.length - 1 || delta.lines[numRangeRows].length != numRangeLastLineChars)\n        throwDeltaError(delta, \"delta.range must match delta lines\");\n}\n\nexports.applyDelta = function(docLines, delta, doNotValidate) {\n    \n    var row = delta.start.row;\n    var startColumn = delta.start.column;\n    var line = docLines[row] || \"\";\n    switch (delta.action) {\n        case \"insert\":\n            var lines = delta.lines;\n            if (lines.length === 1) {\n                docLines[row] = line.substring(0, startColumn) + delta.lines[0] + line.substring(startColumn);\n            } else {\n                var args = [row, 1].concat(delta.lines);\n                docLines.splice.apply(docLines, args);\n                docLines[row] = line.substring(0, startColumn) + docLines[row];\n                docLines[row + delta.lines.length - 1] += line.substring(startColumn);\n            }\n            break;\n        case \"remove\":\n            var endColumn = delta.end.column;\n            var endRow = delta.end.row;\n            if (row === endRow) {\n                docLines[row] = line.substring(0, startColumn) + line.substring(endColumn);\n            } else {\n                docLines.splice(\n                    row, endRow - row + 1,\n                    line.substring(0, startColumn) + docLines[endRow].substring(endColumn)\n                );\n            }\n            break;\n    }\n};\n});\n\nace.define(\"ace/anchor\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/event_emitter\"], function(require, exports, module) {\n\"use strict\";\n\nvar oop = require(\"./lib/oop\");\nvar EventEmitter = require(\"./lib/event_emitter\").EventEmitter;\n\nvar Anchor = exports.Anchor = function(doc, row, column) {\n    this.$onChange = this.onChange.bind(this);\n    this.attach(doc);\n    \n    if (typeof column == \"undefined\")\n        this.setPosition(row.row, row.column);\n    else\n        this.setPosition(row, column);\n};\n\n(function() {\n\n    oop.implement(this, EventEmitter);\n    this.getPosition = function() {\n        return this.$clipPositionToDocument(this.row, this.column);\n    };\n    this.getDocument = function() {\n        return this.document;\n    };\n    this.$insertRight = false;\n    this.onChange = function(delta) {\n        if (delta.start.row == delta.end.row && delta.start.row != this.row)\n            return;\n\n        if (delta.start.row > this.row)\n            return;\n            \n        var point = $getTransformedPoint(delta, {row: this.row, column: this.column}, this.$insertRight);\n        this.setPosition(point.row, point.column, true);\n    };\n    \n    function $pointsInOrder(point1, point2, equalPointsInOrder) {\n        var bColIsAfter = equalPointsInOrder ? point1.column <= point2.column : point1.column < point2.column;\n        return (point1.row < point2.row) || (point1.row == point2.row && bColIsAfter);\n    }\n            \n    function $getTransformedPoint(delta, point, moveIfEqual) {\n        var deltaIsInsert = delta.action == \"insert\";\n        var deltaRowShift = (deltaIsInsert ? 1 : -1) * (delta.end.row    - delta.start.row);\n        var deltaColShift = (deltaIsInsert ? 1 : -1) * (delta.end.column - delta.start.column);\n        var deltaStart = delta.start;\n        var deltaEnd = deltaIsInsert ? deltaStart : delta.end; // Collapse insert range.\n        if ($pointsInOrder(point, deltaStart, moveIfEqual)) {\n            return {\n                row: point.row,\n                column: point.column\n            };\n        }\n        if ($pointsInOrder(deltaEnd, point, !moveIfEqual)) {\n            return {\n                row: point.row + deltaRowShift,\n                column: point.column + (point.row == deltaEnd.row ? deltaColShift : 0)\n            };\n        }\n        \n        return {\n            row: deltaStart.row,\n            column: deltaStart.column\n        };\n    }\n    this.setPosition = function(row, column, noClip) {\n        var pos;\n        if (noClip) {\n            pos = {\n                row: row,\n                column: column\n            };\n        } else {\n            pos = this.$clipPositionToDocument(row, column);\n        }\n\n        if (this.row == pos.row && this.column == pos.column)\n            return;\n\n        var old = {\n            row: this.row,\n            column: this.column\n        };\n\n        this.row = pos.row;\n        this.column = pos.column;\n        this._signal(\"change\", {\n            old: old,\n            value: pos\n        });\n    };\n    this.detach = function() {\n        this.document.removeEventListener(\"change\", this.$onChange);\n    };\n    this.attach = function(doc) {\n        this.document = doc || this.document;\n        this.document.on(\"change\", this.$onChange);\n    };\n    this.$clipPositionToDocument = function(row, column) {\n        var pos = {};\n\n        if (row >= this.document.getLength()) {\n            pos.row = Math.max(0, this.document.getLength() - 1);\n            pos.column = this.document.getLine(pos.row).length;\n        }\n        else if (row < 0) {\n            pos.row = 0;\n            pos.column = 0;\n        }\n        else {\n            pos.row = row;\n            pos.column = Math.min(this.document.getLine(pos.row).length, Math.max(0, column));\n        }\n\n        if (column < 0)\n            pos.column = 0;\n\n        return pos;\n    };\n\n}).call(Anchor.prototype);\n\n});\n\nace.define(\"ace/document\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/apply_delta\",\"ace/lib/event_emitter\",\"ace/range\",\"ace/anchor\"], function(require, exports, module) {\n\"use strict\";\n\nvar oop = require(\"./lib/oop\");\nvar applyDelta = require(\"./apply_delta\").applyDelta;\nvar EventEmitter = require(\"./lib/event_emitter\").EventEmitter;\nvar Range = require(\"./range\").Range;\nvar Anchor = require(\"./anchor\").Anchor;\n\nvar Document = function(textOrLines) {\n    this.$lines = [\"\"];\n    if (textOrLines.length === 0) {\n        this.$lines = [\"\"];\n    } else if (Array.isArray(textOrLines)) {\n        this.insertMergedLines({row: 0, column: 0}, textOrLines);\n    } else {\n        this.insert({row: 0, column:0}, textOrLines);\n    }\n};\n\n(function() {\n\n    oop.implement(this, EventEmitter);\n    this.setValue = function(text) {\n        var len = this.getLength() - 1;\n        this.remove(new Range(0, 0, len, this.getLine(len).length));\n        this.insert({row: 0, column: 0}, text);\n    };\n    this.getValue = function() {\n        return this.getAllLines().join(this.getNewLineCharacter());\n    };\n    this.createAnchor = function(row, column) {\n        return new Anchor(this, row, column);\n    };\n    if (\"aaa\".split(/a/).length === 0) {\n        this.$split = function(text) {\n            return text.replace(/\\r\\n|\\r/g, \"\\n\").split(\"\\n\");\n        };\n    } else {\n        this.$split = function(text) {\n            return text.split(/\\r\\n|\\r|\\n/);\n        };\n    }\n\n\n    this.$detectNewLine = function(text) {\n        var match = text.match(/^.*?(\\r\\n|\\r|\\n)/m);\n        this.$autoNewLine = match ? match[1] : \"\\n\";\n        this._signal(\"changeNewLineMode\");\n    };\n    this.getNewLineCharacter = function() {\n        switch (this.$newLineMode) {\n          case \"windows\":\n            return \"\\r\\n\";\n          case \"unix\":\n            return \"\\n\";\n          default:\n            return this.$autoNewLine || \"\\n\";\n        }\n    };\n\n    this.$autoNewLine = \"\";\n    this.$newLineMode = \"auto\";\n    this.setNewLineMode = function(newLineMode) {\n        if (this.$newLineMode === newLineMode)\n            return;\n\n        this.$newLineMode = newLineMode;\n        this._signal(\"changeNewLineMode\");\n    };\n    this.getNewLineMode = function() {\n        return this.$newLineMode;\n    };\n    this.isNewLine = function(text) {\n        return (text == \"\\r\\n\" || text == \"\\r\" || text == \"\\n\");\n    };\n    this.getLine = function(row) {\n        return this.$lines[row] || \"\";\n    };\n    this.getLines = function(firstRow, lastRow) {\n        return this.$lines.slice(firstRow, lastRow + 1);\n    };\n    this.getAllLines = function() {\n        return this.getLines(0, this.getLength());\n    };\n    this.getLength = function() {\n        return this.$lines.length;\n    };\n    this.getTextRange = function(range) {\n        return this.getLinesForRange(range).join(this.getNewLineCharacter());\n    };\n    this.getLinesForRange = function(range) {\n        var lines;\n        if (range.start.row === range.end.row) {\n            lines = [this.getLine(range.start.row).substring(range.start.column, range.end.column)];\n        } else {\n            lines = this.getLines(range.start.row, range.end.row);\n            lines[0] = (lines[0] || \"\").substring(range.start.column);\n            var l = lines.length - 1;\n            if (range.end.row - range.start.row == l)\n                lines[l] = lines[l].substring(0, range.end.column);\n        }\n        return lines;\n    };\n    this.insertLines = function(row, lines) {\n        console.warn(\"Use of document.insertLines is deprecated. Use the insertFullLines method instead.\");\n        return this.insertFullLines(row, lines);\n    };\n    this.removeLines = function(firstRow, lastRow) {\n        console.warn(\"Use of document.removeLines is deprecated. Use the removeFullLines method instead.\");\n        return this.removeFullLines(firstRow, lastRow);\n    };\n    this.insertNewLine = function(position) {\n        console.warn(\"Use of document.insertNewLine is deprecated. Use insertMergedLines(position, ['', '']) instead.\");\n        return this.insertMergedLines(position, [\"\", \"\"]);\n    };\n    this.insert = function(position, text) {\n        if (this.getLength() <= 1)\n            this.$detectNewLine(text);\n        \n        return this.insertMergedLines(position, this.$split(text));\n    };\n    this.insertInLine = function(position, text) {\n        var start = this.clippedPos(position.row, position.column);\n        var end = this.pos(position.row, position.column + text.length);\n        \n        this.applyDelta({\n            start: start,\n            end: end,\n            action: \"insert\",\n            lines: [text]\n        }, true);\n        \n        return this.clonePos(end);\n    };\n    \n    this.clippedPos = function(row, column) {\n        var length = this.getLength();\n        if (row === undefined) {\n            row = length;\n        } else if (row < 0) {\n            row = 0;\n        } else if (row >= length) {\n            row = length - 1;\n            column = undefined;\n        }\n        var line = this.getLine(row);\n        if (column == undefined)\n            column = line.length;\n        column = Math.min(Math.max(column, 0), line.length);\n        return {row: row, column: column};\n    };\n    \n    this.clonePos = function(pos) {\n        return {row: pos.row, column: pos.column};\n    };\n    \n    this.pos = function(row, column) {\n        return {row: row, column: column};\n    };\n    \n    this.$clipPosition = function(position) {\n        var length = this.getLength();\n        if (position.row >= length) {\n            position.row = Math.max(0, length - 1);\n            position.column = this.getLine(length - 1).length;\n        } else {\n            position.row = Math.max(0, position.row);\n            position.column = Math.min(Math.max(position.column, 0), this.getLine(position.row).length);\n        }\n        return position;\n    };\n    this.insertFullLines = function(row, lines) {\n        row = Math.min(Math.max(row, 0), this.getLength());\n        var column = 0;\n        if (row < this.getLength()) {\n            lines = lines.concat([\"\"]);\n            column = 0;\n        } else {\n            lines = [\"\"].concat(lines);\n            row--;\n            column = this.$lines[row].length;\n        }\n        this.insertMergedLines({row: row, column: column}, lines);\n    };    \n    this.insertMergedLines = function(position, lines) {\n        var start = this.clippedPos(position.row, position.column);\n        var end = {\n            row: start.row + lines.length - 1,\n            column: (lines.length == 1 ? start.column : 0) + lines[lines.length - 1].length\n        };\n        \n        this.applyDelta({\n            start: start,\n            end: end,\n            action: \"insert\",\n            lines: lines\n        });\n        \n        return this.clonePos(end);\n    };\n    this.remove = function(range) {\n        var start = this.clippedPos(range.start.row, range.start.column);\n        var end = this.clippedPos(range.end.row, range.end.column);\n        this.applyDelta({\n            start: start,\n            end: end,\n            action: \"remove\",\n            lines: this.getLinesForRange({start: start, end: end})\n        });\n        return this.clonePos(start);\n    };\n    this.removeInLine = function(row, startColumn, endColumn) {\n        var start = this.clippedPos(row, startColumn);\n        var end = this.clippedPos(row, endColumn);\n        \n        this.applyDelta({\n            start: start,\n            end: end,\n            action: \"remove\",\n            lines: this.getLinesForRange({start: start, end: end})\n        }, true);\n        \n        return this.clonePos(start);\n    };\n    this.removeFullLines = function(firstRow, lastRow) {\n        firstRow = Math.min(Math.max(0, firstRow), this.getLength() - 1);\n        lastRow  = Math.min(Math.max(0, lastRow ), this.getLength() - 1);\n        var deleteFirstNewLine = lastRow == this.getLength() - 1 && firstRow > 0;\n        var deleteLastNewLine  = lastRow  < this.getLength() - 1;\n        var startRow = ( deleteFirstNewLine ? firstRow - 1                  : firstRow                    );\n        var startCol = ( deleteFirstNewLine ? this.getLine(startRow).length : 0                           );\n        var endRow   = ( deleteLastNewLine  ? lastRow + 1                   : lastRow                     );\n        var endCol   = ( deleteLastNewLine  ? 0                             : this.getLine(endRow).length ); \n        var range = new Range(startRow, startCol, endRow, endCol);\n        var deletedLines = this.$lines.slice(firstRow, lastRow + 1);\n        \n        this.applyDelta({\n            start: range.start,\n            end: range.end,\n            action: \"remove\",\n            lines: this.getLinesForRange(range)\n        });\n        return deletedLines;\n    };\n    this.removeNewLine = function(row) {\n        if (row < this.getLength() - 1 && row >= 0) {\n            this.applyDelta({\n                start: this.pos(row, this.getLine(row).length),\n                end: this.pos(row + 1, 0),\n                action: \"remove\",\n                lines: [\"\", \"\"]\n            });\n        }\n    };\n    this.replace = function(range, text) {\n        if (!(range instanceof Range))\n            range = Range.fromPoints(range.start, range.end);\n        if (text.length === 0 && range.isEmpty())\n            return range.start;\n        if (text == this.getTextRange(range))\n            return range.end;\n\n        this.remove(range);\n        var end;\n        if (text) {\n            end = this.insert(range.start, text);\n        }\n        else {\n            end = range.start;\n        }\n        \n        return end;\n    };\n    this.applyDeltas = function(deltas) {\n        for (var i=0; i<deltas.length; i++) {\n            this.applyDelta(deltas[i]);\n        }\n    };\n    this.revertDeltas = function(deltas) {\n        for (var i=deltas.length-1; i>=0; i--) {\n            this.revertDelta(deltas[i]);\n        }\n    };\n    this.applyDelta = function(delta, doNotValidate) {\n        var isInsert = delta.action == \"insert\";\n        if (isInsert ? delta.lines.length <= 1 && !delta.lines[0]\n            : !Range.comparePoints(delta.start, delta.end)) {\n            return;\n        }\n        \n        if (isInsert && delta.lines.length > 20000) {\n            this.$splitAndapplyLargeDelta(delta, 20000);\n        }\n        else {\n            applyDelta(this.$lines, delta, doNotValidate);\n            this._signal(\"change\", delta);\n        }\n    };\n    \n    this.$splitAndapplyLargeDelta = function(delta, MAX) {\n        var lines = delta.lines;\n        var l = lines.length - MAX + 1;\n        var row = delta.start.row; \n        var column = delta.start.column;\n        for (var from = 0, to = 0; from < l; from = to) {\n            to += MAX - 1;\n            var chunk = lines.slice(from, to);\n            chunk.push(\"\");\n            this.applyDelta({\n                start: this.pos(row + from, column),\n                end: this.pos(row + to, column = 0),\n                action: delta.action,\n                lines: chunk\n            }, true);\n        }\n        delta.lines = lines.slice(from);\n        delta.start.row = row + from;\n        delta.start.column = column;\n        this.applyDelta(delta, true);\n    };\n    this.revertDelta = function(delta) {\n        this.applyDelta({\n            start: this.clonePos(delta.start),\n            end: this.clonePos(delta.end),\n            action: (delta.action == \"insert\" ? \"remove\" : \"insert\"),\n            lines: delta.lines.slice()\n        });\n    };\n    this.indexToPosition = function(index, startRow) {\n        var lines = this.$lines || this.getAllLines();\n        var newlineLength = this.getNewLineCharacter().length;\n        for (var i = startRow || 0, l = lines.length; i < l; i++) {\n            index -= lines[i].length + newlineLength;\n            if (index < 0)\n                return {row: i, column: index + lines[i].length + newlineLength};\n        }\n        return {row: l-1, column: index + lines[l-1].length + newlineLength};\n    };\n    this.positionToIndex = function(pos, startRow) {\n        var lines = this.$lines || this.getAllLines();\n        var newlineLength = this.getNewLineCharacter().length;\n        var index = 0;\n        var row = Math.min(pos.row, lines.length);\n        for (var i = startRow || 0; i < row; ++i)\n            index += lines[i].length + newlineLength;\n\n        return index + pos.column;\n    };\n\n}).call(Document.prototype);\n\nexports.Document = Document;\n});\n\nace.define(\"ace/background_tokenizer\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/event_emitter\"], function(require, exports, module) {\n\"use strict\";\n\nvar oop = require(\"./lib/oop\");\nvar EventEmitter = require(\"./lib/event_emitter\").EventEmitter;\n\nvar BackgroundTokenizer = function(tokenizer, editor) {\n    this.running = false;\n    this.lines = [];\n    this.states = [];\n    this.currentLine = 0;\n    this.tokenizer = tokenizer;\n\n    var self = this;\n\n    this.$worker = function() {\n        if (!self.running) { return; }\n\n        var workerStart = new Date();\n        var currentLine = self.currentLine;\n        var endLine = -1;\n        var doc = self.doc;\n\n        var startLine = currentLine;\n        while (self.lines[currentLine])\n            currentLine++;\n        \n        var len = doc.getLength();\n        var processedLines = 0;\n        self.running = false;\n        while (currentLine < len) {\n            self.$tokenizeRow(currentLine);\n            endLine = currentLine;\n            do {\n                currentLine++;\n            } while (self.lines[currentLine]);\n            processedLines ++;\n            if ((processedLines % 5 === 0) && (new Date() - workerStart) > 20) {\n                self.running = setTimeout(self.$worker, 20);\n                break;\n            }\n        }\n        self.currentLine = currentLine;\n        \n        if (endLine == -1)\n            endLine = currentLine;\n        \n        if (startLine <= endLine)\n            self.fireUpdateEvent(startLine, endLine);\n    };\n};\n\n(function(){\n\n    oop.implement(this, EventEmitter);\n    this.setTokenizer = function(tokenizer) {\n        this.tokenizer = tokenizer;\n        this.lines = [];\n        this.states = [];\n\n        this.start(0);\n    };\n    this.setDocument = function(doc) {\n        this.doc = doc;\n        this.lines = [];\n        this.states = [];\n\n        this.stop();\n    };\n    this.fireUpdateEvent = function(firstRow, lastRow) {\n        var data = {\n            first: firstRow,\n            last: lastRow\n        };\n        this._signal(\"update\", {data: data});\n    };\n    this.start = function(startRow) {\n        this.currentLine = Math.min(startRow || 0, this.currentLine, this.doc.getLength());\n        this.lines.splice(this.currentLine, this.lines.length);\n        this.states.splice(this.currentLine, this.states.length);\n\n        this.stop();\n        this.running = setTimeout(this.$worker, 700);\n    };\n    \n    this.scheduleStart = function() {\n        if (!this.running)\n            this.running = setTimeout(this.$worker, 700);\n    };\n\n    this.$updateOnChange = function(delta) {\n        var startRow = delta.start.row;\n        var len = delta.end.row - startRow;\n\n        if (len === 0) {\n            this.lines[startRow] = null;\n        } else if (delta.action == \"remove\") {\n            this.lines.splice(startRow, len + 1, null);\n            this.states.splice(startRow, len + 1, null);\n        } else {\n            var args = Array(len + 1);\n            args.unshift(startRow, 1);\n            this.lines.splice.apply(this.lines, args);\n            this.states.splice.apply(this.states, args);\n        }\n\n        this.currentLine = Math.min(startRow, this.currentLine, this.doc.getLength());\n\n        this.stop();\n    };\n    this.stop = function() {\n        if (this.running)\n            clearTimeout(this.running);\n        this.running = false;\n    };\n    this.getTokens = function(row) {\n        return this.lines[row] || this.$tokenizeRow(row);\n    };\n    this.getState = function(row) {\n        if (this.currentLine == row)\n            this.$tokenizeRow(row);\n        return this.states[row] || \"start\";\n    };\n\n    this.$tokenizeRow = function(row) {\n        var line = this.doc.getLine(row);\n        var state = this.states[row - 1];\n\n        var data = this.tokenizer.getLineTokens(line, state, row);\n\n        if (this.states[row] + \"\" !== data.state + \"\") {\n            this.states[row] = data.state;\n            this.lines[row + 1] = null;\n            if (this.currentLine > row + 1)\n                this.currentLine = row + 1;\n        } else if (this.currentLine == row) {\n            this.currentLine = row + 1;\n        }\n\n        return this.lines[row] = data.tokens;\n    };\n\n}).call(BackgroundTokenizer.prototype);\n\nexports.BackgroundTokenizer = BackgroundTokenizer;\n});\n\nace.define(\"ace/search_highlight\",[\"require\",\"exports\",\"module\",\"ace/lib/lang\",\"ace/lib/oop\",\"ace/range\"], function(require, exports, module) {\n\"use strict\";\n\nvar lang = require(\"./lib/lang\");\nvar oop = require(\"./lib/oop\");\nvar Range = require(\"./range\").Range;\n\nvar SearchHighlight = function(regExp, clazz, type) {\n    this.setRegexp(regExp);\n    this.clazz = clazz;\n    this.type = type || \"text\";\n};\n\n(function() {\n    this.MAX_RANGES = 500;\n    \n    this.setRegexp = function(regExp) {\n        if (this.regExp+\"\" == regExp+\"\")\n            return;\n        this.regExp = regExp;\n        this.cache = [];\n    };\n\n    this.update = function(html, markerLayer, session, config) {\n        if (!this.regExp)\n            return;\n        var start = config.firstRow, end = config.lastRow;\n\n        for (var i = start; i <= end; i++) {\n            var ranges = this.cache[i];\n            if (ranges == null) {\n                ranges = lang.getMatchOffsets(session.getLine(i), this.regExp);\n                if (ranges.length > this.MAX_RANGES)\n                    ranges = ranges.slice(0, this.MAX_RANGES);\n                ranges = ranges.map(function(match) {\n                    return new Range(i, match.offset, i, match.offset + match.length);\n                });\n                this.cache[i] = ranges.length ? ranges : \"\";\n            }\n\n            for (var j = ranges.length; j --; ) {\n                markerLayer.drawSingleLineMarker(\n                    html, ranges[j].toScreenRange(session), this.clazz, config);\n            }\n        }\n    };\n\n}).call(SearchHighlight.prototype);\n\nexports.SearchHighlight = SearchHighlight;\n});\n\nace.define(\"ace/edit_session/fold_line\",[\"require\",\"exports\",\"module\",\"ace/range\"], function(require, exports, module) {\n\"use strict\";\n\nvar Range = require(\"../range\").Range;\nfunction FoldLine(foldData, folds) {\n    this.foldData = foldData;\n    if (Array.isArray(folds)) {\n        this.folds = folds;\n    } else {\n        folds = this.folds = [ folds ];\n    }\n\n    var last = folds[folds.length - 1];\n    this.range = new Range(folds[0].start.row, folds[0].start.column,\n                           last.end.row, last.end.column);\n    this.start = this.range.start;\n    this.end   = this.range.end;\n\n    this.folds.forEach(function(fold) {\n        fold.setFoldLine(this);\n    }, this);\n}\n\n(function() {\n    this.shiftRow = function(shift) {\n        this.start.row += shift;\n        this.end.row += shift;\n        this.folds.forEach(function(fold) {\n            fold.start.row += shift;\n            fold.end.row += shift;\n        });\n    };\n\n    this.addFold = function(fold) {\n        if (fold.sameRow) {\n            if (fold.start.row < this.startRow || fold.endRow > this.endRow) {\n                throw new Error(\"Can't add a fold to this FoldLine as it has no connection\");\n            }\n            this.folds.push(fold);\n            this.folds.sort(function(a, b) {\n                return -a.range.compareEnd(b.start.row, b.start.column);\n            });\n            if (this.range.compareEnd(fold.start.row, fold.start.column) > 0) {\n                this.end.row = fold.end.row;\n                this.end.column =  fold.end.column;\n            } else if (this.range.compareStart(fold.end.row, fold.end.column) < 0) {\n                this.start.row = fold.start.row;\n                this.start.column = fold.start.column;\n            }\n        } else if (fold.start.row == this.end.row) {\n            this.folds.push(fold);\n            this.end.row = fold.end.row;\n            this.end.column = fold.end.column;\n        } else if (fold.end.row == this.start.row) {\n            this.folds.unshift(fold);\n            this.start.row = fold.start.row;\n            this.start.column = fold.start.column;\n        } else {\n            throw new Error(\"Trying to add fold to FoldRow that doesn't have a matching row\");\n        }\n        fold.foldLine = this;\n    };\n\n    this.containsRow = function(row) {\n        return row >= this.start.row && row <= this.end.row;\n    };\n\n    this.walk = function(callback, endRow, endColumn) {\n        var lastEnd = 0,\n            folds = this.folds,\n            fold,\n            cmp, stop, isNewRow = true;\n\n        if (endRow == null) {\n            endRow = this.end.row;\n            endColumn = this.end.column;\n        }\n\n        for (var i = 0; i < folds.length; i++) {\n            fold = folds[i];\n\n            cmp = fold.range.compareStart(endRow, endColumn);\n            if (cmp == -1) {\n                callback(null, endRow, endColumn, lastEnd, isNewRow);\n                return;\n            }\n\n            stop = callback(null, fold.start.row, fold.start.column, lastEnd, isNewRow);\n            stop = !stop && callback(fold.placeholder, fold.start.row, fold.start.column, lastEnd);\n            if (stop || cmp === 0) {\n                return;\n            }\n            isNewRow = !fold.sameRow;\n            lastEnd = fold.end.column;\n        }\n        callback(null, endRow, endColumn, lastEnd, isNewRow);\n    };\n\n    this.getNextFoldTo = function(row, column) {\n        var fold, cmp;\n        for (var i = 0; i < this.folds.length; i++) {\n            fold = this.folds[i];\n            cmp = fold.range.compareEnd(row, column);\n            if (cmp == -1) {\n                return {\n                    fold: fold,\n                    kind: \"after\"\n                };\n            } else if (cmp === 0) {\n                return {\n                    fold: fold,\n                    kind: \"inside\"\n                };\n            }\n        }\n        return null;\n    };\n\n    this.addRemoveChars = function(row, column, len) {\n        var ret = this.getNextFoldTo(row, column),\n            fold, folds;\n        if (ret) {\n            fold = ret.fold;\n            if (ret.kind == \"inside\"\n                && fold.start.column != column\n                && fold.start.row != row)\n            {\n                window.console && window.console.log(row, column, fold);\n            } else if (fold.start.row == row) {\n                folds = this.folds;\n                var i = folds.indexOf(fold);\n                if (i === 0) {\n                    this.start.column += len;\n                }\n                for (i; i < folds.length; i++) {\n                    fold = folds[i];\n                    fold.start.column += len;\n                    if (!fold.sameRow) {\n                        return;\n                    }\n                    fold.end.column += len;\n                }\n                this.end.column += len;\n            }\n        }\n    };\n\n    this.split = function(row, column) {\n        var pos = this.getNextFoldTo(row, column);\n        \n        if (!pos || pos.kind == \"inside\")\n            return null;\n            \n        var fold = pos.fold;\n        var folds = this.folds;\n        var foldData = this.foldData;\n        \n        var i = folds.indexOf(fold);\n        var foldBefore = folds[i - 1];\n        this.end.row = foldBefore.end.row;\n        this.end.column = foldBefore.end.column;\n        folds = folds.splice(i, folds.length - i);\n\n        var newFoldLine = new FoldLine(foldData, folds);\n        foldData.splice(foldData.indexOf(this) + 1, 0, newFoldLine);\n        return newFoldLine;\n    };\n\n    this.merge = function(foldLineNext) {\n        var folds = foldLineNext.folds;\n        for (var i = 0; i < folds.length; i++) {\n            this.addFold(folds[i]);\n        }\n        var foldData = this.foldData;\n        foldData.splice(foldData.indexOf(foldLineNext), 1);\n    };\n\n    this.toString = function() {\n        var ret = [this.range.toString() + \": [\" ];\n\n        this.folds.forEach(function(fold) {\n            ret.push(\"  \" + fold.toString());\n        });\n        ret.push(\"]\");\n        return ret.join(\"\\n\");\n    };\n\n    this.idxToPosition = function(idx) {\n        var lastFoldEndColumn = 0;\n\n        for (var i = 0; i < this.folds.length; i++) {\n            var fold = this.folds[i];\n\n            idx -= fold.start.column - lastFoldEndColumn;\n            if (idx < 0) {\n                return {\n                    row: fold.start.row,\n                    column: fold.start.column + idx\n                };\n            }\n\n            idx -= fold.placeholder.length;\n            if (idx < 0) {\n                return fold.start;\n            }\n\n            lastFoldEndColumn = fold.end.column;\n        }\n\n        return {\n            row: this.end.row,\n            column: this.end.column + idx\n        };\n    };\n}).call(FoldLine.prototype);\n\nexports.FoldLine = FoldLine;\n});\n\nace.define(\"ace/range_list\",[\"require\",\"exports\",\"module\",\"ace/range\"], function(require, exports, module) {\n\"use strict\";\nvar Range = require(\"./range\").Range;\nvar comparePoints = Range.comparePoints;\n\nvar RangeList = function() {\n    this.ranges = [];\n    this.$bias = 1;\n};\n\n(function() {\n    this.comparePoints = comparePoints;\n\n    this.pointIndex = function(pos, excludeEdges, startIndex) {\n        var list = this.ranges;\n\n        for (var i = startIndex || 0; i < list.length; i++) {\n            var range = list[i];\n            var cmpEnd = comparePoints(pos, range.end);\n            if (cmpEnd > 0)\n                continue;\n            var cmpStart = comparePoints(pos, range.start);\n            if (cmpEnd === 0)\n                return excludeEdges && cmpStart !== 0 ? -i-2 : i;\n            if (cmpStart > 0 || (cmpStart === 0 && !excludeEdges))\n                return i;\n\n            return -i-1;\n        }\n        return -i - 1;\n    };\n\n    this.add = function(range) {\n        var excludeEdges = !range.isEmpty();\n        var startIndex = this.pointIndex(range.start, excludeEdges);\n        if (startIndex < 0)\n            startIndex = -startIndex - 1;\n\n        var endIndex = this.pointIndex(range.end, excludeEdges, startIndex);\n\n        if (endIndex < 0)\n            endIndex = -endIndex - 1;\n        else\n            endIndex++;\n        return this.ranges.splice(startIndex, endIndex - startIndex, range);\n    };\n\n    this.addList = function(list) {\n        var removed = [];\n        for (var i = list.length; i--; ) {\n            removed.push.apply(removed, this.add(list[i]));\n        }\n        return removed;\n    };\n\n    this.substractPoint = function(pos) {\n        var i = this.pointIndex(pos);\n\n        if (i >= 0)\n            return this.ranges.splice(i, 1);\n    };\n    this.merge = function() {\n        var removed = [];\n        var list = this.ranges;\n        \n        list = list.sort(function(a, b) {\n            return comparePoints(a.start, b.start);\n        });\n        \n        var next = list[0], range;\n        for (var i = 1; i < list.length; i++) {\n            range = next;\n            next = list[i];\n            var cmp = comparePoints(range.end, next.start);\n            if (cmp < 0)\n                continue;\n\n            if (cmp == 0 && !range.isEmpty() && !next.isEmpty())\n                continue;\n\n            if (comparePoints(range.end, next.end) < 0) {\n                range.end.row = next.end.row;\n                range.end.column = next.end.column;\n            }\n\n            list.splice(i, 1);\n            removed.push(next);\n            next = range;\n            i--;\n        }\n        \n        this.ranges = list;\n\n        return removed;\n    };\n\n    this.contains = function(row, column) {\n        return this.pointIndex({row: row, column: column}) >= 0;\n    };\n\n    this.containsPoint = function(pos) {\n        return this.pointIndex(pos) >= 0;\n    };\n\n    this.rangeAtPoint = function(pos) {\n        var i = this.pointIndex(pos);\n        if (i >= 0)\n            return this.ranges[i];\n    };\n\n\n    this.clipRows = function(startRow, endRow) {\n        var list = this.ranges;\n        if (list[0].start.row > endRow || list[list.length - 1].start.row < startRow)\n            return [];\n\n        var startIndex = this.pointIndex({row: startRow, column: 0});\n        if (startIndex < 0)\n            startIndex = -startIndex - 1;\n        var endIndex = this.pointIndex({row: endRow, column: 0}, startIndex);\n        if (endIndex < 0)\n            endIndex = -endIndex - 1;\n\n        var clipped = [];\n        for (var i = startIndex; i < endIndex; i++) {\n            clipped.push(list[i]);\n        }\n        return clipped;\n    };\n\n    this.removeAll = function() {\n        return this.ranges.splice(0, this.ranges.length);\n    };\n\n    this.attach = function(session) {\n        if (this.session)\n            this.detach();\n\n        this.session = session;\n        this.onChange = this.$onChange.bind(this);\n\n        this.session.on('change', this.onChange);\n    };\n\n    this.detach = function() {\n        if (!this.session)\n            return;\n        this.session.removeListener('change', this.onChange);\n        this.session = null;\n    };\n\n    this.$onChange = function(delta) {\n        var start = delta.start;\n        var end = delta.end;\n        var startRow = start.row;\n        var endRow = end.row;\n        var ranges = this.ranges;\n        for (var i = 0, n = ranges.length; i < n; i++) {\n            var r = ranges[i];\n            if (r.end.row >= startRow)\n                break;\n        }\n        \n        if (delta.action == \"insert\") {\n            var lineDif = endRow - startRow;\n            var colDiff = -start.column + end.column;\n            for (; i < n; i++) {\n                var r = ranges[i];\n                if (r.start.row > startRow)\n                    break;\n    \n                if (r.start.row == startRow && r.start.column >= start.column) {\n                    if (r.start.column == start.column && this.$bias <= 0) {\n                    } else {\n                        r.start.column += colDiff;\n                        r.start.row += lineDif;\n                    }\n                }\n                if (r.end.row == startRow && r.end.column >= start.column) {\n                    if (r.end.column == start.column && this.$bias < 0) {\n                        continue;\n                    }\n                    if (r.end.column == start.column && colDiff > 0 && i < n - 1) {\n                        if (r.end.column > r.start.column && r.end.column == ranges[i+1].start.column)\n                            r.end.column -= colDiff;\n                    }\n                    r.end.column += colDiff;\n                    r.end.row += lineDif;\n                }\n            }\n        } else {\n            var lineDif = startRow - endRow;\n            var colDiff = start.column - end.column;\n            for (; i < n; i++) {\n                var r = ranges[i];\n                \n                if (r.start.row > endRow)\n                    break;\n                    \n                if (r.end.row < endRow\n                    && (\n                        startRow < r.end.row \n                        || startRow == r.end.row && start.column < r.end.column\n                    )\n                ) {\n                    r.end.row = startRow;\n                    r.end.column = start.column;\n                }\n                else if (r.end.row == endRow) {\n                    if (r.end.column <= end.column) {\n                        if (lineDif || r.end.column > start.column) {\n                            r.end.column = start.column;\n                            r.end.row = start.row;\n                        }\n                    }\n                    else {\n                        r.end.column += colDiff;\n                        r.end.row += lineDif;\n                    }\n                }\n                else if (r.end.row > endRow) {\n                    r.end.row += lineDif;\n                }\n                \n                if (r.start.row < endRow\n                    && (\n                        startRow < r.start.row \n                        || startRow == r.start.row && start.column < r.start.column\n                    )\n                ) {\n                    r.start.row = startRow;\n                    r.start.column = start.column;\n                }\n                else if (r.start.row == endRow) {\n                    if (r.start.column <= end.column) {\n                        if (lineDif || r.start.column > start.column) {\n                            r.start.column = start.column;\n                            r.start.row = start.row;\n                        }\n                    }\n                    else {\n                        r.start.column += colDiff;\n                        r.start.row += lineDif;\n                    }\n                }\n                else if (r.start.row > endRow) {\n                    r.start.row += lineDif;\n                }\n            }\n        }\n\n        if (lineDif != 0 && i < n) {\n            for (; i < n; i++) {\n                var r = ranges[i];\n                r.start.row += lineDif;\n                r.end.row += lineDif;\n            }\n        }\n    };\n\n}).call(RangeList.prototype);\n\nexports.RangeList = RangeList;\n});\n\nace.define(\"ace/edit_session/fold\",[\"require\",\"exports\",\"module\",\"ace/range_list\",\"ace/lib/oop\"], function(require, exports, module) {\n\"use strict\";\n\nvar RangeList = require(\"../range_list\").RangeList;\nvar oop = require(\"../lib/oop\");\nvar Fold = exports.Fold = function(range, placeholder) {\n    this.foldLine = null;\n    this.placeholder = placeholder;\n    this.range = range;\n    this.start = range.start;\n    this.end = range.end;\n\n    this.sameRow = range.start.row == range.end.row;\n    this.subFolds = this.ranges = [];\n};\n\noop.inherits(Fold, RangeList);\n\n(function() {\n\n    this.toString = function() {\n        return '\"' + this.placeholder + '\" ' + this.range.toString();\n    };\n\n    this.setFoldLine = function(foldLine) {\n        this.foldLine = foldLine;\n        this.subFolds.forEach(function(fold) {\n            fold.setFoldLine(foldLine);\n        });\n    };\n\n    this.clone = function() {\n        var range = this.range.clone();\n        var fold = new Fold(range, this.placeholder);\n        this.subFolds.forEach(function(subFold) {\n            fold.subFolds.push(subFold.clone());\n        });\n        fold.collapseChildren = this.collapseChildren;\n        return fold;\n    };\n\n    this.addSubFold = function(fold) {\n        if (this.range.isEqual(fold))\n            return;\n        consumeRange(fold, this.start);\n\n        var row = fold.start.row, column = fold.start.column;\n        for (var i = 0, cmp = -1; i < this.subFolds.length; i++) {\n            cmp = this.subFolds[i].range.compare(row, column);\n            if (cmp != 1)\n                break;\n        }\n        var afterStart = this.subFolds[i];\n        var firstConsumed = 0;\n\n        if (cmp == 0) {\n            if (afterStart.range.containsRange(fold))\n                return afterStart.addSubFold(fold);\n            else\n                firstConsumed = 1;\n        }\n        var row = fold.range.end.row, column = fold.range.end.column;\n        for (var j = i, cmp = -1; j < this.subFolds.length; j++) {\n            cmp = this.subFolds[j].range.compare(row, column);\n            if (cmp != 1)\n                break;\n        }\n        if (cmp == 0)  j++;\n        var consumedFolds = this.subFolds.splice(i, j - i, fold);\n        var last = cmp == 0 ? consumedFolds.length - 1 : consumedFolds.length;\n        for (var k = firstConsumed; k < last; k++) {\n            fold.addSubFold(consumedFolds[k]);\n        }\n        fold.setFoldLine(this.foldLine);\n\n        return fold;\n    };\n    \n    this.restoreRange = function(range) {\n        return restoreRange(range, this.start);\n    };\n\n}).call(Fold.prototype);\n\nfunction consumePoint(point, anchor) {\n    point.row -= anchor.row;\n    if (point.row == 0)\n        point.column -= anchor.column;\n}\nfunction consumeRange(range, anchor) {\n    consumePoint(range.start, anchor);\n    consumePoint(range.end, anchor);\n}\nfunction restorePoint(point, anchor) {\n    if (point.row == 0)\n        point.column += anchor.column;\n    point.row += anchor.row;\n}\nfunction restoreRange(range, anchor) {\n    restorePoint(range.start, anchor);\n    restorePoint(range.end, anchor);\n}\n\n});\n\nace.define(\"ace/edit_session/folding\",[\"require\",\"exports\",\"module\",\"ace/range\",\"ace/edit_session/fold_line\",\"ace/edit_session/fold\",\"ace/token_iterator\"], function(require, exports, module) {\n\"use strict\";\n\nvar Range = require(\"../range\").Range;\nvar FoldLine = require(\"./fold_line\").FoldLine;\nvar Fold = require(\"./fold\").Fold;\nvar TokenIterator = require(\"../token_iterator\").TokenIterator;\n\nfunction Folding() {\n    this.getFoldAt = function(row, column, side) {\n        var foldLine = this.getFoldLine(row);\n        if (!foldLine)\n            return null;\n\n        var folds = foldLine.folds;\n        for (var i = 0; i < folds.length; i++) {\n            var range = folds[i].range;\n            if (range.contains(row, column)) {\n                if (side == 1 && range.isEnd(row, column) && !range.isEmpty()) {\n                    continue;\n                } else if (side == -1 && range.isStart(row, column) && !range.isEmpty()) {\n                    continue;\n                }\n                return folds[i];\n            }\n        }\n    };\n    this.getFoldsInRange = function(range) {\n        var start = range.start;\n        var end = range.end;\n        var foldLines = this.$foldData;\n        var foundFolds = [];\n\n        start.column += 1;\n        end.column -= 1;\n\n        for (var i = 0; i < foldLines.length; i++) {\n            var cmp = foldLines[i].range.compareRange(range);\n            if (cmp == 2) {\n                continue;\n            }\n            else if (cmp == -2) {\n                break;\n            }\n\n            var folds = foldLines[i].folds;\n            for (var j = 0; j < folds.length; j++) {\n                var fold = folds[j];\n                cmp = fold.range.compareRange(range);\n                if (cmp == -2) {\n                    break;\n                } else if (cmp == 2) {\n                    continue;\n                } else\n                if (cmp == 42) {\n                    break;\n                }\n                foundFolds.push(fold);\n            }\n        }\n        start.column -= 1;\n        end.column += 1;\n\n        return foundFolds;\n    };\n\n    this.getFoldsInRangeList = function(ranges) {\n        if (Array.isArray(ranges)) {\n            var folds = [];\n            ranges.forEach(function(range) {\n                folds = folds.concat(this.getFoldsInRange(range));\n            }, this);\n        } else {\n            var folds = this.getFoldsInRange(ranges);\n        }\n        return folds;\n    };\n    this.getAllFolds = function() {\n        var folds = [];\n        var foldLines = this.$foldData;\n        \n        for (var i = 0; i < foldLines.length; i++)\n            for (var j = 0; j < foldLines[i].folds.length; j++)\n                folds.push(foldLines[i].folds[j]);\n\n        return folds;\n    };\n    this.getFoldStringAt = function(row, column, trim, foldLine) {\n        foldLine = foldLine || this.getFoldLine(row);\n        if (!foldLine)\n            return null;\n\n        var lastFold = {\n            end: { column: 0 }\n        };\n        var str, fold;\n        for (var i = 0; i < foldLine.folds.length; i++) {\n            fold = foldLine.folds[i];\n            var cmp = fold.range.compareEnd(row, column);\n            if (cmp == -1) {\n                str = this\n                    .getLine(fold.start.row)\n                    .substring(lastFold.end.column, fold.start.column);\n                break;\n            }\n            else if (cmp === 0) {\n                return null;\n            }\n            lastFold = fold;\n        }\n        if (!str)\n            str = this.getLine(fold.start.row).substring(lastFold.end.column);\n\n        if (trim == -1)\n            return str.substring(0, column - lastFold.end.column);\n        else if (trim == 1)\n            return str.substring(column - lastFold.end.column);\n        else\n            return str;\n    };\n\n    this.getFoldLine = function(docRow, startFoldLine) {\n        var foldData = this.$foldData;\n        var i = 0;\n        if (startFoldLine)\n            i = foldData.indexOf(startFoldLine);\n        if (i == -1)\n            i = 0;\n        for (i; i < foldData.length; i++) {\n            var foldLine = foldData[i];\n            if (foldLine.start.row <= docRow && foldLine.end.row >= docRow) {\n                return foldLine;\n            } else if (foldLine.end.row > docRow) {\n                return null;\n            }\n        }\n        return null;\n    };\n    this.getNextFoldLine = function(docRow, startFoldLine) {\n        var foldData = this.$foldData;\n        var i = 0;\n        if (startFoldLine)\n            i = foldData.indexOf(startFoldLine);\n        if (i == -1)\n            i = 0;\n        for (i; i < foldData.length; i++) {\n            var foldLine = foldData[i];\n            if (foldLine.end.row >= docRow) {\n                return foldLine;\n            }\n        }\n        return null;\n    };\n\n    this.getFoldedRowCount = function(first, last) {\n        var foldData = this.$foldData, rowCount = last-first+1;\n        for (var i = 0; i < foldData.length; i++) {\n            var foldLine = foldData[i],\n                end = foldLine.end.row,\n                start = foldLine.start.row;\n            if (end >= last) {\n                if (start < last) {\n                    if (start >= first)\n                        rowCount -= last-start;\n                    else\n                        rowCount = 0; // in one fold\n                }\n                break;\n            } else if (end >= first){\n                if (start >= first) // fold inside range\n                    rowCount -=  end-start;\n                else\n                    rowCount -=  end-first+1;\n            }\n        }\n        return rowCount;\n    };\n\n    this.$addFoldLine = function(foldLine) {\n        this.$foldData.push(foldLine);\n        this.$foldData.sort(function(a, b) {\n            return a.start.row - b.start.row;\n        });\n        return foldLine;\n    };\n    this.addFold = function(placeholder, range) {\n        var foldData = this.$foldData;\n        var added = false;\n        var fold;\n        \n        if (placeholder instanceof Fold)\n            fold = placeholder;\n        else {\n            fold = new Fold(range, placeholder);\n            fold.collapseChildren = range.collapseChildren;\n        }\n        this.$clipRangeToDocument(fold.range);\n\n        var startRow = fold.start.row;\n        var startColumn = fold.start.column;\n        var endRow = fold.end.row;\n        var endColumn = fold.end.column;\n\n        var startFold = this.getFoldAt(startRow, startColumn, 1);\n        var endFold = this.getFoldAt(endRow, endColumn, -1);\n        if (startFold && endFold == startFold)\n            return startFold.addSubFold(fold);\n\n        if (startFold && !startFold.range.isStart(startRow, startColumn))\n            this.removeFold(startFold);\n        \n        if (endFold && !endFold.range.isEnd(endRow, endColumn))\n            this.removeFold(endFold);\n        var folds = this.getFoldsInRange(fold.range);\n        if (folds.length > 0) {\n            this.removeFolds(folds);\n            folds.forEach(function(subFold) {\n                fold.addSubFold(subFold);\n            });\n        }\n\n        for (var i = 0; i < foldData.length; i++) {\n            var foldLine = foldData[i];\n            if (endRow == foldLine.start.row) {\n                foldLine.addFold(fold);\n                added = true;\n                break;\n            } else if (startRow == foldLine.end.row) {\n                foldLine.addFold(fold);\n                added = true;\n                if (!fold.sameRow) {\n                    var foldLineNext = foldData[i + 1];\n                    if (foldLineNext && foldLineNext.start.row == endRow) {\n                        foldLine.merge(foldLineNext);\n                        break;\n                    }\n                }\n                break;\n            } else if (endRow <= foldLine.start.row) {\n                break;\n            }\n        }\n\n        if (!added)\n            foldLine = this.$addFoldLine(new FoldLine(this.$foldData, fold));\n\n        if (this.$useWrapMode)\n            this.$updateWrapData(foldLine.start.row, foldLine.start.row);\n        else\n            this.$updateRowLengthCache(foldLine.start.row, foldLine.start.row);\n        this.$modified = true;\n        this._signal(\"changeFold\", { data: fold, action: \"add\" });\n\n        return fold;\n    };\n\n    this.addFolds = function(folds) {\n        folds.forEach(function(fold) {\n            this.addFold(fold);\n        }, this);\n    };\n\n    this.removeFold = function(fold) {\n        var foldLine = fold.foldLine;\n        var startRow = foldLine.start.row;\n        var endRow = foldLine.end.row;\n\n        var foldLines = this.$foldData;\n        var folds = foldLine.folds;\n        if (folds.length == 1) {\n            foldLines.splice(foldLines.indexOf(foldLine), 1);\n        } else\n        if (foldLine.range.isEnd(fold.end.row, fold.end.column)) {\n            folds.pop();\n            foldLine.end.row = folds[folds.length - 1].end.row;\n            foldLine.end.column = folds[folds.length - 1].end.column;\n        } else\n        if (foldLine.range.isStart(fold.start.row, fold.start.column)) {\n            folds.shift();\n            foldLine.start.row = folds[0].start.row;\n            foldLine.start.column = folds[0].start.column;\n        } else\n        if (fold.sameRow) {\n            folds.splice(folds.indexOf(fold), 1);\n        } else\n        {\n            var newFoldLine = foldLine.split(fold.start.row, fold.start.column);\n            folds = newFoldLine.folds;\n            folds.shift();\n            newFoldLine.start.row = folds[0].start.row;\n            newFoldLine.start.column = folds[0].start.column;\n        }\n\n        if (!this.$updating) {\n            if (this.$useWrapMode)\n                this.$updateWrapData(startRow, endRow);\n            else\n                this.$updateRowLengthCache(startRow, endRow);\n        }\n        this.$modified = true;\n        this._signal(\"changeFold\", { data: fold, action: \"remove\" });\n    };\n\n    this.removeFolds = function(folds) {\n        var cloneFolds = [];\n        for (var i = 0; i < folds.length; i++) {\n            cloneFolds.push(folds[i]);\n        }\n\n        cloneFolds.forEach(function(fold) {\n            this.removeFold(fold);\n        }, this);\n        this.$modified = true;\n    };\n\n    this.expandFold = function(fold) {\n        this.removeFold(fold);\n        fold.subFolds.forEach(function(subFold) {\n            fold.restoreRange(subFold);\n            this.addFold(subFold);\n        }, this);\n        if (fold.collapseChildren > 0) {\n            this.foldAll(fold.start.row+1, fold.end.row, fold.collapseChildren-1);\n        }\n        fold.subFolds = [];\n    };\n\n    this.expandFolds = function(folds) {\n        folds.forEach(function(fold) {\n            this.expandFold(fold);\n        }, this);\n    };\n\n    this.unfold = function(location, expandInner) {\n        var range, folds;\n        if (location == null) {\n            range = new Range(0, 0, this.getLength(), 0);\n            expandInner = true;\n        } else if (typeof location == \"number\")\n            range = new Range(location, 0, location, this.getLine(location).length);\n        else if (\"row\" in location)\n            range = Range.fromPoints(location, location);\n        else\n            range = location;\n        \n        folds = this.getFoldsInRangeList(range);\n        if (expandInner) {\n            this.removeFolds(folds);\n        } else {\n            var subFolds = folds;\n            while (subFolds.length) {\n                this.expandFolds(subFolds);\n                subFolds = this.getFoldsInRangeList(range);\n            }\n        }\n        if (folds.length)\n            return folds;\n    };\n    this.isRowFolded = function(docRow, startFoldRow) {\n        return !!this.getFoldLine(docRow, startFoldRow);\n    };\n\n    this.getRowFoldEnd = function(docRow, startFoldRow) {\n        var foldLine = this.getFoldLine(docRow, startFoldRow);\n        return foldLine ? foldLine.end.row : docRow;\n    };\n\n    this.getRowFoldStart = function(docRow, startFoldRow) {\n        var foldLine = this.getFoldLine(docRow, startFoldRow);\n        return foldLine ? foldLine.start.row : docRow;\n    };\n\n    this.getFoldDisplayLine = function(foldLine, endRow, endColumn, startRow, startColumn) {\n        if (startRow == null)\n            startRow = foldLine.start.row;\n        if (startColumn == null)\n            startColumn = 0;\n        if (endRow == null)\n            endRow = foldLine.end.row;\n        if (endColumn == null)\n            endColumn = this.getLine(endRow).length;\n        var doc = this.doc;\n        var textLine = \"\";\n\n        foldLine.walk(function(placeholder, row, column, lastColumn) {\n            if (row < startRow)\n                return;\n            if (row == startRow) {\n                if (column < startColumn)\n                    return;\n                lastColumn = Math.max(startColumn, lastColumn);\n            }\n\n            if (placeholder != null) {\n                textLine += placeholder;\n            } else {\n                textLine += doc.getLine(row).substring(lastColumn, column);\n            }\n        }, endRow, endColumn);\n        return textLine;\n    };\n\n    this.getDisplayLine = function(row, endColumn, startRow, startColumn) {\n        var foldLine = this.getFoldLine(row);\n\n        if (!foldLine) {\n            var line;\n            line = this.doc.getLine(row);\n            return line.substring(startColumn || 0, endColumn || line.length);\n        } else {\n            return this.getFoldDisplayLine(\n                foldLine, row, endColumn, startRow, startColumn);\n        }\n    };\n\n    this.$cloneFoldData = function() {\n        var fd = [];\n        fd = this.$foldData.map(function(foldLine) {\n            var folds = foldLine.folds.map(function(fold) {\n                return fold.clone();\n            });\n            return new FoldLine(fd, folds);\n        });\n\n        return fd;\n    };\n\n    this.toggleFold = function(tryToUnfold) {\n        var selection = this.selection;\n        var range = selection.getRange();\n        var fold;\n        var bracketPos;\n\n        if (range.isEmpty()) {\n            var cursor = range.start;\n            fold = this.getFoldAt(cursor.row, cursor.column);\n\n            if (fold) {\n                this.expandFold(fold);\n                return;\n            } else if (bracketPos = this.findMatchingBracket(cursor)) {\n                if (range.comparePoint(bracketPos) == 1) {\n                    range.end = bracketPos;\n                } else {\n                    range.start = bracketPos;\n                    range.start.column++;\n                    range.end.column--;\n                }\n            } else if (bracketPos = this.findMatchingBracket({row: cursor.row, column: cursor.column + 1})) {\n                if (range.comparePoint(bracketPos) == 1)\n                    range.end = bracketPos;\n                else\n                    range.start = bracketPos;\n\n                range.start.column++;\n            } else {\n                range = this.getCommentFoldRange(cursor.row, cursor.column) || range;\n            }\n        } else {\n            var folds = this.getFoldsInRange(range);\n            if (tryToUnfold && folds.length) {\n                this.expandFolds(folds);\n                return;\n            } else if (folds.length == 1 ) {\n                fold = folds[0];\n            }\n        }\n\n        if (!fold)\n            fold = this.getFoldAt(range.start.row, range.start.column);\n\n        if (fold && fold.range.toString() == range.toString()) {\n            this.expandFold(fold);\n            return;\n        }\n\n        var placeholder = \"...\";\n        if (!range.isMultiLine()) {\n            placeholder = this.getTextRange(range);\n            if (placeholder.length < 4)\n                return;\n            placeholder = placeholder.trim().substring(0, 2) + \"..\";\n        }\n\n        this.addFold(placeholder, range);\n    };\n\n    this.getCommentFoldRange = function(row, column, dir) {\n        var iterator = new TokenIterator(this, row, column);\n        var token = iterator.getCurrentToken();\n        var type = token.type;\n        if (token && /^comment|string/.test(type)) {\n            type = type.match(/comment|string/)[0];\n            if (type == \"comment\")\n                type += \"|doc-start\";\n            var re = new RegExp(type);\n            var range = new Range();\n            if (dir != 1) {\n                do {\n                    token = iterator.stepBackward();\n                } while (token && re.test(token.type));\n                iterator.stepForward();\n            }\n            \n            range.start.row = iterator.getCurrentTokenRow();\n            range.start.column = iterator.getCurrentTokenColumn() + 2;\n\n            iterator = new TokenIterator(this, row, column);\n            \n            if (dir != -1) {\n                var lastRow = -1;\n                do {\n                    token = iterator.stepForward();\n                    if (lastRow == -1) {\n                        var state = this.getState(iterator.$row);\n                        if (!re.test(state))\n                            lastRow = iterator.$row;\n                    } else if (iterator.$row > lastRow) {\n                        break;\n                    }\n                } while (token && re.test(token.type));\n                token = iterator.stepBackward();\n            } else\n                token = iterator.getCurrentToken();\n\n            range.end.row = iterator.getCurrentTokenRow();\n            range.end.column = iterator.getCurrentTokenColumn() + token.value.length - 2;\n            return range;\n        }\n    };\n\n    this.foldAll = function(startRow, endRow, depth) {\n        if (depth == undefined)\n            depth = 100000; // JSON.stringify doesn't hanle Infinity\n        var foldWidgets = this.foldWidgets;\n        if (!foldWidgets)\n            return; // mode doesn't support folding\n        endRow = endRow || this.getLength();\n        startRow = startRow || 0;\n        for (var row = startRow; row < endRow; row++) {\n            if (foldWidgets[row] == null)\n                foldWidgets[row] = this.getFoldWidget(row);\n            if (foldWidgets[row] != \"start\")\n                continue;\n\n            var range = this.getFoldWidgetRange(row);\n            if (range && range.isMultiLine()\n                && range.end.row <= endRow\n                && range.start.row >= startRow\n            ) {\n                row = range.end.row;\n                try {\n                    var fold = this.addFold(\"...\", range);\n                    if (fold)\n                        fold.collapseChildren = depth;\n                } catch(e) {}\n            }\n        }\n    };\n    this.$foldStyles = {\n        \"manual\": 1,\n        \"markbegin\": 1,\n        \"markbeginend\": 1\n    };\n    this.$foldStyle = \"markbegin\";\n    this.setFoldStyle = function(style) {\n        if (!this.$foldStyles[style])\n            throw new Error(\"invalid fold style: \" + style + \"[\" + Object.keys(this.$foldStyles).join(\", \") + \"]\");\n        \n        if (this.$foldStyle == style)\n            return;\n\n        this.$foldStyle = style;\n        \n        if (style == \"manual\")\n            this.unfold();\n        var mode = this.$foldMode;\n        this.$setFolding(null);\n        this.$setFolding(mode);\n    };\n\n    this.$setFolding = function(foldMode) {\n        if (this.$foldMode == foldMode)\n            return;\n            \n        this.$foldMode = foldMode;\n        \n        this.off('change', this.$updateFoldWidgets);\n        this.off('tokenizerUpdate', this.$tokenizerUpdateFoldWidgets);\n        this._signal(\"changeAnnotation\");\n        \n        if (!foldMode || this.$foldStyle == \"manual\") {\n            this.foldWidgets = null;\n            return;\n        }\n        \n        this.foldWidgets = [];\n        this.getFoldWidget = foldMode.getFoldWidget.bind(foldMode, this, this.$foldStyle);\n        this.getFoldWidgetRange = foldMode.getFoldWidgetRange.bind(foldMode, this, this.$foldStyle);\n        \n        this.$updateFoldWidgets = this.updateFoldWidgets.bind(this);\n        this.$tokenizerUpdateFoldWidgets = this.tokenizerUpdateFoldWidgets.bind(this);\n        this.on('change', this.$updateFoldWidgets);\n        this.on('tokenizerUpdate', this.$tokenizerUpdateFoldWidgets);\n    };\n\n    this.getParentFoldRangeData = function (row, ignoreCurrent) {\n        var fw = this.foldWidgets;\n        if (!fw || (ignoreCurrent && fw[row]))\n            return {};\n\n        var i = row - 1, firstRange;\n        while (i >= 0) {\n            var c = fw[i];\n            if (c == null)\n                c = fw[i] = this.getFoldWidget(i);\n\n            if (c == \"start\") {\n                var range = this.getFoldWidgetRange(i);\n                if (!firstRange)\n                    firstRange = range;\n                if (range && range.end.row >= row)\n                    break;\n            }\n            i--;\n        }\n\n        return {\n            range: i !== -1 && range,\n            firstRange: firstRange\n        };\n    };\n\n    this.onFoldWidgetClick = function(row, e) {\n        e = e.domEvent;\n        var options = {\n            children: e.shiftKey,\n            all: e.ctrlKey || e.metaKey,\n            siblings: e.altKey\n        };\n        \n        var range = this.$toggleFoldWidget(row, options);\n        if (!range) {\n            var el = (e.target || e.srcElement);\n            if (el && /ace_fold-widget/.test(el.className))\n                el.className += \" ace_invalid\";\n        }\n    };\n    \n    this.$toggleFoldWidget = function(row, options) {\n        if (!this.getFoldWidget)\n            return;\n        var type = this.getFoldWidget(row);\n        var line = this.getLine(row);\n\n        var dir = type === \"end\" ? -1 : 1;\n        var fold = this.getFoldAt(row, dir === -1 ? 0 : line.length, dir);\n\n        if (fold) {\n            if (options.children || options.all)\n                this.removeFold(fold);\n            else\n                this.expandFold(fold);\n            return fold;\n        }\n\n        var range = this.getFoldWidgetRange(row, true);\n        if (range && !range.isMultiLine()) {\n            fold = this.getFoldAt(range.start.row, range.start.column, 1);\n            if (fold && range.isEqual(fold.range)) {\n                this.removeFold(fold);\n                return fold;\n            }\n        }\n        \n        if (options.siblings) {\n            var data = this.getParentFoldRangeData(row);\n            if (data.range) {\n                var startRow = data.range.start.row + 1;\n                var endRow = data.range.end.row;\n            }\n            this.foldAll(startRow, endRow, options.all ? 10000 : 0);\n        } else if (options.children) {\n            endRow = range ? range.end.row : this.getLength();\n            this.foldAll(row + 1, endRow, options.all ? 10000 : 0);\n        } else if (range) {\n            if (options.all) \n                range.collapseChildren = 10000;\n            this.addFold(\"...\", range);\n        }\n        \n        return range;\n    };\n    \n    \n    \n    this.toggleFoldWidget = function(toggleParent) {\n        var row = this.selection.getCursor().row;\n        row = this.getRowFoldStart(row);\n        var range = this.$toggleFoldWidget(row, {});\n        \n        if (range)\n            return;\n        var data = this.getParentFoldRangeData(row, true);\n        range = data.range || data.firstRange;\n        \n        if (range) {\n            row = range.start.row;\n            var fold = this.getFoldAt(row, this.getLine(row).length, 1);\n\n            if (fold) {\n                this.removeFold(fold);\n            } else {\n                this.addFold(\"...\", range);\n            }\n        }\n    };\n\n    this.updateFoldWidgets = function(delta) {\n        var firstRow = delta.start.row;\n        var len = delta.end.row - firstRow;\n\n        if (len === 0) {\n            this.foldWidgets[firstRow] = null;\n        } else if (delta.action == 'remove') {\n            this.foldWidgets.splice(firstRow, len + 1, null);\n        } else {\n            var args = Array(len + 1);\n            args.unshift(firstRow, 1);\n            this.foldWidgets.splice.apply(this.foldWidgets, args);\n        }\n    };\n    this.tokenizerUpdateFoldWidgets = function(e) {\n        var rows = e.data;\n        if (rows.first != rows.last) {\n            if (this.foldWidgets.length > rows.first)\n                this.foldWidgets.splice(rows.first, this.foldWidgets.length);\n        }\n    };\n}\n\nexports.Folding = Folding;\n\n});\n\nace.define(\"ace/edit_session/bracket_match\",[\"require\",\"exports\",\"module\",\"ace/token_iterator\",\"ace/range\"], function(require, exports, module) {\n\"use strict\";\n\nvar TokenIterator = require(\"../token_iterator\").TokenIterator;\nvar Range = require(\"../range\").Range;\n\n\nfunction BracketMatch() {\n\n    this.findMatchingBracket = function(position, chr) {\n        if (position.column == 0) return null;\n\n        var charBeforeCursor = chr || this.getLine(position.row).charAt(position.column-1);\n        if (charBeforeCursor == \"\") return null;\n\n        var match = charBeforeCursor.match(/([\\(\\[\\{])|([\\)\\]\\}])/);\n        if (!match)\n            return null;\n\n        if (match[1])\n            return this.$findClosingBracket(match[1], position);\n        else\n            return this.$findOpeningBracket(match[2], position);\n    };\n    \n    this.getBracketRange = function(pos) {\n        var line = this.getLine(pos.row);\n        var before = true, range;\n\n        var chr = line.charAt(pos.column - 1);\n        var match = chr && chr.match(/([\\(\\[\\{])|([\\)\\]\\}])/);\n        if (!match) {\n            chr = line.charAt(pos.column);\n            pos = {row: pos.row, column: pos.column + 1};\n            match = chr && chr.match(/([\\(\\[\\{])|([\\)\\]\\}])/);\n            before = false;\n        }\n        if (!match)\n            return null;\n\n        if (match[1]) {\n            var bracketPos = this.$findClosingBracket(match[1], pos);\n            if (!bracketPos)\n                return null;\n            range = Range.fromPoints(pos, bracketPos);\n            if (!before) {\n                range.end.column++;\n                range.start.column--;\n            }\n            range.cursor = range.end;\n        } else {\n            var bracketPos = this.$findOpeningBracket(match[2], pos);\n            if (!bracketPos)\n                return null;\n            range = Range.fromPoints(bracketPos, pos);\n            if (!before) {\n                range.start.column++;\n                range.end.column--;\n            }\n            range.cursor = range.start;\n        }\n        \n        return range;\n    };\n    this.getMatchingBracketRanges = function(pos) {\n        var line = this.getLine(pos.row);\n\n        var chr = line.charAt(pos.column - 1);\n        var match = chr && chr.match(/([\\(\\[\\{])|([\\)\\]\\}])/);\n        if (!match) {\n            chr = line.charAt(pos.column);\n            pos = {row: pos.row, column: pos.column + 1};\n            match = chr && chr.match(/([\\(\\[\\{])|([\\)\\]\\}])/);\n        }\n\n        if (!match)\n            return null;\n\n        var startRange = new Range(pos.row, pos.column - 1, pos.row, pos.column);\n        var bracketPos = match[1] ? this.$findClosingBracket(match[1], pos)\n            : this.$findOpeningBracket(match[2], pos);\n        if (!bracketPos)\n            return [startRange];\n        var endRange = new Range(bracketPos.row, bracketPos.column, bracketPos.row, bracketPos.column + 1);\n\n        return [startRange, endRange];\n    };\n\n    this.$brackets = {\n        \")\": \"(\",\n        \"(\": \")\",\n        \"]\": \"[\",\n        \"[\": \"]\",\n        \"{\": \"}\",\n        \"}\": \"{\",\n        \"<\": \">\",\n        \">\": \"<\"\n    };\n\n    this.$findOpeningBracket = function(bracket, position, typeRe) {\n        var openBracket = this.$brackets[bracket];\n        var depth = 1;\n\n        var iterator = new TokenIterator(this, position.row, position.column);\n        var token = iterator.getCurrentToken();\n        if (!token)\n            token = iterator.stepForward();\n        if (!token)\n            return;\n        \n         if (!typeRe){\n            typeRe = new RegExp(\n                \"(\\\\.?\" +\n                token.type.replace(\".\", \"\\\\.\").replace(\"rparen\", \".paren\")\n                    .replace(/\\b(?:end)\\b/, \"(?:start|begin|end)\")\n                + \")+\"\n            );\n        }\n        var valueIndex = position.column - iterator.getCurrentTokenColumn() - 2;\n        var value = token.value;\n        \n        while (true) {\n        \n            while (valueIndex >= 0) {\n                var chr = value.charAt(valueIndex);\n                if (chr == openBracket) {\n                    depth -= 1;\n                    if (depth == 0) {\n                        return {row: iterator.getCurrentTokenRow(),\n                            column: valueIndex + iterator.getCurrentTokenColumn()};\n                    }\n                }\n                else if (chr == bracket) {\n                    depth += 1;\n                }\n                valueIndex -= 1;\n            }\n            do {\n                token = iterator.stepBackward();\n            } while (token && !typeRe.test(token.type));\n\n            if (token == null)\n                break;\n                \n            value = token.value;\n            valueIndex = value.length - 1;\n        }\n        \n        return null;\n    };\n\n    this.$findClosingBracket = function(bracket, position, typeRe) {\n        var closingBracket = this.$brackets[bracket];\n        var depth = 1;\n\n        var iterator = new TokenIterator(this, position.row, position.column);\n        var token = iterator.getCurrentToken();\n        if (!token)\n            token = iterator.stepForward();\n        if (!token)\n            return;\n\n        if (!typeRe){\n            typeRe = new RegExp(\n                \"(\\\\.?\" +\n                token.type.replace(\".\", \"\\\\.\").replace(\"lparen\", \".paren\")\n                    .replace(/\\b(?:start|begin)\\b/, \"(?:start|begin|end)\")\n                + \")+\"\n            );\n        }\n        var valueIndex = position.column - iterator.getCurrentTokenColumn();\n\n        while (true) {\n\n            var value = token.value;\n            var valueLength = value.length;\n            while (valueIndex < valueLength) {\n                var chr = value.charAt(valueIndex);\n                if (chr == closingBracket) {\n                    depth -= 1;\n                    if (depth == 0) {\n                        return {row: iterator.getCurrentTokenRow(),\n                            column: valueIndex + iterator.getCurrentTokenColumn()};\n                    }\n                }\n                else if (chr == bracket) {\n                    depth += 1;\n                }\n                valueIndex += 1;\n            }\n            do {\n                token = iterator.stepForward();\n            } while (token && !typeRe.test(token.type));\n\n            if (token == null)\n                break;\n\n            valueIndex = 0;\n        }\n        \n        return null;\n    };\n}\nexports.BracketMatch = BracketMatch;\n\n});\n\nace.define(\"ace/edit_session\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/lang\",\"ace/bidihandler\",\"ace/config\",\"ace/lib/event_emitter\",\"ace/selection\",\"ace/mode/text\",\"ace/range\",\"ace/document\",\"ace/background_tokenizer\",\"ace/search_highlight\",\"ace/edit_session/folding\",\"ace/edit_session/bracket_match\"], function(require, exports, module) {\n\"use strict\";\n\nvar oop = require(\"./lib/oop\");\nvar lang = require(\"./lib/lang\");\nvar BidiHandler = require(\"./bidihandler\").BidiHandler;\nvar config = require(\"./config\");\nvar EventEmitter = require(\"./lib/event_emitter\").EventEmitter;\nvar Selection = require(\"./selection\").Selection;\nvar TextMode = require(\"./mode/text\").Mode;\nvar Range = require(\"./range\").Range;\nvar Document = require(\"./document\").Document;\nvar BackgroundTokenizer = require(\"./background_tokenizer\").BackgroundTokenizer;\nvar SearchHighlight = require(\"./search_highlight\").SearchHighlight;\n\nvar EditSession = function(text, mode) {\n    this.$breakpoints = [];\n    this.$decorations = [];\n    this.$frontMarkers = {};\n    this.$backMarkers = {};\n    this.$markerId = 1;\n    this.$undoSelect = true;\n\n    this.$foldData = [];\n    this.id = \"session\" + (++EditSession.$uid);\n    this.$foldData.toString = function() {\n        return this.join(\"\\n\");\n    };\n    this.on(\"changeFold\", this.onChangeFold.bind(this));\n    this.$onChange = this.onChange.bind(this);\n\n    if (typeof text != \"object\" || !text.getLine)\n        text = new Document(text);\n\n    this.setDocument(text);\n    this.selection = new Selection(this);\n    this.$bidiHandler = new BidiHandler(this);\n\n    config.resetOptions(this);\n    this.setMode(mode);\n    config._signal(\"session\", this);\n};\n\n\nEditSession.$uid = 0;\n\n(function() {\n\n    oop.implement(this, EventEmitter);\n    this.setDocument = function(doc) {\n        if (this.doc)\n            this.doc.removeListener(\"change\", this.$onChange);\n\n        this.doc = doc;\n        doc.on(\"change\", this.$onChange);\n\n        if (this.bgTokenizer)\n            this.bgTokenizer.setDocument(this.getDocument());\n\n        this.resetCaches();\n    };\n    this.getDocument = function() {\n        return this.doc;\n    };\n    this.$resetRowCache = function(docRow) {\n        if (!docRow) {\n            this.$docRowCache = [];\n            this.$screenRowCache = [];\n            return;\n        }\n        var l = this.$docRowCache.length;\n        var i = this.$getRowCacheIndex(this.$docRowCache, docRow) + 1;\n        if (l > i) {\n            this.$docRowCache.splice(i, l);\n            this.$screenRowCache.splice(i, l);\n        }\n    };\n\n    this.$getRowCacheIndex = function(cacheArray, val) {\n        var low = 0;\n        var hi = cacheArray.length - 1;\n\n        while (low <= hi) {\n            var mid = (low + hi) >> 1;\n            var c = cacheArray[mid];\n\n            if (val > c)\n                low = mid + 1;\n            else if (val < c)\n                hi = mid - 1;\n            else\n                return mid;\n        }\n\n        return low -1;\n    };\n\n    this.resetCaches = function() {\n        this.$modified = true;\n        this.$wrapData = [];\n        this.$rowLengthCache = [];\n        this.$resetRowCache(0);\n        if (this.bgTokenizer)\n            this.bgTokenizer.start(0);\n    };\n\n    this.onChangeFold = function(e) {\n        var fold = e.data;\n        this.$resetRowCache(fold.start.row);\n    };\n\n    this.onChange = function(delta) {\n        this.$modified = true;\n        this.$bidiHandler.onChange(delta);\n        this.$resetRowCache(delta.start.row);\n\n        var removedFolds = this.$updateInternalDataOnChange(delta);\n        if (!this.$fromUndo && this.$undoManager) {\n            if (removedFolds && removedFolds.length) {\n                this.$undoManager.add({\n                    action: \"removeFolds\",\n                    folds:  removedFolds\n                }, this.mergeUndoDeltas);\n                this.mergeUndoDeltas = true;\n            }\n            this.$undoManager.add(delta, this.mergeUndoDeltas);\n            this.mergeUndoDeltas = true;\n            \n            this.$informUndoManager.schedule();\n        }\n\n        this.bgTokenizer && this.bgTokenizer.$updateOnChange(delta);\n        this._signal(\"change\", delta);\n    };\n    this.setValue = function(text) {\n        this.doc.setValue(text);\n        this.selection.moveTo(0, 0);\n\n        this.$resetRowCache(0);\n        this.setUndoManager(this.$undoManager);\n        this.getUndoManager().reset();\n    };\n    this.getValue =\n    this.toString = function() {\n        return this.doc.getValue();\n    };\n    this.getSelection = function() {\n        return this.selection;\n    };\n    this.getState = function(row) {\n        return this.bgTokenizer.getState(row);\n    };\n    this.getTokens = function(row) {\n        return this.bgTokenizer.getTokens(row);\n    };\n    this.getTokenAt = function(row, column) {\n        var tokens = this.bgTokenizer.getTokens(row);\n        var token, c = 0;\n        if (column == null) {\n            var i = tokens.length - 1;\n            c = this.getLine(row).length;\n        } else {\n            for (var i = 0; i < tokens.length; i++) {\n                c += tokens[i].value.length;\n                if (c >= column)\n                    break;\n            }\n        }\n        token = tokens[i];\n        if (!token)\n            return null;\n        token.index = i;\n        token.start = c - token.value.length;\n        return token;\n    };\n    this.setUndoManager = function(undoManager) {\n        this.$undoManager = undoManager;\n        \n        if (this.$informUndoManager)\n            this.$informUndoManager.cancel();\n        \n        if (undoManager) {\n            var self = this;\n            undoManager.addSession(this);\n            this.$syncInformUndoManager = function() {\n                self.$informUndoManager.cancel();\n                self.mergeUndoDeltas = false;\n            };\n            this.$informUndoManager = lang.delayedCall(this.$syncInformUndoManager);\n        } else {\n            this.$syncInformUndoManager = function() {};\n        }\n    };\n    this.markUndoGroup = function() {\n        if (this.$syncInformUndoManager)\n            this.$syncInformUndoManager();\n    };\n    \n    this.$defaultUndoManager = {\n        undo: function() {},\n        redo: function() {},\n        hasUndo: function() {},\n        hasRedo: function() {},\n        reset: function() {},\n        add: function() {},\n        addSelection: function() {},\n        startNewGroup: function() {},\n        addSession: function() {}\n    };\n    this.getUndoManager = function() {\n        return this.$undoManager || this.$defaultUndoManager;\n    };\n    this.getTabString = function() {\n        if (this.getUseSoftTabs()) {\n            return lang.stringRepeat(\" \", this.getTabSize());\n        } else {\n            return \"\\t\";\n        }\n    };\n    this.setUseSoftTabs = function(val) {\n        this.setOption(\"useSoftTabs\", val);\n    };\n    this.getUseSoftTabs = function() {\n        return this.$useSoftTabs && !this.$mode.$indentWithTabs;\n    };\n    this.setTabSize = function(tabSize) {\n        this.setOption(\"tabSize\", tabSize);\n    };\n    this.getTabSize = function() {\n        return this.$tabSize;\n    };\n    this.isTabStop = function(position) {\n        return this.$useSoftTabs && (position.column % this.$tabSize === 0);\n    };\n    this.setNavigateWithinSoftTabs = function (navigateWithinSoftTabs) {\n        this.setOption(\"navigateWithinSoftTabs\", navigateWithinSoftTabs);\n    };\n    this.getNavigateWithinSoftTabs = function() {\n        return this.$navigateWithinSoftTabs;\n    };\n\n    this.$overwrite = false;\n    this.setOverwrite = function(overwrite) {\n        this.setOption(\"overwrite\", overwrite);\n    };\n    this.getOverwrite = function() {\n        return this.$overwrite;\n    };\n    this.toggleOverwrite = function() {\n        this.setOverwrite(!this.$overwrite);\n    };\n    this.addGutterDecoration = function(row, className) {\n        if (!this.$decorations[row])\n            this.$decorations[row] = \"\";\n        this.$decorations[row] += \" \" + className;\n        this._signal(\"changeBreakpoint\", {});\n    };\n    this.removeGutterDecoration = function(row, className) {\n        this.$decorations[row] = (this.$decorations[row] || \"\").replace(\" \" + className, \"\");\n        this._signal(\"changeBreakpoint\", {});\n    };\n    this.getBreakpoints = function() {\n        return this.$breakpoints;\n    };\n    this.setBreakpoints = function(rows) {\n        this.$breakpoints = [];\n        for (var i=0; i<rows.length; i++) {\n            this.$breakpoints[rows[i]] = \"ace_breakpoint\";\n        }\n        this._signal(\"changeBreakpoint\", {});\n    };\n    this.clearBreakpoints = function() {\n        this.$breakpoints = [];\n        this._signal(\"changeBreakpoint\", {});\n    };\n    this.setBreakpoint = function(row, className) {\n        if (className === undefined)\n            className = \"ace_breakpoint\";\n        if (className)\n            this.$breakpoints[row] = className;\n        else\n            delete this.$breakpoints[row];\n        this._signal(\"changeBreakpoint\", {});\n    };\n    this.clearBreakpoint = function(row) {\n        delete this.$breakpoints[row];\n        this._signal(\"changeBreakpoint\", {});\n    };\n    this.addMarker = function(range, clazz, type, inFront) {\n        var id = this.$markerId++;\n\n        var marker = {\n            range : range,\n            type : type || \"line\",\n            renderer: typeof type == \"function\" ? type : null,\n            clazz : clazz,\n            inFront: !!inFront,\n            id: id\n        };\n\n        if (inFront) {\n            this.$frontMarkers[id] = marker;\n            this._signal(\"changeFrontMarker\");\n        } else {\n            this.$backMarkers[id] = marker;\n            this._signal(\"changeBackMarker\");\n        }\n\n        return id;\n    };\n    this.addDynamicMarker = function(marker, inFront) {\n        if (!marker.update)\n            return;\n        var id = this.$markerId++;\n        marker.id = id;\n        marker.inFront = !!inFront;\n\n        if (inFront) {\n            this.$frontMarkers[id] = marker;\n            this._signal(\"changeFrontMarker\");\n        } else {\n            this.$backMarkers[id] = marker;\n            this._signal(\"changeBackMarker\");\n        }\n\n        return marker;\n    };\n    this.removeMarker = function(markerId) {\n        var marker = this.$frontMarkers[markerId] || this.$backMarkers[markerId];\n        if (!marker)\n            return;\n\n        var markers = marker.inFront ? this.$frontMarkers : this.$backMarkers;\n        delete (markers[markerId]);\n        this._signal(marker.inFront ? \"changeFrontMarker\" : \"changeBackMarker\");\n    };\n    this.getMarkers = function(inFront) {\n        return inFront ? this.$frontMarkers : this.$backMarkers;\n    };\n\n    this.highlight = function(re) {\n        if (!this.$searchHighlight) {\n            var highlight = new SearchHighlight(null, \"ace_selected-word\", \"text\");\n            this.$searchHighlight = this.addDynamicMarker(highlight);\n        }\n        this.$searchHighlight.setRegexp(re);\n    };\n    this.highlightLines = function(startRow, endRow, clazz, inFront) {\n        if (typeof endRow != \"number\") {\n            clazz = endRow;\n            endRow = startRow;\n        }\n        if (!clazz)\n            clazz = \"ace_step\";\n\n        var range = new Range(startRow, 0, endRow, Infinity);\n        range.id = this.addMarker(range, clazz, \"fullLine\", inFront);\n        return range;\n    };\n    this.setAnnotations = function(annotations) {\n        this.$annotations = annotations;\n        this._signal(\"changeAnnotation\", {});\n    };\n    this.getAnnotations = function() {\n        return this.$annotations || [];\n    };\n    this.clearAnnotations = function() {\n        this.setAnnotations([]);\n    };\n    this.$detectNewLine = function(text) {\n        var match = text.match(/^.*?(\\r?\\n)/m);\n        if (match) {\n            this.$autoNewLine = match[1];\n        } else {\n            this.$autoNewLine = \"\\n\";\n        }\n    };\n    this.getWordRange = function(row, column) {\n        var line = this.getLine(row);\n\n        var inToken = false;\n        if (column > 0)\n            inToken = !!line.charAt(column - 1).match(this.tokenRe);\n\n        if (!inToken)\n            inToken = !!line.charAt(column).match(this.tokenRe);\n\n        if (inToken)\n            var re = this.tokenRe;\n        else if (/^\\s+$/.test(line.slice(column-1, column+1)))\n            var re = /\\s/;\n        else\n            var re = this.nonTokenRe;\n\n        var start = column;\n        if (start > 0) {\n            do {\n                start--;\n            }\n            while (start >= 0 && line.charAt(start).match(re));\n            start++;\n        }\n\n        var end = column;\n        while (end < line.length && line.charAt(end).match(re)) {\n            end++;\n        }\n\n        return new Range(row, start, row, end);\n    };\n    this.getAWordRange = function(row, column) {\n        var wordRange = this.getWordRange(row, column);\n        var line = this.getLine(wordRange.end.row);\n\n        while (line.charAt(wordRange.end.column).match(/[ \\t]/)) {\n            wordRange.end.column += 1;\n        }\n        return wordRange;\n    };\n    this.setNewLineMode = function(newLineMode) {\n        this.doc.setNewLineMode(newLineMode);\n    };\n    this.getNewLineMode = function() {\n        return this.doc.getNewLineMode();\n    };\n    this.setUseWorker = function(useWorker) { this.setOption(\"useWorker\", useWorker); };\n    this.getUseWorker = function() { return this.$useWorker; };\n    this.onReloadTokenizer = function(e) {\n        var rows = e.data;\n        this.bgTokenizer.start(rows.first);\n        this._signal(\"tokenizerUpdate\", e);\n    };\n\n    this.$modes = config.$modes;\n    this.$mode = null;\n    this.$modeId = null;\n    this.setMode = function(mode, cb) {\n        if (mode && typeof mode === \"object\") {\n            if (mode.getTokenizer)\n                return this.$onChangeMode(mode);\n            var options = mode;\n            var path = options.path;\n        } else {\n            path = mode || \"ace/mode/text\";\n        }\n        if (!this.$modes[\"ace/mode/text\"])\n            this.$modes[\"ace/mode/text\"] = new TextMode();\n\n        if (this.$modes[path] && !options) {\n            this.$onChangeMode(this.$modes[path]);\n            cb && cb();\n            return;\n        }\n        this.$modeId = path;\n        config.loadModule([\"mode\", path], function(m) {\n            if (this.$modeId !== path)\n                return cb && cb();\n            if (this.$modes[path] && !options) {\n                this.$onChangeMode(this.$modes[path]);\n            } else if (m && m.Mode) {\n                m = new m.Mode(options);\n                if (!options) {\n                    this.$modes[path] = m;\n                    m.$id = path;\n                }\n                this.$onChangeMode(m);\n            }\n            cb && cb();\n        }.bind(this));\n        if (!this.$mode)\n            this.$onChangeMode(this.$modes[\"ace/mode/text\"], true);\n    };\n\n    this.$onChangeMode = function(mode, $isPlaceholder) {\n        if (!$isPlaceholder)\n            this.$modeId = mode.$id;\n        if (this.$mode === mode) \n            return;\n\n        this.$mode = mode;\n\n        this.$stopWorker();\n\n        if (this.$useWorker)\n            this.$startWorker();\n\n        var tokenizer = mode.getTokenizer();\n\n        if(tokenizer.addEventListener !== undefined) {\n            var onReloadTokenizer = this.onReloadTokenizer.bind(this);\n            tokenizer.addEventListener(\"update\", onReloadTokenizer);\n        }\n\n        if (!this.bgTokenizer) {\n            this.bgTokenizer = new BackgroundTokenizer(tokenizer);\n            var _self = this;\n            this.bgTokenizer.addEventListener(\"update\", function(e) {\n                _self._signal(\"tokenizerUpdate\", e);\n            });\n        } else {\n            this.bgTokenizer.setTokenizer(tokenizer);\n        }\n\n        this.bgTokenizer.setDocument(this.getDocument());\n\n        this.tokenRe = mode.tokenRe;\n        this.nonTokenRe = mode.nonTokenRe;\n\n        \n        if (!$isPlaceholder) {\n            if (mode.attachToSession)\n                mode.attachToSession(this);\n            this.$options.wrapMethod.set.call(this, this.$wrapMethod);\n            this.$setFolding(mode.foldingRules);\n            this.bgTokenizer.start(0);\n            this._emit(\"changeMode\");\n        }\n    };\n\n    this.$stopWorker = function() {\n        if (this.$worker) {\n            this.$worker.terminate();\n            this.$worker = null;\n        }\n    };\n\n    this.$startWorker = function() {\n        try {\n            this.$worker = this.$mode.createWorker(this);\n        } catch (e) {\n            config.warn(\"Could not load worker\", e);\n            this.$worker = null;\n        }\n    };\n    this.getMode = function() {\n        return this.$mode;\n    };\n\n    this.$scrollTop = 0;\n    this.setScrollTop = function(scrollTop) {\n        if (this.$scrollTop === scrollTop || isNaN(scrollTop))\n            return;\n\n        this.$scrollTop = scrollTop;\n        this._signal(\"changeScrollTop\", scrollTop);\n    };\n    this.getScrollTop = function() {\n        return this.$scrollTop;\n    };\n\n    this.$scrollLeft = 0;\n    this.setScrollLeft = function(scrollLeft) {\n        if (this.$scrollLeft === scrollLeft || isNaN(scrollLeft))\n            return;\n\n        this.$scrollLeft = scrollLeft;\n        this._signal(\"changeScrollLeft\", scrollLeft);\n    };\n    this.getScrollLeft = function() {\n        return this.$scrollLeft;\n    };\n    this.getScreenWidth = function() {\n        this.$computeWidth();\n        if (this.lineWidgets) \n            return Math.max(this.getLineWidgetMaxWidth(), this.screenWidth);\n        return this.screenWidth;\n    };\n    \n    this.getLineWidgetMaxWidth = function() {\n        if (this.lineWidgetsWidth != null) return this.lineWidgetsWidth;\n        var width = 0;\n        this.lineWidgets.forEach(function(w) {\n            if (w && w.screenWidth > width)\n                width = w.screenWidth;\n        });\n        return this.lineWidgetWidth = width;\n    };\n\n    this.$computeWidth = function(force) {\n        if (this.$modified || force) {\n            this.$modified = false;\n\n            if (this.$useWrapMode)\n                return this.screenWidth = this.$wrapLimit;\n\n            var lines = this.doc.getAllLines();\n            var cache = this.$rowLengthCache;\n            var longestScreenLine = 0;\n            var foldIndex = 0;\n            var foldLine = this.$foldData[foldIndex];\n            var foldStart = foldLine ? foldLine.start.row : Infinity;\n            var len = lines.length;\n\n            for (var i = 0; i < len; i++) {\n                if (i > foldStart) {\n                    i = foldLine.end.row + 1;\n                    if (i >= len)\n                        break;\n                    foldLine = this.$foldData[foldIndex++];\n                    foldStart = foldLine ? foldLine.start.row : Infinity;\n                }\n\n                if (cache[i] == null)\n                    cache[i] = this.$getStringScreenWidth(lines[i])[0];\n\n                if (cache[i] > longestScreenLine)\n                    longestScreenLine = cache[i];\n            }\n            this.screenWidth = longestScreenLine;\n        }\n    };\n    this.getLine = function(row) {\n        return this.doc.getLine(row);\n    };\n    this.getLines = function(firstRow, lastRow) {\n        return this.doc.getLines(firstRow, lastRow);\n    };\n    this.getLength = function() {\n        return this.doc.getLength();\n    };\n    this.getTextRange = function(range) {\n        return this.doc.getTextRange(range || this.selection.getRange());\n    };\n    this.insert = function(position, text) {\n        return this.doc.insert(position, text);\n    };\n    this.remove = function(range) {\n        return this.doc.remove(range);\n    };\n    this.removeFullLines = function(firstRow, lastRow){\n        return this.doc.removeFullLines(firstRow, lastRow);\n    };\n    this.undoChanges = function(deltas, dontSelect) {\n        if (!deltas.length)\n            return;\n\n        this.$fromUndo = true;\n        for (var i = deltas.length - 1; i != -1; i--) {\n            var delta = deltas[i];\n            if (delta.action == \"insert\" || delta.action == \"remove\") {\n                this.doc.revertDelta(delta);\n            } else if (delta.folds) {\n                this.addFolds(delta.folds);\n            }\n        }\n        if (!dontSelect && this.$undoSelect) {\n            if (deltas.selectionBefore)\n                this.selection.fromJSON(deltas.selectionBefore);\n            else\n                this.selection.setRange(this.$getUndoSelection(deltas, true));\n        }\n        this.$fromUndo = false;\n    };\n    this.redoChanges = function(deltas, dontSelect) {\n        if (!deltas.length)\n            return;\n\n        this.$fromUndo = true;\n        for (var i = 0; i < deltas.length; i++) {\n            var delta = deltas[i];\n            if (delta.action == \"insert\" || delta.action == \"remove\") {\n                this.doc.applyDelta(delta);\n            }\n        }\n\n        if (!dontSelect && this.$undoSelect) {\n            if (deltas.selectionAfter)\n                this.selection.fromJSON(deltas.selectionAfter);\n            else\n                this.selection.setRange(this.$getUndoSelection(deltas, false));\n        }\n        this.$fromUndo = false;\n    };\n    this.setUndoSelect = function(enable) {\n        this.$undoSelect = enable;\n    };\n\n    this.$getUndoSelection = function(deltas, isUndo) {\n        function isInsert(delta) {\n            return isUndo ? delta.action !== \"insert\" : delta.action === \"insert\";\n        }\n\n        var range, point;\n        var lastDeltaIsInsert;\n\n        for (var i = 0; i < deltas.length; i++) {\n            var delta = deltas[i];\n            if (!delta.start) continue; // skip folds\n            if (!range) {\n                if (isInsert(delta)) {\n                    range = Range.fromPoints(delta.start, delta.end);\n                    lastDeltaIsInsert = true;\n                } else {\n                    range = Range.fromPoints(delta.start, delta.start);\n                    lastDeltaIsInsert = false;\n                }\n                continue;\n            }\n            \n            if (isInsert(delta)) {\n                point = delta.start;\n                if (range.compare(point.row, point.column) == -1) {\n                    range.setStart(point);\n                }\n                point = delta.end;\n                if (range.compare(point.row, point.column) == 1) {\n                    range.setEnd(point);\n                }\n                lastDeltaIsInsert = true;\n            } else {\n                point = delta.start;\n                if (range.compare(point.row, point.column) == -1) {\n                    range = Range.fromPoints(delta.start, delta.start);\n                }\n                lastDeltaIsInsert = false;\n            }\n        }\n        return range;\n    };\n    this.replace = function(range, text) {\n        return this.doc.replace(range, text);\n    };\n    this.moveText = function(fromRange, toPosition, copy) {\n        var text = this.getTextRange(fromRange);\n        var folds = this.getFoldsInRange(fromRange);\n\n        var toRange = Range.fromPoints(toPosition, toPosition);\n        if (!copy) {\n            this.remove(fromRange);\n            var rowDiff = fromRange.start.row - fromRange.end.row;\n            var collDiff = rowDiff ? -fromRange.end.column : fromRange.start.column - fromRange.end.column;\n            if (collDiff) {\n                if (toRange.start.row == fromRange.end.row && toRange.start.column > fromRange.end.column)\n                    toRange.start.column += collDiff;\n                if (toRange.end.row == fromRange.end.row && toRange.end.column > fromRange.end.column)\n                    toRange.end.column += collDiff;\n            }\n            if (rowDiff && toRange.start.row >= fromRange.end.row) {\n                toRange.start.row += rowDiff;\n                toRange.end.row += rowDiff;\n            }\n        }\n\n        toRange.end = this.insert(toRange.start, text);\n        if (folds.length) {\n            var oldStart = fromRange.start;\n            var newStart = toRange.start;\n            var rowDiff = newStart.row - oldStart.row;\n            var collDiff = newStart.column - oldStart.column;\n            this.addFolds(folds.map(function(x) {\n                x = x.clone();\n                if (x.start.row == oldStart.row)\n                    x.start.column += collDiff;\n                if (x.end.row == oldStart.row)\n                    x.end.column += collDiff;\n                x.start.row += rowDiff;\n                x.end.row += rowDiff;\n                return x;\n            }));\n        }\n\n        return toRange;\n    };\n    this.indentRows = function(startRow, endRow, indentString) {\n        indentString = indentString.replace(/\\t/g, this.getTabString());\n        for (var row=startRow; row<=endRow; row++)\n            this.doc.insertInLine({row: row, column: 0}, indentString);\n    };\n    this.outdentRows = function (range) {\n        var rowRange = range.collapseRows();\n        var deleteRange = new Range(0, 0, 0, 0);\n        var size = this.getTabSize();\n\n        for (var i = rowRange.start.row; i <= rowRange.end.row; ++i) {\n            var line = this.getLine(i);\n\n            deleteRange.start.row = i;\n            deleteRange.end.row = i;\n            for (var j = 0; j < size; ++j)\n                if (line.charAt(j) != ' ')\n                    break;\n            if (j < size && line.charAt(j) == '\\t') {\n                deleteRange.start.column = j;\n                deleteRange.end.column = j + 1;\n            } else {\n                deleteRange.start.column = 0;\n                deleteRange.end.column = j;\n            }\n            this.remove(deleteRange);\n        }\n    };\n\n    this.$moveLines = function(firstRow, lastRow, dir) {\n        firstRow = this.getRowFoldStart(firstRow);\n        lastRow = this.getRowFoldEnd(lastRow);\n        if (dir < 0) {\n            var row = this.getRowFoldStart(firstRow + dir);\n            if (row < 0) return 0;\n            var diff = row-firstRow;\n        } else if (dir > 0) {\n            var row = this.getRowFoldEnd(lastRow + dir);\n            if (row > this.doc.getLength()-1) return 0;\n            var diff = row-lastRow;\n        } else {\n            firstRow = this.$clipRowToDocument(firstRow);\n            lastRow = this.$clipRowToDocument(lastRow);\n            var diff = lastRow - firstRow + 1;\n        }\n\n        var range = new Range(firstRow, 0, lastRow, Number.MAX_VALUE);\n        var folds = this.getFoldsInRange(range).map(function(x){\n            x = x.clone();\n            x.start.row += diff;\n            x.end.row += diff;\n            return x;\n        });\n        \n        var lines = dir == 0\n            ? this.doc.getLines(firstRow, lastRow)\n            : this.doc.removeFullLines(firstRow, lastRow);\n        this.doc.insertFullLines(firstRow+diff, lines);\n        folds.length && this.addFolds(folds);\n        return diff;\n    };\n    this.moveLinesUp = function(firstRow, lastRow) {\n        return this.$moveLines(firstRow, lastRow, -1);\n    };\n    this.moveLinesDown = function(firstRow, lastRow) {\n        return this.$moveLines(firstRow, lastRow, 1);\n    };\n    this.duplicateLines = function(firstRow, lastRow) {\n        return this.$moveLines(firstRow, lastRow, 0);\n    };\n\n\n    this.$clipRowToDocument = function(row) {\n        return Math.max(0, Math.min(row, this.doc.getLength()-1));\n    };\n\n    this.$clipColumnToRow = function(row, column) {\n        if (column < 0)\n            return 0;\n        return Math.min(this.doc.getLine(row).length, column);\n    };\n\n\n    this.$clipPositionToDocument = function(row, column) {\n        column = Math.max(0, column);\n\n        if (row < 0) {\n            row = 0;\n            column = 0;\n        } else {\n            var len = this.doc.getLength();\n            if (row >= len) {\n                row = len - 1;\n                column = this.doc.getLine(len-1).length;\n            } else {\n                column = Math.min(this.doc.getLine(row).length, column);\n            }\n        }\n\n        return {\n            row: row,\n            column: column\n        };\n    };\n\n    this.$clipRangeToDocument = function(range) {\n        if (range.start.row < 0) {\n            range.start.row = 0;\n            range.start.column = 0;\n        } else {\n            range.start.column = this.$clipColumnToRow(\n                range.start.row,\n                range.start.column\n            );\n        }\n\n        var len = this.doc.getLength() - 1;\n        if (range.end.row > len) {\n            range.end.row = len;\n            range.end.column = this.doc.getLine(len).length;\n        } else {\n            range.end.column = this.$clipColumnToRow(\n                range.end.row,\n                range.end.column\n            );\n        }\n        return range;\n    };\n    this.$wrapLimit = 80;\n    this.$useWrapMode = false;\n    this.$wrapLimitRange = {\n        min : null,\n        max : null\n    };\n    this.setUseWrapMode = function(useWrapMode) {\n        if (useWrapMode != this.$useWrapMode) {\n            this.$useWrapMode = useWrapMode;\n            this.$modified = true;\n            this.$resetRowCache(0);\n            if (useWrapMode) {\n                var len = this.getLength();\n                this.$wrapData = Array(len);\n                this.$updateWrapData(0, len - 1);\n            }\n\n            this._signal(\"changeWrapMode\");\n        }\n    };\n    this.getUseWrapMode = function() {\n        return this.$useWrapMode;\n    };\n    this.setWrapLimitRange = function(min, max) {\n        if (this.$wrapLimitRange.min !== min || this.$wrapLimitRange.max !== max) {\n            this.$wrapLimitRange = { min: min, max: max };\n            this.$modified = true;\n            this.$bidiHandler.markAsDirty();\n            if (this.$useWrapMode)\n                this._signal(\"changeWrapMode\");\n        }\n    };\n    this.adjustWrapLimit = function(desiredLimit, $printMargin) {\n        var limits = this.$wrapLimitRange;\n        if (limits.max < 0)\n            limits = {min: $printMargin, max: $printMargin};\n        var wrapLimit = this.$constrainWrapLimit(desiredLimit, limits.min, limits.max);\n        if (wrapLimit != this.$wrapLimit && wrapLimit > 1) {\n            this.$wrapLimit = wrapLimit;\n            this.$modified = true;\n            if (this.$useWrapMode) {\n                this.$updateWrapData(0, this.getLength() - 1);\n                this.$resetRowCache(0);\n                this._signal(\"changeWrapLimit\");\n            }\n            return true;\n        }\n        return false;\n    };\n\n    this.$constrainWrapLimit = function(wrapLimit, min, max) {\n        if (min)\n            wrapLimit = Math.max(min, wrapLimit);\n\n        if (max)\n            wrapLimit = Math.min(max, wrapLimit);\n\n        return wrapLimit;\n    };\n    this.getWrapLimit = function() {\n        return this.$wrapLimit;\n    };\n    this.setWrapLimit = function (limit) {\n        this.setWrapLimitRange(limit, limit);\n    };\n    this.getWrapLimitRange = function() {\n        return {\n            min : this.$wrapLimitRange.min,\n            max : this.$wrapLimitRange.max\n        };\n    };\n\n    this.$updateInternalDataOnChange = function(delta) {\n        var useWrapMode = this.$useWrapMode;\n        var action = delta.action;\n        var start = delta.start;\n        var end = delta.end;\n        var firstRow = start.row;\n        var lastRow = end.row;\n        var len = lastRow - firstRow;\n        var removedFolds = null;\n        \n        this.$updating = true;\n        if (len != 0) {\n            if (action === \"remove\") {\n                this[useWrapMode ? \"$wrapData\" : \"$rowLengthCache\"].splice(firstRow, len);\n\n                var foldLines = this.$foldData;\n                removedFolds = this.getFoldsInRange(delta);\n                this.removeFolds(removedFolds);\n\n                var foldLine = this.getFoldLine(end.row);\n                var idx = 0;\n                if (foldLine) {\n                    foldLine.addRemoveChars(end.row, end.column, start.column - end.column);\n                    foldLine.shiftRow(-len);\n\n                    var foldLineBefore = this.getFoldLine(firstRow);\n                    if (foldLineBefore && foldLineBefore !== foldLine) {\n                        foldLineBefore.merge(foldLine);\n                        foldLine = foldLineBefore;\n                    }\n                    idx = foldLines.indexOf(foldLine) + 1;\n                }\n\n                for (idx; idx < foldLines.length; idx++) {\n                    var foldLine = foldLines[idx];\n                    if (foldLine.start.row >= end.row) {\n                        foldLine.shiftRow(-len);\n                    }\n                }\n\n                lastRow = firstRow;\n            } else {\n                var args = Array(len);\n                args.unshift(firstRow, 0);\n                var arr = useWrapMode ? this.$wrapData : this.$rowLengthCache;\n                arr.splice.apply(arr, args);\n                var foldLines = this.$foldData;\n                var foldLine = this.getFoldLine(firstRow);\n                var idx = 0;\n                if (foldLine) {\n                    var cmp = foldLine.range.compareInside(start.row, start.column);\n                    if (cmp == 0) {\n                        foldLine = foldLine.split(start.row, start.column);\n                        if (foldLine) {\n                            foldLine.shiftRow(len);\n                            foldLine.addRemoveChars(lastRow, 0, end.column - start.column);\n                        }\n                    } else\n                    if (cmp == -1) {\n                        foldLine.addRemoveChars(firstRow, 0, end.column - start.column);\n                        foldLine.shiftRow(len);\n                    }\n                    idx = foldLines.indexOf(foldLine) + 1;\n                }\n\n                for (idx; idx < foldLines.length; idx++) {\n                    var foldLine = foldLines[idx];\n                    if (foldLine.start.row >= firstRow) {\n                        foldLine.shiftRow(len);\n                    }\n                }\n            }\n        } else {\n            len = Math.abs(delta.start.column - delta.end.column);\n            if (action === \"remove\") {\n                removedFolds = this.getFoldsInRange(delta);\n                this.removeFolds(removedFolds);\n\n                len = -len;\n            }\n            var foldLine = this.getFoldLine(firstRow);\n            if (foldLine) {\n                foldLine.addRemoveChars(firstRow, start.column, len);\n            }\n        }\n\n        if (useWrapMode && this.$wrapData.length != this.doc.getLength()) {\n            console.error(\"doc.getLength() and $wrapData.length have to be the same!\");\n        }\n        this.$updating = false;\n\n        if (useWrapMode)\n            this.$updateWrapData(firstRow, lastRow);\n        else\n            this.$updateRowLengthCache(firstRow, lastRow);\n\n        return removedFolds;\n    };\n\n    this.$updateRowLengthCache = function(firstRow, lastRow, b) {\n        this.$rowLengthCache[firstRow] = null;\n        this.$rowLengthCache[lastRow] = null;\n    };\n\n    this.$updateWrapData = function(firstRow, lastRow) {\n        var lines = this.doc.getAllLines();\n        var tabSize = this.getTabSize();\n        var wrapData = this.$wrapData;\n        var wrapLimit = this.$wrapLimit;\n        var tokens;\n        var foldLine;\n\n        var row = firstRow;\n        lastRow = Math.min(lastRow, lines.length - 1);\n        while (row <= lastRow) {\n            foldLine = this.getFoldLine(row, foldLine);\n            if (!foldLine) {\n                tokens = this.$getDisplayTokens(lines[row]);\n                wrapData[row] = this.$computeWrapSplits(tokens, wrapLimit, tabSize);\n                row ++;\n            } else {\n                tokens = [];\n                foldLine.walk(function(placeholder, row, column, lastColumn) {\n                        var walkTokens;\n                        if (placeholder != null) {\n                            walkTokens = this.$getDisplayTokens(\n                                            placeholder, tokens.length);\n                            walkTokens[0] = PLACEHOLDER_START;\n                            for (var i = 1; i < walkTokens.length; i++) {\n                                walkTokens[i] = PLACEHOLDER_BODY;\n                            }\n                        } else {\n                            walkTokens = this.$getDisplayTokens(\n                                lines[row].substring(lastColumn, column),\n                                tokens.length);\n                        }\n                        tokens = tokens.concat(walkTokens);\n                    }.bind(this),\n                    foldLine.end.row,\n                    lines[foldLine.end.row].length + 1\n                );\n\n                wrapData[foldLine.start.row] = this.$computeWrapSplits(tokens, wrapLimit, tabSize);\n                row = foldLine.end.row + 1;\n            }\n        }\n    };\n    var CHAR = 1,\n        CHAR_EXT = 2,\n        PLACEHOLDER_START = 3,\n        PLACEHOLDER_BODY =  4,\n        PUNCTUATION = 9,\n        SPACE = 10,\n        TAB = 11,\n        TAB_SPACE = 12;\n\n\n    this.$computeWrapSplits = function(tokens, wrapLimit, tabSize) {\n        if (tokens.length == 0) {\n            return [];\n        }\n\n        var splits = [];\n        var displayLength = tokens.length;\n        var lastSplit = 0, lastDocSplit = 0;\n\n        var isCode = this.$wrapAsCode;\n\n        var indentedSoftWrap = this.$indentedSoftWrap;\n        var maxIndent = wrapLimit <= Math.max(2 * tabSize, 8)\n            || indentedSoftWrap === false ? 0 : Math.floor(wrapLimit / 2);\n\n        function getWrapIndent() {\n            var indentation = 0;\n            if (maxIndent === 0)\n                return indentation;\n            if (indentedSoftWrap) {\n                for (var i = 0; i < tokens.length; i++) {\n                    var token = tokens[i];\n                    if (token == SPACE)\n                        indentation += 1;\n                    else if (token == TAB)\n                        indentation += tabSize;\n                    else if (token == TAB_SPACE)\n                        continue;\n                    else\n                        break;\n                }\n            }\n            if (isCode && indentedSoftWrap !== false)\n                indentation += tabSize;\n            return Math.min(indentation, maxIndent);\n        }\n        function addSplit(screenPos) {\n            var len = screenPos - lastSplit;\n            for (var i = lastSplit; i < screenPos; i++) {\n                var ch = tokens[i];\n                if (ch === 12 || ch === 2) len -= 1;\n            }\n\n            if (!splits.length) {\n                indent = getWrapIndent();\n                splits.indent = indent;\n            }\n            lastDocSplit += len;\n            splits.push(lastDocSplit);\n            lastSplit = screenPos;\n        }\n        var indent = 0;\n        while (displayLength - lastSplit > wrapLimit - indent) {\n            var split = lastSplit + wrapLimit - indent;\n            if (tokens[split - 1] >= SPACE && tokens[split] >= SPACE) {\n                addSplit(split);\n                continue;\n            }\n            if (tokens[split] == PLACEHOLDER_START || tokens[split] == PLACEHOLDER_BODY) {\n                for (split; split != lastSplit - 1; split--) {\n                    if (tokens[split] == PLACEHOLDER_START) {\n                        break;\n                    }\n                }\n                if (split > lastSplit) {\n                    addSplit(split);\n                    continue;\n                }\n                split = lastSplit + wrapLimit;\n                for (split; split < tokens.length; split++) {\n                    if (tokens[split] != PLACEHOLDER_BODY) {\n                        break;\n                    }\n                }\n                if (split == tokens.length) {\n                    break;  // Breaks the while-loop.\n                }\n                addSplit(split);\n                continue;\n            }\n            var minSplit = Math.max(split - (wrapLimit -(wrapLimit>>2)), lastSplit - 1);\n            while (split > minSplit && tokens[split] < PLACEHOLDER_START) {\n                split --;\n            }\n            if (isCode) {\n                while (split > minSplit && tokens[split] < PLACEHOLDER_START) {\n                    split --;\n                }\n                while (split > minSplit && tokens[split] == PUNCTUATION) {\n                    split --;\n                }\n            } else {\n                while (split > minSplit && tokens[split] < SPACE) {\n                    split --;\n                }\n            }\n            if (split > minSplit) {\n                addSplit(++split);\n                continue;\n            }\n            split = lastSplit + wrapLimit;\n            if (tokens[split] == CHAR_EXT)\n                split--;\n            addSplit(split - indent);\n        }\n        return splits;\n    };\n    this.$getDisplayTokens = function(str, offset) {\n        var arr = [];\n        var tabSize;\n        offset = offset || 0;\n\n        for (var i = 0; i < str.length; i++) {\n            var c = str.charCodeAt(i);\n            if (c == 9) {\n                tabSize = this.getScreenTabSize(arr.length + offset);\n                arr.push(TAB);\n                for (var n = 1; n < tabSize; n++) {\n                    arr.push(TAB_SPACE);\n                }\n            }\n            else if (c == 32) {\n                arr.push(SPACE);\n            } else if((c > 39 && c < 48) || (c > 57 && c < 64)) {\n                arr.push(PUNCTUATION);\n            }\n            else if (c >= 0x1100 && isFullWidth(c)) {\n                arr.push(CHAR, CHAR_EXT);\n            } else {\n                arr.push(CHAR);\n            }\n        }\n        return arr;\n    };\n    this.$getStringScreenWidth = function(str, maxScreenColumn, screenColumn) {\n        if (maxScreenColumn == 0)\n            return [0, 0];\n        if (maxScreenColumn == null)\n            maxScreenColumn = Infinity;\n        screenColumn = screenColumn || 0;\n\n        var c, column;\n        for (column = 0; column < str.length; column++) {\n            c = str.charCodeAt(column);\n            if (c == 9) {\n                screenColumn += this.getScreenTabSize(screenColumn);\n            }\n            else if (c >= 0x1100 && isFullWidth(c)) {\n                screenColumn += 2;\n            } else {\n                screenColumn += 1;\n            }\n            if (screenColumn > maxScreenColumn) {\n                break;\n            }\n        }\n\n        return [screenColumn, column];\n    };\n\n    this.lineWidgets = null;\n    this.getRowLength = function(row) {\n        var h = 1;\n        if (this.lineWidgets)\n            h += this.lineWidgets[row] && this.lineWidgets[row].rowCount || 0;\n        \n        if (!this.$useWrapMode || !this.$wrapData[row])\n            return h;\n        else\n            return this.$wrapData[row].length + h;\n    };\n    this.getRowLineCount = function(row) {\n        if (!this.$useWrapMode || !this.$wrapData[row]) {\n            return 1;\n        } else {\n            return this.$wrapData[row].length + 1;\n        }\n    };\n\n    this.getRowWrapIndent = function(screenRow) {\n        if (this.$useWrapMode) {\n            var pos = this.screenToDocumentPosition(screenRow, Number.MAX_VALUE);\n            var splits = this.$wrapData[pos.row];\n            return splits.length && splits[0] < pos.column ? splits.indent : 0;\n        } else {\n            return 0;\n        }\n    };\n    this.getScreenLastRowColumn = function(screenRow) {\n        var pos = this.screenToDocumentPosition(screenRow, Number.MAX_VALUE);\n        return this.documentToScreenColumn(pos.row, pos.column);\n    };\n    this.getDocumentLastRowColumn = function(docRow, docColumn) {\n        var screenRow = this.documentToScreenRow(docRow, docColumn);\n        return this.getScreenLastRowColumn(screenRow);\n    };\n    this.getDocumentLastRowColumnPosition = function(docRow, docColumn) {\n        var screenRow = this.documentToScreenRow(docRow, docColumn);\n        return this.screenToDocumentPosition(screenRow, Number.MAX_VALUE / 10);\n    };\n    this.getRowSplitData = function(row) {\n        if (!this.$useWrapMode) {\n            return undefined;\n        } else {\n            return this.$wrapData[row];\n        }\n    };\n    this.getScreenTabSize = function(screenColumn) {\n        return this.$tabSize - (screenColumn % this.$tabSize | 0);\n    };\n\n\n    this.screenToDocumentRow = function(screenRow, screenColumn) {\n        return this.screenToDocumentPosition(screenRow, screenColumn).row;\n    };\n\n\n    this.screenToDocumentColumn = function(screenRow, screenColumn) {\n        return this.screenToDocumentPosition(screenRow, screenColumn).column;\n    };\n    this.screenToDocumentPosition = function(screenRow, screenColumn, offsetX) {\n        if (screenRow < 0)\n            return {row: 0, column: 0};\n\n        var line;\n        var docRow = 0;\n        var docColumn = 0;\n        var column;\n        var row = 0;\n        var rowLength = 0;\n\n        var rowCache = this.$screenRowCache;\n        var i = this.$getRowCacheIndex(rowCache, screenRow);\n        var l = rowCache.length;\n        if (l && i >= 0) {\n            var row = rowCache[i];\n            var docRow = this.$docRowCache[i];\n            var doCache = screenRow > rowCache[l - 1];\n        } else {\n            var doCache = !l;\n        }\n\n        var maxRow = this.getLength() - 1;\n        var foldLine = this.getNextFoldLine(docRow);\n        var foldStart = foldLine ? foldLine.start.row : Infinity;\n\n        while (row <= screenRow) {\n            rowLength = this.getRowLength(docRow);\n            if (row + rowLength > screenRow || docRow >= maxRow) {\n                break;\n            } else {\n                row += rowLength;\n                docRow++;\n                if (docRow > foldStart) {\n                    docRow = foldLine.end.row+1;\n                    foldLine = this.getNextFoldLine(docRow, foldLine);\n                    foldStart = foldLine ? foldLine.start.row : Infinity;\n                }\n            }\n\n            if (doCache) {\n                this.$docRowCache.push(docRow);\n                this.$screenRowCache.push(row);\n            }\n        }\n\n        if (foldLine && foldLine.start.row <= docRow) {\n            line = this.getFoldDisplayLine(foldLine);\n            docRow = foldLine.start.row;\n        } else if (row + rowLength <= screenRow || docRow > maxRow) {\n            return {\n                row: maxRow,\n                column: this.getLine(maxRow).length\n            };\n        } else {\n            line = this.getLine(docRow);\n            foldLine = null;\n        }\n        var wrapIndent = 0, splitIndex = Math.floor(screenRow - row);\n        if (this.$useWrapMode) {\n            var splits = this.$wrapData[docRow];\n            if (splits) {\n                column = splits[splitIndex];\n                if(splitIndex > 0 && splits.length) {\n                    wrapIndent = splits.indent;\n                    docColumn = splits[splitIndex - 1] || splits[splits.length - 1];\n                    line = line.substring(docColumn);\n                }\n            }\n        }\n\n        if (offsetX !== undefined && this.$bidiHandler.isBidiRow(row + splitIndex, docRow, splitIndex))\n            screenColumn = this.$bidiHandler.offsetToCol(offsetX);\n\n        docColumn += this.$getStringScreenWidth(line, screenColumn - wrapIndent)[1];\n        if (this.$useWrapMode && docColumn >= column)\n            docColumn = column - 1;\n\n        if (foldLine)\n            return foldLine.idxToPosition(docColumn);\n\n        return {row: docRow, column: docColumn};\n    };\n    this.documentToScreenPosition = function(docRow, docColumn) {\n        if (typeof docColumn === \"undefined\")\n            var pos = this.$clipPositionToDocument(docRow.row, docRow.column);\n        else\n            pos = this.$clipPositionToDocument(docRow, docColumn);\n\n        docRow = pos.row;\n        docColumn = pos.column;\n\n        var screenRow = 0;\n        var foldStartRow = null;\n        var fold = null;\n        fold = this.getFoldAt(docRow, docColumn, 1);\n        if (fold) {\n            docRow = fold.start.row;\n            docColumn = fold.start.column;\n        }\n\n        var rowEnd, row = 0;\n\n\n        var rowCache = this.$docRowCache;\n        var i = this.$getRowCacheIndex(rowCache, docRow);\n        var l = rowCache.length;\n        if (l && i >= 0) {\n            var row = rowCache[i];\n            var screenRow = this.$screenRowCache[i];\n            var doCache = docRow > rowCache[l - 1];\n        } else {\n            var doCache = !l;\n        }\n\n        var foldLine = this.getNextFoldLine(row);\n        var foldStart = foldLine ?foldLine.start.row :Infinity;\n\n        while (row < docRow) {\n            if (row >= foldStart) {\n                rowEnd = foldLine.end.row + 1;\n                if (rowEnd > docRow)\n                    break;\n                foldLine = this.getNextFoldLine(rowEnd, foldLine);\n                foldStart = foldLine ?foldLine.start.row :Infinity;\n            }\n            else {\n                rowEnd = row + 1;\n            }\n\n            screenRow += this.getRowLength(row);\n            row = rowEnd;\n\n            if (doCache) {\n                this.$docRowCache.push(row);\n                this.$screenRowCache.push(screenRow);\n            }\n        }\n        var textLine = \"\";\n        if (foldLine && row >= foldStart) {\n            textLine = this.getFoldDisplayLine(foldLine, docRow, docColumn);\n            foldStartRow = foldLine.start.row;\n        } else {\n            textLine = this.getLine(docRow).substring(0, docColumn);\n            foldStartRow = docRow;\n        }\n        var wrapIndent = 0;\n        if (this.$useWrapMode) {\n            var wrapRow = this.$wrapData[foldStartRow];\n            if (wrapRow) {\n                var screenRowOffset = 0;\n                while (textLine.length >= wrapRow[screenRowOffset]) {\n                    screenRow ++;\n                    screenRowOffset++;\n                }\n                textLine = textLine.substring(\n                    wrapRow[screenRowOffset - 1] || 0, textLine.length\n                );\n                wrapIndent = screenRowOffset > 0 ? wrapRow.indent : 0;\n            }\n        }\n        \n        if (this.lineWidgets && this.lineWidgets[row] && this.lineWidgets[row].rowsAbove)\n            screenRow += this.lineWidgets[row].rowsAbove;\n\n        return {\n            row: screenRow,\n            column: wrapIndent + this.$getStringScreenWidth(textLine)[0]\n        };\n    };\n    this.documentToScreenColumn = function(row, docColumn) {\n        return this.documentToScreenPosition(row, docColumn).column;\n    };\n    this.documentToScreenRow = function(docRow, docColumn) {\n        return this.documentToScreenPosition(docRow, docColumn).row;\n    };\n    this.getScreenLength = function() {\n        var screenRows = 0;\n        var fold = null;\n        if (!this.$useWrapMode) {\n            screenRows = this.getLength();\n            var foldData = this.$foldData;\n            for (var i = 0; i < foldData.length; i++) {\n                fold = foldData[i];\n                screenRows -= fold.end.row - fold.start.row;\n            }\n        } else {\n            var lastRow = this.$wrapData.length;\n            var row = 0, i = 0;\n            var fold = this.$foldData[i++];\n            var foldStart = fold ? fold.start.row :Infinity;\n\n            while (row < lastRow) {\n                var splits = this.$wrapData[row];\n                screenRows += splits ? splits.length + 1 : 1;\n                row ++;\n                if (row > foldStart) {\n                    row = fold.end.row+1;\n                    fold = this.$foldData[i++];\n                    foldStart = fold ?fold.start.row :Infinity;\n                }\n            }\n        }\n        if (this.lineWidgets)\n            screenRows += this.$getWidgetScreenLength();\n\n        return screenRows;\n    };\n    this.$setFontMetrics = function(fm) {\n        if (!this.$enableVarChar) return;\n        this.$getStringScreenWidth = function(str, maxScreenColumn, screenColumn) {\n            if (maxScreenColumn === 0)\n                return [0, 0];\n            if (!maxScreenColumn)\n                maxScreenColumn = Infinity;\n            screenColumn = screenColumn || 0;\n            \n            var c, column;\n            for (column = 0; column < str.length; column++) {\n                c = str.charAt(column);\n                if (c === \"\\t\") {\n                    screenColumn += this.getScreenTabSize(screenColumn);\n                } else {\n                    screenColumn += fm.getCharacterWidth(c);\n                }\n                if (screenColumn > maxScreenColumn) {\n                    break;\n                }\n            }\n            \n            return [screenColumn, column];\n        };\n    };\n    \n    this.destroy = function() {\n        if (this.bgTokenizer) {\n            this.bgTokenizer.setDocument(null);\n            this.bgTokenizer = null;\n        }\n        this.$stopWorker();\n    };\n\n    this.isFullWidth = isFullWidth;\n    function isFullWidth(c) {\n        if (c < 0x1100)\n            return false;\n        return c >= 0x1100 && c <= 0x115F ||\n               c >= 0x11A3 && c <= 0x11A7 ||\n               c >= 0x11FA && c <= 0x11FF ||\n               c >= 0x2329 && c <= 0x232A ||\n               c >= 0x2E80 && c <= 0x2E99 ||\n               c >= 0x2E9B && c <= 0x2EF3 ||\n               c >= 0x2F00 && c <= 0x2FD5 ||\n               c >= 0x2FF0 && c <= 0x2FFB ||\n               c >= 0x3000 && c <= 0x303E ||\n               c >= 0x3041 && c <= 0x3096 ||\n               c >= 0x3099 && c <= 0x30FF ||\n               c >= 0x3105 && c <= 0x312D ||\n               c >= 0x3131 && c <= 0x318E ||\n               c >= 0x3190 && c <= 0x31BA ||\n               c >= 0x31C0 && c <= 0x31E3 ||\n               c >= 0x31F0 && c <= 0x321E ||\n               c >= 0x3220 && c <= 0x3247 ||\n               c >= 0x3250 && c <= 0x32FE ||\n               c >= 0x3300 && c <= 0x4DBF ||\n               c >= 0x4E00 && c <= 0xA48C ||\n               c >= 0xA490 && c <= 0xA4C6 ||\n               c >= 0xA960 && c <= 0xA97C ||\n               c >= 0xAC00 && c <= 0xD7A3 ||\n               c >= 0xD7B0 && c <= 0xD7C6 ||\n               c >= 0xD7CB && c <= 0xD7FB ||\n               c >= 0xF900 && c <= 0xFAFF ||\n               c >= 0xFE10 && c <= 0xFE19 ||\n               c >= 0xFE30 && c <= 0xFE52 ||\n               c >= 0xFE54 && c <= 0xFE66 ||\n               c >= 0xFE68 && c <= 0xFE6B ||\n               c >= 0xFF01 && c <= 0xFF60 ||\n               c >= 0xFFE0 && c <= 0xFFE6;\n    }\n\n}).call(EditSession.prototype);\n\nrequire(\"./edit_session/folding\").Folding.call(EditSession.prototype);\nrequire(\"./edit_session/bracket_match\").BracketMatch.call(EditSession.prototype);\n\n\nconfig.defineOptions(EditSession.prototype, \"session\", {\n    wrap: {\n        set: function(value) {\n            if (!value || value == \"off\")\n                value = false;\n            else if (value == \"free\")\n                value = true;\n            else if (value == \"printMargin\")\n                value = -1;\n            else if (typeof value == \"string\")\n                value = parseInt(value, 10) || false;\n\n            if (this.$wrap == value)\n                return;\n            this.$wrap = value;\n            if (!value) {\n                this.setUseWrapMode(false);\n            } else {\n                var col = typeof value == \"number\" ? value : null;\n                this.setWrapLimitRange(col, col);\n                this.setUseWrapMode(true);\n            }\n        },\n        get: function() {\n            if (this.getUseWrapMode()) {\n                if (this.$wrap == -1)\n                    return \"printMargin\";\n                if (!this.getWrapLimitRange().min)\n                    return \"free\";\n                return this.$wrap;\n            }\n            return \"off\";\n        },\n        handlesSet: true\n    },    \n    wrapMethod: {\n        set: function(val) {\n            val = val == \"auto\"\n                ? this.$mode.type != \"text\"\n                : val != \"text\";\n            if (val != this.$wrapAsCode) {\n                this.$wrapAsCode = val;\n                if (this.$useWrapMode) {\n                    this.$useWrapMode = false;\n                    this.setUseWrapMode(true);\n                }\n            }\n        },\n        initialValue: \"auto\"\n    },\n    indentedSoftWrap: {\n        set: function() {\n            if (this.$useWrapMode) {\n                this.$useWrapMode = false;\n                this.setUseWrapMode(true);\n            }\n        },\n        initialValue: true \n    },\n    firstLineNumber: {\n        set: function() {this._signal(\"changeBreakpoint\");},\n        initialValue: 1\n    },\n    useWorker: {\n        set: function(useWorker) {\n            this.$useWorker = useWorker;\n\n            this.$stopWorker();\n            if (useWorker)\n                this.$startWorker();\n        },\n        initialValue: true\n    },\n    useSoftTabs: {initialValue: true},\n    tabSize: {\n        set: function(tabSize) {\n            tabSize = parseInt(tabSize);\n            if (tabSize > 0 && this.$tabSize !== tabSize) {\n                this.$modified = true;\n                this.$rowLengthCache = [];\n                this.$tabSize = tabSize;\n                this._signal(\"changeTabSize\");\n            }\n        },\n        initialValue: 4,\n        handlesSet: true\n    },\n    navigateWithinSoftTabs: {initialValue: false},\n    foldStyle: {\n        set: function(val) {this.setFoldStyle(val);},\n        handlesSet: true\n    },\n    overwrite: {\n        set: function(val) {this._signal(\"changeOverwrite\");},\n        initialValue: false\n    },\n    newLineMode: {\n        set: function(val) {this.doc.setNewLineMode(val);},\n        get: function() {return this.doc.getNewLineMode();},\n        handlesSet: true\n    },\n    mode: {\n        set: function(val) { this.setMode(val); },\n        get: function() { return this.$modeId; },\n        handlesSet: true\n    }\n});\n\nexports.EditSession = EditSession;\n});\n\nace.define(\"ace/search\",[\"require\",\"exports\",\"module\",\"ace/lib/lang\",\"ace/lib/oop\",\"ace/range\"], function(require, exports, module) {\n\"use strict\";\n\nvar lang = require(\"./lib/lang\");\nvar oop = require(\"./lib/oop\");\nvar Range = require(\"./range\").Range;\n\nvar Search = function() {\n    this.$options = {};\n};\n\n(function() {\n    this.set = function(options) {\n        oop.mixin(this.$options, options);\n        return this;\n    };\n    this.getOptions = function() {\n        return lang.copyObject(this.$options);\n    };\n    this.setOptions = function(options) {\n        this.$options = options;\n    };\n    this.find = function(session) {\n        var options = this.$options;\n        var iterator = this.$matchIterator(session, options);\n        if (!iterator)\n            return false;\n\n        var firstRange = null;\n        iterator.forEach(function(sr, sc, er, ec) {\n            firstRange = new Range(sr, sc, er, ec);\n            if (sc == ec && options.start && options.start.start\n                && options.skipCurrent != false && firstRange.isEqual(options.start)\n            ) {\n                firstRange = null;\n                return false;\n            }\n            \n            return true;\n        });\n\n        return firstRange;\n    };\n    this.findAll = function(session) {\n        var options = this.$options;\n        if (!options.needle)\n            return [];\n        this.$assembleRegExp(options);\n\n        var range = options.range;\n        var lines = range\n            ? session.getLines(range.start.row, range.end.row)\n            : session.doc.getAllLines();\n\n        var ranges = [];\n        var re = options.re;\n        if (options.$isMultiLine) {\n            var len = re.length;\n            var maxRow = lines.length - len;\n            var prevRange;\n            outer: for (var row = re.offset || 0; row <= maxRow; row++) {\n                for (var j = 0; j < len; j++)\n                    if (lines[row + j].search(re[j]) == -1)\n                        continue outer;\n                \n                var startLine = lines[row];\n                var line = lines[row + len - 1];\n                var startIndex = startLine.length - startLine.match(re[0])[0].length;\n                var endIndex = line.match(re[len - 1])[0].length;\n                \n                if (prevRange && prevRange.end.row === row &&\n                    prevRange.end.column > startIndex\n                ) {\n                    continue;\n                }\n                ranges.push(prevRange = new Range(\n                    row, startIndex, row + len - 1, endIndex\n                ));\n                if (len > 2)\n                    row = row + len - 2;\n            }\n        } else {\n            for (var i = 0; i < lines.length; i++) {\n                var matches = lang.getMatchOffsets(lines[i], re);\n                for (var j = 0; j < matches.length; j++) {\n                    var match = matches[j];\n                    ranges.push(new Range(i, match.offset, i, match.offset + match.length));\n                }\n            }\n        }\n\n        if (range) {\n            var startColumn = range.start.column;\n            var endColumn = range.start.column;\n            var i = 0, j = ranges.length - 1;\n            while (i < j && ranges[i].start.column < startColumn && ranges[i].start.row == range.start.row)\n                i++;\n\n            while (i < j && ranges[j].end.column > endColumn && ranges[j].end.row == range.end.row)\n                j--;\n            \n            ranges = ranges.slice(i, j + 1);\n            for (i = 0, j = ranges.length; i < j; i++) {\n                ranges[i].start.row += range.start.row;\n                ranges[i].end.row += range.start.row;\n            }\n        }\n\n        return ranges;\n    };\n    this.replace = function(input, replacement) {\n        var options = this.$options;\n\n        var re = this.$assembleRegExp(options);\n        if (options.$isMultiLine)\n            return replacement;\n\n        if (!re)\n            return;\n\n        var match = re.exec(input);\n        if (!match || match[0].length != input.length)\n            return null;\n        \n        replacement = input.replace(re, replacement);\n        if (options.preserveCase) {\n            replacement = replacement.split(\"\");\n            for (var i = Math.min(input.length, input.length); i--; ) {\n                var ch = input[i];\n                if (ch && ch.toLowerCase() != ch)\n                    replacement[i] = replacement[i].toUpperCase();\n                else\n                    replacement[i] = replacement[i].toLowerCase();\n            }\n            replacement = replacement.join(\"\");\n        }\n        \n        return replacement;\n    };\n\n    this.$assembleRegExp = function(options, $disableFakeMultiline) {\n        if (options.needle instanceof RegExp)\n            return options.re = options.needle;\n\n        var needle = options.needle;\n\n        if (!options.needle)\n            return options.re = false;\n\n        if (!options.regExp)\n            needle = lang.escapeRegExp(needle);\n\n        if (options.wholeWord)\n            needle = addWordBoundary(needle, options);\n\n        var modifier = options.caseSensitive ? \"gm\" : \"gmi\";\n\n        options.$isMultiLine = !$disableFakeMultiline && /[\\n\\r]/.test(needle);\n        if (options.$isMultiLine)\n            return options.re = this.$assembleMultilineRegExp(needle, modifier);\n\n        try {\n            var re = new RegExp(needle, modifier);\n        } catch(e) {\n            re = false;\n        }\n        return options.re = re;\n    };\n\n    this.$assembleMultilineRegExp = function(needle, modifier) {\n        var parts = needle.replace(/\\r\\n|\\r|\\n/g, \"$\\n^\").split(\"\\n\");\n        var re = [];\n        for (var i = 0; i < parts.length; i++) try {\n            re.push(new RegExp(parts[i], modifier));\n        } catch(e) {\n            return false;\n        }\n        return re;\n    };\n\n    this.$matchIterator = function(session, options) {\n        var re = this.$assembleRegExp(options);\n        if (!re)\n            return false;\n        var backwards = options.backwards == true;\n        var skipCurrent = options.skipCurrent != false;\n\n        var range = options.range;\n        var start = options.start;\n        if (!start)\n            start = range ? range[backwards ? \"end\" : \"start\"] : session.selection.getRange();\n         \n        if (start.start)\n            start = start[skipCurrent != backwards ? \"end\" : \"start\"];\n\n        var firstRow = range ? range.start.row : 0;\n        var lastRow = range ? range.end.row : session.getLength() - 1;\n        \n        if (backwards) {\n            var forEach = function(callback) {\n                var row = start.row;\n                if (forEachInLine(row, start.column, callback))\n                    return;\n                for (row--; row >= firstRow; row--)\n                    if (forEachInLine(row, Number.MAX_VALUE, callback))\n                        return;\n                if (options.wrap == false)\n                    return;\n                for (row = lastRow, firstRow = start.row; row >= firstRow; row--)\n                    if (forEachInLine(row, Number.MAX_VALUE, callback))\n                        return;\n            };\n        }\n        else {\n            var forEach = function(callback) {\n                var row = start.row;\n                if (forEachInLine(row, start.column, callback))\n                    return;\n                for (row = row + 1; row <= lastRow; row++)\n                    if (forEachInLine(row, 0, callback))\n                        return;\n                if (options.wrap == false)\n                    return;\n                for (row = firstRow, lastRow = start.row; row <= lastRow; row++)\n                    if (forEachInLine(row, 0, callback))\n                        return;\n            };\n        }\n        \n        if (options.$isMultiLine) {\n            var len = re.length;\n            var forEachInLine = function(row, offset, callback) {\n                var startRow = backwards ? row - len + 1 : row;\n                if (startRow < 0) return;\n                var line = session.getLine(startRow);\n                var startIndex = line.search(re[0]);\n                if (!backwards && startIndex < offset || startIndex === -1) return;\n                for (var i = 1; i < len; i++) {\n                    line = session.getLine(startRow + i);\n                    if (line.search(re[i]) == -1)\n                        return;\n                }\n                var endIndex = line.match(re[len - 1])[0].length;\n                if (backwards && endIndex > offset) return;\n                if (callback(startRow, startIndex, startRow + len - 1, endIndex))\n                    return true;\n            };\n        }\n        else if (backwards) {\n            var forEachInLine = function(row, endIndex, callback) {\n                var line = session.getLine(row);\n                var matches = [];\n                var m, last = 0;\n                re.lastIndex = 0;\n                while((m = re.exec(line))) {\n                    var length = m[0].length;\n                    last = m.index;\n                    if (!length) {\n                        if (last >= line.length) break;\n                        re.lastIndex = last += 1;\n                    }\n                    if (m.index + length > endIndex)\n                        break;\n                    matches.push(m.index, length);\n                }\n                for (var i = matches.length - 1; i >= 0; i -= 2) {\n                    var column = matches[i - 1];\n                    var length = matches[i];\n                    if (callback(row, column, row, column + length))\n                        return true;\n                }\n            };\n        }\n        else {\n            var forEachInLine = function(row, startIndex, callback) {\n                var line = session.getLine(row);\n                var last;\n                var m;\n                re.lastIndex = startIndex;\n                while((m = re.exec(line))) {\n                    var length = m[0].length;\n                    last = m.index;\n                    if (callback(row, last, row,last + length))\n                        return true;\n                    if (!length) {\n                        re.lastIndex = last += 1;\n                        if (last >= line.length) return false;\n                    }\n                }\n            };\n        }\n        return {forEach: forEach};\n    };\n\n}).call(Search.prototype);\n\nfunction addWordBoundary(needle, options) {\n    function wordBoundary(c) {\n        if (/\\w/.test(c) || options.regExp) return \"\\\\b\";\n        return \"\";\n    }\n    return wordBoundary(needle[0]) + needle\n        + wordBoundary(needle[needle.length - 1]);\n}\n\nexports.Search = Search;\n});\n\nace.define(\"ace/keyboard/hash_handler\",[\"require\",\"exports\",\"module\",\"ace/lib/keys\",\"ace/lib/useragent\"], function(require, exports, module) {\n\"use strict\";\n\nvar keyUtil = require(\"../lib/keys\");\nvar useragent = require(\"../lib/useragent\");\nvar KEY_MODS = keyUtil.KEY_MODS;\n\nfunction HashHandler(config, platform) {\n    this.platform = platform || (useragent.isMac ? \"mac\" : \"win\");\n    this.commands = {};\n    this.commandKeyBinding = {};\n    this.addCommands(config);\n    this.$singleCommand = true;\n}\n\nfunction MultiHashHandler(config, platform) {\n    HashHandler.call(this, config, platform);\n    this.$singleCommand = false;\n}\n\nMultiHashHandler.prototype = HashHandler.prototype;\n\n(function() {\n    \n\n    this.addCommand = function(command) {\n        if (this.commands[command.name])\n            this.removeCommand(command);\n\n        this.commands[command.name] = command;\n\n        if (command.bindKey)\n            this._buildKeyHash(command);\n    };\n\n    this.removeCommand = function(command, keepCommand) {\n        var name = command && (typeof command === 'string' ? command : command.name);\n        command = this.commands[name];\n        if (!keepCommand)\n            delete this.commands[name];\n        var ckb = this.commandKeyBinding;\n        for (var keyId in ckb) {\n            var cmdGroup = ckb[keyId];\n            if (cmdGroup == command) {\n                delete ckb[keyId];\n            } else if (Array.isArray(cmdGroup)) {\n                var i = cmdGroup.indexOf(command);\n                if (i != -1) {\n                    cmdGroup.splice(i, 1);\n                    if (cmdGroup.length == 1)\n                        ckb[keyId] = cmdGroup[0];\n                }\n            }\n        }\n    };\n\n    this.bindKey = function(key, command, position) {\n        if (typeof key == \"object\" && key) {\n            if (position == undefined)\n                position = key.position;\n            key = key[this.platform];\n        }\n        if (!key)\n            return;\n        if (typeof command == \"function\")\n            return this.addCommand({exec: command, bindKey: key, name: command.name || key});\n        \n        key.split(\"|\").forEach(function(keyPart) {\n            var chain = \"\";\n            if (keyPart.indexOf(\" \") != -1) {\n                var parts = keyPart.split(/\\s+/);\n                keyPart = parts.pop();\n                parts.forEach(function(keyPart) {\n                    var binding = this.parseKeys(keyPart);\n                    var id = KEY_MODS[binding.hashId] + binding.key;\n                    chain += (chain ? \" \" : \"\") + id;\n                    this._addCommandToBinding(chain, \"chainKeys\");\n                }, this);\n                chain += \" \";\n            }\n            var binding = this.parseKeys(keyPart);\n            var id = KEY_MODS[binding.hashId] + binding.key;\n            this._addCommandToBinding(chain + id, command, position);\n        }, this);\n    };\n    \n    function getPosition(command) {\n        return typeof command == \"object\" && command.bindKey\n            && command.bindKey.position \n            || (command.isDefault ? -100 : 0);\n    }\n    this._addCommandToBinding = function(keyId, command, position) {\n        var ckb = this.commandKeyBinding, i;\n        if (!command) {\n            delete ckb[keyId];\n        } else if (!ckb[keyId] || this.$singleCommand) {\n            ckb[keyId] = command;\n        } else {\n            if (!Array.isArray(ckb[keyId])) {\n                ckb[keyId] = [ckb[keyId]];\n            } else if ((i = ckb[keyId].indexOf(command)) != -1) {\n                ckb[keyId].splice(i, 1);\n            }\n            \n            if (typeof position != \"number\") {\n                position = getPosition(command);\n            }\n\n            var commands = ckb[keyId];\n            for (i = 0; i < commands.length; i++) {\n                var other = commands[i];\n                var otherPos = getPosition(other);\n                if (otherPos > position)\n                    break;\n            }\n            commands.splice(i, 0, command);\n        }\n    };\n\n    this.addCommands = function(commands) {\n        commands && Object.keys(commands).forEach(function(name) {\n            var command = commands[name];\n            if (!command)\n                return;\n            \n            if (typeof command === \"string\")\n                return this.bindKey(command, name);\n\n            if (typeof command === \"function\")\n                command = { exec: command };\n\n            if (typeof command !== \"object\")\n                return;\n\n            if (!command.name)\n                command.name = name;\n\n            this.addCommand(command);\n        }, this);\n    };\n\n    this.removeCommands = function(commands) {\n        Object.keys(commands).forEach(function(name) {\n            this.removeCommand(commands[name]);\n        }, this);\n    };\n\n    this.bindKeys = function(keyList) {\n        Object.keys(keyList).forEach(function(key) {\n            this.bindKey(key, keyList[key]);\n        }, this);\n    };\n\n    this._buildKeyHash = function(command) {\n        this.bindKey(command.bindKey, command);\n    };\n    this.parseKeys = function(keys) {\n        var parts = keys.toLowerCase().split(/[\\-\\+]([\\-\\+])?/).filter(function(x){return x;});\n        var key = parts.pop();\n\n        var keyCode = keyUtil[key];\n        if (keyUtil.FUNCTION_KEYS[keyCode])\n            key = keyUtil.FUNCTION_KEYS[keyCode].toLowerCase();\n        else if (!parts.length)\n            return {key: key, hashId: -1};\n        else if (parts.length == 1 && parts[0] == \"shift\")\n            return {key: key.toUpperCase(), hashId: -1};\n\n        var hashId = 0;\n        for (var i = parts.length; i--;) {\n            var modifier = keyUtil.KEY_MODS[parts[i]];\n            if (modifier == null) {\n                if (typeof console != \"undefined\")\n                    console.error(\"invalid modifier \" + parts[i] + \" in \" + keys);\n                return false;\n            }\n            hashId |= modifier;\n        }\n        return {key: key, hashId: hashId};\n    };\n\n    this.findKeyCommand = function findKeyCommand(hashId, keyString) {\n        var key = KEY_MODS[hashId] + keyString;\n        return this.commandKeyBinding[key];\n    };\n\n    this.handleKeyboard = function(data, hashId, keyString, keyCode) {\n        if (keyCode < 0) return;\n        var key = KEY_MODS[hashId] + keyString;\n        var command = this.commandKeyBinding[key];\n        if (data.$keyChain) {\n            data.$keyChain += \" \" + key;\n            command = this.commandKeyBinding[data.$keyChain] || command;\n        }\n        \n        if (command) {\n            if (command == \"chainKeys\" || command[command.length - 1] == \"chainKeys\") {\n                data.$keyChain = data.$keyChain || key;\n                return {command: \"null\"};\n            }\n        }\n        \n        if (data.$keyChain) {\n            if ((!hashId || hashId == 4) && keyString.length == 1)\n                data.$keyChain = data.$keyChain.slice(0, -key.length - 1); // wait for input\n            else if (hashId == -1 || keyCode > 0)\n                data.$keyChain = \"\"; // reset keyChain\n        }\n        return {command: command};\n    };\n    \n    this.getStatusText = function(editor, data) {\n        return data.$keyChain || \"\";\n    };\n\n}).call(HashHandler.prototype);\n\nexports.HashHandler = HashHandler;\nexports.MultiHashHandler = MultiHashHandler;\n});\n\nace.define(\"ace/commands/command_manager\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/keyboard/hash_handler\",\"ace/lib/event_emitter\"], function(require, exports, module) {\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar MultiHashHandler = require(\"../keyboard/hash_handler\").MultiHashHandler;\nvar EventEmitter = require(\"../lib/event_emitter\").EventEmitter;\n\nvar CommandManager = function(platform, commands) {\n    MultiHashHandler.call(this, commands, platform);\n    this.byName = this.commands;\n    this.setDefaultHandler(\"exec\", function(e) {\n        return e.command.exec(e.editor, e.args || {});\n    });\n};\n\noop.inherits(CommandManager, MultiHashHandler);\n\n(function() {\n\n    oop.implement(this, EventEmitter);\n\n    this.exec = function(command, editor, args) {\n        if (Array.isArray(command)) {\n            for (var i = command.length; i--; ) {\n                if (this.exec(command[i], editor, args)) return true;\n            }\n            return false;\n        }\n\n        if (typeof command === \"string\")\n            command = this.commands[command];\n\n        if (!command)\n            return false;\n\n        if (editor && editor.$readOnly && !command.readOnly)\n            return false;\n\n        if (this.$checkCommandState != false && command.isAvailable && !command.isAvailable(editor))\n            return false;\n\n        var e = {editor: editor, command: command, args: args};\n        e.returnValue = this._emit(\"exec\", e);\n        this._signal(\"afterExec\", e);\n\n        return e.returnValue === false ? false : true;\n    };\n\n    this.toggleRecording = function(editor) {\n        if (this.$inReplay)\n            return;\n\n        editor && editor._emit(\"changeStatus\");\n        if (this.recording) {\n            this.macro.pop();\n            this.removeEventListener(\"exec\", this.$addCommandToMacro);\n\n            if (!this.macro.length)\n                this.macro = this.oldMacro;\n\n            return this.recording = false;\n        }\n        if (!this.$addCommandToMacro) {\n            this.$addCommandToMacro = function(e) {\n                this.macro.push([e.command, e.args]);\n            }.bind(this);\n        }\n\n        this.oldMacro = this.macro;\n        this.macro = [];\n        this.on(\"exec\", this.$addCommandToMacro);\n        return this.recording = true;\n    };\n\n    this.replay = function(editor) {\n        if (this.$inReplay || !this.macro)\n            return;\n\n        if (this.recording)\n            return this.toggleRecording(editor);\n\n        try {\n            this.$inReplay = true;\n            this.macro.forEach(function(x) {\n                if (typeof x == \"string\")\n                    this.exec(x, editor);\n                else\n                    this.exec(x[0], editor, x[1]);\n            }, this);\n        } finally {\n            this.$inReplay = false;\n        }\n    };\n\n    this.trimMacro = function(m) {\n        return m.map(function(x){\n            if (typeof x[0] != \"string\")\n                x[0] = x[0].name;\n            if (!x[1])\n                x = x[0];\n            return x;\n        });\n    };\n\n}).call(CommandManager.prototype);\n\nexports.CommandManager = CommandManager;\n\n});\n\nace.define(\"ace/commands/default_commands\",[\"require\",\"exports\",\"module\",\"ace/lib/lang\",\"ace/config\",\"ace/range\"], function(require, exports, module) {\n\"use strict\";\n\nvar lang = require(\"../lib/lang\");\nvar config = require(\"../config\");\nvar Range = require(\"../range\").Range;\n\nfunction bindKey(win, mac) {\n    return {win: win, mac: mac};\n}\nexports.commands = [{\n    name: \"showSettingsMenu\",\n    bindKey: bindKey(\"Ctrl-,\", \"Command-,\"),\n    exec: function(editor) {\n        config.loadModule(\"ace/ext/settings_menu\", function(module) {\n            module.init(editor);\n            editor.showSettingsMenu();\n        });\n    },\n    readOnly: true\n}, {\n    name: \"goToNextError\",\n    bindKey: bindKey(\"Alt-E\", \"F4\"),\n    exec: function(editor) {\n        config.loadModule(\"./ext/error_marker\", function(module) {\n            module.showErrorMarker(editor, 1);\n        });\n    },\n    scrollIntoView: \"animate\",\n    readOnly: true\n}, {\n    name: \"goToPreviousError\",\n    bindKey: bindKey(\"Alt-Shift-E\", \"Shift-F4\"),\n    exec: function(editor) {\n        config.loadModule(\"./ext/error_marker\", function(module) {\n            module.showErrorMarker(editor, -1);\n        });\n    },\n    scrollIntoView: \"animate\",\n    readOnly: true\n}, {\n    name: \"selectall\",\n    description: \"Select all\",\n    bindKey: bindKey(\"Ctrl-A\", \"Command-A\"),\n    exec: function(editor) { editor.selectAll(); },\n    readOnly: true\n}, {\n    name: \"centerselection\",\n    description: \"Center selection\",\n    bindKey: bindKey(null, \"Ctrl-L\"),\n    exec: function(editor) { editor.centerSelection(); },\n    readOnly: true\n}, {\n    name: \"gotoline\",\n    description: \"Go to line...\",\n    bindKey: bindKey(\"Ctrl-L\", \"Command-L\"),\n    exec: function(editor, line) {\n        if (typeof line === \"number\" && !isNaN(line))\n            editor.gotoLine(line);\n        editor.prompt({ $type: \"gotoLine\" });\n    },\n    readOnly: true\n}, {\n    name: \"fold\",\n    bindKey: bindKey(\"Alt-L|Ctrl-F1\", \"Command-Alt-L|Command-F1\"),\n    exec: function(editor) { editor.session.toggleFold(false); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"center\",\n    readOnly: true\n}, {\n    name: \"unfold\",\n    bindKey: bindKey(\"Alt-Shift-L|Ctrl-Shift-F1\", \"Command-Alt-Shift-L|Command-Shift-F1\"),\n    exec: function(editor) { editor.session.toggleFold(true); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"center\",\n    readOnly: true\n}, {\n    name: \"toggleFoldWidget\",\n    bindKey: bindKey(\"F2\", \"F2\"),\n    exec: function(editor) { editor.session.toggleFoldWidget(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"center\",\n    readOnly: true\n}, {\n    name: \"toggleParentFoldWidget\",\n    bindKey: bindKey(\"Alt-F2\", \"Alt-F2\"),\n    exec: function(editor) { editor.session.toggleFoldWidget(true); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"center\",\n    readOnly: true\n}, {\n    name: \"foldall\",\n    description: \"Fold all\",\n    bindKey: bindKey(null, \"Ctrl-Command-Option-0\"),\n    exec: function(editor) { editor.session.foldAll(); },\n    scrollIntoView: \"center\",\n    readOnly: true\n}, {\n    name: \"foldOther\",\n    description: \"Fold other\",\n    bindKey: bindKey(\"Alt-0\", \"Command-Option-0\"),\n    exec: function(editor) { \n        editor.session.foldAll();\n        editor.session.unfold(editor.selection.getAllRanges());\n    },\n    scrollIntoView: \"center\",\n    readOnly: true\n}, {\n    name: \"unfoldall\",\n    description: \"Unfold all\",\n    bindKey: bindKey(\"Alt-Shift-0\", \"Command-Option-Shift-0\"),\n    exec: function(editor) { editor.session.unfold(); },\n    scrollIntoView: \"center\",\n    readOnly: true\n}, {\n    name: \"findnext\",\n    description: \"Find next\",\n    bindKey: bindKey(\"Ctrl-K\", \"Command-G\"),\n    exec: function(editor) { editor.findNext(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"center\",\n    readOnly: true\n}, {\n    name: \"findprevious\",\n    description: \"Find previous\",\n    bindKey: bindKey(\"Ctrl-Shift-K\", \"Command-Shift-G\"),\n    exec: function(editor) { editor.findPrevious(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"center\",\n    readOnly: true\n}, {\n    name: \"selectOrFindNext\",\n    description: \"Select or find next\",\n    bindKey: bindKey(\"Alt-K\", \"Ctrl-G\"),\n    exec: function(editor) {\n        if (editor.selection.isEmpty())\n            editor.selection.selectWord();\n        else\n            editor.findNext(); \n    },\n    readOnly: true\n}, {\n    name: \"selectOrFindPrevious\",\n    description: \"Select or find previous\",\n    bindKey: bindKey(\"Alt-Shift-K\", \"Ctrl-Shift-G\"),\n    exec: function(editor) { \n        if (editor.selection.isEmpty())\n            editor.selection.selectWord();\n        else\n            editor.findPrevious();\n    },\n    readOnly: true\n}, {\n    name: \"find\",\n    description: \"Find\",\n    bindKey: bindKey(\"Ctrl-F\", \"Command-F\"),\n    exec: function(editor) {\n        config.loadModule(\"ace/ext/searchbox\", function(e) {e.Search(editor);});\n    },\n    readOnly: true\n}, {\n    name: \"overwrite\",\n    description: \"Overwrite\",\n    bindKey: \"Insert\",\n    exec: function(editor) { editor.toggleOverwrite(); },\n    readOnly: true\n}, {\n    name: \"selecttostart\",\n    description: \"Select to start\",\n    bindKey: bindKey(\"Ctrl-Shift-Home\", \"Command-Shift-Home|Command-Shift-Up\"),\n    exec: function(editor) { editor.getSelection().selectFileStart(); },\n    multiSelectAction: \"forEach\",\n    readOnly: true,\n    scrollIntoView: \"animate\",\n    aceCommandGroup: \"fileJump\"\n}, {\n    name: \"gotostart\",\n    description: \"Go to start\",\n    bindKey: bindKey(\"Ctrl-Home\", \"Command-Home|Command-Up\"),\n    exec: function(editor) { editor.navigateFileStart(); },\n    multiSelectAction: \"forEach\",\n    readOnly: true,\n    scrollIntoView: \"animate\",\n    aceCommandGroup: \"fileJump\"\n}, {\n    name: \"selectup\",\n    description: \"Select up\",\n    bindKey: bindKey(\"Shift-Up\", \"Shift-Up|Ctrl-Shift-P\"),\n    exec: function(editor) { editor.getSelection().selectUp(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"golineup\",\n    description: \"Go line up\",\n    bindKey: bindKey(\"Up\", \"Up|Ctrl-P\"),\n    exec: function(editor, args) { editor.navigateUp(args.times); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"selecttoend\",\n    description: \"Select to end\",\n    bindKey: bindKey(\"Ctrl-Shift-End\", \"Command-Shift-End|Command-Shift-Down\"),\n    exec: function(editor) { editor.getSelection().selectFileEnd(); },\n    multiSelectAction: \"forEach\",\n    readOnly: true,\n    scrollIntoView: \"animate\",\n    aceCommandGroup: \"fileJump\"\n}, {\n    name: \"gotoend\",\n    description: \"Go to end\",\n    bindKey: bindKey(\"Ctrl-End\", \"Command-End|Command-Down\"),\n    exec: function(editor) { editor.navigateFileEnd(); },\n    multiSelectAction: \"forEach\",\n    readOnly: true,\n    scrollIntoView: \"animate\",\n    aceCommandGroup: \"fileJump\"\n}, {\n    name: \"selectdown\",\n    description: \"Select down\",\n    bindKey: bindKey(\"Shift-Down\", \"Shift-Down|Ctrl-Shift-N\"),\n    exec: function(editor) { editor.getSelection().selectDown(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"golinedown\",\n    description: \"Go line down\",\n    bindKey: bindKey(\"Down\", \"Down|Ctrl-N\"),\n    exec: function(editor, args) { editor.navigateDown(args.times); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"selectwordleft\",\n    description: \"Select word left\",\n    bindKey: bindKey(\"Ctrl-Shift-Left\", \"Option-Shift-Left\"),\n    exec: function(editor) { editor.getSelection().selectWordLeft(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"gotowordleft\",\n    description: \"Go to word left\",\n    bindKey: bindKey(\"Ctrl-Left\", \"Option-Left\"),\n    exec: function(editor) { editor.navigateWordLeft(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"selecttolinestart\",\n    description: \"Select to line start\",\n    bindKey: bindKey(\"Alt-Shift-Left\", \"Command-Shift-Left|Ctrl-Shift-A\"),\n    exec: function(editor) { editor.getSelection().selectLineStart(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"gotolinestart\",\n    description: \"Go to line start\",\n    bindKey: bindKey(\"Alt-Left|Home\", \"Command-Left|Home|Ctrl-A\"),\n    exec: function(editor) { editor.navigateLineStart(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"selectleft\",\n    description: \"Select left\",\n    bindKey: bindKey(\"Shift-Left\", \"Shift-Left|Ctrl-Shift-B\"),\n    exec: function(editor) { editor.getSelection().selectLeft(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"gotoleft\",\n    description: \"Go to left\",\n    bindKey: bindKey(\"Left\", \"Left|Ctrl-B\"),\n    exec: function(editor, args) { editor.navigateLeft(args.times); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"selectwordright\",\n    description: \"Select word right\",\n    bindKey: bindKey(\"Ctrl-Shift-Right\", \"Option-Shift-Right\"),\n    exec: function(editor) { editor.getSelection().selectWordRight(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"gotowordright\",\n    description: \"Go to word right\",\n    bindKey: bindKey(\"Ctrl-Right\", \"Option-Right\"),\n    exec: function(editor) { editor.navigateWordRight(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"selecttolineend\",\n    description: \"Select to line end\",\n    bindKey: bindKey(\"Alt-Shift-Right\", \"Command-Shift-Right|Shift-End|Ctrl-Shift-E\"),\n    exec: function(editor) { editor.getSelection().selectLineEnd(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"gotolineend\",\n    description: \"Go to line end\",\n    bindKey: bindKey(\"Alt-Right|End\", \"Command-Right|End|Ctrl-E\"),\n    exec: function(editor) { editor.navigateLineEnd(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"selectright\",\n    description: \"Select right\",\n    bindKey: bindKey(\"Shift-Right\", \"Shift-Right\"),\n    exec: function(editor) { editor.getSelection().selectRight(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"gotoright\",\n    description: \"Go to right\",\n    bindKey: bindKey(\"Right\", \"Right|Ctrl-F\"),\n    exec: function(editor, args) { editor.navigateRight(args.times); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"selectpagedown\",\n    description: \"Select page down\",\n    bindKey: \"Shift-PageDown\",\n    exec: function(editor) { editor.selectPageDown(); },\n    readOnly: true\n}, {\n    name: \"pagedown\",\n    description: \"Page down\",\n    bindKey: bindKey(null, \"Option-PageDown\"),\n    exec: function(editor) { editor.scrollPageDown(); },\n    readOnly: true\n}, {\n    name: \"gotopagedown\",\n    description: \"Go to page down\",\n    bindKey: bindKey(\"PageDown\", \"PageDown|Ctrl-V\"),\n    exec: function(editor) { editor.gotoPageDown(); },\n    readOnly: true\n}, {\n    name: \"selectpageup\",\n    description: \"Select page up\",\n    bindKey: \"Shift-PageUp\",\n    exec: function(editor) { editor.selectPageUp(); },\n    readOnly: true\n}, {\n    name: \"pageup\",\n    description: \"Page up\",\n    bindKey: bindKey(null, \"Option-PageUp\"),\n    exec: function(editor) { editor.scrollPageUp(); },\n    readOnly: true\n}, {\n    name: \"gotopageup\",\n    description: \"Go to page up\",\n    bindKey: \"PageUp\",\n    exec: function(editor) { editor.gotoPageUp(); },\n    readOnly: true\n}, {\n    name: \"scrollup\",\n    description: \"Scroll up\",\n    bindKey: bindKey(\"Ctrl-Up\", null),\n    exec: function(e) { e.renderer.scrollBy(0, -2 * e.renderer.layerConfig.lineHeight); },\n    readOnly: true\n}, {\n    name: \"scrolldown\",\n    description: \"Scroll down\",\n    bindKey: bindKey(\"Ctrl-Down\", null),\n    exec: function(e) { e.renderer.scrollBy(0, 2 * e.renderer.layerConfig.lineHeight); },\n    readOnly: true\n}, {\n    name: \"selectlinestart\",\n    description: \"Select line start\",\n    bindKey: \"Shift-Home\",\n    exec: function(editor) { editor.getSelection().selectLineStart(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"selectlineend\",\n    description: \"Select line end\",\n    bindKey: \"Shift-End\",\n    exec: function(editor) { editor.getSelection().selectLineEnd(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"togglerecording\",\n    description: \"Toggle recording\",\n    bindKey: bindKey(\"Ctrl-Alt-E\", \"Command-Option-E\"),\n    exec: function(editor) { editor.commands.toggleRecording(editor); },\n    readOnly: true\n}, {\n    name: \"replaymacro\",\n    description: \"Replay macro\",\n    bindKey: bindKey(\"Ctrl-Shift-E\", \"Command-Shift-E\"),\n    exec: function(editor) { editor.commands.replay(editor); },\n    readOnly: true\n}, {\n    name: \"jumptomatching\",\n    description: \"Jump to matching\",\n    bindKey: bindKey(\"Ctrl-\\\\|Ctrl-P\", \"Command-\\\\\"),\n    exec: function(editor) { editor.jumpToMatching(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"animate\",\n    readOnly: true\n}, {\n    name: \"selecttomatching\",\n    description: \"Select to matching\",\n    bindKey: bindKey(\"Ctrl-Shift-\\\\|Ctrl-Shift-P\", \"Command-Shift-\\\\\"),\n    exec: function(editor) { editor.jumpToMatching(true); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"animate\",\n    readOnly: true\n}, {\n    name: \"expandToMatching\",\n    description: \"Expand to matching\",\n    bindKey: bindKey(\"Ctrl-Shift-M\", \"Ctrl-Shift-M\"),\n    exec: function(editor) { editor.jumpToMatching(true, true); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"animate\",\n    readOnly: true\n}, {\n    name: \"passKeysToBrowser\",\n    description: \"Pass keys to browser\",\n    bindKey: bindKey(null, null),\n    exec: function() {},\n    passEvent: true,\n    readOnly: true\n}, {\n    name: \"copy\",\n    description: \"Copy\",\n    exec: function(editor) {\n    },\n    readOnly: true\n},\n{\n    name: \"cut\",\n    description: \"Cut\",\n    exec: function(editor) {\n        var cutLine = editor.$copyWithEmptySelection && editor.selection.isEmpty();\n        var range = cutLine ? editor.selection.getLineRange() : editor.selection.getRange();\n        editor._emit(\"cut\", range);\n\n        if (!range.isEmpty())\n            editor.session.remove(range);\n        editor.clearSelection();\n    },\n    scrollIntoView: \"cursor\",\n    multiSelectAction: \"forEach\"\n}, {\n    name: \"paste\",\n    description: \"Paste\",\n    exec: function(editor, args) {\n        editor.$handlePaste(args);\n    },\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"removeline\",\n    description: \"Remove line\",\n    bindKey: bindKey(\"Ctrl-D\", \"Command-D\"),\n    exec: function(editor) { editor.removeLines(); },\n    scrollIntoView: \"cursor\",\n    multiSelectAction: \"forEachLine\"\n}, {\n    name: \"duplicateSelection\",\n    description: \"Duplicate selection\",\n    bindKey: bindKey(\"Ctrl-Shift-D\", \"Command-Shift-D\"),\n    exec: function(editor) { editor.duplicateSelection(); },\n    scrollIntoView: \"cursor\",\n    multiSelectAction: \"forEach\"\n}, {\n    name: \"sortlines\",\n    description: \"Sort lines\",\n    bindKey: bindKey(\"Ctrl-Alt-S\", \"Command-Alt-S\"),\n    exec: function(editor) { editor.sortLines(); },\n    scrollIntoView: \"selection\",\n    multiSelectAction: \"forEachLine\"\n}, {\n    name: \"togglecomment\",\n    description: \"Toggle comment\",\n    bindKey: bindKey(\"Ctrl-/\", \"Command-/\"),\n    exec: function(editor) { editor.toggleCommentLines(); },\n    multiSelectAction: \"forEachLine\",\n    scrollIntoView: \"selectionPart\"\n}, {\n    name: \"toggleBlockComment\",\n    description: \"Toggle block comment\",\n    bindKey: bindKey(\"Ctrl-Shift-/\", \"Command-Shift-/\"),\n    exec: function(editor) { editor.toggleBlockComment(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"selectionPart\"\n}, {\n    name: \"modifyNumberUp\",\n    description: \"Modify number up\",\n    bindKey: bindKey(\"Ctrl-Shift-Up\", \"Alt-Shift-Up\"),\n    exec: function(editor) { editor.modifyNumber(1); },\n    scrollIntoView: \"cursor\",\n    multiSelectAction: \"forEach\"\n}, {\n    name: \"modifyNumberDown\",\n    description: \"Modify number down\",\n    bindKey: bindKey(\"Ctrl-Shift-Down\", \"Alt-Shift-Down\"),\n    exec: function(editor) { editor.modifyNumber(-1); },\n    scrollIntoView: \"cursor\",\n    multiSelectAction: \"forEach\"\n}, {\n    name: \"replace\",\n    description: \"Replace\",\n    bindKey: bindKey(\"Ctrl-H\", \"Command-Option-F\"),\n    exec: function(editor) {\n        config.loadModule(\"ace/ext/searchbox\", function(e) {e.Search(editor, true);});\n    }\n}, {\n    name: \"undo\",\n    description: \"Undo\",\n    bindKey: bindKey(\"Ctrl-Z\", \"Command-Z\"),\n    exec: function(editor) { editor.undo(); }\n}, {\n    name: \"redo\",\n    description: \"Redo\",\n    bindKey: bindKey(\"Ctrl-Shift-Z|Ctrl-Y\", \"Command-Shift-Z|Command-Y\"),\n    exec: function(editor) { editor.redo(); }\n}, {\n    name: \"copylinesup\",\n    description: \"Copy lines up\",\n    bindKey: bindKey(\"Alt-Shift-Up\", \"Command-Option-Up\"),\n    exec: function(editor) { editor.copyLinesUp(); },\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"movelinesup\",\n    description: \"Move lines up\",\n    bindKey: bindKey(\"Alt-Up\", \"Option-Up\"),\n    exec: function(editor) { editor.moveLinesUp(); },\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"copylinesdown\",\n    description: \"Copy lines down\",\n    bindKey: bindKey(\"Alt-Shift-Down\", \"Command-Option-Down\"),\n    exec: function(editor) { editor.copyLinesDown(); },\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"movelinesdown\",\n    description: \"Move lines down\",\n    bindKey: bindKey(\"Alt-Down\", \"Option-Down\"),\n    exec: function(editor) { editor.moveLinesDown(); },\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"del\",\n    description: \"Delete\",\n    bindKey: bindKey(\"Delete\", \"Delete|Ctrl-D|Shift-Delete\"),\n    exec: function(editor) { editor.remove(\"right\"); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"backspace\",\n    description: \"Backspace\",\n    bindKey: bindKey(\n        \"Shift-Backspace|Backspace\",\n        \"Ctrl-Backspace|Shift-Backspace|Backspace|Ctrl-H\"\n    ),\n    exec: function(editor) { editor.remove(\"left\"); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"cut_or_delete\",\n    description: \"Cut or delete\",\n    bindKey: bindKey(\"Shift-Delete\", null),\n    exec: function(editor) { \n        if (editor.selection.isEmpty()) {\n            editor.remove(\"left\");\n        } else {\n            return false;\n        }\n    },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"removetolinestart\",\n    description: \"Remove to line start\",\n    bindKey: bindKey(\"Alt-Backspace\", \"Command-Backspace\"),\n    exec: function(editor) { editor.removeToLineStart(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"removetolineend\",\n    description: \"Remove to line end\",\n    bindKey: bindKey(\"Alt-Delete\", \"Ctrl-K|Command-Delete\"),\n    exec: function(editor) { editor.removeToLineEnd(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"removetolinestarthard\",\n    description: \"Remove to line start hard\",\n    bindKey: bindKey(\"Ctrl-Shift-Backspace\", null),\n    exec: function(editor) {\n        var range = editor.selection.getRange();\n        range.start.column = 0;\n        editor.session.remove(range);\n    },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"removetolineendhard\",\n    description: \"Remove to line end hard\",\n    bindKey: bindKey(\"Ctrl-Shift-Delete\", null),\n    exec: function(editor) {\n        var range = editor.selection.getRange();\n        range.end.column = Number.MAX_VALUE;\n        editor.session.remove(range);\n    },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"removewordleft\",\n    description: \"Remove word left\",\n    bindKey: bindKey(\"Ctrl-Backspace\", \"Alt-Backspace|Ctrl-Alt-Backspace\"),\n    exec: function(editor) { editor.removeWordLeft(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"removewordright\",\n    description: \"Remove word right\",\n    bindKey: bindKey(\"Ctrl-Delete\", \"Alt-Delete\"),\n    exec: function(editor) { editor.removeWordRight(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"outdent\",\n    description: \"Outdent\",\n    bindKey: bindKey(\"Shift-Tab\", \"Shift-Tab\"),\n    exec: function(editor) { editor.blockOutdent(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"selectionPart\"\n}, {\n    name: \"indent\",\n    description: \"Indent\",\n    bindKey: bindKey(\"Tab\", \"Tab\"),\n    exec: function(editor) { editor.indent(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"selectionPart\"\n}, {\n    name: \"blockoutdent\",\n    description: \"Block outdent\",\n    bindKey: bindKey(\"Ctrl-[\", \"Ctrl-[\"),\n    exec: function(editor) { editor.blockOutdent(); },\n    multiSelectAction: \"forEachLine\",\n    scrollIntoView: \"selectionPart\"\n}, {\n    name: \"blockindent\",\n    description: \"Block indent\",\n    bindKey: bindKey(\"Ctrl-]\", \"Ctrl-]\"),\n    exec: function(editor) { editor.blockIndent(); },\n    multiSelectAction: \"forEachLine\",\n    scrollIntoView: \"selectionPart\"\n}, {\n    name: \"insertstring\",\n    description: \"Insert string\",\n    exec: function(editor, str) { editor.insert(str); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"inserttext\",\n    description: \"Insert text\",\n    exec: function(editor, args) {\n        editor.insert(lang.stringRepeat(args.text  || \"\", args.times || 1));\n    },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"splitline\",\n    description: \"Split line\",\n    bindKey: bindKey(null, \"Ctrl-O\"),\n    exec: function(editor) { editor.splitLine(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"transposeletters\",\n    description: \"Transpose letters\",\n    bindKey: bindKey(\"Alt-Shift-X\", \"Ctrl-T\"),\n    exec: function(editor) { editor.transposeLetters(); },\n    multiSelectAction: function(editor) {editor.transposeSelections(1); },\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"touppercase\",\n    description: \"To uppercase\",\n    bindKey: bindKey(\"Ctrl-U\", \"Ctrl-U\"),\n    exec: function(editor) { editor.toUpperCase(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"tolowercase\",\n    description: \"To lowercase\",\n    bindKey: bindKey(\"Ctrl-Shift-U\", \"Ctrl-Shift-U\"),\n    exec: function(editor) { editor.toLowerCase(); },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"expandtoline\",\n    description: \"Expand to line\",\n    bindKey: bindKey(\"Ctrl-Shift-L\", \"Command-Shift-L\"),\n    exec: function(editor) {\n        var range = editor.selection.getRange();\n\n        range.start.column = range.end.column = 0;\n        range.end.row++;\n        editor.selection.setRange(range, false);\n    },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"joinlines\",\n    description: \"Join lines\",\n    bindKey: bindKey(null, null),\n    exec: function(editor) {\n        var isBackwards = editor.selection.isBackwards();\n        var selectionStart = isBackwards ? editor.selection.getSelectionLead() : editor.selection.getSelectionAnchor();\n        var selectionEnd = isBackwards ? editor.selection.getSelectionAnchor() : editor.selection.getSelectionLead();\n        var firstLineEndCol = editor.session.doc.getLine(selectionStart.row).length;\n        var selectedText = editor.session.doc.getTextRange(editor.selection.getRange());\n        var selectedCount = selectedText.replace(/\\n\\s*/, \" \").length;\n        var insertLine = editor.session.doc.getLine(selectionStart.row);\n\n        for (var i = selectionStart.row + 1; i <= selectionEnd.row + 1; i++) {\n            var curLine = lang.stringTrimLeft(lang.stringTrimRight(editor.session.doc.getLine(i)));\n            if (curLine.length !== 0) {\n                curLine = \" \" + curLine;\n            }\n            insertLine += curLine;\n        }\n\n        if (selectionEnd.row + 1 < (editor.session.doc.getLength() - 1)) {\n            insertLine += editor.session.doc.getNewLineCharacter();\n        }\n\n        editor.clearSelection();\n        editor.session.doc.replace(new Range(selectionStart.row, 0, selectionEnd.row + 2, 0), insertLine);\n\n        if (selectedCount > 0) {\n            editor.selection.moveCursorTo(selectionStart.row, selectionStart.column);\n            editor.selection.selectTo(selectionStart.row, selectionStart.column + selectedCount);\n        } else {\n            firstLineEndCol = editor.session.doc.getLine(selectionStart.row).length > firstLineEndCol ? (firstLineEndCol + 1) : firstLineEndCol;\n            editor.selection.moveCursorTo(selectionStart.row, firstLineEndCol);\n        }\n    },\n    multiSelectAction: \"forEach\",\n    readOnly: true\n}, {\n    name: \"invertSelection\",\n    description: \"Invert selection\",\n    bindKey: bindKey(null, null),\n    exec: function(editor) {\n        var endRow = editor.session.doc.getLength() - 1;\n        var endCol = editor.session.doc.getLine(endRow).length;\n        var ranges = editor.selection.rangeList.ranges;\n        var newRanges = [];\n        if (ranges.length < 1) {\n            ranges = [editor.selection.getRange()];\n        }\n\n        for (var i = 0; i < ranges.length; i++) {\n            if (i == (ranges.length - 1)) {\n                if (!(ranges[i].end.row === endRow && ranges[i].end.column === endCol)) {\n                    newRanges.push(new Range(ranges[i].end.row, ranges[i].end.column, endRow, endCol));\n                }\n            }\n\n            if (i === 0) {\n                if (!(ranges[i].start.row === 0 && ranges[i].start.column === 0)) {\n                    newRanges.push(new Range(0, 0, ranges[i].start.row, ranges[i].start.column));\n                }\n            } else {\n                newRanges.push(new Range(ranges[i-1].end.row, ranges[i-1].end.column, ranges[i].start.row, ranges[i].start.column));\n            }\n        }\n\n        editor.exitMultiSelectMode();\n        editor.clearSelection();\n\n        for(var i = 0; i < newRanges.length; i++) {\n            editor.selection.addRange(newRanges[i], false);\n        }\n    },\n    readOnly: true,\n    scrollIntoView: \"none\"\n}, {\n    name: \"addLineAfter\",\n    exec: function(editor) {\n        editor.selection.clearSelection();\n        editor.navigateLineEnd();\n        editor.insert(\"\\n\");\n    },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"addLineBefore\",\n    exec: function(editor) {\n        editor.selection.clearSelection();\n        var cursor = editor.getCursorPosition();\n        editor.selection.moveTo(cursor.row - 1, Number.MAX_VALUE);\n        editor.insert(\"\\n\");\n        if (cursor.row === 0) editor.navigateUp();\n    },\n    multiSelectAction: \"forEach\",\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"openCommandPallete\",\n    description: \"Open command pallete\",\n    bindKey: bindKey(\"F1\", \"F1\"),\n    exec: function(editor) {\n        editor.prompt({ $type: \"commands\" });\n    },\n    readOnly: true\n}, {\n    name: \"modeSelect\",\n    description: \"Change language mode...\",\n    bindKey: bindKey(null, null),\n    exec: function(editor) {\n        editor.prompt({ $type: \"modes\" });\n    },\n    readOnly: true\n}];\n\n});\n\nace.define(\"ace/editor\",[\"require\",\"exports\",\"module\",\"ace/lib/fixoldbrowsers\",\"ace/lib/oop\",\"ace/lib/dom\",\"ace/lib/lang\",\"ace/lib/useragent\",\"ace/keyboard/textinput\",\"ace/mouse/mouse_handler\",\"ace/mouse/fold_handler\",\"ace/keyboard/keybinding\",\"ace/edit_session\",\"ace/search\",\"ace/range\",\"ace/lib/event_emitter\",\"ace/commands/command_manager\",\"ace/commands/default_commands\",\"ace/config\",\"ace/token_iterator\",\"ace/clipboard\"], function(require, exports, module) {\n\"use strict\";\n\nrequire(\"./lib/fixoldbrowsers\");\n\nvar oop = require(\"./lib/oop\");\nvar dom = require(\"./lib/dom\");\nvar lang = require(\"./lib/lang\");\nvar useragent = require(\"./lib/useragent\");\nvar TextInput = require(\"./keyboard/textinput\").TextInput;\nvar MouseHandler = require(\"./mouse/mouse_handler\").MouseHandler;\nvar FoldHandler = require(\"./mouse/fold_handler\").FoldHandler;\nvar KeyBinding = require(\"./keyboard/keybinding\").KeyBinding;\nvar EditSession = require(\"./edit_session\").EditSession;\nvar Search = require(\"./search\").Search;\nvar Range = require(\"./range\").Range;\nvar EventEmitter = require(\"./lib/event_emitter\").EventEmitter;\nvar CommandManager = require(\"./commands/command_manager\").CommandManager;\nvar defaultCommands = require(\"./commands/default_commands\").commands;\nvar config = require(\"./config\");\nvar TokenIterator = require(\"./token_iterator\").TokenIterator;\n\nvar clipboard = require(\"./clipboard\");\nvar Editor = function(renderer, session, options) {\n    var container = renderer.getContainerElement();\n    this.container = container;\n    this.renderer = renderer;\n    this.id = \"editor\" + (++Editor.$uid);\n\n    this.commands = new CommandManager(useragent.isMac ? \"mac\" : \"win\", defaultCommands);\n    if (typeof document == \"object\") {\n        this.textInput = new TextInput(renderer.getTextAreaContainer(), this);\n        this.renderer.textarea = this.textInput.getElement();\n        this.$mouseHandler = new MouseHandler(this);\n        new FoldHandler(this);\n    }\n\n    this.keyBinding = new KeyBinding(this);\n\n    this.$search = new Search().set({\n        wrap: true\n    });\n\n    this.$historyTracker = this.$historyTracker.bind(this);\n    this.commands.on(\"exec\", this.$historyTracker);\n\n    this.$initOperationListeners();\n    \n    this._$emitInputEvent = lang.delayedCall(function() {\n        this._signal(\"input\", {});\n        if (this.session && this.session.bgTokenizer)\n            this.session.bgTokenizer.scheduleStart();\n    }.bind(this));\n    \n    this.on(\"change\", function(_, _self) {\n        _self._$emitInputEvent.schedule(31);\n    });\n\n    this.setSession(session || options && options.session || new EditSession(\"\"));\n    config.resetOptions(this);\n    if (options)\n        this.setOptions(options);\n    config._signal(\"editor\", this);\n};\n\nEditor.$uid = 0;\n\n(function(){\n\n    oop.implement(this, EventEmitter);\n\n    this.$initOperationListeners = function() {\n        this.commands.on(\"exec\", this.startOperation.bind(this), true);\n        this.commands.on(\"afterExec\", this.endOperation.bind(this), true);\n\n        this.$opResetTimer = lang.delayedCall(this.endOperation.bind(this, true));\n        this.on(\"change\", function() {\n            if (!this.curOp) {\n                this.startOperation();\n                this.curOp.selectionBefore = this.$lastSel;\n            }\n            this.curOp.docChanged = true;\n        }.bind(this), true);\n        \n        this.on(\"changeSelection\", function() {\n            if (!this.curOp) {\n                this.startOperation();\n                this.curOp.selectionBefore = this.$lastSel;\n            }\n            this.curOp.selectionChanged = true;\n        }.bind(this), true);\n    };\n\n    this.curOp = null;\n    this.prevOp = {};\n    this.startOperation = function(commandEvent) {\n        if (this.curOp) {\n            if (!commandEvent || this.curOp.command)\n                return;\n            this.prevOp = this.curOp;\n        }\n        if (!commandEvent) {\n            this.previousCommand = null;\n            commandEvent = {};\n        }\n\n        this.$opResetTimer.schedule();\n        this.curOp = this.session.curOp = {\n            command: commandEvent.command || {},\n            args: commandEvent.args,\n            scrollTop: this.renderer.scrollTop\n        };\n        this.curOp.selectionBefore = this.selection.toJSON();\n    };\n\n    this.endOperation = function(e) {\n        if (this.curOp) {\n            if (e && e.returnValue === false)\n                return (this.curOp = null);\n            if (e == true && this.curOp.command && this.curOp.command.name == \"mouse\")\n                return;\n            this._signal(\"beforeEndOperation\");\n            if (!this.curOp) return;\n            var command = this.curOp.command;\n            var scrollIntoView = command && command.scrollIntoView;\n            if (scrollIntoView) {\n                switch (scrollIntoView) {\n                    case \"center-animate\":\n                        scrollIntoView = \"animate\";\n                    case \"center\":\n                        this.renderer.scrollCursorIntoView(null, 0.5);\n                        break;\n                    case \"animate\":\n                    case \"cursor\":\n                        this.renderer.scrollCursorIntoView();\n                        break;\n                    case \"selectionPart\":\n                        var range = this.selection.getRange();\n                        var config = this.renderer.layerConfig;\n                        if (range.start.row >= config.lastRow || range.end.row <= config.firstRow) {\n                            this.renderer.scrollSelectionIntoView(this.selection.anchor, this.selection.lead);\n                        }\n                        break;\n                    default:\n                        break;\n                }\n                if (scrollIntoView == \"animate\")\n                    this.renderer.animateScrolling(this.curOp.scrollTop);\n            }\n            var sel = this.selection.toJSON();\n            this.curOp.selectionAfter = sel;\n            this.$lastSel = this.selection.toJSON();\n            this.session.getUndoManager().addSelection(sel);\n            this.prevOp = this.curOp;\n            this.curOp = null;\n        }\n    };\n    this.$mergeableCommands = [\"backspace\", \"del\", \"insertstring\"];\n    this.$historyTracker = function(e) {\n        if (!this.$mergeUndoDeltas)\n            return;\n\n        var prev = this.prevOp;\n        var mergeableCommands = this.$mergeableCommands;\n        var shouldMerge = prev.command && (e.command.name == prev.command.name);\n        if (e.command.name == \"insertstring\") {\n            var text = e.args;\n            if (this.mergeNextCommand === undefined)\n                this.mergeNextCommand = true;\n\n            shouldMerge = shouldMerge\n                && this.mergeNextCommand // previous command allows to coalesce with\n                && (!/\\s/.test(text) || /\\s/.test(prev.args)); // previous insertion was of same type\n\n            this.mergeNextCommand = true;\n        } else {\n            shouldMerge = shouldMerge\n                && mergeableCommands.indexOf(e.command.name) !== -1; // the command is mergeable\n        }\n\n        if (\n            this.$mergeUndoDeltas != \"always\"\n            && Date.now() - this.sequenceStartTime > 2000\n        ) {\n            shouldMerge = false; // the sequence is too long\n        }\n\n        if (shouldMerge)\n            this.session.mergeUndoDeltas = true;\n        else if (mergeableCommands.indexOf(e.command.name) !== -1)\n            this.sequenceStartTime = Date.now();\n    };\n    this.setKeyboardHandler = function(keyboardHandler, cb) {\n        if (keyboardHandler && typeof keyboardHandler === \"string\" && keyboardHandler != \"ace\") {\n            this.$keybindingId = keyboardHandler;\n            var _self = this;\n            config.loadModule([\"keybinding\", keyboardHandler], function(module) {\n                if (_self.$keybindingId == keyboardHandler)\n                    _self.keyBinding.setKeyboardHandler(module && module.handler);\n                cb && cb();\n            });\n        } else {\n            this.$keybindingId = null;\n            this.keyBinding.setKeyboardHandler(keyboardHandler);\n            cb && cb();\n        }\n    };\n    this.getKeyboardHandler = function() {\n        return this.keyBinding.getKeyboardHandler();\n    };\n    this.setSession = function(session) {\n        if (this.session == session)\n            return;\n        if (this.curOp) this.endOperation();\n        this.curOp = {};\n\n        var oldSession = this.session;\n        if (oldSession) {\n            this.session.off(\"change\", this.$onDocumentChange);\n            this.session.off(\"changeMode\", this.$onChangeMode);\n            this.session.off(\"tokenizerUpdate\", this.$onTokenizerUpdate);\n            this.session.off(\"changeTabSize\", this.$onChangeTabSize);\n            this.session.off(\"changeWrapLimit\", this.$onChangeWrapLimit);\n            this.session.off(\"changeWrapMode\", this.$onChangeWrapMode);\n            this.session.off(\"changeFold\", this.$onChangeFold);\n            this.session.off(\"changeFrontMarker\", this.$onChangeFrontMarker);\n            this.session.off(\"changeBackMarker\", this.$onChangeBackMarker);\n            this.session.off(\"changeBreakpoint\", this.$onChangeBreakpoint);\n            this.session.off(\"changeAnnotation\", this.$onChangeAnnotation);\n            this.session.off(\"changeOverwrite\", this.$onCursorChange);\n            this.session.off(\"changeScrollTop\", this.$onScrollTopChange);\n            this.session.off(\"changeScrollLeft\", this.$onScrollLeftChange);\n\n            var selection = this.session.getSelection();\n            selection.off(\"changeCursor\", this.$onCursorChange);\n            selection.off(\"changeSelection\", this.$onSelectionChange);\n        }\n\n        this.session = session;\n        if (session) {\n            this.$onDocumentChange = this.onDocumentChange.bind(this);\n            session.on(\"change\", this.$onDocumentChange);\n            this.renderer.setSession(session);\n    \n            this.$onChangeMode = this.onChangeMode.bind(this);\n            session.on(\"changeMode\", this.$onChangeMode);\n    \n            this.$onTokenizerUpdate = this.onTokenizerUpdate.bind(this);\n            session.on(\"tokenizerUpdate\", this.$onTokenizerUpdate);\n    \n            this.$onChangeTabSize = this.renderer.onChangeTabSize.bind(this.renderer);\n            session.on(\"changeTabSize\", this.$onChangeTabSize);\n    \n            this.$onChangeWrapLimit = this.onChangeWrapLimit.bind(this);\n            session.on(\"changeWrapLimit\", this.$onChangeWrapLimit);\n    \n            this.$onChangeWrapMode = this.onChangeWrapMode.bind(this);\n            session.on(\"changeWrapMode\", this.$onChangeWrapMode);\n    \n            this.$onChangeFold = this.onChangeFold.bind(this);\n            session.on(\"changeFold\", this.$onChangeFold);\n    \n            this.$onChangeFrontMarker = this.onChangeFrontMarker.bind(this);\n            this.session.on(\"changeFrontMarker\", this.$onChangeFrontMarker);\n    \n            this.$onChangeBackMarker = this.onChangeBackMarker.bind(this);\n            this.session.on(\"changeBackMarker\", this.$onChangeBackMarker);\n    \n            this.$onChangeBreakpoint = this.onChangeBreakpoint.bind(this);\n            this.session.on(\"changeBreakpoint\", this.$onChangeBreakpoint);\n    \n            this.$onChangeAnnotation = this.onChangeAnnotation.bind(this);\n            this.session.on(\"changeAnnotation\", this.$onChangeAnnotation);\n    \n            this.$onCursorChange = this.onCursorChange.bind(this);\n            this.session.on(\"changeOverwrite\", this.$onCursorChange);\n    \n            this.$onScrollTopChange = this.onScrollTopChange.bind(this);\n            this.session.on(\"changeScrollTop\", this.$onScrollTopChange);\n    \n            this.$onScrollLeftChange = this.onScrollLeftChange.bind(this);\n            this.session.on(\"changeScrollLeft\", this.$onScrollLeftChange);\n    \n            this.selection = session.getSelection();\n            this.selection.on(\"changeCursor\", this.$onCursorChange);\n    \n            this.$onSelectionChange = this.onSelectionChange.bind(this);\n            this.selection.on(\"changeSelection\", this.$onSelectionChange);\n    \n            this.onChangeMode();\n    \n            this.onCursorChange();\n    \n            this.onScrollTopChange();\n            this.onScrollLeftChange();\n            this.onSelectionChange();\n            this.onChangeFrontMarker();\n            this.onChangeBackMarker();\n            this.onChangeBreakpoint();\n            this.onChangeAnnotation();\n            this.session.getUseWrapMode() && this.renderer.adjustWrapLimit();\n            this.renderer.updateFull();\n        } else {\n            this.selection = null;\n            this.renderer.setSession(session);\n        }\n\n        this._signal(\"changeSession\", {\n            session: session,\n            oldSession: oldSession\n        });\n        \n        this.curOp = null;\n        \n        oldSession && oldSession._signal(\"changeEditor\", {oldEditor: this});\n        session && session._signal(\"changeEditor\", {editor: this});\n        \n        if (session && session.bgTokenizer)\n            session.bgTokenizer.scheduleStart();\n    };\n    this.getSession = function() {\n        return this.session;\n    };\n    this.setValue = function(val, cursorPos) {\n        this.session.doc.setValue(val);\n\n        if (!cursorPos)\n            this.selectAll();\n        else if (cursorPos == 1)\n            this.navigateFileEnd();\n        else if (cursorPos == -1)\n            this.navigateFileStart();\n\n        return val;\n    };\n    this.getValue = function() {\n        return this.session.getValue();\n    };\n    this.getSelection = function() {\n        return this.selection;\n    };\n    this.resize = function(force) {\n        this.renderer.onResize(force);\n    };\n    this.setTheme = function(theme, cb) {\n        this.renderer.setTheme(theme, cb);\n    };\n    this.getTheme = function() {\n        return this.renderer.getTheme();\n    };\n    this.setStyle = function(style) {\n        this.renderer.setStyle(style);\n    };\n    this.unsetStyle = function(style) {\n        this.renderer.unsetStyle(style);\n    };\n    this.getFontSize = function () {\n        return this.getOption(\"fontSize\") ||\n           dom.computedStyle(this.container).fontSize;\n    };\n    this.setFontSize = function(size) {\n        this.setOption(\"fontSize\", size);\n    };\n\n    this.$highlightBrackets = function() {\n        if (this.$highlightPending) {\n            return;\n        }\n        var self = this;\n        this.$highlightPending = true;\n        setTimeout(function () {\n            self.$highlightPending = false;\n            var session = self.session;\n            if (!session || !session.bgTokenizer) return;\n            if (session.$bracketHighlight) {\n                session.$bracketHighlight.markerIds.forEach(function(id) {\n                    session.removeMarker(id);\n                });\n                session.$bracketHighlight = null;\n            }\n            var ranges = session.getMatchingBracketRanges(self.getCursorPosition());\n            if (!ranges && session.$mode.getMatching) \n                ranges = session.$mode.getMatching(self.session);\n            if (!ranges)\n                return;\n\n            var markerType = \"ace_bracket\";\n            if (!Array.isArray(ranges)) {\n                ranges = [ranges];\n            } else if (ranges.length == 1) {\n                markerType = \"ace_error_bracket\";\n            }\n            if (ranges.length == 2) {\n                if (Range.comparePoints(ranges[0].end, ranges[1].start) == 0)\n                    ranges = [Range.fromPoints(ranges[0].start, ranges[1].end)];\n                else if (Range.comparePoints(ranges[0].start, ranges[1].end) == 0)\n                    ranges = [Range.fromPoints(ranges[1].start, ranges[0].end)];\n            }\n\n            session.$bracketHighlight = {\n                ranges: ranges,\n                markerIds: ranges.map(function(range) {\n                    return session.addMarker(range, markerType, \"text\");\n                })\n            };\n        }, 50);\n    };\n    this.$highlightTags = function() {\n        if (this.$highlightTagPending)\n            return;\n        var self = this;\n        this.$highlightTagPending = true;\n        setTimeout(function() {\n            self.$highlightTagPending = false;\n            \n            var session = self.session;\n            if (!session || !session.bgTokenizer) return;\n            \n            var pos = self.getCursorPosition();\n            var iterator = new TokenIterator(self.session, pos.row, pos.column);\n            var token = iterator.getCurrentToken();\n            \n            if (!token || !/\\b(?:tag-open|tag-name)/.test(token.type)) {\n                session.removeMarker(session.$tagHighlight);\n                session.$tagHighlight = null;\n                return;\n            }\n            \n            if (token.type.indexOf(\"tag-open\") != -1) {\n                token = iterator.stepForward();\n                if (!token)\n                    return;\n            }\n            \n            var tag = token.value;\n            var depth = 0;\n            var prevToken = iterator.stepBackward();\n            \n            if (prevToken.value == '<'){\n                do {\n                    prevToken = token;\n                    token = iterator.stepForward();\n                    \n                    if (token && token.value === tag && token.type.indexOf('tag-name') !== -1) {\n                        if (prevToken.value === '<'){\n                            depth++;\n                        } else if (prevToken.value === '</'){\n                            depth--;\n                        }\n                    }\n                    \n                } while (token && depth >= 0);\n            } else {\n                do {\n                    token = prevToken;\n                    prevToken = iterator.stepBackward();\n                    \n                    if (token && token.value === tag && token.type.indexOf('tag-name') !== -1) {\n                        if (prevToken.value === '<') {\n                            depth++;\n                        } else if (prevToken.value === '</') {\n                            depth--;\n                        }\n                    }\n                } while (prevToken && depth <= 0);\n                iterator.stepForward();\n            }\n            \n            if (!token) {\n                session.removeMarker(session.$tagHighlight);\n                session.$tagHighlight = null;\n                return;\n            }\n            \n            var row = iterator.getCurrentTokenRow();\n            var column = iterator.getCurrentTokenColumn();\n            var range = new Range(row, column, row, column+token.value.length);\n            var sbm = session.$backMarkers[session.$tagHighlight];\n            if (session.$tagHighlight && sbm != undefined && range.compareRange(sbm.range) !== 0) {\n                session.removeMarker(session.$tagHighlight);\n                session.$tagHighlight = null;\n            }\n            \n            if (!session.$tagHighlight)\n                session.$tagHighlight = session.addMarker(range, \"ace_bracket\", \"text\");\n        }, 50);\n    };\n    this.focus = function() {\n        var _self = this;\n        setTimeout(function() {\n            if (!_self.isFocused())\n                _self.textInput.focus();\n        });\n        this.textInput.focus();\n    };\n    this.isFocused = function() {\n        return this.textInput.isFocused();\n    };\n    this.blur = function() {\n        this.textInput.blur();\n    };\n    this.onFocus = function(e) {\n        if (this.$isFocused)\n            return;\n        this.$isFocused = true;\n        this.renderer.showCursor();\n        this.renderer.visualizeFocus();\n        this._emit(\"focus\", e);\n    };\n    this.onBlur = function(e) {\n        if (!this.$isFocused)\n            return;\n        this.$isFocused = false;\n        this.renderer.hideCursor();\n        this.renderer.visualizeBlur();\n        this._emit(\"blur\", e);\n    };\n\n    this.$cursorChange = function() {\n        this.renderer.updateCursor();\n    };\n    this.onDocumentChange = function(delta) {\n        var wrap = this.session.$useWrapMode;\n        var lastRow = (delta.start.row == delta.end.row ? delta.end.row : Infinity);\n        this.renderer.updateLines(delta.start.row, lastRow, wrap);\n\n        this._signal(\"change\", delta);\n        this.$cursorChange();\n        this.$updateHighlightActiveLine();\n    };\n\n    this.onTokenizerUpdate = function(e) {\n        var rows = e.data;\n        this.renderer.updateLines(rows.first, rows.last);\n    };\n\n\n    this.onScrollTopChange = function() {\n        this.renderer.scrollToY(this.session.getScrollTop());\n    };\n\n    this.onScrollLeftChange = function() {\n        this.renderer.scrollToX(this.session.getScrollLeft());\n    };\n    this.onCursorChange = function() {\n        this.$cursorChange();\n\n        this.$highlightBrackets();\n        this.$highlightTags();\n        this.$updateHighlightActiveLine();\n        this._signal(\"changeSelection\");\n    };\n\n    this.$updateHighlightActiveLine = function() {\n        var session = this.getSession();\n\n        var highlight;\n        if (this.$highlightActiveLine) {\n            if (this.$selectionStyle != \"line\" || !this.selection.isMultiLine())\n                highlight = this.getCursorPosition();\n            if (this.renderer.theme && this.renderer.theme.$selectionColorConflict && !this.selection.isEmpty())\n                highlight = false;\n            if (this.renderer.$maxLines && this.session.getLength() === 1 && !(this.renderer.$minLines > 1))\n                highlight = false;\n        }\n\n        if (session.$highlightLineMarker && !highlight) {\n            session.removeMarker(session.$highlightLineMarker.id);\n            session.$highlightLineMarker = null;\n        } else if (!session.$highlightLineMarker && highlight) {\n            var range = new Range(highlight.row, highlight.column, highlight.row, Infinity);\n            range.id = session.addMarker(range, \"ace_active-line\", \"screenLine\");\n            session.$highlightLineMarker = range;\n        } else if (highlight) {\n            session.$highlightLineMarker.start.row = highlight.row;\n            session.$highlightLineMarker.end.row = highlight.row;\n            session.$highlightLineMarker.start.column = highlight.column;\n            session._signal(\"changeBackMarker\");\n        }\n    };\n\n    this.onSelectionChange = function(e) {\n        var session = this.session;\n\n        if (session.$selectionMarker) {\n            session.removeMarker(session.$selectionMarker);\n        }\n        session.$selectionMarker = null;\n\n        if (!this.selection.isEmpty()) {\n            var range = this.selection.getRange();\n            var style = this.getSelectionStyle();\n            session.$selectionMarker = session.addMarker(range, \"ace_selection\", style);\n        } else {\n            this.$updateHighlightActiveLine();\n        }\n\n        var re = this.$highlightSelectedWord && this.$getSelectionHighLightRegexp();\n        this.session.highlight(re);\n\n        this._signal(\"changeSelection\");\n    };\n\n    this.$getSelectionHighLightRegexp = function() {\n        var session = this.session;\n\n        var selection = this.getSelectionRange();\n        if (selection.isEmpty() || selection.isMultiLine())\n            return;\n\n        var startColumn = selection.start.column;\n        var endColumn = selection.end.column;\n        var line = session.getLine(selection.start.row);\n        \n        var needle = line.substring(startColumn, endColumn);\n        if (needle.length > 5000 || !/[\\w\\d]/.test(needle))\n            return;\n\n        var re = this.$search.$assembleRegExp({\n            wholeWord: true,\n            caseSensitive: true,\n            needle: needle\n        });\n        \n        var wordWithBoundary = line.substring(startColumn - 1, endColumn + 1);\n        if (!re.test(wordWithBoundary))\n            return;\n        \n        return re;\n    };\n\n\n    this.onChangeFrontMarker = function() {\n        this.renderer.updateFrontMarkers();\n    };\n\n    this.onChangeBackMarker = function() {\n        this.renderer.updateBackMarkers();\n    };\n\n\n    this.onChangeBreakpoint = function() {\n        this.renderer.updateBreakpoints();\n    };\n\n    this.onChangeAnnotation = function() {\n        this.renderer.setAnnotations(this.session.getAnnotations());\n    };\n\n\n    this.onChangeMode = function(e) {\n        this.renderer.updateText();\n        this._emit(\"changeMode\", e);\n    };\n\n\n    this.onChangeWrapLimit = function() {\n        this.renderer.updateFull();\n    };\n\n    this.onChangeWrapMode = function() {\n        this.renderer.onResize(true);\n    };\n\n\n    this.onChangeFold = function() {\n        this.$updateHighlightActiveLine();\n        this.renderer.updateFull();\n    };\n    this.getSelectedText = function() {\n        return this.session.getTextRange(this.getSelectionRange());\n    };\n    this.getCopyText = function() {\n        var text = this.getSelectedText();\n        var nl = this.session.doc.getNewLineCharacter();\n        var copyLine= false;\n        if (!text && this.$copyWithEmptySelection) {\n            copyLine = true;\n            var ranges = this.selection.getAllRanges();\n            for (var i = 0; i < ranges.length; i++) {\n                var range = ranges[i];\n                if (i && ranges[i - 1].start.row == range.start.row)\n                    continue;\n                text += this.session.getLine(range.start.row) + nl;\n            }\n        }\n        var e = {text: text};\n        this._signal(\"copy\", e);\n        clipboard.lineMode = copyLine ? e.text : \"\";\n        return e.text;\n    };\n    this.onCopy = function() {\n        this.commands.exec(\"copy\", this);\n    };\n    this.onCut = function() {\n        this.commands.exec(\"cut\", this);\n    };\n    this.onPaste = function(text, event) {\n        var e = {text: text, event: event};\n        this.commands.exec(\"paste\", this, e);\n    };\n    \n    this.$handlePaste = function(e) {\n        if (typeof e == \"string\") \n            e = {text: e};\n        this._signal(\"paste\", e);\n        var text = e.text;\n\n        var lineMode = text == clipboard.lineMode;\n        var session = this.session;\n        if (!this.inMultiSelectMode || this.inVirtualSelectionMode) {\n            if (lineMode)\n                session.insert({ row: this.selection.lead.row, column: 0 }, text);\n            else\n                this.insert(text);\n        } else if (lineMode) {\n            this.selection.rangeList.ranges.forEach(function(range) {\n                session.insert({ row: range.start.row, column: 0 }, text);\n            });\n        } else {\n            var lines = text.split(/\\r\\n|\\r|\\n/);\n            var ranges = this.selection.rangeList.ranges;\n    \n            var isFullLine = lines.length == 2 && (!lines[0] || !lines[1]);\n            if (lines.length != ranges.length || isFullLine)\n                return this.commands.exec(\"insertstring\", this, text);\n    \n            for (var i = ranges.length; i--;) {\n                var range = ranges[i];\n                if (!range.isEmpty())\n                    session.remove(range);\n    \n                session.insert(range.start, lines[i]);\n            }\n        }\n    };\n\n    this.execCommand = function(command, args) {\n        return this.commands.exec(command, this, args);\n    };\n    this.insert = function(text, pasted) {\n        var session = this.session;\n        var mode = session.getMode();\n        var cursor = this.getCursorPosition();\n\n        if (this.getBehavioursEnabled() && !pasted) {\n            var transform = mode.transformAction(session.getState(cursor.row), 'insertion', this, session, text);\n            if (transform) {\n                if (text !== transform.text) {\n                    if (!this.inVirtualSelectionMode) {\n                        this.session.mergeUndoDeltas = false;\n                        this.mergeNextCommand = false;\n                    }\n                }\n                text = transform.text;\n\n            }\n        }\n        \n        if (text == \"\\t\")\n            text = this.session.getTabString();\n        if (!this.selection.isEmpty()) {\n            var range = this.getSelectionRange();\n            cursor = this.session.remove(range);\n            this.clearSelection();\n        }\n        else if (this.session.getOverwrite() && text.indexOf(\"\\n\") == -1) {\n            var range = new Range.fromPoints(cursor, cursor);\n            range.end.column += text.length;\n            this.session.remove(range);\n        }\n\n        if (text == \"\\n\" || text == \"\\r\\n\") {\n            var line = session.getLine(cursor.row);\n            if (cursor.column > line.search(/\\S|$/)) {\n                var d = line.substr(cursor.column).search(/\\S|$/);\n                session.doc.removeInLine(cursor.row, cursor.column, cursor.column + d);\n            }\n        }\n        this.clearSelection();\n\n        var start = cursor.column;\n        var lineState = session.getState(cursor.row);\n        var line = session.getLine(cursor.row);\n        var shouldOutdent = mode.checkOutdent(lineState, line, text);\n        session.insert(cursor, text);\n\n        if (transform && transform.selection) {\n            if (transform.selection.length == 2) { // Transform relative to the current column\n                this.selection.setSelectionRange(\n                    new Range(cursor.row, start + transform.selection[0],\n                              cursor.row, start + transform.selection[1]));\n            } else { // Transform relative to the current row.\n                this.selection.setSelectionRange(\n                    new Range(cursor.row + transform.selection[0],\n                              transform.selection[1],\n                              cursor.row + transform.selection[2],\n                              transform.selection[3]));\n            }\n        }\n\n        if (session.getDocument().isNewLine(text)) {\n            var lineIndent = mode.getNextLineIndent(lineState, line.slice(0, cursor.column), session.getTabString());\n\n            session.insert({row: cursor.row+1, column: 0}, lineIndent);\n        }\n        if (shouldOutdent)\n            mode.autoOutdent(lineState, session, cursor.row);\n    };\n\n    this.onTextInput = function(text, composition) {\n        if (!composition)\n            return this.keyBinding.onTextInput(text);\n        \n        this.startOperation({command: { name: \"insertstring\" }});\n        var applyComposition = this.applyComposition.bind(this, text, composition);\n        if (this.selection.rangeCount)\n            this.forEachSelection(applyComposition);\n        else\n            applyComposition();\n        this.endOperation();\n    };\n    \n    this.applyComposition = function(text, composition) {\n        if (composition.extendLeft || composition.extendRight) {\n            var r = this.selection.getRange();\n            r.start.column -= composition.extendLeft;\n            r.end.column += composition.extendRight;\n            this.selection.setRange(r);\n            if (!text && !r.isEmpty())\n                this.remove();\n        }\n        if (text || !this.selection.isEmpty())\n            this.insert(text, true);\n        if (composition.restoreStart || composition.restoreEnd) {\n            var r = this.selection.getRange();\n            r.start.column -= composition.restoreStart;\n            r.end.column -= composition.restoreEnd;\n            this.selection.setRange(r);\n        }\n    };\n\n    this.onCommandKey = function(e, hashId, keyCode) {\n        return this.keyBinding.onCommandKey(e, hashId, keyCode);\n    };\n    this.setOverwrite = function(overwrite) {\n        this.session.setOverwrite(overwrite);\n    };\n    this.getOverwrite = function() {\n        return this.session.getOverwrite();\n    };\n    this.toggleOverwrite = function() {\n        this.session.toggleOverwrite();\n    };\n    this.setScrollSpeed = function(speed) {\n        this.setOption(\"scrollSpeed\", speed);\n    };\n    this.getScrollSpeed = function() {\n        return this.getOption(\"scrollSpeed\");\n    };\n    this.setDragDelay = function(dragDelay) {\n        this.setOption(\"dragDelay\", dragDelay);\n    };\n    this.getDragDelay = function() {\n        return this.getOption(\"dragDelay\");\n    };\n    this.setSelectionStyle = function(val) {\n        this.setOption(\"selectionStyle\", val);\n    };\n    this.getSelectionStyle = function() {\n        return this.getOption(\"selectionStyle\");\n    };\n    this.setHighlightActiveLine = function(shouldHighlight) {\n        this.setOption(\"highlightActiveLine\", shouldHighlight);\n    };\n    this.getHighlightActiveLine = function() {\n        return this.getOption(\"highlightActiveLine\");\n    };\n    this.setHighlightGutterLine = function(shouldHighlight) {\n        this.setOption(\"highlightGutterLine\", shouldHighlight);\n    };\n\n    this.getHighlightGutterLine = function() {\n        return this.getOption(\"highlightGutterLine\");\n    };\n    this.setHighlightSelectedWord = function(shouldHighlight) {\n        this.setOption(\"highlightSelectedWord\", shouldHighlight);\n    };\n    this.getHighlightSelectedWord = function() {\n        return this.$highlightSelectedWord;\n    };\n\n    this.setAnimatedScroll = function(shouldAnimate){\n        this.renderer.setAnimatedScroll(shouldAnimate);\n    };\n\n    this.getAnimatedScroll = function(){\n        return this.renderer.getAnimatedScroll();\n    };\n    this.setShowInvisibles = function(showInvisibles) {\n        this.renderer.setShowInvisibles(showInvisibles);\n    };\n    this.getShowInvisibles = function() {\n        return this.renderer.getShowInvisibles();\n    };\n\n    this.setDisplayIndentGuides = function(display) {\n        this.renderer.setDisplayIndentGuides(display);\n    };\n\n    this.getDisplayIndentGuides = function() {\n        return this.renderer.getDisplayIndentGuides();\n    };\n    this.setShowPrintMargin = function(showPrintMargin) {\n        this.renderer.setShowPrintMargin(showPrintMargin);\n    };\n    this.getShowPrintMargin = function() {\n        return this.renderer.getShowPrintMargin();\n    };\n    this.setPrintMarginColumn = function(showPrintMargin) {\n        this.renderer.setPrintMarginColumn(showPrintMargin);\n    };\n    this.getPrintMarginColumn = function() {\n        return this.renderer.getPrintMarginColumn();\n    };\n    this.setReadOnly = function(readOnly) {\n        this.setOption(\"readOnly\", readOnly);\n    };\n    this.getReadOnly = function() {\n        return this.getOption(\"readOnly\");\n    };\n    this.setBehavioursEnabled = function (enabled) {\n        this.setOption(\"behavioursEnabled\", enabled);\n    };\n    this.getBehavioursEnabled = function () {\n        return this.getOption(\"behavioursEnabled\");\n    };\n    this.setWrapBehavioursEnabled = function (enabled) {\n        this.setOption(\"wrapBehavioursEnabled\", enabled);\n    };\n    this.getWrapBehavioursEnabled = function () {\n        return this.getOption(\"wrapBehavioursEnabled\");\n    };\n    this.setShowFoldWidgets = function(show) {\n        this.setOption(\"showFoldWidgets\", show);\n\n    };\n    this.getShowFoldWidgets = function() {\n        return this.getOption(\"showFoldWidgets\");\n    };\n\n    this.setFadeFoldWidgets = function(fade) {\n        this.setOption(\"fadeFoldWidgets\", fade);\n    };\n\n    this.getFadeFoldWidgets = function() {\n        return this.getOption(\"fadeFoldWidgets\");\n    };\n    this.remove = function(dir) {\n        if (this.selection.isEmpty()){\n            if (dir == \"left\")\n                this.selection.selectLeft();\n            else\n                this.selection.selectRight();\n        }\n\n        var range = this.getSelectionRange();\n        if (this.getBehavioursEnabled()) {\n            var session = this.session;\n            var state = session.getState(range.start.row);\n            var new_range = session.getMode().transformAction(state, 'deletion', this, session, range);\n\n            if (range.end.column === 0) {\n                var text = session.getTextRange(range);\n                if (text[text.length - 1] == \"\\n\") {\n                    var line = session.getLine(range.end.row);\n                    if (/^\\s+$/.test(line)) {\n                        range.end.column = line.length;\n                    }\n                }\n            }\n            if (new_range)\n                range = new_range;\n        }\n\n        this.session.remove(range);\n        this.clearSelection();\n    };\n    this.removeWordRight = function() {\n        if (this.selection.isEmpty())\n            this.selection.selectWordRight();\n\n        this.session.remove(this.getSelectionRange());\n        this.clearSelection();\n    };\n    this.removeWordLeft = function() {\n        if (this.selection.isEmpty())\n            this.selection.selectWordLeft();\n\n        this.session.remove(this.getSelectionRange());\n        this.clearSelection();\n    };\n    this.removeToLineStart = function() {\n        if (this.selection.isEmpty())\n            this.selection.selectLineStart();\n        if (this.selection.isEmpty())\n            this.selection.selectLeft();\n        this.session.remove(this.getSelectionRange());\n        this.clearSelection();\n    };\n    this.removeToLineEnd = function() {\n        if (this.selection.isEmpty())\n            this.selection.selectLineEnd();\n\n        var range = this.getSelectionRange();\n        if (range.start.column == range.end.column && range.start.row == range.end.row) {\n            range.end.column = 0;\n            range.end.row++;\n        }\n\n        this.session.remove(range);\n        this.clearSelection();\n    };\n    this.splitLine = function() {\n        if (!this.selection.isEmpty()) {\n            this.session.remove(this.getSelectionRange());\n            this.clearSelection();\n        }\n\n        var cursor = this.getCursorPosition();\n        this.insert(\"\\n\");\n        this.moveCursorToPosition(cursor);\n    };\n    this.transposeLetters = function() {\n        if (!this.selection.isEmpty()) {\n            return;\n        }\n\n        var cursor = this.getCursorPosition();\n        var column = cursor.column;\n        if (column === 0)\n            return;\n\n        var line = this.session.getLine(cursor.row);\n        var swap, range;\n        if (column < line.length) {\n            swap = line.charAt(column) + line.charAt(column-1);\n            range = new Range(cursor.row, column-1, cursor.row, column+1);\n        }\n        else {\n            swap = line.charAt(column-1) + line.charAt(column-2);\n            range = new Range(cursor.row, column-2, cursor.row, column);\n        }\n        this.session.replace(range, swap);\n        this.session.selection.moveToPosition(range.end);\n    };\n    this.toLowerCase = function() {\n        var originalRange = this.getSelectionRange();\n        if (this.selection.isEmpty()) {\n            this.selection.selectWord();\n        }\n\n        var range = this.getSelectionRange();\n        var text = this.session.getTextRange(range);\n        this.session.replace(range, text.toLowerCase());\n        this.selection.setSelectionRange(originalRange);\n    };\n    this.toUpperCase = function() {\n        var originalRange = this.getSelectionRange();\n        if (this.selection.isEmpty()) {\n            this.selection.selectWord();\n        }\n\n        var range = this.getSelectionRange();\n        var text = this.session.getTextRange(range);\n        this.session.replace(range, text.toUpperCase());\n        this.selection.setSelectionRange(originalRange);\n    };\n    this.indent = function() {\n        var session = this.session;\n        var range = this.getSelectionRange();\n\n        if (range.start.row < range.end.row) {\n            var rows = this.$getSelectedRows();\n            session.indentRows(rows.first, rows.last, \"\\t\");\n            return;\n        } else if (range.start.column < range.end.column) {\n            var text = session.getTextRange(range);\n            if (!/^\\s+$/.test(text)) {\n                var rows = this.$getSelectedRows();\n                session.indentRows(rows.first, rows.last, \"\\t\");\n                return;\n            }\n        }\n        \n        var line = session.getLine(range.start.row);\n        var position = range.start;\n        var size = session.getTabSize();\n        var column = session.documentToScreenColumn(position.row, position.column);\n\n        if (this.session.getUseSoftTabs()) {\n            var count = (size - column % size);\n            var indentString = lang.stringRepeat(\" \", count);\n        } else {\n            var count = column % size;\n            while (line[range.start.column - 1] == \" \" && count) {\n                range.start.column--;\n                count--;\n            }\n            this.selection.setSelectionRange(range);\n            indentString = \"\\t\";\n        }\n        return this.insert(indentString);\n    };\n    this.blockIndent = function() {\n        var rows = this.$getSelectedRows();\n        this.session.indentRows(rows.first, rows.last, \"\\t\");\n    };\n    this.blockOutdent = function() {\n        var selection = this.session.getSelection();\n        this.session.outdentRows(selection.getRange());\n    };\n    this.sortLines = function() {\n        var rows = this.$getSelectedRows();\n        var session = this.session;\n\n        var lines = [];\n        for (var i = rows.first; i <= rows.last; i++)\n            lines.push(session.getLine(i));\n\n        lines.sort(function(a, b) {\n            if (a.toLowerCase() < b.toLowerCase()) return -1;\n            if (a.toLowerCase() > b.toLowerCase()) return 1;\n            return 0;\n        });\n\n        var deleteRange = new Range(0, 0, 0, 0);\n        for (var i = rows.first; i <= rows.last; i++) {\n            var line = session.getLine(i);\n            deleteRange.start.row = i;\n            deleteRange.end.row = i;\n            deleteRange.end.column = line.length;\n            session.replace(deleteRange, lines[i-rows.first]);\n        }\n    };\n    this.toggleCommentLines = function() {\n        var state = this.session.getState(this.getCursorPosition().row);\n        var rows = this.$getSelectedRows();\n        this.session.getMode().toggleCommentLines(state, this.session, rows.first, rows.last);\n    };\n\n    this.toggleBlockComment = function() {\n        var cursor = this.getCursorPosition();\n        var state = this.session.getState(cursor.row);\n        var range = this.getSelectionRange();\n        this.session.getMode().toggleBlockComment(state, this.session, range, cursor);\n    };\n    this.getNumberAt = function(row, column) {\n        var _numberRx = /[\\-]?[0-9]+(?:\\.[0-9]+)?/g;\n        _numberRx.lastIndex = 0;\n\n        var s = this.session.getLine(row);\n        while (_numberRx.lastIndex < column) {\n            var m = _numberRx.exec(s);\n            if(m.index <= column && m.index+m[0].length >= column){\n                var number = {\n                    value: m[0],\n                    start: m.index,\n                    end: m.index+m[0].length\n                };\n                return number;\n            }\n        }\n        return null;\n    };\n    this.modifyNumber = function(amount) {\n        var row = this.selection.getCursor().row;\n        var column = this.selection.getCursor().column;\n        var charRange = new Range(row, column-1, row, column);\n\n        var c = this.session.getTextRange(charRange);\n        if (!isNaN(parseFloat(c)) && isFinite(c)) {\n            var nr = this.getNumberAt(row, column);\n            if (nr) {\n                var fp = nr.value.indexOf(\".\") >= 0 ? nr.start + nr.value.indexOf(\".\") + 1 : nr.end;\n                var decimals = nr.start + nr.value.length - fp;\n\n                var t = parseFloat(nr.value);\n                t *= Math.pow(10, decimals);\n\n\n                if(fp !== nr.end && column < fp){\n                    amount *= Math.pow(10, nr.end - column - 1);\n                } else {\n                    amount *= Math.pow(10, nr.end - column);\n                }\n\n                t += amount;\n                t /= Math.pow(10, decimals);\n                var nnr = t.toFixed(decimals);\n                var replaceRange = new Range(row, nr.start, row, nr.end);\n                this.session.replace(replaceRange, nnr);\n                this.moveCursorTo(row, Math.max(nr.start +1, column + nnr.length - nr.value.length));\n\n            }\n        } else {\n            this.toggleWord();\n        }\n    };\n\n    this.$toggleWordPairs = [\n        [\"first\", \"last\"],\n        [\"true\", \"false\"],\n        [\"yes\", \"no\"],\n        [\"width\", \"height\"],\n        [\"top\", \"bottom\"],\n        [\"right\", \"left\"],\n        [\"on\", \"off\"],\n        [\"x\", \"y\"],\n        [\"get\", \"set\"],\n        [\"max\", \"min\"],\n        [\"horizontal\", \"vertical\"],\n        [\"show\", \"hide\"],\n        [\"add\", \"remove\"],\n        [\"up\", \"down\"],\n        [\"before\", \"after\"],\n        [\"even\", \"odd\"],\n        [\"in\", \"out\"],\n        [\"inside\", \"outside\"],\n        [\"next\", \"previous\"],\n        [\"increase\", \"decrease\"],\n        [\"attach\", \"detach\"],\n        [\"&&\", \"||\"],\n        [\"==\", \"!=\"]\n    ];\n\n    this.toggleWord = function () {\n        var row = this.selection.getCursor().row;\n        var column = this.selection.getCursor().column;\n        this.selection.selectWord();\n        var currentState = this.getSelectedText();\n        var currWordStart = this.selection.getWordRange().start.column;\n        var wordParts = currentState.replace(/([a-z]+|[A-Z]+)(?=[A-Z_]|$)/g, '$1 ').split(/\\s/);\n        var delta = column - currWordStart - 1;\n        if (delta < 0) delta = 0;\n        var curLength = 0, itLength = 0;\n        var that = this;\n        if (currentState.match(/[A-Za-z0-9_]+/)) {\n            wordParts.forEach(function (item, i) {\n                itLength = curLength + item.length;\n                if (delta >= curLength && delta <= itLength) {\n                    currentState = item;\n                    that.selection.clearSelection();\n                    that.moveCursorTo(row, curLength + currWordStart);\n                    that.selection.selectTo(row, itLength + currWordStart);\n                }\n                curLength = itLength;\n            });\n        }\n\n        var wordPairs = this.$toggleWordPairs;\n        var reg;\n        for (var i = 0; i < wordPairs.length; i++) {\n            var item = wordPairs[i];\n            for (var j = 0; j <= 1; j++) {\n                var negate = +!j;\n                var firstCondition = currentState.match(new RegExp('^\\\\s?_?(' + lang.escapeRegExp(item[j]) + ')\\\\s?$', 'i'));\n                if (firstCondition) {\n                    var secondCondition = currentState.match(new RegExp('([_]|^|\\\\s)(' + lang.escapeRegExp(firstCondition[1]) + ')($|\\\\s)', 'g'));\n                    if (secondCondition) {\n                        reg = currentState.replace(new RegExp(lang.escapeRegExp(item[j]), 'i'), function (result) {\n                            var res = item[negate];\n                            if (result.toUpperCase() == result) {\n                                res = res.toUpperCase();\n                            } else if (result.charAt(0).toUpperCase() == result.charAt(0)) {\n                                res = res.substr(0, 0) + item[negate].charAt(0).toUpperCase() + res.substr(1);\n                            }\n                            return res;\n                        });\n                        this.insert(reg);\n                        reg = \"\";\n                    }\n                }\n            }\n        }\n    };\n    this.removeLines = function() {\n        var rows = this.$getSelectedRows();\n        this.session.removeFullLines(rows.first, rows.last);\n        this.clearSelection();\n    };\n\n    this.duplicateSelection = function() {\n        var sel = this.selection;\n        var doc = this.session;\n        var range = sel.getRange();\n        var reverse = sel.isBackwards();\n        if (range.isEmpty()) {\n            var row = range.start.row;\n            doc.duplicateLines(row, row);\n        } else {\n            var point = reverse ? range.start : range.end;\n            var endPoint = doc.insert(point, doc.getTextRange(range), false);\n            range.start = point;\n            range.end = endPoint;\n\n            sel.setSelectionRange(range, reverse);\n        }\n    };\n    this.moveLinesDown = function() {\n        this.$moveLines(1, false);\n    };\n    this.moveLinesUp = function() {\n        this.$moveLines(-1, false);\n    };\n    this.moveText = function(range, toPosition, copy) {\n        return this.session.moveText(range, toPosition, copy);\n    };\n    this.copyLinesUp = function() {\n        this.$moveLines(-1, true);\n    };\n    this.copyLinesDown = function() {\n        this.$moveLines(1, true);\n    };\n    this.$moveLines = function(dir, copy) {\n        var rows, moved;\n        var selection = this.selection;\n        if (!selection.inMultiSelectMode || this.inVirtualSelectionMode) {\n            var range = selection.toOrientedRange();\n            rows = this.$getSelectedRows(range);\n            moved = this.session.$moveLines(rows.first, rows.last, copy ? 0 : dir);\n            if (copy && dir == -1) moved = 0;\n            range.moveBy(moved, 0);\n            selection.fromOrientedRange(range);\n        } else {\n            var ranges = selection.rangeList.ranges;\n            selection.rangeList.detach(this.session);\n            this.inVirtualSelectionMode = true;\n            \n            var diff = 0;\n            var totalDiff = 0;\n            var l = ranges.length;\n            for (var i = 0; i < l; i++) {\n                var rangeIndex = i;\n                ranges[i].moveBy(diff, 0);\n                rows = this.$getSelectedRows(ranges[i]);\n                var first = rows.first;\n                var last = rows.last;\n                while (++i < l) {\n                    if (totalDiff) ranges[i].moveBy(totalDiff, 0);\n                    var subRows = this.$getSelectedRows(ranges[i]);\n                    if (copy && subRows.first != last)\n                        break;\n                    else if (!copy && subRows.first > last + 1)\n                        break;\n                    last = subRows.last;\n                }\n                i--;\n                diff = this.session.$moveLines(first, last, copy ? 0 : dir);\n                if (copy && dir == -1) rangeIndex = i + 1;\n                while (rangeIndex <= i) {\n                    ranges[rangeIndex].moveBy(diff, 0);\n                    rangeIndex++;\n                }\n                if (!copy) diff = 0;\n                totalDiff += diff;\n            }\n            \n            selection.fromOrientedRange(selection.ranges[0]);\n            selection.rangeList.attach(this.session);\n            this.inVirtualSelectionMode = false;\n        }\n    };\n    this.$getSelectedRows = function(range) {\n        range = (range || this.getSelectionRange()).collapseRows();\n\n        return {\n            first: this.session.getRowFoldStart(range.start.row),\n            last: this.session.getRowFoldEnd(range.end.row)\n        };\n    };\n\n    this.onCompositionStart = function(compositionState) {\n        this.renderer.showComposition(compositionState);\n    };\n\n    this.onCompositionUpdate = function(text) {\n        this.renderer.setCompositionText(text);\n    };\n\n    this.onCompositionEnd = function() {\n        this.renderer.hideComposition();\n    };\n    this.getFirstVisibleRow = function() {\n        return this.renderer.getFirstVisibleRow();\n    };\n    this.getLastVisibleRow = function() {\n        return this.renderer.getLastVisibleRow();\n    };\n    this.isRowVisible = function(row) {\n        return (row >= this.getFirstVisibleRow() && row <= this.getLastVisibleRow());\n    };\n    this.isRowFullyVisible = function(row) {\n        return (row >= this.renderer.getFirstFullyVisibleRow() && row <= this.renderer.getLastFullyVisibleRow());\n    };\n    this.$getVisibleRowCount = function() {\n        return this.renderer.getScrollBottomRow() - this.renderer.getScrollTopRow() + 1;\n    };\n\n    this.$moveByPage = function(dir, select) {\n        var renderer = this.renderer;\n        var config = this.renderer.layerConfig;\n        var rows = dir * Math.floor(config.height / config.lineHeight);\n\n        if (select === true) {\n            this.selection.$moveSelection(function(){\n                this.moveCursorBy(rows, 0);\n            });\n        } else if (select === false) {\n            this.selection.moveCursorBy(rows, 0);\n            this.selection.clearSelection();\n        }\n\n        var scrollTop = renderer.scrollTop;\n\n        renderer.scrollBy(0, rows * config.lineHeight);\n        if (select != null)\n            renderer.scrollCursorIntoView(null, 0.5);\n\n        renderer.animateScrolling(scrollTop);\n    };\n    this.selectPageDown = function() {\n        this.$moveByPage(1, true);\n    };\n    this.selectPageUp = function() {\n        this.$moveByPage(-1, true);\n    };\n    this.gotoPageDown = function() {\n       this.$moveByPage(1, false);\n    };\n    this.gotoPageUp = function() {\n        this.$moveByPage(-1, false);\n    };\n    this.scrollPageDown = function() {\n        this.$moveByPage(1);\n    };\n    this.scrollPageUp = function() {\n        this.$moveByPage(-1);\n    };\n    this.scrollToRow = function(row) {\n        this.renderer.scrollToRow(row);\n    };\n    this.scrollToLine = function(line, center, animate, callback) {\n        this.renderer.scrollToLine(line, center, animate, callback);\n    };\n    this.centerSelection = function() {\n        var range = this.getSelectionRange();\n        var pos = {\n            row: Math.floor(range.start.row + (range.end.row - range.start.row) / 2),\n            column: Math.floor(range.start.column + (range.end.column - range.start.column) / 2)\n        };\n        this.renderer.alignCursor(pos, 0.5);\n    };\n    this.getCursorPosition = function() {\n        return this.selection.getCursor();\n    };\n    this.getCursorPositionScreen = function() {\n        return this.session.documentToScreenPosition(this.getCursorPosition());\n    };\n    this.getSelectionRange = function() {\n        return this.selection.getRange();\n    };\n    this.selectAll = function() {\n        this.selection.selectAll();\n    };\n    this.clearSelection = function() {\n        this.selection.clearSelection();\n    };\n    this.moveCursorTo = function(row, column) {\n        this.selection.moveCursorTo(row, column);\n    };\n    this.moveCursorToPosition = function(pos) {\n        this.selection.moveCursorToPosition(pos);\n    };\n    this.jumpToMatching = function(select, expand) {\n        var cursor = this.getCursorPosition();\n        var iterator = new TokenIterator(this.session, cursor.row, cursor.column);\n        var prevToken = iterator.getCurrentToken();\n        var token = prevToken || iterator.stepForward();\n\n        if (!token) return;\n        var matchType;\n        var found = false;\n        var depth = {};\n        var i = cursor.column - token.start;\n        var bracketType;\n        var brackets = {\n            \")\": \"(\",\n            \"(\": \"(\",\n            \"]\": \"[\",\n            \"[\": \"[\",\n            \"{\": \"{\",\n            \"}\": \"{\"\n        };\n        \n        do {\n            if (token.value.match(/[{}()\\[\\]]/g)) {\n                for (; i < token.value.length && !found; i++) {\n                    if (!brackets[token.value[i]]) {\n                        continue;\n                    }\n\n                    bracketType = brackets[token.value[i]] + '.' + token.type.replace(\"rparen\", \"lparen\");\n\n                    if (isNaN(depth[bracketType])) {\n                        depth[bracketType] = 0;\n                    }\n\n                    switch (token.value[i]) {\n                        case '(':\n                        case '[':\n                        case '{':\n                            depth[bracketType]++;\n                            break;\n                        case ')':\n                        case ']':\n                        case '}':\n                            depth[bracketType]--;\n\n                            if (depth[bracketType] === -1) {\n                                matchType = 'bracket';\n                                found = true;\n                            }\n                        break;\n                    }\n                }\n            }\n            else if (token.type.indexOf('tag-name') !== -1) {\n                if (isNaN(depth[token.value])) {\n                    depth[token.value] = 0;\n                }\n                \n                if (prevToken.value === '<') {\n                    depth[token.value]++;\n                }\n                else if (prevToken.value === '</') {\n                    depth[token.value]--;\n                }\n                \n                if (depth[token.value] === -1) {\n                    matchType = 'tag';\n                    found = true;\n                }\n            }\n\n            if (!found) {\n                prevToken = token;\n                token = iterator.stepForward();\n                i = 0;\n            }\n        } while (token && !found);\n        if (!matchType)\n            return;\n\n        var range, pos;\n        if (matchType === 'bracket') {\n            range = this.session.getBracketRange(cursor);\n            if (!range) {\n                range = new Range(\n                    iterator.getCurrentTokenRow(),\n                    iterator.getCurrentTokenColumn() + i - 1,\n                    iterator.getCurrentTokenRow(),\n                    iterator.getCurrentTokenColumn() + i - 1\n                );\n                pos = range.start;\n                if (expand || pos.row === cursor.row && Math.abs(pos.column - cursor.column) < 2)\n                    range = this.session.getBracketRange(pos);\n            }\n        }\n        else if (matchType === 'tag') {\n            if (token && token.type.indexOf('tag-name') !== -1) \n                var tag = token.value;\n            else\n                return;\n\n            range = new Range(\n                iterator.getCurrentTokenRow(),\n                iterator.getCurrentTokenColumn() - 2,\n                iterator.getCurrentTokenRow(),\n                iterator.getCurrentTokenColumn() - 2\n            );\n            if (range.compare(cursor.row, cursor.column) === 0) {\n                found = false;\n                do {\n                    token = prevToken;\n                    prevToken = iterator.stepBackward();\n                    \n                    if (prevToken) {\n                        if (prevToken.type.indexOf('tag-close') !== -1) {\n                            range.setEnd(iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn() + 1);\n                        }\n\n                        if (token.value === tag && token.type.indexOf('tag-name') !== -1) {\n                            if (prevToken.value === '<') {\n                                depth[tag]++;\n                            }\n                            else if (prevToken.value === '</') {\n                                depth[tag]--;\n                            }\n                            \n                            if (depth[tag] === 0)\n                                found = true;\n                        }\n                    }\n                } while (prevToken && !found);\n            }\n            if (token && token.type.indexOf('tag-name')) {\n                pos = range.start;\n                if (pos.row == cursor.row && Math.abs(pos.column - cursor.column) < 2)\n                    pos = range.end;\n            }\n        }\n\n        pos = range && range.cursor || pos;\n        if (pos) {\n            if (select) {\n                if (range && expand) {\n                    this.selection.setRange(range);\n                } else if (range && range.isEqual(this.getSelectionRange())) {\n                    this.clearSelection();\n                } else {\n                    this.selection.selectTo(pos.row, pos.column);\n                }\n            } else {\n                this.selection.moveTo(pos.row, pos.column);\n            }\n        }\n    };\n    this.gotoLine = function(lineNumber, column, animate) {\n        this.selection.clearSelection();\n        this.session.unfold({row: lineNumber - 1, column: column || 0});\n        this.exitMultiSelectMode && this.exitMultiSelectMode();\n        this.moveCursorTo(lineNumber - 1, column || 0);\n\n        if (!this.isRowFullyVisible(lineNumber - 1))\n            this.scrollToLine(lineNumber - 1, true, animate);\n    };\n    this.navigateTo = function(row, column) {\n        this.selection.moveTo(row, column);\n    };\n    this.navigateUp = function(times) {\n        if (this.selection.isMultiLine() && !this.selection.isBackwards()) {\n            var selectionStart = this.selection.anchor.getPosition();\n            return this.moveCursorToPosition(selectionStart);\n        }\n        this.selection.clearSelection();\n        this.selection.moveCursorBy(-times || -1, 0);\n    };\n    this.navigateDown = function(times) {\n        if (this.selection.isMultiLine() && this.selection.isBackwards()) {\n            var selectionEnd = this.selection.anchor.getPosition();\n            return this.moveCursorToPosition(selectionEnd);\n        }\n        this.selection.clearSelection();\n        this.selection.moveCursorBy(times || 1, 0);\n    };\n    this.navigateLeft = function(times) {\n        if (!this.selection.isEmpty()) {\n            var selectionStart = this.getSelectionRange().start;\n            this.moveCursorToPosition(selectionStart);\n        }\n        else {\n            times = times || 1;\n            while (times--) {\n                this.selection.moveCursorLeft();\n            }\n        }\n        this.clearSelection();\n    };\n    this.navigateRight = function(times) {\n        if (!this.selection.isEmpty()) {\n            var selectionEnd = this.getSelectionRange().end;\n            this.moveCursorToPosition(selectionEnd);\n        }\n        else {\n            times = times || 1;\n            while (times--) {\n                this.selection.moveCursorRight();\n            }\n        }\n        this.clearSelection();\n    };\n    this.navigateLineStart = function() {\n        this.selection.moveCursorLineStart();\n        this.clearSelection();\n    };\n    this.navigateLineEnd = function() {\n        this.selection.moveCursorLineEnd();\n        this.clearSelection();\n    };\n    this.navigateFileEnd = function() {\n        this.selection.moveCursorFileEnd();\n        this.clearSelection();\n    };\n    this.navigateFileStart = function() {\n        this.selection.moveCursorFileStart();\n        this.clearSelection();\n    };\n    this.navigateWordRight = function() {\n        this.selection.moveCursorWordRight();\n        this.clearSelection();\n    };\n    this.navigateWordLeft = function() {\n        this.selection.moveCursorWordLeft();\n        this.clearSelection();\n    };\n    this.replace = function(replacement, options) {\n        if (options)\n            this.$search.set(options);\n\n        var range = this.$search.find(this.session);\n        var replaced = 0;\n        if (!range)\n            return replaced;\n\n        if (this.$tryReplace(range, replacement)) {\n            replaced = 1;\n        }\n\n        this.selection.setSelectionRange(range);\n        this.renderer.scrollSelectionIntoView(range.start, range.end);\n\n        return replaced;\n    };\n    this.replaceAll = function(replacement, options) {\n        if (options) {\n            this.$search.set(options);\n        }\n\n        var ranges = this.$search.findAll(this.session);\n        var replaced = 0;\n        if (!ranges.length)\n            return replaced;\n\n        var selection = this.getSelectionRange();\n        this.selection.moveTo(0, 0);\n\n        for (var i = ranges.length - 1; i >= 0; --i) {\n            if(this.$tryReplace(ranges[i], replacement)) {\n                replaced++;\n            }\n        }\n\n        this.selection.setSelectionRange(selection);\n\n        return replaced;\n    };\n\n    this.$tryReplace = function(range, replacement) {\n        var input = this.session.getTextRange(range);\n        replacement = this.$search.replace(input, replacement);\n        if (replacement !== null) {\n            range.end = this.session.replace(range, replacement);\n            return range;\n        } else {\n            return null;\n        }\n    };\n    this.getLastSearchOptions = function() {\n        return this.$search.getOptions();\n    };\n    this.find = function(needle, options, animate) {\n        if (!options)\n            options = {};\n\n        if (typeof needle == \"string\" || needle instanceof RegExp)\n            options.needle = needle;\n        else if (typeof needle == \"object\")\n            oop.mixin(options, needle);\n\n        var range = this.selection.getRange();\n        if (options.needle == null) {\n            needle = this.session.getTextRange(range)\n                || this.$search.$options.needle;\n            if (!needle) {\n                range = this.session.getWordRange(range.start.row, range.start.column);\n                needle = this.session.getTextRange(range);\n            }\n            this.$search.set({needle: needle});\n        }\n\n        this.$search.set(options);\n        if (!options.start)\n            this.$search.set({start: range});\n\n        var newRange = this.$search.find(this.session);\n        if (options.preventScroll)\n            return newRange;\n        if (newRange) {\n            this.revealRange(newRange, animate);\n            return newRange;\n        }\n        if (options.backwards)\n            range.start = range.end;\n        else\n            range.end = range.start;\n        this.selection.setRange(range);\n    };\n    this.findNext = function(options, animate) {\n        this.find({skipCurrent: true, backwards: false}, options, animate);\n    };\n    this.findPrevious = function(options, animate) {\n        this.find(options, {skipCurrent: true, backwards: true}, animate);\n    };\n\n    this.revealRange = function(range, animate) {\n        this.session.unfold(range);\n        this.selection.setSelectionRange(range);\n\n        var scrollTop = this.renderer.scrollTop;\n        this.renderer.scrollSelectionIntoView(range.start, range.end, 0.5);\n        if (animate !== false)\n            this.renderer.animateScrolling(scrollTop);\n    };\n    this.undo = function() {\n        this.session.getUndoManager().undo(this.session);\n        this.renderer.scrollCursorIntoView(null, 0.5);\n    };\n    this.redo = function() {\n        this.session.getUndoManager().redo(this.session);\n        this.renderer.scrollCursorIntoView(null, 0.5);\n    };\n    this.destroy = function() {\n        this.renderer.destroy();\n        this._signal(\"destroy\", this);\n        if (this.session)\n            this.session.destroy();\n        if (this._$emitInputEvent)\n            this._$emitInputEvent.cancel();\n        this.session = null;\n    };\n    this.setAutoScrollEditorIntoView = function(enable) {\n        if (!enable)\n            return;\n        var rect;\n        var self = this;\n        var shouldScroll = false;\n        if (!this.$scrollAnchor)\n            this.$scrollAnchor = document.createElement(\"div\");\n        var scrollAnchor = this.$scrollAnchor;\n        scrollAnchor.style.cssText = \"position:absolute\";\n        this.container.insertBefore(scrollAnchor, this.container.firstChild);\n        var onChangeSelection = this.on(\"changeSelection\", function() {\n            shouldScroll = true;\n        });\n        var onBeforeRender = this.renderer.on(\"beforeRender\", function() {\n            if (shouldScroll)\n                rect = self.renderer.container.getBoundingClientRect();\n        });\n        var onAfterRender = this.renderer.on(\"afterRender\", function() {\n            if (shouldScroll && rect && (self.isFocused()\n                || self.searchBox && self.searchBox.isFocused())\n            ) {\n                var renderer = self.renderer;\n                var pos = renderer.$cursorLayer.$pixelPos;\n                var config = renderer.layerConfig;\n                var top = pos.top - config.offset;\n                if (pos.top >= 0 && top + rect.top < 0) {\n                    shouldScroll = true;\n                } else if (pos.top < config.height &&\n                    pos.top + rect.top + config.lineHeight > window.innerHeight) {\n                    shouldScroll = false;\n                } else {\n                    shouldScroll = null;\n                }\n                if (shouldScroll != null) {\n                    scrollAnchor.style.top = top + \"px\";\n                    scrollAnchor.style.left = pos.left + \"px\";\n                    scrollAnchor.style.height = config.lineHeight + \"px\";\n                    scrollAnchor.scrollIntoView(shouldScroll);\n                }\n                shouldScroll = rect = null;\n            }\n        });\n        this.setAutoScrollEditorIntoView = function(enable) {\n            if (enable)\n                return;\n            delete this.setAutoScrollEditorIntoView;\n            this.off(\"changeSelection\", onChangeSelection);\n            this.renderer.off(\"afterRender\", onAfterRender);\n            this.renderer.off(\"beforeRender\", onBeforeRender);\n        };\n    };\n\n\n    this.$resetCursorStyle = function() {\n        var style = this.$cursorStyle || \"ace\";\n        var cursorLayer = this.renderer.$cursorLayer;\n        if (!cursorLayer)\n            return;\n        cursorLayer.setSmoothBlinking(/smooth/.test(style));\n        cursorLayer.isBlinking = !this.$readOnly && style != \"wide\";\n        dom.setCssClass(cursorLayer.element, \"ace_slim-cursors\", /slim/.test(style));\n    };\n    this.prompt = function(message, options, callback) {\n        var editor = this;\n        config.loadModule(\"./ext/prompt\", function (module) {\n            module.prompt(editor, message, options, callback);\n        });\n    };\n\n}).call(Editor.prototype);\n\n\n\nconfig.defineOptions(Editor.prototype, \"editor\", {\n    selectionStyle: {\n        set: function(style) {\n            this.onSelectionChange();\n            this._signal(\"changeSelectionStyle\", {data: style});\n        },\n        initialValue: \"line\"\n    },\n    highlightActiveLine: {\n        set: function() {this.$updateHighlightActiveLine();},\n        initialValue: true\n    },\n    highlightSelectedWord: {\n        set: function(shouldHighlight) {this.$onSelectionChange();},\n        initialValue: true\n    },\n    readOnly: {\n        set: function(readOnly) {\n            this.textInput.setReadOnly(readOnly);\n            this.$resetCursorStyle(); \n        },\n        initialValue: false\n    },\n    copyWithEmptySelection: {\n        set: function(value) {\n            this.textInput.setCopyWithEmptySelection(value);\n        },\n        initialValue: false\n    },\n    cursorStyle: {\n        set: function(val) { this.$resetCursorStyle(); },\n        values: [\"ace\", \"slim\", \"smooth\", \"wide\"],\n        initialValue: \"ace\"\n    },\n    mergeUndoDeltas: {\n        values: [false, true, \"always\"],\n        initialValue: true\n    },\n    behavioursEnabled: {initialValue: true},\n    wrapBehavioursEnabled: {initialValue: true},\n    autoScrollEditorIntoView: {\n        set: function(val) {this.setAutoScrollEditorIntoView(val);}\n    },\n    keyboardHandler: {\n        set: function(val) { this.setKeyboardHandler(val); },\n        get: function() { return this.$keybindingId; },\n        handlesSet: true\n    },\n    value: {\n        set: function(val) { this.session.setValue(val); },\n        get: function() { return this.getValue(); },\n        handlesSet: true,\n        hidden: true\n    },\n    session: {\n        set: function(val) { this.setSession(val); },\n        get: function() { return this.session; },\n        handlesSet: true,\n        hidden: true\n    },\n    \n    showLineNumbers: {\n        set: function(show) {\n            this.renderer.$gutterLayer.setShowLineNumbers(show);\n            this.renderer.$loop.schedule(this.renderer.CHANGE_GUTTER);\n            if (show && this.$relativeLineNumbers)\n                relativeNumberRenderer.attach(this);\n            else\n                relativeNumberRenderer.detach(this);\n        },\n        initialValue: true\n    },\n    relativeLineNumbers: {\n        set: function(value) {\n            if (this.$showLineNumbers && value)\n                relativeNumberRenderer.attach(this);\n            else\n                relativeNumberRenderer.detach(this);\n        }\n    },\n    placeholder: {\n        set: function(message) {\n            if (!this.$updatePlaceholder) {\n                this.$updatePlaceholder = function() {\n                    var value = this.renderer.$composition || this.getValue();\n                    if (value && this.renderer.placeholderNode) {\n                        this.renderer.off(\"afterRender\", this.$updatePlaceholder);\n                        dom.removeCssClass(this.container, \"ace_hasPlaceholder\");\n                        this.renderer.placeholderNode.remove();\n                        this.renderer.placeholderNode = null;\n                    } else if (!value && !this.renderer.placeholderNode) {\n                        this.renderer.on(\"afterRender\", this.$updatePlaceholder);\n                        dom.addCssClass(this.container, \"ace_hasPlaceholder\");\n                        var el = dom.createElement(\"div\");\n                        el.className = \"ace_placeholder\";\n                        el.textContent = this.$placeholder || \"\";\n                        this.renderer.placeholderNode = el;\n                        this.renderer.content.appendChild(this.renderer.placeholderNode);\n                    }\n                }.bind(this);\n                this.on(\"input\", this.$updatePlaceholder);\n            }\n            this.$updatePlaceholder();\n        }\n    },\n\n    hScrollBarAlwaysVisible: \"renderer\",\n    vScrollBarAlwaysVisible: \"renderer\",\n    highlightGutterLine: \"renderer\",\n    animatedScroll: \"renderer\",\n    showInvisibles: \"renderer\",\n    showPrintMargin: \"renderer\",\n    printMarginColumn: \"renderer\",\n    printMargin: \"renderer\",\n    fadeFoldWidgets: \"renderer\",\n    showFoldWidgets: \"renderer\",\n    displayIndentGuides: \"renderer\",\n    showGutter: \"renderer\",\n    fontSize: \"renderer\",\n    fontFamily: \"renderer\",\n    maxLines: \"renderer\",\n    minLines: \"renderer\",\n    scrollPastEnd: \"renderer\",\n    fixedWidthGutter: \"renderer\",\n    theme: \"renderer\",\n    hasCssTransforms: \"renderer\",\n    maxPixelHeight: \"renderer\",\n    useTextareaForIME: \"renderer\",\n\n    scrollSpeed: \"$mouseHandler\",\n    dragDelay: \"$mouseHandler\",\n    dragEnabled: \"$mouseHandler\",\n    focusTimeout: \"$mouseHandler\",\n    tooltipFollowsMouse: \"$mouseHandler\",\n\n    firstLineNumber: \"session\",\n    overwrite: \"session\",\n    newLineMode: \"session\",\n    useWorker: \"session\",\n    useSoftTabs: \"session\",\n    navigateWithinSoftTabs: \"session\",\n    tabSize: \"session\",\n    wrap: \"session\",\n    indentedSoftWrap: \"session\",\n    foldStyle: \"session\",\n    mode: \"session\"\n});\n\n\nvar relativeNumberRenderer = {\n    getText: function(session, row) {\n        return (Math.abs(session.selection.lead.row - row) || (row + 1 + (row < 9 ? \"\\xb7\" : \"\"))) + \"\";\n    },\n    getWidth: function(session, lastLineNumber, config) {\n        return Math.max(\n            lastLineNumber.toString().length,\n            (config.lastRow + 1).toString().length,\n            2\n        ) * config.characterWidth;\n    },\n    update: function(e, editor) {\n        editor.renderer.$loop.schedule(editor.renderer.CHANGE_GUTTER);\n    },\n    attach: function(editor) {\n        editor.renderer.$gutterLayer.$renderer = this;\n        editor.on(\"changeSelection\", this.update);\n        this.update(null, editor);\n    },\n    detach: function(editor) {\n        if (editor.renderer.$gutterLayer.$renderer == this)\n            editor.renderer.$gutterLayer.$renderer = null;\n        editor.off(\"changeSelection\", this.update);\n        this.update(null, editor);\n    }\n};\n\nexports.Editor = Editor;\n});\n\nace.define(\"ace/undomanager\",[\"require\",\"exports\",\"module\",\"ace/range\"], function(require, exports, module) {\n\"use strict\";\nvar UndoManager = function() {\n    this.$maxRev = 0;\n    this.$fromUndo = false;\n    this.reset();\n};\n\n(function() {\n    \n    this.addSession = function(session) {\n        this.$session = session;\n    };\n    this.add = function(delta, allowMerge, session) {\n        if (this.$fromUndo) return;\n        if (delta == this.$lastDelta) return;\n        if (!this.$keepRedoStack) this.$redoStack.length = 0;\n        if (allowMerge === false || !this.lastDeltas) {\n            this.lastDeltas = [];\n            this.$undoStack.push(this.lastDeltas);\n            delta.id = this.$rev = ++this.$maxRev;\n        }\n        if (delta.action == \"remove\" || delta.action == \"insert\")\n            this.$lastDelta = delta;\n        this.lastDeltas.push(delta);\n    };\n    \n    this.addSelection = function(selection, rev) {\n        this.selections.push({\n            value: selection,\n            rev: rev || this.$rev\n        });\n    };\n    \n    this.startNewGroup = function() {\n        this.lastDeltas = null;\n        return this.$rev;\n    };\n    \n    this.markIgnored = function(from, to) {\n        if (to == null) to = this.$rev + 1;\n        var stack = this.$undoStack;\n        for (var i = stack.length; i--;) {\n            var delta = stack[i][0];\n            if (delta.id <= from)\n                break;\n            if (delta.id < to)\n                delta.ignore = true;\n        }\n        this.lastDeltas = null;\n    };\n    \n    this.getSelection = function(rev, after) {\n        var stack = this.selections;\n        for (var i = stack.length; i--;) {\n            var selection = stack[i];\n            if (selection.rev < rev) {\n                if (after)\n                    selection = stack[i + 1];\n                return selection;\n            }\n        }\n    };\n    \n    this.getRevision = function() {\n        return this.$rev;\n    };\n    \n    this.getDeltas = function(from, to) {\n        if (to == null) to = this.$rev + 1;\n        var stack = this.$undoStack;\n        var end = null, start = 0;\n        for (var i = stack.length; i--;) {\n            var delta = stack[i][0];\n            if (delta.id < to && !end)\n                end = i+1;\n            if (delta.id <= from) {\n                start = i + 1;\n                break;\n            }\n        }\n        return stack.slice(start, end);\n    };\n    \n    this.getChangedRanges = function(from, to) {\n        if (to == null) to = this.$rev + 1;\n        \n    };\n    \n    this.getChangedLines = function(from, to) {\n        if (to == null) to = this.$rev + 1;\n        \n    };\n\n    this.validateDeltaBoundaries = function(deltaSet, docLength, invertAction) {\n        if (!deltaSet) {\n            return false;\n        }\n        return deltaSet.every(function(delta) {\n            var action = delta.action;\n            if (invertAction && delta.action === \"insert\") action = \"remove\";\n            if (invertAction && delta.action === \"remove\") action = \"insert\";\n            switch(action) {\n                case \"insert\":\n                    return delta.start.row <= docLength;\n                case \"remove\":\n                    return delta.start.row < docLength && delta.end.row < docLength;\n                default:\n                    return true;\n            }\n        });\n    };\n    this.undo = function(session, dontSelect) {\n        this.lastDeltas = null;\n        var stack = this.$undoStack;\n        \n        if (!rearrangeUndoStack(stack, stack.length))\n            return;\n        \n        if (!session)\n            session = this.$session;\n        \n        if (this.$redoStackBaseRev !== this.$rev && this.$redoStack.length)\n            this.$redoStack = [];\n        \n        this.$fromUndo = true;\n        \n        var deltaSet = stack.pop();\n        var undoSelectionRange = null;\n        if (this.validateDeltaBoundaries(deltaSet, session.getLength(), true)) {\n            undoSelectionRange = session.undoChanges(deltaSet, dontSelect);\n            this.$redoStack.push(deltaSet);\n            this.$syncRev();\n        }\n        \n        this.$fromUndo = false;\n\n        return undoSelectionRange;\n    };\n    this.redo = function(session, dontSelect) {\n        this.lastDeltas = null;\n        \n        if (!session)\n            session = this.$session;\n        \n        this.$fromUndo = true;\n        if (this.$redoStackBaseRev != this.$rev) {\n            var diff = this.getDeltas(this.$redoStackBaseRev, this.$rev + 1);\n            rebaseRedoStack(this.$redoStack, diff);\n            this.$redoStackBaseRev = this.$rev;\n            this.$redoStack.forEach(function(x) {\n                x[0].id = ++this.$maxRev;\n            }, this);\n        }\n        var deltaSet = this.$redoStack.pop();\n        var redoSelectionRange = null;\n        \n        if (this.validateDeltaBoundaries(deltaSet, session.getLength(), false)) {\n            redoSelectionRange = session.redoChanges(deltaSet, dontSelect);\n            this.$undoStack.push(deltaSet);\n            this.$syncRev();\n        }\n        this.$fromUndo = false;\n        \n        return redoSelectionRange;\n    };\n    \n    this.$syncRev = function() {\n        var stack = this.$undoStack;\n        var nextDelta = stack[stack.length - 1];\n        var id = nextDelta && nextDelta[0].id || 0;\n        this.$redoStackBaseRev = id;\n        this.$rev = id;\n    };\n    this.reset = function() {\n        this.lastDeltas = null;\n        this.$lastDelta = null;\n        this.$undoStack = [];\n        this.$redoStack = [];\n        this.$rev = 0;\n        this.mark = 0;\n        this.$redoStackBaseRev = this.$rev;\n        this.selections = [];\n    };\n    this.canUndo = function() {\n        return this.$undoStack.length > 0;\n    };\n    this.canRedo = function() {\n        return this.$redoStack.length > 0;\n    };\n    this.bookmark = function(rev) {\n        if (rev == undefined)\n            rev = this.$rev;\n        this.mark = rev;\n    };\n    this.isAtBookmark = function() {\n        return this.$rev === this.mark;\n    };\n    \n    this.toJSON = function() {\n        \n    };\n    \n    this.fromJSON = function() {\n        \n    };\n    \n    this.hasUndo = this.canUndo;\n    this.hasRedo = this.canRedo;\n    this.isClean = this.isAtBookmark;\n    this.markClean = this.bookmark;\n    \n    this.$prettyPrint = function(delta) {\n        if (delta) return stringifyDelta(delta);\n        return stringifyDelta(this.$undoStack) + \"\\n---\\n\" + stringifyDelta(this.$redoStack);\n    };\n}).call(UndoManager.prototype);\n\nfunction rearrangeUndoStack(stack, pos) {\n    for (var i = pos; i--; ) {\n        var deltaSet = stack[i];\n        if (deltaSet && !deltaSet[0].ignore) {\n            while(i < pos - 1) {\n                var swapped = swapGroups(stack[i], stack[i + 1]);\n                stack[i] = swapped[0];\n                stack[i + 1] = swapped[1];\n                i++;\n            }\n            return true;\n        }\n    }\n}\n\nvar Range = require(\"./range\").Range;\nvar cmp = Range.comparePoints;\nvar comparePoints = Range.comparePoints;\n\nfunction $updateMarkers(delta) {\n    var isInsert = delta.action == \"insert\";\n    var start = delta.start;\n    var end = delta.end;\n    var rowShift = (end.row - start.row) * (isInsert ? 1 : -1);\n    var colShift = (end.column - start.column) * (isInsert ? 1 : -1);\n    if (isInsert) end = start;\n\n    for (var i in this.marks) {\n        var point = this.marks[i];\n        var cmp = comparePoints(point, start);\n        if (cmp < 0) {\n            continue; // delta starts after the range\n        }\n        if (cmp === 0) {\n            if (isInsert) {\n                if (point.bias == 1) {\n                    cmp = 1;\n                }\n                else {\n                    point.bias == -1;\n                    continue;\n                }\n            }\n        }\n        var cmp2 = isInsert ? cmp : comparePoints(point, end);\n        if (cmp2 > 0) {\n            point.row += rowShift;\n            point.column += point.row == end.row ? colShift : 0;\n            continue;\n        }\n        if (!isInsert && cmp2 <= 0) {\n            point.row = start.row;\n            point.column = start.column;\n            if (cmp2 === 0)\n                point.bias = 1;\n        }\n    }\n}\n\n\n\nfunction clonePos(pos) {\n    return {row: pos.row,column: pos.column};\n}\nfunction cloneDelta(d) {\n    return {\n        start: clonePos(d.start),\n        end: clonePos(d.end),\n        action: d.action,\n        lines: d.lines.slice()\n    };\n}\nfunction stringifyDelta(d) {\n    d = d || this;\n    if (Array.isArray(d)) {\n        return d.map(stringifyDelta).join(\"\\n\");\n    }\n    var type = \"\";\n    if (d.action) {\n        type = d.action == \"insert\" ? \"+\" : \"-\";\n        type += \"[\" + d.lines + \"]\";\n    } else if (d.value) {\n        if (Array.isArray(d.value)) {\n            type = d.value.map(stringifyRange).join(\"\\n\");\n        } else {\n            type = stringifyRange(d.value);\n        }\n    }\n    if (d.start) {\n        type += stringifyRange(d);\n    }\n    if (d.id || d.rev) {\n        type += \"\\t(\" + (d.id || d.rev) + \")\";\n    }\n    return type;\n}\nfunction stringifyRange(r) {\n    return r.start.row + \":\" + r.start.column \n        + \"=>\" + r.end.row + \":\" + r.end.column;\n}\n\nfunction swap(d1, d2) {\n    var i1 = d1.action == \"insert\";\n    var i2 = d2.action == \"insert\";\n    \n    if (i1 && i2) {\n        if (cmp(d2.start, d1.end) >= 0) {\n            shift(d2, d1, -1);\n        } else if (cmp(d2.start, d1.start) <= 0) {\n            shift(d1, d2, +1);\n        } else {\n            return null;\n        }\n    } else if (i1 && !i2) {\n        if (cmp(d2.start, d1.end) >= 0) {\n            shift(d2, d1, -1);\n        } else if (cmp(d2.end, d1.start) <= 0) {\n            shift(d1, d2, -1);\n        } else {\n            return null;\n        }\n    } else if (!i1 && i2) {\n        if (cmp(d2.start, d1.start) >= 0) {\n            shift(d2, d1, +1);\n        } else if (cmp(d2.start, d1.start) <= 0) {\n            shift(d1, d2, +1);\n        } else {\n            return null;\n        }\n    } else if (!i1 && !i2) {\n        if (cmp(d2.start, d1.start) >= 0) {\n            shift(d2, d1, +1);\n        } else if (cmp(d2.end, d1.start) <= 0) {\n            shift(d1, d2, -1);\n        } else {\n            return null;\n        }\n    }\n    return [d2, d1];\n}\nfunction swapGroups(ds1, ds2) {\n    for (var i = ds1.length; i--; ) {\n        for (var j = 0; j < ds2.length; j++) {\n            if (!swap(ds1[i], ds2[j])) {\n                while (i < ds1.length) {\n                    while (j--) {\n                        swap(ds2[j], ds1[i]);\n                    }\n                    j = ds2.length;\n                    i++;\n                }                \n                return [ds1, ds2];\n            }\n        }\n    }\n    ds1.selectionBefore = ds2.selectionBefore = \n    ds1.selectionAfter = ds2.selectionAfter = null;\n    return [ds2, ds1];\n}\nfunction xform(d1, c1) {\n    var i1 = d1.action == \"insert\";\n    var i2 = c1.action == \"insert\";\n    \n    if (i1 && i2) {\n        if (cmp(d1.start, c1.start) < 0) {\n            shift(c1, d1, 1);\n        } else {\n            shift(d1, c1, 1);\n        }\n    } else if (i1 && !i2) {\n        if (cmp(d1.start, c1.end) >= 0) {\n            shift(d1, c1, -1);\n        } else if (cmp(d1.start, c1.start) <= 0) {\n            shift(c1, d1, +1);\n        } else {\n            shift(d1, Range.fromPoints(c1.start, d1.start), -1);\n            shift(c1, d1, +1);\n        }\n    } else if (!i1 && i2) {\n        if (cmp(c1.start, d1.end) >= 0) {\n            shift(c1, d1, -1);\n        } else if (cmp(c1.start, d1.start) <= 0) {\n            shift(d1, c1, +1);\n        } else {\n            shift(c1, Range.fromPoints(d1.start, c1.start), -1);\n            shift(d1, c1, +1);\n        }\n    } else if (!i1 && !i2) {\n        if (cmp(c1.start, d1.end) >= 0) {\n            shift(c1, d1, -1);\n        } else if (cmp(c1.end, d1.start) <= 0) {\n            shift(d1, c1, -1);\n        } else {\n            var before, after;\n            if (cmp(d1.start, c1.start) < 0) {\n                before = d1;\n                d1 = splitDelta(d1, c1.start);\n            }\n            if (cmp(d1.end, c1.end) > 0) {\n                after = splitDelta(d1, c1.end);\n            }\n\n            shiftPos(c1.end, d1.start, d1.end, -1);\n            if (after && !before) {\n                d1.lines = after.lines;\n                d1.start = after.start;\n                d1.end = after.end;\n                after = d1;\n            }\n\n            return [c1, before, after].filter(Boolean);\n        }\n    }\n    return [c1, d1];\n}\n    \nfunction shift(d1, d2, dir) {\n    shiftPos(d1.start, d2.start, d2.end, dir);\n    shiftPos(d1.end, d2.start, d2.end, dir);\n}\nfunction shiftPos(pos, start, end, dir) {\n    if (pos.row == (dir == 1 ? start : end).row) {\n        pos.column += dir * (end.column - start.column);\n    }\n    pos.row += dir * (end.row - start.row);\n}\nfunction splitDelta(c, pos) {\n    var lines = c.lines;\n    var end = c.end;\n    c.end = clonePos(pos);    \n    var rowsBefore = c.end.row - c.start.row;\n    var otherLines = lines.splice(rowsBefore, lines.length);\n    \n    var col = rowsBefore ? pos.column : pos.column - c.start.column;\n    lines.push(otherLines[0].substring(0, col));\n    otherLines[0] = otherLines[0].substr(col)   ; \n    var rest = {\n        start: clonePos(pos),\n        end: end,\n        lines: otherLines,\n        action: c.action\n    };\n    return rest;\n}\n\nfunction moveDeltasByOne(redoStack, d) {\n    d = cloneDelta(d);\n    for (var j = redoStack.length; j--;) {\n        var deltaSet = redoStack[j];\n        for (var i = 0; i < deltaSet.length; i++) {\n            var x = deltaSet[i];\n            var xformed = xform(x, d);\n            d = xformed[0];\n            if (xformed.length != 2) {\n                if (xformed[2]) {\n                    deltaSet.splice(i + 1, 1, xformed[1], xformed[2]);\n                    i++;\n                } else if (!xformed[1]) {\n                    deltaSet.splice(i, 1);\n                    i--;\n                }\n            }\n        }\n        if (!deltaSet.length) {\n            redoStack.splice(j, 1); \n        }\n    }\n    return redoStack;\n}\nfunction rebaseRedoStack(redoStack, deltaSets) {\n    for (var i = 0; i < deltaSets.length; i++) {\n        var deltas = deltaSets[i];\n        for (var j = 0; j < deltas.length; j++) {\n            moveDeltasByOne(redoStack, deltas[j]);\n        }\n    }\n}\n\nexports.UndoManager = UndoManager;\n\n});\n\nace.define(\"ace/layer/lines\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\"], function(require, exports, module) {\n\"use strict\";\n\nvar dom = require(\"../lib/dom\");\n\nvar Lines = function(element, canvasHeight) {\n    this.element = element;\n    this.canvasHeight = canvasHeight || 500000;\n    this.element.style.height = (this.canvasHeight * 2) + \"px\";\n    \n    this.cells = [];\n    this.cellCache = [];\n    this.$offsetCoefficient = 0;\n};\n\n(function() {\n    \n    this.moveContainer = function(config) {\n        dom.translate(this.element, 0, -((config.firstRowScreen * config.lineHeight) % this.canvasHeight) - config.offset * this.$offsetCoefficient);\n    };    \n    \n    this.pageChanged = function(oldConfig, newConfig) {\n        return (\n            Math.floor((oldConfig.firstRowScreen * oldConfig.lineHeight) / this.canvasHeight) !==\n            Math.floor((newConfig.firstRowScreen * newConfig.lineHeight) / this.canvasHeight)\n        );\n    };\n    \n    this.computeLineTop = function(row, config, session) {\n        var screenTop = config.firstRowScreen * config.lineHeight;\n        var screenPage = Math.floor(screenTop / this.canvasHeight);\n        var lineTop = session.documentToScreenRow(row, 0) * config.lineHeight;\n        return lineTop - (screenPage * this.canvasHeight);\n    };\n    \n    this.computeLineHeight = function(row, config, session) {\n        return config.lineHeight * session.getRowLineCount(row);\n    };\n    \n    this.getLength = function() {\n        return this.cells.length;\n    };\n    \n    this.get = function(index) {\n        return this.cells[index];\n    };\n    \n    this.shift = function() {\n        this.$cacheCell(this.cells.shift());\n    };\n    \n    this.pop = function() {\n        this.$cacheCell(this.cells.pop());\n    };\n    \n    this.push = function(cell) {\n        if (Array.isArray(cell)) {\n            this.cells.push.apply(this.cells, cell);\n            var fragment = dom.createFragment(this.element);\n            for (var i=0; i<cell.length; i++) {\n                fragment.appendChild(cell[i].element);\n            }\n            this.element.appendChild(fragment);\n        } else {\n            this.cells.push(cell);\n            this.element.appendChild(cell.element);\n        }\n    };\n    \n    this.unshift = function(cell) {\n        if (Array.isArray(cell)) {\n            this.cells.unshift.apply(this.cells, cell);\n            var fragment = dom.createFragment(this.element);\n            for (var i=0; i<cell.length; i++) {\n                fragment.appendChild(cell[i].element);\n            }\n            if (this.element.firstChild)\n                this.element.insertBefore(fragment, this.element.firstChild);\n            else\n                this.element.appendChild(fragment);\n        } else {\n            this.cells.unshift(cell);\n            this.element.insertAdjacentElement(\"afterbegin\", cell.element);\n        }\n    };\n    \n    this.last = function() {\n        if (this.cells.length)\n            return this.cells[this.cells.length-1];\n        else\n            return null;\n    };\n    \n    this.$cacheCell = function(cell) {\n        if (!cell)\n            return;\n            \n        cell.element.remove();\n        this.cellCache.push(cell);\n    };\n    \n    this.createCell = function(row, config, session, initElement) {\n        var cell = this.cellCache.pop();\n        if (!cell) {\n            var element = dom.createElement(\"div\");\n            if (initElement)\n                initElement(element);\n            \n            this.element.appendChild(element);\n            \n            cell = {\n                element: element,\n                text: \"\",\n                row: row\n            };\n        }\n        cell.row = row;\n        \n        return cell;\n    };\n    \n}).call(Lines.prototype);\n\nexports.Lines = Lines;\n\n});\n\nace.define(\"ace/layer/gutter\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\",\"ace/lib/oop\",\"ace/lib/lang\",\"ace/lib/event_emitter\",\"ace/layer/lines\"], function(require, exports, module) {\n\"use strict\";\n\nvar dom = require(\"../lib/dom\");\nvar oop = require(\"../lib/oop\");\nvar lang = require(\"../lib/lang\");\nvar EventEmitter = require(\"../lib/event_emitter\").EventEmitter;\nvar Lines = require(\"./lines\").Lines;\n\nvar Gutter = function(parentEl) {\n    this.element = dom.createElement(\"div\");\n    this.element.className = \"ace_layer ace_gutter-layer\";\n    parentEl.appendChild(this.element);\n    this.setShowFoldWidgets(this.$showFoldWidgets);\n    \n    this.gutterWidth = 0;\n\n    this.$annotations = [];\n    this.$updateAnnotations = this.$updateAnnotations.bind(this);\n    \n    this.$lines = new Lines(this.element);\n    this.$lines.$offsetCoefficient = 1;\n};\n\n(function() {\n\n    oop.implement(this, EventEmitter);\n\n    this.setSession = function(session) {\n        if (this.session)\n            this.session.removeEventListener(\"change\", this.$updateAnnotations);\n        this.session = session;\n        if (session)\n            session.on(\"change\", this.$updateAnnotations);\n    };\n\n    this.addGutterDecoration = function(row, className) {\n        if (window.console)\n            console.warn && console.warn(\"deprecated use session.addGutterDecoration\");\n        this.session.addGutterDecoration(row, className);\n    };\n\n    this.removeGutterDecoration = function(row, className) {\n        if (window.console)\n            console.warn && console.warn(\"deprecated use session.removeGutterDecoration\");\n        this.session.removeGutterDecoration(row, className);\n    };\n\n    this.setAnnotations = function(annotations) {\n        this.$annotations = [];\n        for (var i = 0; i < annotations.length; i++) {\n            var annotation = annotations[i];\n            var row = annotation.row;\n            var rowInfo = this.$annotations[row];\n            if (!rowInfo)\n                rowInfo = this.$annotations[row] = {text: []};\n           \n            var annoText = annotation.text;\n            annoText = annoText ? lang.escapeHTML(annoText) : annotation.html || \"\";\n\n            if (rowInfo.text.indexOf(annoText) === -1)\n                rowInfo.text.push(annoText);\n\n            var type = annotation.type;\n            if (type == \"error\")\n                rowInfo.className = \" ace_error\";\n            else if (type == \"warning\" && rowInfo.className != \" ace_error\")\n                rowInfo.className = \" ace_warning\";\n            else if (type == \"info\" && (!rowInfo.className))\n                rowInfo.className = \" ace_info\";\n        }\n    };\n\n    this.$updateAnnotations = function (delta) {\n        if (!this.$annotations.length)\n            return;\n        var firstRow = delta.start.row;\n        var len = delta.end.row - firstRow;\n        if (len === 0) {\n        } else if (delta.action == 'remove') {\n            this.$annotations.splice(firstRow, len + 1, null);\n        } else {\n            var args = new Array(len + 1);\n            args.unshift(firstRow, 1);\n            this.$annotations.splice.apply(this.$annotations, args);\n        }\n    };\n\n    this.update = function(config) {\n        this.config = config;\n        \n        var session = this.session;\n        var firstRow = config.firstRow;\n        var lastRow = Math.min(config.lastRow + config.gutterOffset,  // needed to compensate for hor scollbar\n            session.getLength() - 1);\n            \n        this.oldLastRow = lastRow;\n        this.config = config;\n        \n        this.$lines.moveContainer(config);\n        this.$updateCursorRow();\n            \n        var fold = session.getNextFoldLine(firstRow);\n        var foldStart = fold ? fold.start.row : Infinity;\n\n        var cell = null;\n        var index = -1;\n        var row = firstRow;\n        \n        while (true) {\n            if (row > foldStart) {\n                row = fold.end.row + 1;\n                fold = session.getNextFoldLine(row, fold);\n                foldStart = fold ? fold.start.row : Infinity;\n            }\n            if (row > lastRow) {\n                while (this.$lines.getLength() > index + 1)\n                    this.$lines.pop();\n                    \n                break;\n            }\n\n            cell = this.$lines.get(++index);\n            if (cell) {\n                cell.row = row;\n            } else {\n                cell = this.$lines.createCell(row, config, this.session, onCreateCell);\n                this.$lines.push(cell);\n            }\n\n            this.$renderCell(cell, config, fold, row);\n            row++;\n        }\n        \n        this._signal(\"afterRender\");\n        this.$updateGutterWidth(config);\n    };\n\n    this.$updateGutterWidth = function(config) {\n        var session = this.session;\n        \n        var gutterRenderer = session.gutterRenderer || this.$renderer;\n        \n        var firstLineNumber = session.$firstLineNumber;\n        var lastLineText = this.$lines.last() ? this.$lines.last().text : \"\";\n        \n        if (this.$fixedWidth || session.$useWrapMode)\n            lastLineText = session.getLength() + firstLineNumber - 1;\n\n        var gutterWidth = gutterRenderer \n            ? gutterRenderer.getWidth(session, lastLineText, config)\n            : lastLineText.toString().length * config.characterWidth;\n        \n        var padding = this.$padding || this.$computePadding();\n        gutterWidth += padding.left + padding.right;\n        if (gutterWidth !== this.gutterWidth && !isNaN(gutterWidth)) {\n            this.gutterWidth = gutterWidth;\n            this.element.parentNode.style.width = \n            this.element.style.width = Math.ceil(this.gutterWidth) + \"px\";\n            this._signal(\"changeGutterWidth\", gutterWidth);\n        }\n    };\n    \n    this.$updateCursorRow = function() {\n        if (!this.$highlightGutterLine)\n            return;\n            \n        var position = this.session.selection.getCursor();\n        if (this.$cursorRow === position.row)\n            return;\n        \n        this.$cursorRow = position.row;\n    };\n    \n    this.updateLineHighlight = function() {\n        if (!this.$highlightGutterLine)\n            return;\n        var row = this.session.selection.cursor.row;\n        this.$cursorRow = row;\n\n        if (this.$cursorCell && this.$cursorCell.row == row)\n            return;\n        if (this.$cursorCell)\n            this.$cursorCell.element.className = this.$cursorCell.element.className.replace(\"ace_gutter-active-line \", \"\");\n        var cells = this.$lines.cells;\n        this.$cursorCell = null;\n        for (var i = 0; i < cells.length; i++) {\n            var cell = cells[i];\n            if (cell.row >= this.$cursorRow) {\n                if (cell.row > this.$cursorRow) {\n                    var fold = this.session.getFoldLine(this.$cursorRow);\n                    if (i > 0 && fold && fold.start.row == cells[i - 1].row)\n                        cell = cells[i - 1];\n                    else\n                        break;\n                }\n                cell.element.className = \"ace_gutter-active-line \" + cell.element.className;\n                this.$cursorCell = cell;\n                break;\n            }\n        }\n    };\n    \n    this.scrollLines = function(config) {\n        var oldConfig = this.config;\n        this.config = config;\n        \n        this.$updateCursorRow();\n        if (this.$lines.pageChanged(oldConfig, config))\n            return this.update(config);\n        \n        this.$lines.moveContainer(config);\n\n        var lastRow = Math.min(config.lastRow + config.gutterOffset,  // needed to compensate for hor scollbar\n            this.session.getLength() - 1);\n        var oldLastRow = this.oldLastRow;\n        this.oldLastRow = lastRow;\n        \n        if (!oldConfig || oldLastRow < config.firstRow)\n            return this.update(config);\n\n        if (lastRow < oldConfig.firstRow)\n            return this.update(config);\n\n        if (oldConfig.firstRow < config.firstRow)\n            for (var row=this.session.getFoldedRowCount(oldConfig.firstRow, config.firstRow - 1); row>0; row--)\n                this.$lines.shift();\n\n        if (oldLastRow > lastRow)\n            for (var row=this.session.getFoldedRowCount(lastRow + 1, oldLastRow); row>0; row--)\n                this.$lines.pop();\n\n        if (config.firstRow < oldConfig.firstRow) {\n            this.$lines.unshift(this.$renderLines(config, config.firstRow, oldConfig.firstRow - 1));\n        }\n\n        if (lastRow > oldLastRow) {\n            this.$lines.push(this.$renderLines(config, oldLastRow + 1, lastRow));\n        }\n        \n        this.updateLineHighlight();\n        \n        this._signal(\"afterRender\");\n        this.$updateGutterWidth(config);\n    };\n\n    this.$renderLines = function(config, firstRow, lastRow) {\n        var fragment = [];\n        var row = firstRow;\n        var foldLine = this.session.getNextFoldLine(row);\n        var foldStart = foldLine ? foldLine.start.row : Infinity;\n\n        while (true) {\n            if (row > foldStart) {\n                row = foldLine.end.row+1;\n                foldLine = this.session.getNextFoldLine(row, foldLine);\n                foldStart = foldLine ? foldLine.start.row : Infinity;\n            }\n            if (row > lastRow)\n                break;\n\n            var cell = this.$lines.createCell(row, config, this.session, onCreateCell);\n            this.$renderCell(cell, config, foldLine, row);\n            fragment.push(cell);\n\n            row++;\n        }\n        return fragment;\n    };\n    \n    this.$renderCell = function(cell, config, fold, row) {\n        var element = cell.element;\n        \n        var session = this.session;\n        \n        var textNode = element.childNodes[0];\n        var foldWidget = element.childNodes[1];\n\n        var firstLineNumber = session.$firstLineNumber;\n        \n        var breakpoints = session.$breakpoints;\n        var decorations = session.$decorations;\n        var gutterRenderer = session.gutterRenderer || this.$renderer;\n        var foldWidgets = this.$showFoldWidgets && session.foldWidgets;\n        var foldStart = fold ? fold.start.row : Number.MAX_VALUE;\n        \n        var className = \"ace_gutter-cell \";\n        if (this.$highlightGutterLine) {\n            if (row == this.$cursorRow || (fold && row < this.$cursorRow && row >= foldStart &&  this.$cursorRow <= fold.end.row)) {\n                className += \"ace_gutter-active-line \";\n                if (this.$cursorCell != cell) {\n                    if (this.$cursorCell)\n                        this.$cursorCell.element.className = this.$cursorCell.element.className.replace(\"ace_gutter-active-line \", \"\");\n                    this.$cursorCell = cell;\n                }\n            }\n        }\n        \n        if (breakpoints[row])\n            className += breakpoints[row];\n        if (decorations[row])\n            className += decorations[row];\n        if (this.$annotations[row])\n            className += this.$annotations[row].className;\n        if (element.className != className)\n            element.className = className;\n\n        if (foldWidgets) {\n            var c = foldWidgets[row];\n            if (c == null)\n                c = foldWidgets[row] = session.getFoldWidget(row);\n        }\n\n        if (c) {\n            var className = \"ace_fold-widget ace_\" + c;\n            if (c == \"start\" && row == foldStart && row < fold.end.row)\n                className += \" ace_closed\";\n            else\n                className += \" ace_open\";\n            if (foldWidget.className != className)\n                foldWidget.className = className;\n\n            var foldHeight = config.lineHeight + \"px\";\n            dom.setStyle(foldWidget.style, \"height\", foldHeight);\n            dom.setStyle(foldWidget.style, \"display\", \"inline-block\");\n        } else {\n            if (foldWidget) {\n                dom.setStyle(foldWidget.style, \"display\", \"none\");\n            }\n        }\n        \n        var text = (gutterRenderer\n            ? gutterRenderer.getText(session, row)\n            : row + firstLineNumber).toString();\n            \n        if (text !== textNode.data) {\n            textNode.data = text;\n        }\n        \n        dom.setStyle(cell.element.style, \"height\", this.$lines.computeLineHeight(row, config, session) + \"px\");\n        dom.setStyle(cell.element.style, \"top\", this.$lines.computeLineTop(row, config, session) + \"px\");\n        \n        cell.text = text;\n        return cell;\n    };\n\n    this.$fixedWidth = false;\n    \n    this.$highlightGutterLine = true;\n    this.$renderer = \"\";\n    this.setHighlightGutterLine = function(highlightGutterLine) {\n        this.$highlightGutterLine = highlightGutterLine;\n    };\n    \n    this.$showLineNumbers = true;\n    this.$renderer = \"\";\n    this.setShowLineNumbers = function(show) {\n        this.$renderer = !show && {\n            getWidth: function() {return 0;},\n            getText: function() {return \"\";}\n        };\n    };\n    \n    this.getShowLineNumbers = function() {\n        return this.$showLineNumbers;\n    };\n    \n    this.$showFoldWidgets = true;\n    this.setShowFoldWidgets = function(show) {\n        if (show)\n            dom.addCssClass(this.element, \"ace_folding-enabled\");\n        else\n            dom.removeCssClass(this.element, \"ace_folding-enabled\");\n\n        this.$showFoldWidgets = show;\n        this.$padding = null;\n    };\n    \n    this.getShowFoldWidgets = function() {\n        return this.$showFoldWidgets;\n    };\n\n    this.$computePadding = function() {\n        if (!this.element.firstChild)\n            return {left: 0, right: 0};\n        var style = dom.computedStyle(this.element.firstChild);\n        this.$padding = {};\n        this.$padding.left = (parseInt(style.borderLeftWidth) || 0)\n            + (parseInt(style.paddingLeft) || 0) + 1;\n        this.$padding.right = (parseInt(style.borderRightWidth) || 0)\n            + (parseInt(style.paddingRight) || 0);\n        return this.$padding;\n    };\n\n    this.getRegion = function(point) {\n        var padding = this.$padding || this.$computePadding();\n        var rect = this.element.getBoundingClientRect();\n        if (point.x < padding.left + rect.left)\n            return \"markers\";\n        if (this.$showFoldWidgets && point.x > rect.right - padding.right)\n            return \"foldWidgets\";\n    };\n\n}).call(Gutter.prototype);\n\nfunction onCreateCell(element) {\n    var textNode = document.createTextNode('');\n    element.appendChild(textNode);\n    \n    var foldWidget = dom.createElement(\"span\");\n    element.appendChild(foldWidget);\n    \n    return element;\n}\n\nexports.Gutter = Gutter;\n\n});\n\nace.define(\"ace/layer/marker\",[\"require\",\"exports\",\"module\",\"ace/range\",\"ace/lib/dom\"], function(require, exports, module) {\n\"use strict\";\n\nvar Range = require(\"../range\").Range;\nvar dom = require(\"../lib/dom\");\n\nvar Marker = function(parentEl) {\n    this.element = dom.createElement(\"div\");\n    this.element.className = \"ace_layer ace_marker-layer\";\n    parentEl.appendChild(this.element);\n};\n\n(function() {\n\n    this.$padding = 0;\n\n    this.setPadding = function(padding) {\n        this.$padding = padding;\n    };\n    this.setSession = function(session) {\n        this.session = session;\n    };\n    \n    this.setMarkers = function(markers) {\n        this.markers = markers;\n    };\n    \n    this.elt = function(className, css) {\n        var x = this.i != -1 && this.element.childNodes[this.i];\n        if (!x) {\n            x = document.createElement(\"div\");\n            this.element.appendChild(x);\n            this.i = -1;\n        } else {\n            this.i++;\n        }\n        x.style.cssText = css;\n        x.className = className;\n    };\n\n    this.update = function(config) {\n        if (!config) return;\n\n        this.config = config;\n\n        this.i = 0;\n        var html;\n        for (var key in this.markers) {\n            var marker = this.markers[key];\n\n            if (!marker.range) {\n                marker.update(html, this, this.session, config);\n                continue;\n            }\n\n            var range = marker.range.clipRows(config.firstRow, config.lastRow);\n            if (range.isEmpty()) continue;\n\n            range = range.toScreenRange(this.session);\n            if (marker.renderer) {\n                var top = this.$getTop(range.start.row, config);\n                var left = this.$padding + range.start.column * config.characterWidth;\n                marker.renderer(html, range, left, top, config);\n            } else if (marker.type == \"fullLine\") {\n                this.drawFullLineMarker(html, range, marker.clazz, config);\n            } else if (marker.type == \"screenLine\") {\n                this.drawScreenLineMarker(html, range, marker.clazz, config);\n            } else if (range.isMultiLine()) {\n                if (marker.type == \"text\")\n                    this.drawTextMarker(html, range, marker.clazz, config);\n                else\n                    this.drawMultiLineMarker(html, range, marker.clazz, config);\n            } else {\n                this.drawSingleLineMarker(html, range, marker.clazz + \" ace_start\" + \" ace_br15\", config);\n            }\n        }\n        if (this.i !=-1) {\n            while (this.i < this.element.childElementCount)\n                this.element.removeChild(this.element.lastChild);\n        }\n    };\n\n    this.$getTop = function(row, layerConfig) {\n        return (row - layerConfig.firstRowScreen) * layerConfig.lineHeight;\n    };\n\n    function getBorderClass(tl, tr, br, bl) {\n        return (tl ? 1 : 0) | (tr ? 2 : 0) | (br ? 4 : 0) | (bl ? 8 : 0);\n    }\n    this.drawTextMarker = function(stringBuilder, range, clazz, layerConfig, extraStyle) {\n        var session = this.session;\n        var start = range.start.row;\n        var end = range.end.row;\n        var row = start;\n        var prev = 0; \n        var curr = 0;\n        var next = session.getScreenLastRowColumn(row);\n        var lineRange = new Range(row, range.start.column, row, curr);\n        for (; row <= end; row++) {\n            lineRange.start.row = lineRange.end.row = row;\n            lineRange.start.column = row == start ? range.start.column : session.getRowWrapIndent(row);\n            lineRange.end.column = next;\n            prev = curr;\n            curr = next;\n            next = row + 1 < end ? session.getScreenLastRowColumn(row + 1) : row == end ? 0 : range.end.column;\n            this.drawSingleLineMarker(stringBuilder, lineRange, \n                clazz + (row == start  ? \" ace_start\" : \"\") + \" ace_br\"\n                    + getBorderClass(row == start || row == start + 1 && range.start.column, prev < curr, curr > next, row == end),\n                layerConfig, row == end ? 0 : 1, extraStyle);\n        }\n    };\n    this.drawMultiLineMarker = function(stringBuilder, range, clazz, config, extraStyle) {\n        var padding = this.$padding;\n        var height = config.lineHeight;\n        var top = this.$getTop(range.start.row, config);\n        var left = padding + range.start.column * config.characterWidth;\n        extraStyle = extraStyle || \"\";\n\n        if (this.session.$bidiHandler.isBidiRow(range.start.row)) {\n           var range1 = range.clone();\n           range1.end.row = range1.start.row;\n           range1.end.column = this.session.getLine(range1.start.row).length;\n           this.drawBidiSingleLineMarker(stringBuilder, range1, clazz + \" ace_br1 ace_start\", config, null, extraStyle);\n        } else {\n            this.elt(\n                clazz + \" ace_br1 ace_start\",\n                \"height:\"+ height+ \"px;\"+ \"right:0;\"+ \"top:\"+top+ \"px;left:\"+ left+ \"px;\" + (extraStyle || \"\")\n            );\n        }\n        if (this.session.$bidiHandler.isBidiRow(range.end.row)) {\n           var range1 = range.clone();\n           range1.start.row = range1.end.row;\n           range1.start.column = 0;\n           this.drawBidiSingleLineMarker(stringBuilder, range1, clazz + \" ace_br12\", config, null, extraStyle);\n        } else {\n            top = this.$getTop(range.end.row, config);\n            var width = range.end.column * config.characterWidth;\n\n            this.elt(\n                clazz + \" ace_br12\",\n                \"height:\"+ height+ \"px;\"+\n                \"width:\"+ width+ \"px;\"+\n                \"top:\"+ top+ \"px;\"+\n                \"left:\"+ padding+ \"px;\"+ (extraStyle || \"\")\n            );\n        }\n        height = (range.end.row - range.start.row - 1) * config.lineHeight;\n        if (height <= 0)\n            return;\n        top = this.$getTop(range.start.row + 1, config);\n        \n        var radiusClass = (range.start.column ? 1 : 0) | (range.end.column ? 0 : 8);\n\n        this.elt(\n            clazz + (radiusClass ? \" ace_br\" + radiusClass : \"\"),\n            \"height:\"+ height+ \"px;\"+\n            \"right:0;\"+\n            \"top:\"+ top+ \"px;\"+\n            \"left:\"+ padding+ \"px;\"+ (extraStyle || \"\")\n        );\n    };\n    this.drawSingleLineMarker = function(stringBuilder, range, clazz, config, extraLength, extraStyle) {\n        if (this.session.$bidiHandler.isBidiRow(range.start.row))\n            return this.drawBidiSingleLineMarker(stringBuilder, range, clazz, config, extraLength, extraStyle);\n        var height = config.lineHeight;\n        var width = (range.end.column + (extraLength || 0) - range.start.column) * config.characterWidth;\n\n        var top = this.$getTop(range.start.row, config);\n        var left = this.$padding + range.start.column * config.characterWidth;\n\n        this.elt(\n            clazz,\n            \"height:\"+ height+ \"px;\"+\n            \"width:\"+ width+ \"px;\"+\n            \"top:\"+ top+ \"px;\"+\n            \"left:\"+ left+ \"px;\"+ (extraStyle || \"\")\n        );\n    };\n    this.drawBidiSingleLineMarker = function(stringBuilder, range, clazz, config, extraLength, extraStyle) {\n        var height = config.lineHeight, top = this.$getTop(range.start.row, config), padding = this.$padding;\n        var selections = this.session.$bidiHandler.getSelections(range.start.column, range.end.column);\n\n        selections.forEach(function(selection) {\n            this.elt(\n                clazz,\n                \"height:\" + height + \"px;\" +\n                \"width:\" + selection.width + (extraLength || 0) + \"px;\" +\n                \"top:\" + top + \"px;\" +\n                \"left:\" + (padding + selection.left) + \"px;\" + (extraStyle || \"\")\n            );\n        }, this);\n    };\n\n    this.drawFullLineMarker = function(stringBuilder, range, clazz, config, extraStyle) {\n        var top = this.$getTop(range.start.row, config);\n        var height = config.lineHeight;\n        if (range.start.row != range.end.row)\n            height += this.$getTop(range.end.row, config) - top;\n\n        this.elt(\n            clazz,\n            \"height:\"+ height+ \"px;\"+\n            \"top:\"+ top+ \"px;\"+\n            \"left:0;right:0;\"+ (extraStyle || \"\")\n        );\n    };\n    \n    this.drawScreenLineMarker = function(stringBuilder, range, clazz, config, extraStyle) {\n        var top = this.$getTop(range.start.row, config);\n        var height = config.lineHeight;\n\n        this.elt(\n            clazz,\n            \"height:\"+ height+ \"px;\"+\n            \"top:\"+ top+ \"px;\"+\n            \"left:0;right:0;\"+ (extraStyle || \"\")\n        );\n    };\n\n}).call(Marker.prototype);\n\nexports.Marker = Marker;\n\n});\n\nace.define(\"ace/layer/text\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/dom\",\"ace/lib/lang\",\"ace/layer/lines\",\"ace/lib/event_emitter\"], function(require, exports, module) {\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar dom = require(\"../lib/dom\");\nvar lang = require(\"../lib/lang\");\nvar Lines = require(\"./lines\").Lines;\nvar EventEmitter = require(\"../lib/event_emitter\").EventEmitter;\n\nvar Text = function(parentEl) {\n    this.dom = dom; \n    this.element = this.dom.createElement(\"div\");\n    this.element.className = \"ace_layer ace_text-layer\";\n    parentEl.appendChild(this.element);\n    this.$updateEolChar = this.$updateEolChar.bind(this);\n    this.$lines = new Lines(this.element);\n};\n\n(function() {\n\n    oop.implement(this, EventEmitter);\n\n    this.EOF_CHAR = \"\\xB6\";\n    this.EOL_CHAR_LF = \"\\xAC\";\n    this.EOL_CHAR_CRLF = \"\\xa4\";\n    this.EOL_CHAR = this.EOL_CHAR_LF;\n    this.TAB_CHAR = \"\\u2014\"; //\"\\u21E5\";\n    this.SPACE_CHAR = \"\\xB7\";\n    this.$padding = 0;\n    this.MAX_LINE_LENGTH = 10000;\n\n    this.$updateEolChar = function() {\n        var doc = this.session.doc;\n        var unixMode = doc.getNewLineCharacter() == \"\\n\" && doc.getNewLineMode() != \"windows\";\n        var EOL_CHAR = unixMode ? this.EOL_CHAR_LF : this.EOL_CHAR_CRLF;\n        if (this.EOL_CHAR != EOL_CHAR) {\n            this.EOL_CHAR = EOL_CHAR;\n            return true;\n        }\n    };\n\n    this.setPadding = function(padding) {\n        this.$padding = padding;\n        this.element.style.margin = \"0 \" + padding + \"px\";\n    };\n\n    this.getLineHeight = function() {\n        return this.$fontMetrics.$characterSize.height || 0;\n    };\n\n    this.getCharacterWidth = function() {\n        return this.$fontMetrics.$characterSize.width || 0;\n    };\n    \n    this.$setFontMetrics = function(measure) {\n        this.$fontMetrics = measure;\n        this.$fontMetrics.on(\"changeCharacterSize\", function(e) {\n            this._signal(\"changeCharacterSize\", e);\n        }.bind(this));\n        this.$pollSizeChanges();\n    };\n\n    this.checkForSizeChanges = function() {\n        this.$fontMetrics.checkForSizeChanges();\n    };\n    this.$pollSizeChanges = function() {\n        return this.$pollSizeChangesTimer = this.$fontMetrics.$pollSizeChanges();\n    };\n    this.setSession = function(session) {\n        this.session = session;\n        if (session)\n            this.$computeTabString();\n    };\n\n    this.showInvisibles = false;\n    this.setShowInvisibles = function(showInvisibles) {\n        if (this.showInvisibles == showInvisibles)\n            return false;\n\n        this.showInvisibles = showInvisibles;\n        this.$computeTabString();\n        return true;\n    };\n\n    this.displayIndentGuides = true;\n    this.setDisplayIndentGuides = function(display) {\n        if (this.displayIndentGuides == display)\n            return false;\n\n        this.displayIndentGuides = display;\n        this.$computeTabString();\n        return true;\n    };\n\n    this.$tabStrings = [];\n    this.onChangeTabSize =\n    this.$computeTabString = function() {\n        var tabSize = this.session.getTabSize();\n        this.tabSize = tabSize;\n        var tabStr = this.$tabStrings = [0];\n        for (var i = 1; i < tabSize + 1; i++) {\n            if (this.showInvisibles) {\n                var span = this.dom.createElement(\"span\");\n                span.className = \"ace_invisible ace_invisible_tab\";\n                span.textContent = lang.stringRepeat(this.TAB_CHAR, i);\n                tabStr.push(span);\n            } else {\n                tabStr.push(this.dom.createTextNode(lang.stringRepeat(\" \", i), this.element));\n            }\n        }\n        if (this.displayIndentGuides) {\n            this.$indentGuideRe =  /\\s\\S| \\t|\\t |\\s$/;\n            var className = \"ace_indent-guide\";\n            var spaceClass = \"\";\n            var tabClass = \"\";\n            if (this.showInvisibles) {\n                className += \" ace_invisible\";\n                spaceClass = \" ace_invisible_space\";\n                tabClass = \" ace_invisible_tab\";\n                var spaceContent = lang.stringRepeat(this.SPACE_CHAR, this.tabSize);\n                var tabContent = lang.stringRepeat(this.TAB_CHAR, this.tabSize);\n            } else {\n                var spaceContent = lang.stringRepeat(\" \", this.tabSize);\n                var tabContent = spaceContent;\n            }\n\n            var span = this.dom.createElement(\"span\");\n            span.className = className + spaceClass;\n            span.textContent = spaceContent;\n            this.$tabStrings[\" \"] = span;\n            \n            var span = this.dom.createElement(\"span\");\n            span.className = className + tabClass;\n            span.textContent = tabContent;\n            this.$tabStrings[\"\\t\"] = span;\n        }\n    };\n\n    this.updateLines = function(config, firstRow, lastRow) {\n        if (this.config.lastRow != config.lastRow ||\n            this.config.firstRow != config.firstRow) {\n            return this.update(config);\n        }\n        \n        this.config = config;\n\n        var first = Math.max(firstRow, config.firstRow);\n        var last = Math.min(lastRow, config.lastRow);\n\n        var lineElements = this.element.childNodes;\n        var lineElementsIdx = 0;\n\n        for (var row = config.firstRow; row < first; row++) {\n            var foldLine = this.session.getFoldLine(row);\n            if (foldLine) {\n                if (foldLine.containsRow(first)) {\n                    first = foldLine.start.row;\n                    break;\n                } else {\n                    row = foldLine.end.row;\n                }\n            }\n            lineElementsIdx ++;\n        }\n\n        var heightChanged = false;\n        var row = first;\n        var foldLine = this.session.getNextFoldLine(row);\n        var foldStart = foldLine ? foldLine.start.row : Infinity;\n\n        while (true) {\n            if (row > foldStart) {\n                row = foldLine.end.row+1;\n                foldLine = this.session.getNextFoldLine(row, foldLine);\n                foldStart = foldLine ? foldLine.start.row :Infinity;\n            }\n            if (row > last)\n                break;\n\n            var lineElement = lineElements[lineElementsIdx++];\n            if (lineElement) {\n                this.dom.removeChildren(lineElement);\n                this.$renderLine(\n                    lineElement, row, row == foldStart ? foldLine : false\n                );\n\n                if (heightChanged)\n                    lineElement.style.top = this.$lines.computeLineTop(row, config, this.session) + \"px\";\n\n                var height = (config.lineHeight * this.session.getRowLength(row)) + \"px\";\n                if (lineElement.style.height != height) {\n                    heightChanged = true;\n                    lineElement.style.height = height;\n                }\n            }\n            row++;\n        }\n        if (heightChanged) {\n            while (lineElementsIdx < this.$lines.cells.length) {\n                var cell = this.$lines.cells[lineElementsIdx++];\n                cell.element.style.top = this.$lines.computeLineTop(cell.row, config, this.session) + \"px\";\n            }\n        }\n    };\n\n    this.scrollLines = function(config) {\n        var oldConfig = this.config;\n        this.config = config;\n\n        if (this.$lines.pageChanged(oldConfig, config))\n            return this.update(config);\n            \n        this.$lines.moveContainer(config);\n        \n        var lastRow = config.lastRow;\n        var oldLastRow = oldConfig ? oldConfig.lastRow : -1;\n\n        if (!oldConfig || oldLastRow < config.firstRow)\n            return this.update(config);\n\n        if (lastRow < oldConfig.firstRow)\n            return this.update(config);\n\n        if (!oldConfig || oldConfig.lastRow < config.firstRow)\n            return this.update(config);\n\n        if (config.lastRow < oldConfig.firstRow)\n            return this.update(config);\n\n        if (oldConfig.firstRow < config.firstRow)\n            for (var row=this.session.getFoldedRowCount(oldConfig.firstRow, config.firstRow - 1); row>0; row--)\n                this.$lines.shift();\n\n        if (oldConfig.lastRow > config.lastRow)\n            for (var row=this.session.getFoldedRowCount(config.lastRow + 1, oldConfig.lastRow); row>0; row--)\n                this.$lines.pop();\n\n        if (config.firstRow < oldConfig.firstRow) {\n            this.$lines.unshift(this.$renderLinesFragment(config, config.firstRow, oldConfig.firstRow - 1));\n        }\n\n        if (config.lastRow > oldConfig.lastRow) {\n            this.$lines.push(this.$renderLinesFragment(config, oldConfig.lastRow + 1, config.lastRow));\n        }\n    };\n\n    this.$renderLinesFragment = function(config, firstRow, lastRow) {\n        var fragment = [];\n        var row = firstRow;\n        var foldLine = this.session.getNextFoldLine(row);\n        var foldStart = foldLine ? foldLine.start.row : Infinity;\n\n        while (true) {\n            if (row > foldStart) {\n                row = foldLine.end.row+1;\n                foldLine = this.session.getNextFoldLine(row, foldLine);\n                foldStart = foldLine ? foldLine.start.row : Infinity;\n            }\n            if (row > lastRow)\n                break;\n\n            var line = this.$lines.createCell(row, config, this.session);\n            \n            var lineEl = line.element;\n            this.dom.removeChildren(lineEl);\n            dom.setStyle(lineEl.style, \"height\", this.$lines.computeLineHeight(row, config, this.session) + \"px\");\n            dom.setStyle(lineEl.style, \"top\", this.$lines.computeLineTop(row, config, this.session) + \"px\");\n            this.$renderLine(lineEl, row, row == foldStart ? foldLine : false);\n\n            if (this.$useLineGroups()) {\n                lineEl.className = \"ace_line_group\";\n            } else {\n                lineEl.className = \"ace_line\";\n            }\n            fragment.push(line);\n\n            row++;\n        }\n        return fragment;\n    };\n\n    this.update = function(config) {\n        this.$lines.moveContainer(config);\n        \n        this.config = config;\n\n        var firstRow = config.firstRow;\n        var lastRow = config.lastRow;\n\n        var lines = this.$lines;\n        while (lines.getLength())\n            lines.pop();\n            \n        lines.push(this.$renderLinesFragment(config, firstRow, lastRow));\n    };\n\n    this.$textToken = {\n        \"text\": true,\n        \"rparen\": true,\n        \"lparen\": true\n    };\n\n    this.$renderToken = function(parent, screenColumn, token, value) {\n        var self = this;\n        var re = /(\\t)|( +)|([\\x00-\\x1f\\x80-\\xa0\\xad\\u1680\\u180E\\u2000-\\u200f\\u2028\\u2029\\u202F\\u205F\\uFEFF\\uFFF9-\\uFFFC]+)|(\\u3000)|([\\u1100-\\u115F\\u11A3-\\u11A7\\u11FA-\\u11FF\\u2329-\\u232A\\u2E80-\\u2E99\\u2E9B-\\u2EF3\\u2F00-\\u2FD5\\u2FF0-\\u2FFB\\u3001-\\u303E\\u3041-\\u3096\\u3099-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u3190-\\u31BA\\u31C0-\\u31E3\\u31F0-\\u321E\\u3220-\\u3247\\u3250-\\u32FE\\u3300-\\u4DBF\\u4E00-\\uA48C\\uA490-\\uA4C6\\uA960-\\uA97C\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFAFF\\uFE10-\\uFE19\\uFE30-\\uFE52\\uFE54-\\uFE66\\uFE68-\\uFE6B\\uFF01-\\uFF60\\uFFE0-\\uFFE6]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF])/g;\n        \n        var valueFragment = this.dom.createFragment(this.element);\n\n        var m;\n        var i = 0;\n        while (m = re.exec(value)) {\n            var tab = m[1];\n            var simpleSpace = m[2];\n            var controlCharacter = m[3];\n            var cjkSpace = m[4];\n            var cjk = m[5];\n            \n            if (!self.showInvisibles && simpleSpace)\n                continue;\n\n            var before = i != m.index ? value.slice(i, m.index) : \"\";\n\n            i = m.index + m[0].length;\n            \n            if (before) {\n                valueFragment.appendChild(this.dom.createTextNode(before, this.element));\n            }\n                \n            if (tab) {\n                var tabSize = self.session.getScreenTabSize(screenColumn + m.index);\n                valueFragment.appendChild(self.$tabStrings[tabSize].cloneNode(true));\n                screenColumn += tabSize - 1;\n            } else if (simpleSpace) {\n                if (self.showInvisibles) {\n                    var span = this.dom.createElement(\"span\");\n                    span.className = \"ace_invisible ace_invisible_space\";\n                    span.textContent = lang.stringRepeat(self.SPACE_CHAR, simpleSpace.length);\n                    valueFragment.appendChild(span);\n                } else {\n                    valueFragment.appendChild(this.com.createTextNode(simpleSpace, this.element));\n                }\n            } else if (controlCharacter) {\n                var span = this.dom.createElement(\"span\");\n                span.className = \"ace_invisible ace_invisible_space ace_invalid\";\n                span.textContent = lang.stringRepeat(self.SPACE_CHAR, controlCharacter.length);\n                valueFragment.appendChild(span);\n            } else if (cjkSpace) {\n                screenColumn += 1;\n                \n                var span = this.dom.createElement(\"span\");\n                span.style.width = (self.config.characterWidth * 2) + \"px\";\n                span.className = self.showInvisibles ? \"ace_cjk ace_invisible ace_invisible_space\" : \"ace_cjk\";\n                span.textContent = self.showInvisibles ? self.SPACE_CHAR : cjkSpace;\n                valueFragment.appendChild(span);\n            } else if (cjk) {\n                screenColumn += 1;\n                var span = this.dom.createElement(\"span\");\n                span.style.width = (self.config.characterWidth * 2) + \"px\";\n                span.className = \"ace_cjk\";\n                span.textContent = cjk;\n                valueFragment.appendChild(span);\n            }\n        }\n        \n        valueFragment.appendChild(this.dom.createTextNode(i ? value.slice(i) : value, this.element));\n\n        if (!this.$textToken[token.type]) {\n            var classes = \"ace_\" + token.type.replace(/\\./g, \" ace_\");\n            var span = this.dom.createElement(\"span\");\n            if (token.type == \"fold\")\n                span.style.width = (token.value.length * this.config.characterWidth) + \"px\";\n                \n            span.className = classes;\n            span.appendChild(valueFragment);\n            \n            parent.appendChild(span);\n        }\n        else {\n            parent.appendChild(valueFragment);\n        }\n        \n        return screenColumn + value.length;\n    };\n\n    this.renderIndentGuide = function(parent, value, max) {\n        var cols = value.search(this.$indentGuideRe);\n        if (cols <= 0 || cols >= max)\n            return value;\n        if (value[0] == \" \") {\n            cols -= cols % this.tabSize;\n            var count = cols/this.tabSize;\n            for (var i=0; i<count; i++) {\n                parent.appendChild(this.$tabStrings[\" \"].cloneNode(true));\n            }\n            return value.substr(cols);\n        } else if (value[0] == \"\\t\") {\n            for (var i=0; i<cols; i++) {\n                parent.appendChild(this.$tabStrings[\"\\t\"].cloneNode(true));\n            }\n            return value.substr(cols);\n        }\n        return value;\n    };\n\n    this.$createLineElement = function(parent) {\n        var lineEl = this.dom.createElement(\"div\");\n        lineEl.className = \"ace_line\";\n        lineEl.style.height = this.config.lineHeight + \"px\";\n        \n        return lineEl;\n    };\n\n    this.$renderWrappedLine = function(parent, tokens, splits) {\n        var chars = 0;\n        var split = 0;\n        var splitChars = splits[0];\n        var screenColumn = 0;\n\n        var lineEl = this.$createLineElement();\n        parent.appendChild(lineEl);\n        \n        for (var i = 0; i < tokens.length; i++) {\n            var token = tokens[i];\n            var value = token.value;\n            if (i == 0 && this.displayIndentGuides) {\n                chars = value.length;\n                value = this.renderIndentGuide(lineEl, value, splitChars);\n                if (!value)\n                    continue;\n                chars -= value.length;\n            }\n\n            if (chars + value.length < splitChars) {\n                screenColumn = this.$renderToken(lineEl, screenColumn, token, value);\n                chars += value.length;\n            } else {\n                while (chars + value.length >= splitChars) {\n                    screenColumn = this.$renderToken(\n                        lineEl, screenColumn,\n                        token, value.substring(0, splitChars - chars)\n                    );\n                    value = value.substring(splitChars - chars);\n                    chars = splitChars;\n\n                    lineEl = this.$createLineElement();\n                    parent.appendChild(lineEl);\n\n                    lineEl.appendChild(this.dom.createTextNode(lang.stringRepeat(\"\\xa0\", splits.indent), this.element));\n\n                    split ++;\n                    screenColumn = 0;\n                    splitChars = splits[split] || Number.MAX_VALUE;\n                }\n                if (value.length != 0) {\n                    chars += value.length;\n                    screenColumn = this.$renderToken(\n                        lineEl, screenColumn, token, value\n                    );\n                }\n            }\n        }\n        \n        if (splits[splits.length - 1] > this.MAX_LINE_LENGTH)\n            this.$renderOverflowMessage(lineEl, screenColumn, null, \"\", true);\n    };\n\n    this.$renderSimpleLine = function(parent, tokens) {\n        var screenColumn = 0;\n        var token = tokens[0];\n        var value = token.value;\n        if (this.displayIndentGuides)\n            value = this.renderIndentGuide(parent, value);\n        if (value)\n            screenColumn = this.$renderToken(parent, screenColumn, token, value);\n        for (var i = 1; i < tokens.length; i++) {\n            token = tokens[i];\n            value = token.value;\n            if (screenColumn + value.length > this.MAX_LINE_LENGTH)\n                return this.$renderOverflowMessage(parent, screenColumn, token, value);\n            screenColumn = this.$renderToken(parent, screenColumn, token, value);\n        }\n    };\n    \n    this.$renderOverflowMessage = function(parent, screenColumn, token, value, hide) {\n        token && this.$renderToken(parent, screenColumn, token,\n            value.slice(0, this.MAX_LINE_LENGTH - screenColumn));\n            \n        var overflowEl = this.dom.createElement(\"span\");\n        overflowEl.className = \"ace_inline_button ace_keyword ace_toggle_wrap\";\n        overflowEl.textContent = hide ? \"<hide>\" : \"<click to see more...>\";\n        \n        parent.appendChild(overflowEl);        \n    };\n    this.$renderLine = function(parent, row, foldLine) {\n        if (!foldLine && foldLine != false)\n            foldLine = this.session.getFoldLine(row);\n\n        if (foldLine)\n            var tokens = this.$getFoldLineTokens(row, foldLine);\n        else\n            var tokens = this.session.getTokens(row);\n\n        var lastLineEl = parent;\n        if (tokens.length) {\n            var splits = this.session.getRowSplitData(row);\n            if (splits && splits.length) {\n                this.$renderWrappedLine(parent, tokens, splits);\n                var lastLineEl = parent.lastChild;\n            } else {\n                var lastLineEl = parent;\n                if (this.$useLineGroups()) {\n                    lastLineEl = this.$createLineElement();\n                    parent.appendChild(lastLineEl);\n                }\n                this.$renderSimpleLine(lastLineEl, tokens);\n            }\n        } else if (this.$useLineGroups()) {\n            lastLineEl = this.$createLineElement();\n            parent.appendChild(lastLineEl);\n        }\n\n        if (this.showInvisibles && lastLineEl) {\n            if (foldLine)\n                row = foldLine.end.row;\n\n            var invisibleEl = this.dom.createElement(\"span\");\n            invisibleEl.className = \"ace_invisible ace_invisible_eol\";\n            invisibleEl.textContent = row == this.session.getLength() - 1 ? this.EOF_CHAR : this.EOL_CHAR;\n            \n            lastLineEl.appendChild(invisibleEl);\n        }\n    };\n\n    this.$getFoldLineTokens = function(row, foldLine) {\n        var session = this.session;\n        var renderTokens = [];\n\n        function addTokens(tokens, from, to) {\n            var idx = 0, col = 0;\n            while ((col + tokens[idx].value.length) < from) {\n                col += tokens[idx].value.length;\n                idx++;\n\n                if (idx == tokens.length)\n                    return;\n            }\n            if (col != from) {\n                var value = tokens[idx].value.substring(from - col);\n                if (value.length > (to - from))\n                    value = value.substring(0, to - from);\n\n                renderTokens.push({\n                    type: tokens[idx].type,\n                    value: value\n                });\n\n                col = from + value.length;\n                idx += 1;\n            }\n\n            while (col < to && idx < tokens.length) {\n                var value = tokens[idx].value;\n                if (value.length + col > to) {\n                    renderTokens.push({\n                        type: tokens[idx].type,\n                        value: value.substring(0, to - col)\n                    });\n                } else\n                    renderTokens.push(tokens[idx]);\n                col += value.length;\n                idx += 1;\n            }\n        }\n\n        var tokens = session.getTokens(row);\n        foldLine.walk(function(placeholder, row, column, lastColumn, isNewRow) {\n            if (placeholder != null) {\n                renderTokens.push({\n                    type: \"fold\",\n                    value: placeholder\n                });\n            } else {\n                if (isNewRow)\n                    tokens = session.getTokens(row);\n\n                if (tokens.length)\n                    addTokens(tokens, lastColumn, column);\n            }\n        }, foldLine.end.row, this.session.getLine(foldLine.end.row).length);\n\n        return renderTokens;\n    };\n\n    this.$useLineGroups = function() {\n        return this.session.getUseWrapMode();\n    };\n\n    this.destroy = function() {};\n}).call(Text.prototype);\n\nexports.Text = Text;\n\n});\n\nace.define(\"ace/layer/cursor\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\"], function(require, exports, module) {\n\"use strict\";\n\nvar dom = require(\"../lib/dom\");\n\nvar Cursor = function(parentEl) {\n    this.element = dom.createElement(\"div\");\n    this.element.className = \"ace_layer ace_cursor-layer\";\n    parentEl.appendChild(this.element);\n    \n    this.isVisible = false;\n    this.isBlinking = true;\n    this.blinkInterval = 1000;\n    this.smoothBlinking = false;\n\n    this.cursors = [];\n    this.cursor = this.addCursor();\n    dom.addCssClass(this.element, \"ace_hidden-cursors\");\n    this.$updateCursors = this.$updateOpacity.bind(this);\n};\n\n(function() {\n    \n    this.$updateOpacity = function(val) {\n        var cursors = this.cursors;\n        for (var i = cursors.length; i--; )\n            dom.setStyle(cursors[i].style, \"opacity\", val ? \"\" : \"0\");\n    };\n\n    this.$startCssAnimation = function() {\n        var cursors = this.cursors;\n        for (var i = cursors.length; i--; )\n            cursors[i].style.animationDuration = this.blinkInterval + \"ms\";\n\n        setTimeout(function() {\n            dom.addCssClass(this.element, \"ace_animate-blinking\");\n        }.bind(this));\n    };\n    \n    this.$stopCssAnimation = function() {\n        dom.removeCssClass(this.element, \"ace_animate-blinking\");\n    };\n\n    this.$padding = 0;\n    this.setPadding = function(padding) {\n        this.$padding = padding;\n    };\n\n    this.setSession = function(session) {\n        this.session = session;\n    };\n\n    this.setBlinking = function(blinking) {\n        if (blinking != this.isBlinking) {\n            this.isBlinking = blinking;\n            this.restartTimer();\n        }\n    };\n\n    this.setBlinkInterval = function(blinkInterval) {\n        if (blinkInterval != this.blinkInterval) {\n            this.blinkInterval = blinkInterval;\n            this.restartTimer();\n        }\n    };\n\n    this.setSmoothBlinking = function(smoothBlinking) {\n        if (smoothBlinking != this.smoothBlinking) {\n            this.smoothBlinking = smoothBlinking;\n            dom.setCssClass(this.element, \"ace_smooth-blinking\", smoothBlinking);\n            this.$updateCursors(true);\n            this.restartTimer();\n        }\n    };\n\n    this.addCursor = function() {\n        var el = dom.createElement(\"div\");\n        el.className = \"ace_cursor\";\n        this.element.appendChild(el);\n        this.cursors.push(el);\n        return el;\n    };\n\n    this.removeCursor = function() {\n        if (this.cursors.length > 1) {\n            var el = this.cursors.pop();\n            el.parentNode.removeChild(el);\n            return el;\n        }\n    };\n\n    this.hideCursor = function() {\n        this.isVisible = false;\n        dom.addCssClass(this.element, \"ace_hidden-cursors\");\n        this.restartTimer();\n    };\n\n    this.showCursor = function() {\n        this.isVisible = true;\n        dom.removeCssClass(this.element, \"ace_hidden-cursors\");\n        this.restartTimer();\n    };\n\n    this.restartTimer = function() {\n        var update = this.$updateCursors;\n        clearInterval(this.intervalId);\n        clearTimeout(this.timeoutId);\n        this.$stopCssAnimation();\n\n        if (this.smoothBlinking) {\n            dom.removeCssClass(this.element, \"ace_smooth-blinking\");\n        }\n        \n        update(true);\n\n        if (!this.isBlinking || !this.blinkInterval || !this.isVisible) {\n            this.$stopCssAnimation();\n            return;\n        }\n\n        if (this.smoothBlinking) {\n            setTimeout(function(){\n                dom.addCssClass(this.element, \"ace_smooth-blinking\");\n            }.bind(this));\n        }\n        \n        if (dom.HAS_CSS_ANIMATION) {\n            this.$startCssAnimation();\n        } else {\n            var blink = function(){\n                this.timeoutId = setTimeout(function() {\n                    update(false);\n                }, 0.6 * this.blinkInterval);\n            }.bind(this);\n    \n            this.intervalId = setInterval(function() {\n                update(true);\n                blink();\n            }, this.blinkInterval);\n            blink();\n        }\n    };\n\n    this.getPixelPosition = function(position, onScreen) {\n        if (!this.config || !this.session)\n            return {left : 0, top : 0};\n\n        if (!position)\n            position = this.session.selection.getCursor();\n        var pos = this.session.documentToScreenPosition(position);\n        var cursorLeft = this.$padding + (this.session.$bidiHandler.isBidiRow(pos.row, position.row)\n            ? this.session.$bidiHandler.getPosLeft(pos.column)\n            : pos.column * this.config.characterWidth);\n\n        var cursorTop = (pos.row - (onScreen ? this.config.firstRowScreen : 0)) *\n            this.config.lineHeight;\n\n        return {left : cursorLeft, top : cursorTop};\n    };\n\n    this.isCursorInView = function(pixelPos, config) {\n        return pixelPos.top >= 0 && pixelPos.top < config.maxHeight;\n    };\n\n    this.update = function(config) {\n        this.config = config;\n\n        var selections = this.session.$selectionMarkers;\n        var i = 0, cursorIndex = 0;\n\n        if (selections === undefined || selections.length === 0){\n            selections = [{cursor: null}];\n        }\n\n        for (var i = 0, n = selections.length; i < n; i++) {\n            var pixelPos = this.getPixelPosition(selections[i].cursor, true);\n            if ((pixelPos.top > config.height + config.offset ||\n                 pixelPos.top < 0) && i > 1) {\n                continue;\n            }\n\n            var element = this.cursors[cursorIndex++] || this.addCursor();\n            var style = element.style;\n            \n            if (!this.drawCursor) {\n                if (!this.isCursorInView(pixelPos, config)) {\n                    dom.setStyle(style, \"display\", \"none\");\n                } else {\n                    dom.setStyle(style, \"display\", \"block\");\n                    dom.translate(element, pixelPos.left, pixelPos.top);\n                    dom.setStyle(style, \"width\", Math.round(config.characterWidth) + \"px\");\n                    dom.setStyle(style, \"height\", config.lineHeight + \"px\");\n                }\n            } else {\n                this.drawCursor(element, pixelPos, config, selections[i], this.session);\n            }\n        }\n        while (this.cursors.length > cursorIndex)\n            this.removeCursor();\n\n        var overwrite = this.session.getOverwrite();\n        this.$setOverwrite(overwrite);\n        this.$pixelPos = pixelPos;\n        this.restartTimer();\n    };\n    \n    this.drawCursor = null;\n\n    this.$setOverwrite = function(overwrite) {\n        if (overwrite != this.overwrite) {\n            this.overwrite = overwrite;\n            if (overwrite)\n                dom.addCssClass(this.element, \"ace_overwrite-cursors\");\n            else\n                dom.removeCssClass(this.element, \"ace_overwrite-cursors\");\n        }\n    };\n\n    this.destroy = function() {\n        clearInterval(this.intervalId);\n        clearTimeout(this.timeoutId);\n    };\n\n}).call(Cursor.prototype);\n\nexports.Cursor = Cursor;\n\n});\n\nace.define(\"ace/scrollbar\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/dom\",\"ace/lib/event\",\"ace/lib/event_emitter\"], function(require, exports, module) {\n\"use strict\";\n\nvar oop = require(\"./lib/oop\");\nvar dom = require(\"./lib/dom\");\nvar event = require(\"./lib/event\");\nvar EventEmitter = require(\"./lib/event_emitter\").EventEmitter;\nvar MAX_SCROLL_H = 0x8000;\nvar ScrollBar = function(parent) {\n    this.element = dom.createElement(\"div\");\n    this.element.className = \"ace_scrollbar ace_scrollbar\" + this.classSuffix;\n\n    this.inner = dom.createElement(\"div\");\n    this.inner.className = \"ace_scrollbar-inner\";\n    this.inner.textContent = \"\\xa0\";\n    this.element.appendChild(this.inner);\n\n    parent.appendChild(this.element);\n\n    this.setVisible(false);\n    this.skipEvent = false;\n\n    event.addListener(this.element, \"scroll\", this.onScroll.bind(this));\n    event.addListener(this.element, \"mousedown\", event.preventDefault);\n};\n\n(function() {\n    oop.implement(this, EventEmitter);\n\n    this.setVisible = function(isVisible) {\n        this.element.style.display = isVisible ? \"\" : \"none\";\n        this.isVisible = isVisible;\n        this.coeff = 1;\n    };\n}).call(ScrollBar.prototype);\nvar VScrollBar = function(parent, renderer) {\n    ScrollBar.call(this, parent);\n    this.scrollTop = 0;\n    this.scrollHeight = 0;\n    renderer.$scrollbarWidth = \n    this.width = dom.scrollbarWidth(parent.ownerDocument);\n    this.inner.style.width =\n    this.element.style.width = (this.width || 15) + 5 + \"px\";\n    this.$minWidth = 0;\n};\n\noop.inherits(VScrollBar, ScrollBar);\n\n(function() {\n\n    this.classSuffix = '-v';\n    this.onScroll = function() {\n        if (!this.skipEvent) {\n            this.scrollTop = this.element.scrollTop;\n            if (this.coeff != 1) {\n                var h = this.element.clientHeight / this.scrollHeight;\n                this.scrollTop = this.scrollTop * (1 - h) / (this.coeff - h);\n            }\n            this._emit(\"scroll\", {data: this.scrollTop});\n        }\n        this.skipEvent = false;\n    };\n    this.getWidth = function() {\n        return Math.max(this.isVisible ? this.width : 0, this.$minWidth || 0);\n    };\n    this.setHeight = function(height) {\n        this.element.style.height = height + \"px\";\n    };\n    this.setInnerHeight = \n    this.setScrollHeight = function(height) {\n        this.scrollHeight = height;\n        if (height > MAX_SCROLL_H) {\n            this.coeff = MAX_SCROLL_H / height;\n            height = MAX_SCROLL_H;\n        } else if (this.coeff != 1) {\n            this.coeff = 1;\n        }\n        this.inner.style.height = height + \"px\";\n    };\n    this.setScrollTop = function(scrollTop) {\n        if (this.scrollTop != scrollTop) {\n            this.skipEvent = true;\n            this.scrollTop = scrollTop;\n            this.element.scrollTop = scrollTop * this.coeff;\n        }\n    };\n\n}).call(VScrollBar.prototype);\nvar HScrollBar = function(parent, renderer) {\n    ScrollBar.call(this, parent);\n    this.scrollLeft = 0;\n    this.height = renderer.$scrollbarWidth;\n    this.inner.style.height =\n    this.element.style.height = (this.height || 15) + 5 + \"px\";\n};\n\noop.inherits(HScrollBar, ScrollBar);\n\n(function() {\n\n    this.classSuffix = '-h';\n    this.onScroll = function() {\n        if (!this.skipEvent) {\n            this.scrollLeft = this.element.scrollLeft;\n            this._emit(\"scroll\", {data: this.scrollLeft});\n        }\n        this.skipEvent = false;\n    };\n    this.getHeight = function() {\n        return this.isVisible ? this.height : 0;\n    };\n    this.setWidth = function(width) {\n        this.element.style.width = width + \"px\";\n    };\n    this.setInnerWidth = function(width) {\n        this.inner.style.width = width + \"px\";\n    };\n    this.setScrollWidth = function(width) {\n        this.inner.style.width = width + \"px\";\n    };\n    this.setScrollLeft = function(scrollLeft) {\n        if (this.scrollLeft != scrollLeft) {\n            this.skipEvent = true;\n            this.scrollLeft = this.element.scrollLeft = scrollLeft;\n        }\n    };\n\n}).call(HScrollBar.prototype);\n\n\nexports.ScrollBar = VScrollBar; // backward compatibility\nexports.ScrollBarV = VScrollBar; // backward compatibility\nexports.ScrollBarH = HScrollBar; // backward compatibility\n\nexports.VScrollBar = VScrollBar;\nexports.HScrollBar = HScrollBar;\n});\n\nace.define(\"ace/renderloop\",[\"require\",\"exports\",\"module\",\"ace/lib/event\"], function(require, exports, module) {\n\"use strict\";\n\nvar event = require(\"./lib/event\");\n\n\nvar RenderLoop = function(onRender, win) {\n    this.onRender = onRender;\n    this.pending = false;\n    this.changes = 0;\n    this.$recursionLimit = 2;\n    this.window = win || window;\n    var _self = this;\n    this._flush = function(ts) {\n        _self.pending = false;\n        var changes = _self.changes;\n\n        if (changes) {\n            event.blockIdle(100);\n            _self.changes = 0;\n            _self.onRender(changes);\n        }\n        \n        if (_self.changes) {\n            if (_self.$recursionLimit-- < 0) return;\n            _self.schedule();\n        } else {\n            _self.$recursionLimit = 2;\n        }\n    };\n};\n\n(function() {\n\n    this.schedule = function(change) {\n        this.changes = this.changes | change;\n        if (this.changes && !this.pending) {\n            event.nextFrame(this._flush);\n            this.pending = true;\n        }\n    };\n\n    this.clear = function(change) {\n        var changes = this.changes;\n        this.changes = 0;\n        return changes;\n    };\n\n}).call(RenderLoop.prototype);\n\nexports.RenderLoop = RenderLoop;\n});\n\nace.define(\"ace/layer/font_metrics\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/dom\",\"ace/lib/lang\",\"ace/lib/event\",\"ace/lib/useragent\",\"ace/lib/event_emitter\"], function(require, exports, module) {\n\nvar oop = require(\"../lib/oop\");\nvar dom = require(\"../lib/dom\");\nvar lang = require(\"../lib/lang\");\nvar event = require(\"../lib/event\");\nvar useragent = require(\"../lib/useragent\");\nvar EventEmitter = require(\"../lib/event_emitter\").EventEmitter;\n\nvar CHAR_COUNT = 256;\nvar USE_OBSERVER = typeof ResizeObserver == \"function\";\nvar L = 200;\n\nvar FontMetrics = exports.FontMetrics = function(parentEl) {\n    this.el = dom.createElement(\"div\");\n    this.$setMeasureNodeStyles(this.el.style, true);\n    \n    this.$main = dom.createElement(\"div\");\n    this.$setMeasureNodeStyles(this.$main.style);\n    \n    this.$measureNode = dom.createElement(\"div\");\n    this.$setMeasureNodeStyles(this.$measureNode.style);\n    \n    \n    this.el.appendChild(this.$main);\n    this.el.appendChild(this.$measureNode);\n    parentEl.appendChild(this.el);\n    \n    this.$measureNode.innerHTML = lang.stringRepeat(\"X\", CHAR_COUNT);\n    \n    this.$characterSize = {width: 0, height: 0};\n    \n    \n    if (USE_OBSERVER)\n        this.$addObserver();\n    else\n        this.checkForSizeChanges();\n};\n\n(function() {\n\n    oop.implement(this, EventEmitter);\n        \n    this.$characterSize = {width: 0, height: 0};\n    \n    this.$setMeasureNodeStyles = function(style, isRoot) {\n        style.width = style.height = \"auto\";\n        style.left = style.top = \"0px\";\n        style.visibility = \"hidden\";\n        style.position = \"absolute\";\n        style.whiteSpace = \"pre\";\n\n        if (useragent.isIE < 8) {\n            style[\"font-family\"] = \"inherit\";\n        } else {\n            style.font = \"inherit\";\n        }\n        style.overflow = isRoot ? \"hidden\" : \"visible\";\n    };\n\n    this.checkForSizeChanges = function(size) {\n        if (size === undefined)\n            size = this.$measureSizes();\n        if (size && (this.$characterSize.width !== size.width || this.$characterSize.height !== size.height)) {\n            this.$measureNode.style.fontWeight = \"bold\";\n            var boldSize = this.$measureSizes();\n            this.$measureNode.style.fontWeight = \"\";\n            this.$characterSize = size;\n            this.charSizes = Object.create(null);\n            this.allowBoldFonts = boldSize && boldSize.width === size.width && boldSize.height === size.height;\n            this._emit(\"changeCharacterSize\", {data: size});\n        }\n    };\n    \n    this.$addObserver = function() {\n        var self = this;\n        this.$observer = new window.ResizeObserver(function(e) {\n            var rect = e[0].contentRect;\n            self.checkForSizeChanges({\n                height: rect.height,\n                width: rect.width / CHAR_COUNT\n            });\n        });\n        this.$observer.observe(this.$measureNode);\n    };\n\n    this.$pollSizeChanges = function() {\n        if (this.$pollSizeChangesTimer || this.$observer)\n            return this.$pollSizeChangesTimer;\n        var self = this;\n        \n        return this.$pollSizeChangesTimer = event.onIdle(function cb() {\n            self.checkForSizeChanges();\n            event.onIdle(cb, 500);\n        }, 500);\n    };\n    \n    this.setPolling = function(val) {\n        if (val) {\n            this.$pollSizeChanges();\n        } else if (this.$pollSizeChangesTimer) {\n            clearInterval(this.$pollSizeChangesTimer);\n            this.$pollSizeChangesTimer = 0;\n        }\n    };\n\n    this.$measureSizes = function(node) {\n        var size = {\n            height: (node || this.$measureNode).clientHeight,\n            width: (node || this.$measureNode).clientWidth / CHAR_COUNT\n        };\n        if (size.width === 0 || size.height === 0)\n            return null;\n        return size;\n    };\n\n    this.$measureCharWidth = function(ch) {\n        this.$main.innerHTML = lang.stringRepeat(ch, CHAR_COUNT);\n        var rect = this.$main.getBoundingClientRect();\n        return rect.width / CHAR_COUNT;\n    };\n    \n    this.getCharacterWidth = function(ch) {\n        var w = this.charSizes[ch];\n        if (w === undefined) {\n            w = this.charSizes[ch] = this.$measureCharWidth(ch) / this.$characterSize.width;\n        }\n        return w;\n    };\n\n    this.destroy = function() {\n        clearInterval(this.$pollSizeChangesTimer);\n        if (this.$observer)\n            this.$observer.disconnect();\n        if (this.el && this.el.parentNode)\n            this.el.parentNode.removeChild(this.el);\n    };\n\n    \n    this.$getZoom = function getZoom(element) {\n        if (!element) return 1;\n        return (window.getComputedStyle(element).zoom || 1) * getZoom(element.parentElement);\n    };\n    this.$initTransformMeasureNodes = function() {\n        var t = function(t, l) {\n            return [\"div\", {\n                style: \"position: absolute;top:\" + t + \"px;left:\" + l + \"px;\"\n            }];\n        };\n        this.els = dom.buildDom([t(0, 0), t(L, 0), t(0, L), t(L, L)], this.el);\n    };\n    this.transformCoordinates = function(clientPos, elPos) {\n        if (clientPos) {\n            var zoom = this.$getZoom(this.el);\n            clientPos = mul(1 / zoom, clientPos);\n        }\n        function solve(l1, l2, r) {\n            var det = l1[1] * l2[0] - l1[0] * l2[1];\n            return [\n                (-l2[1] * r[0] + l2[0] * r[1]) / det,\n                (+l1[1] * r[0] - l1[0] * r[1]) / det\n            ];\n        }\n        function sub(a, b) { return [a[0] - b[0], a[1] - b[1]]; }\n        function add(a, b) { return [a[0] + b[0], a[1] + b[1]]; }\n        function mul(a, b) { return [a * b[0], a * b[1]]; }\n\n        if (!this.els)\n            this.$initTransformMeasureNodes();\n        \n        function p(el) {\n            var r = el.getBoundingClientRect();\n            return [r.left, r.top];\n        }\n\n        var a = p(this.els[0]);\n        var b = p(this.els[1]);\n        var c = p(this.els[2]);\n        var d = p(this.els[3]);\n\n        var h = solve(sub(d, b), sub(d, c), sub(add(b, c), add(d, a)));\n\n        var m1 = mul(1 + h[0], sub(b, a));\n        var m2 = mul(1 + h[1], sub(c, a));\n        \n        if (elPos) {\n            var x = elPos;\n            var k = h[0] * x[0] / L + h[1] * x[1] / L + 1;\n            var ut = add(mul(x[0], m1), mul(x[1], m2));\n            return  add(mul(1 / k / L, ut), a);\n        }\n        var u = sub(clientPos, a);\n        var f = solve(sub(m1, mul(h[0], u)), sub(m2, mul(h[1], u)), u);\n        return mul(L, f);\n    };\n    \n}).call(FontMetrics.prototype);\n\n});\n\nace.define(\"ace/virtual_renderer\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/dom\",\"ace/config\",\"ace/layer/gutter\",\"ace/layer/marker\",\"ace/layer/text\",\"ace/layer/cursor\",\"ace/scrollbar\",\"ace/scrollbar\",\"ace/renderloop\",\"ace/layer/font_metrics\",\"ace/lib/event_emitter\",\"ace/lib/useragent\"], function(require, exports, module) {\n\"use strict\";\n\nvar oop = require(\"./lib/oop\");\nvar dom = require(\"./lib/dom\");\nvar config = require(\"./config\");\nvar GutterLayer = require(\"./layer/gutter\").Gutter;\nvar MarkerLayer = require(\"./layer/marker\").Marker;\nvar TextLayer = require(\"./layer/text\").Text;\nvar CursorLayer = require(\"./layer/cursor\").Cursor;\nvar HScrollBar = require(\"./scrollbar\").HScrollBar;\nvar VScrollBar = require(\"./scrollbar\").VScrollBar;\nvar RenderLoop = require(\"./renderloop\").RenderLoop;\nvar FontMetrics = require(\"./layer/font_metrics\").FontMetrics;\nvar EventEmitter = require(\"./lib/event_emitter\").EventEmitter;\nvar editorCss = \"\\\n.ace_br1 {border-top-left-radius    : 3px;}\\\n.ace_br2 {border-top-right-radius   : 3px;}\\\n.ace_br3 {border-top-left-radius    : 3px; border-top-right-radius:    3px;}\\\n.ace_br4 {border-bottom-right-radius: 3px;}\\\n.ace_br5 {border-top-left-radius    : 3px; border-bottom-right-radius: 3px;}\\\n.ace_br6 {border-top-right-radius   : 3px; border-bottom-right-radius: 3px;}\\\n.ace_br7 {border-top-left-radius    : 3px; border-top-right-radius:    3px; border-bottom-right-radius: 3px;}\\\n.ace_br8 {border-bottom-left-radius : 3px;}\\\n.ace_br9 {border-top-left-radius    : 3px; border-bottom-left-radius:  3px;}\\\n.ace_br10{border-top-right-radius   : 3px; border-bottom-left-radius:  3px;}\\\n.ace_br11{border-top-left-radius    : 3px; border-top-right-radius:    3px; border-bottom-left-radius:  3px;}\\\n.ace_br12{border-bottom-right-radius: 3px; border-bottom-left-radius:  3px;}\\\n.ace_br13{border-top-left-radius    : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius:  3px;}\\\n.ace_br14{border-top-right-radius   : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius:  3px;}\\\n.ace_br15{border-top-left-radius    : 3px; border-top-right-radius:    3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}\\\n.ace_editor {\\\nposition: relative;\\\noverflow: hidden;\\\nfont: 12px/normal 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;\\\ndirection: ltr;\\\ntext-align: left;\\\n-webkit-tap-highlight-color: rgba(0, 0, 0, 0);\\\n}\\\n.ace_scroller {\\\nposition: absolute;\\\noverflow: hidden;\\\ntop: 0;\\\nbottom: 0;\\\nbackground-color: inherit;\\\n-ms-user-select: none;\\\n-moz-user-select: none;\\\n-webkit-user-select: none;\\\nuser-select: none;\\\ncursor: text;\\\n}\\\n.ace_content {\\\nposition: absolute;\\\nbox-sizing: border-box;\\\nmin-width: 100%;\\\ncontain: style size layout;\\\nfont-variant-ligatures: no-common-ligatures;\\\n}\\\n.ace_dragging .ace_scroller:before{\\\nposition: absolute;\\\ntop: 0;\\\nleft: 0;\\\nright: 0;\\\nbottom: 0;\\\ncontent: '';\\\nbackground: rgba(250, 250, 250, 0.01);\\\nz-index: 1000;\\\n}\\\n.ace_dragging.ace_dark .ace_scroller:before{\\\nbackground: rgba(0, 0, 0, 0.01);\\\n}\\\n.ace_selecting, .ace_selecting * {\\\ncursor: text !important;\\\n}\\\n.ace_gutter {\\\nposition: absolute;\\\noverflow : hidden;\\\nwidth: auto;\\\ntop: 0;\\\nbottom: 0;\\\nleft: 0;\\\ncursor: default;\\\nz-index: 4;\\\n-ms-user-select: none;\\\n-moz-user-select: none;\\\n-webkit-user-select: none;\\\nuser-select: none;\\\ncontain: style size layout;\\\n}\\\n.ace_gutter-active-line {\\\nposition: absolute;\\\nleft: 0;\\\nright: 0;\\\n}\\\n.ace_scroller.ace_scroll-left {\\\nbox-shadow: 17px 0 16px -16px rgba(0, 0, 0, 0.4) inset;\\\n}\\\n.ace_gutter-cell {\\\nposition: absolute;\\\ntop: 0;\\\nleft: 0;\\\nright: 0;\\\npadding-left: 19px;\\\npadding-right: 6px;\\\nbackground-repeat: no-repeat;\\\n}\\\n.ace_gutter-cell.ace_error {\\\nbackground-image: url(\\\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABOFBMVEX/////////QRswFAb/Ui4wFAYwFAYwFAaWGAfDRymzOSH/PxswFAb/SiUwFAYwFAbUPRvjQiDllog5HhHdRybsTi3/Tyv9Tir+Syj/UC3////XurebMBIwFAb/RSHbPx/gUzfdwL3kzMivKBAwFAbbvbnhPx66NhowFAYwFAaZJg8wFAaxKBDZurf/RB6mMxb/SCMwFAYwFAbxQB3+RB4wFAb/Qhy4Oh+4QifbNRcwFAYwFAYwFAb/QRzdNhgwFAYwFAbav7v/Uy7oaE68MBK5LxLewr/r2NXewLswFAaxJw4wFAbkPRy2PyYwFAaxKhLm1tMwFAazPiQwFAaUGAb/QBrfOx3bvrv/VC/maE4wFAbRPBq6MRO8Qynew8Dp2tjfwb0wFAbx6eju5+by6uns4uH9/f36+vr/GkHjAAAAYnRSTlMAGt+64rnWu/bo8eAA4InH3+DwoN7j4eLi4xP99Nfg4+b+/u9B/eDs1MD1mO7+4PHg2MXa347g7vDizMLN4eG+Pv7i5evs/v79yu7S3/DV7/498Yv24eH+4ufQ3Ozu/v7+y13sRqwAAADLSURBVHjaZc/XDsFgGIBhtDrshlitmk2IrbHFqL2pvXf/+78DPokj7+Fz9qpU/9UXJIlhmPaTaQ6QPaz0mm+5gwkgovcV6GZzd5JtCQwgsxoHOvJO15kleRLAnMgHFIESUEPmawB9ngmelTtipwwfASilxOLyiV5UVUyVAfbG0cCPHig+GBkzAENHS0AstVF6bacZIOzgLmxsHbt2OecNgJC83JERmePUYq8ARGkJx6XtFsdddBQgZE2nPR6CICZhawjA4Fb/chv+399kfR+MMMDGOQAAAABJRU5ErkJggg==\\\");\\\nbackground-repeat: no-repeat;\\\nbackground-position: 2px center;\\\n}\\\n.ace_gutter-cell.ace_warning {\\\nbackground-image: url(\\\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAmVBMVEX///8AAAD///8AAAAAAABPSzb/5sAAAAB/blH/73z/ulkAAAAAAAD85pkAAAAAAAACAgP/vGz/rkDerGbGrV7/pkQICAf////e0IsAAAD/oED/qTvhrnUAAAD/yHD/njcAAADuv2r/nz//oTj/p064oGf/zHAAAAA9Nir/tFIAAAD/tlTiuWf/tkIAAACynXEAAAAAAAAtIRW7zBpBAAAAM3RSTlMAABR1m7RXO8Ln31Z36zT+neXe5OzooRDfn+TZ4p3h2hTf4t3k3ucyrN1K5+Xaks52Sfs9CXgrAAAAjklEQVR42o3PbQ+CIBQFYEwboPhSYgoYunIqqLn6/z8uYdH8Vmdnu9vz4WwXgN/xTPRD2+sgOcZjsge/whXZgUaYYvT8QnuJaUrjrHUQreGczuEafQCO/SJTufTbroWsPgsllVhq3wJEk2jUSzX3CUEDJC84707djRc5MTAQxoLgupWRwW6UB5fS++NV8AbOZgnsC7BpEAAAAABJRU5ErkJggg==\\\");\\\nbackground-position: 2px center;\\\n}\\\n.ace_gutter-cell.ace_info {\\\nbackground-image: url(\\\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAAAAAA6mKC9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAJ0Uk5TAAB2k804AAAAPklEQVQY02NgIB68QuO3tiLznjAwpKTgNyDbMegwisCHZUETUZV0ZqOquBpXj2rtnpSJT1AEnnRmL2OgGgAAIKkRQap2htgAAAAASUVORK5CYII=\\\");\\\nbackground-position: 2px center;\\\n}\\\n.ace_dark .ace_gutter-cell.ace_info {\\\nbackground-image: url(\\\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAChoaGAgIAqKiq+vr6tra1ZWVmUlJSbm5s8PDxubm56enrdgzg3AAAAAXRSTlMAQObYZgAAAClJREFUeNpjYMAPdsMYHegyJZFQBlsUlMFVCWUYKkAZMxZAGdxlDMQBAG+TBP4B6RyJAAAAAElFTkSuQmCC\\\");\\\n}\\\n.ace_scrollbar {\\\ncontain: strict;\\\nposition: absolute;\\\nright: 0;\\\nbottom: 0;\\\nz-index: 6;\\\n}\\\n.ace_scrollbar-inner {\\\nposition: absolute;\\\ncursor: text;\\\nleft: 0;\\\ntop: 0;\\\n}\\\n.ace_scrollbar-v{\\\noverflow-x: hidden;\\\noverflow-y: scroll;\\\ntop: 0;\\\n}\\\n.ace_scrollbar-h {\\\noverflow-x: scroll;\\\noverflow-y: hidden;\\\nleft: 0;\\\n}\\\n.ace_print-margin {\\\nposition: absolute;\\\nheight: 100%;\\\n}\\\n.ace_text-input {\\\nposition: absolute;\\\nz-index: 0;\\\nwidth: 0.5em;\\\nheight: 1em;\\\nopacity: 0;\\\nbackground: transparent;\\\n-moz-appearance: none;\\\nappearance: none;\\\nborder: none;\\\nresize: none;\\\noutline: none;\\\noverflow: hidden;\\\nfont: inherit;\\\npadding: 0 1px;\\\nmargin: 0 -1px;\\\ncontain: strict;\\\n-ms-user-select: text;\\\n-moz-user-select: text;\\\n-webkit-user-select: text;\\\nuser-select: text;\\\nwhite-space: pre!important;\\\n}\\\n.ace_text-input.ace_composition {\\\nbackground: transparent;\\\ncolor: inherit;\\\nz-index: 1000;\\\nopacity: 1;\\\n}\\\n.ace_composition_placeholder { color: transparent }\\\n.ace_composition_marker { \\\nborder-bottom: 1px solid;\\\nposition: absolute;\\\nborder-radius: 0;\\\nmargin-top: 1px;\\\n}\\\n[ace_nocontext=true] {\\\ntransform: none!important;\\\nfilter: none!important;\\\nclip-path: none!important;\\\nmask : none!important;\\\ncontain: none!important;\\\nperspective: none!important;\\\nmix-blend-mode: initial!important;\\\nz-index: auto;\\\n}\\\n.ace_layer {\\\nz-index: 1;\\\nposition: absolute;\\\noverflow: hidden;\\\nword-wrap: normal;\\\nwhite-space: pre;\\\nheight: 100%;\\\nwidth: 100%;\\\nbox-sizing: border-box;\\\npointer-events: none;\\\n}\\\n.ace_gutter-layer {\\\nposition: relative;\\\nwidth: auto;\\\ntext-align: right;\\\npointer-events: auto;\\\nheight: 1000000px;\\\ncontain: style size layout;\\\n}\\\n.ace_text-layer {\\\nfont: inherit !important;\\\nposition: absolute;\\\nheight: 1000000px;\\\nwidth: 1000000px;\\\ncontain: style size layout;\\\n}\\\n.ace_text-layer > .ace_line, .ace_text-layer > .ace_line_group {\\\ncontain: style size layout;\\\nposition: absolute;\\\ntop: 0;\\\nleft: 0;\\\nright: 0;\\\n}\\\n.ace_hidpi .ace_text-layer,\\\n.ace_hidpi .ace_gutter-layer,\\\n.ace_hidpi .ace_content,\\\n.ace_hidpi .ace_gutter {\\\ncontain: strict;\\\nwill-change: transform;\\\n}\\\n.ace_hidpi .ace_text-layer > .ace_line, \\\n.ace_hidpi .ace_text-layer > .ace_line_group {\\\ncontain: strict;\\\n}\\\n.ace_cjk {\\\ndisplay: inline-block;\\\ntext-align: center;\\\n}\\\n.ace_cursor-layer {\\\nz-index: 4;\\\n}\\\n.ace_cursor {\\\nz-index: 4;\\\nposition: absolute;\\\nbox-sizing: border-box;\\\nborder-left: 2px solid;\\\ntransform: translatez(0);\\\n}\\\n.ace_multiselect .ace_cursor {\\\nborder-left-width: 1px;\\\n}\\\n.ace_slim-cursors .ace_cursor {\\\nborder-left-width: 1px;\\\n}\\\n.ace_overwrite-cursors .ace_cursor {\\\nborder-left-width: 0;\\\nborder-bottom: 1px solid;\\\n}\\\n.ace_hidden-cursors .ace_cursor {\\\nopacity: 0.2;\\\n}\\\n.ace_hasPlaceholder .ace_hidden-cursors .ace_cursor {\\\nopacity: 0;\\\n}\\\n.ace_smooth-blinking .ace_cursor {\\\ntransition: opacity 0.18s;\\\n}\\\n.ace_animate-blinking .ace_cursor {\\\nanimation-duration: 1000ms;\\\nanimation-timing-function: step-end;\\\nanimation-name: blink-ace-animate;\\\nanimation-iteration-count: infinite;\\\n}\\\n.ace_animate-blinking.ace_smooth-blinking .ace_cursor {\\\nanimation-duration: 1000ms;\\\nanimation-timing-function: ease-in-out;\\\nanimation-name: blink-ace-animate-smooth;\\\n}\\\n@keyframes blink-ace-animate {\\\nfrom, to { opacity: 1; }\\\n60% { opacity: 0; }\\\n}\\\n@keyframes blink-ace-animate-smooth {\\\nfrom, to { opacity: 1; }\\\n45% { opacity: 1; }\\\n60% { opacity: 0; }\\\n85% { opacity: 0; }\\\n}\\\n.ace_marker-layer .ace_step, .ace_marker-layer .ace_stack {\\\nposition: absolute;\\\nz-index: 3;\\\n}\\\n.ace_marker-layer .ace_selection {\\\nposition: absolute;\\\nz-index: 5;\\\n}\\\n.ace_marker-layer .ace_bracket {\\\nposition: absolute;\\\nz-index: 6;\\\n}\\\n.ace_marker-layer .ace_error_bracket {\\\nposition: absolute;\\\nborder-bottom: 1px solid #DE5555;\\\nborder-radius: 0;\\\n}\\\n.ace_marker-layer .ace_active-line {\\\nposition: absolute;\\\nz-index: 2;\\\n}\\\n.ace_marker-layer .ace_selected-word {\\\nposition: absolute;\\\nz-index: 4;\\\nbox-sizing: border-box;\\\n}\\\n.ace_line .ace_fold {\\\nbox-sizing: border-box;\\\ndisplay: inline-block;\\\nheight: 11px;\\\nmargin-top: -2px;\\\nvertical-align: middle;\\\nbackground-image:\\\nurl(\\\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII=\\\"),\\\nurl(\\\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACJJREFUeNpi+P//fxgTAwPDBxDxD078RSX+YeEyDFMCIMAAI3INmXiwf2YAAAAASUVORK5CYII=\\\");\\\nbackground-repeat: no-repeat, repeat-x;\\\nbackground-position: center center, top left;\\\ncolor: transparent;\\\nborder: 1px solid black;\\\nborder-radius: 2px;\\\ncursor: pointer;\\\npointer-events: auto;\\\n}\\\n.ace_dark .ace_fold {\\\n}\\\n.ace_fold:hover{\\\nbackground-image:\\\nurl(\\\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII=\\\"),\\\nurl(\\\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACBJREFUeNpi+P//fz4TAwPDZxDxD5X4i5fLMEwJgAADAEPVDbjNw87ZAAAAAElFTkSuQmCC\\\");\\\n}\\\n.ace_tooltip {\\\nbackground-color: #FFF;\\\nbackground-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.1));\\\nborder: 1px solid gray;\\\nborder-radius: 1px;\\\nbox-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);\\\ncolor: black;\\\nmax-width: 100%;\\\npadding: 3px 4px;\\\nposition: fixed;\\\nz-index: 999999;\\\nbox-sizing: border-box;\\\ncursor: default;\\\nwhite-space: pre;\\\nword-wrap: break-word;\\\nline-height: normal;\\\nfont-style: normal;\\\nfont-weight: normal;\\\nletter-spacing: normal;\\\npointer-events: none;\\\n}\\\n.ace_folding-enabled > .ace_gutter-cell {\\\npadding-right: 13px;\\\n}\\\n.ace_fold-widget {\\\nbox-sizing: border-box;\\\nmargin: 0 -12px 0 1px;\\\ndisplay: none;\\\nwidth: 11px;\\\nvertical-align: top;\\\nbackground-image: url(\\\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42mWKsQ0AMAzC8ixLlrzQjzmBiEjp0A6WwBCSPgKAXoLkqSot7nN3yMwR7pZ32NzpKkVoDBUxKAAAAABJRU5ErkJggg==\\\");\\\nbackground-repeat: no-repeat;\\\nbackground-position: center;\\\nborder-radius: 3px;\\\nborder: 1px solid transparent;\\\ncursor: pointer;\\\n}\\\n.ace_folding-enabled .ace_fold-widget {\\\ndisplay: inline-block;   \\\n}\\\n.ace_fold-widget.ace_end {\\\nbackground-image: url(\\\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42m3HwQkAMAhD0YzsRchFKI7sAikeWkrxwScEB0nh5e7KTPWimZki4tYfVbX+MNl4pyZXejUO1QAAAABJRU5ErkJggg==\\\");\\\n}\\\n.ace_fold-widget.ace_closed {\\\nbackground-image: url(\\\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAGCAYAAAAG5SQMAAAAOUlEQVR42jXKwQkAMAgDwKwqKD4EwQ26sSOkVWjgIIHAzPiCgaqiqnJHZnKICBERHN194O5b9vbLuAVRL+l0YWnZAAAAAElFTkSuQmCCXA==\\\");\\\n}\\\n.ace_fold-widget:hover {\\\nborder: 1px solid rgba(0, 0, 0, 0.3);\\\nbackground-color: rgba(255, 255, 255, 0.2);\\\nbox-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);\\\n}\\\n.ace_fold-widget:active {\\\nborder: 1px solid rgba(0, 0, 0, 0.4);\\\nbackground-color: rgba(0, 0, 0, 0.05);\\\nbox-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);\\\n}\\\n.ace_dark .ace_fold-widget {\\\nbackground-image: url(\\\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHklEQVQIW2P4//8/AzoGEQ7oGCaLLAhWiSwB146BAQCSTPYocqT0AAAAAElFTkSuQmCC\\\");\\\n}\\\n.ace_dark .ace_fold-widget.ace_end {\\\nbackground-image: url(\\\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAH0lEQVQIW2P4//8/AxQ7wNjIAjDMgC4AxjCVKBirIAAF0kz2rlhxpAAAAABJRU5ErkJggg==\\\");\\\n}\\\n.ace_dark .ace_fold-widget.ace_closed {\\\nbackground-image: url(\\\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAHElEQVQIW2P4//+/AxAzgDADlOOAznHAKgPWAwARji8UIDTfQQAAAABJRU5ErkJggg==\\\");\\\n}\\\n.ace_dark .ace_fold-widget:hover {\\\nbox-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);\\\nbackground-color: rgba(255, 255, 255, 0.1);\\\n}\\\n.ace_dark .ace_fold-widget:active {\\\nbox-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);\\\n}\\\n.ace_inline_button {\\\nborder: 1px solid lightgray;\\\ndisplay: inline-block;\\\nmargin: -1px 8px;\\\npadding: 0 5px;\\\npointer-events: auto;\\\ncursor: pointer;\\\n}\\\n.ace_inline_button:hover {\\\nborder-color: gray;\\\nbackground: rgba(200,200,200,0.2);\\\ndisplay: inline-block;\\\npointer-events: auto;\\\n}\\\n.ace_fold-widget.ace_invalid {\\\nbackground-color: #FFB4B4;\\\nborder-color: #DE5555;\\\n}\\\n.ace_fade-fold-widgets .ace_fold-widget {\\\ntransition: opacity 0.4s ease 0.05s;\\\nopacity: 0;\\\n}\\\n.ace_fade-fold-widgets:hover .ace_fold-widget {\\\ntransition: opacity 0.05s ease 0.05s;\\\nopacity:1;\\\n}\\\n.ace_underline {\\\ntext-decoration: underline;\\\n}\\\n.ace_bold {\\\nfont-weight: bold;\\\n}\\\n.ace_nobold .ace_bold {\\\nfont-weight: normal;\\\n}\\\n.ace_italic {\\\nfont-style: italic;\\\n}\\\n.ace_error-marker {\\\nbackground-color: rgba(255, 0, 0,0.2);\\\nposition: absolute;\\\nz-index: 9;\\\n}\\\n.ace_highlight-marker {\\\nbackground-color: rgba(255, 255, 0,0.2);\\\nposition: absolute;\\\nz-index: 8;\\\n}\\\n.ace_mobile-menu {\\\nposition: absolute;\\\nline-height: 1.5;\\\nborder-radius: 4px;\\\n-ms-user-select: none;\\\n-moz-user-select: none;\\\n-webkit-user-select: none;\\\nuser-select: none;\\\nbackground: white;\\\nbox-shadow: 1px 3px 2px grey;\\\nborder: 1px solid #dcdcdc;\\\ncolor: black;\\\n}\\\n.ace_dark > .ace_mobile-menu {\\\nbackground: #333;\\\ncolor: #ccc;\\\nbox-shadow: 1px 3px 2px grey;\\\nborder: 1px solid #444;\\\n}\\\n.ace_mobile-button {\\\npadding: 2px;\\\ncursor: pointer;\\\noverflow: hidden;\\\n}\\\n.ace_mobile-button:hover {\\\nbackground-color: #eee;\\\nopacity:1;\\\n}\\\n.ace_mobile-button:active {\\\nbackground-color: #ddd;\\\n}\\\n.ace_placeholder {\\\nfont-family: arial;\\\ntransform: scale(0.9);\\\ntransform-origin: left;\\\nwhite-space: pre;\\\nopacity: 0.7;\\\nmargin: 0 10px;\\\n}\";\n\nvar useragent = require(\"./lib/useragent\");\nvar HIDE_TEXTAREA = useragent.isIE;\n\ndom.importCssString(editorCss, \"ace_editor.css\");\n\nvar VirtualRenderer = function(container, theme) {\n    var _self = this;\n\n    this.container = container || dom.createElement(\"div\");\n\n    dom.addCssClass(this.container, \"ace_editor\");\n    if (dom.HI_DPI) dom.addCssClass(this.container, \"ace_hidpi\");\n\n    this.setTheme(theme);\n\n    this.$gutter = dom.createElement(\"div\");\n    this.$gutter.className = \"ace_gutter\";\n    this.container.appendChild(this.$gutter);\n    this.$gutter.setAttribute(\"aria-hidden\", true);\n\n    this.scroller = dom.createElement(\"div\");\n    this.scroller.className = \"ace_scroller\";\n    \n    this.container.appendChild(this.scroller);\n\n    this.content = dom.createElement(\"div\");\n    this.content.className = \"ace_content\";\n    this.scroller.appendChild(this.content);\n\n    this.$gutterLayer = new GutterLayer(this.$gutter);\n    this.$gutterLayer.on(\"changeGutterWidth\", this.onGutterResize.bind(this));\n\n    this.$markerBack = new MarkerLayer(this.content);\n\n    var textLayer = this.$textLayer = new TextLayer(this.content);\n    this.canvas = textLayer.element;\n\n    this.$markerFront = new MarkerLayer(this.content);\n\n    this.$cursorLayer = new CursorLayer(this.content);\n    this.$horizScroll = false;\n    this.$vScroll = false;\n\n    this.scrollBar = \n    this.scrollBarV = new VScrollBar(this.container, this);\n    this.scrollBarH = new HScrollBar(this.container, this);\n    this.scrollBarV.addEventListener(\"scroll\", function(e) {\n        if (!_self.$scrollAnimation)\n            _self.session.setScrollTop(e.data - _self.scrollMargin.top);\n    });\n    this.scrollBarH.addEventListener(\"scroll\", function(e) {\n        if (!_self.$scrollAnimation)\n            _self.session.setScrollLeft(e.data - _self.scrollMargin.left);\n    });\n\n    this.scrollTop = 0;\n    this.scrollLeft = 0;\n\n    this.cursorPos = {\n        row : 0,\n        column : 0\n    };\n\n    this.$fontMetrics = new FontMetrics(this.container);\n    this.$textLayer.$setFontMetrics(this.$fontMetrics);\n    this.$textLayer.addEventListener(\"changeCharacterSize\", function(e) {\n        _self.updateCharacterSize();\n        _self.onResize(true, _self.gutterWidth, _self.$size.width, _self.$size.height);\n        _self._signal(\"changeCharacterSize\", e);\n    });\n\n    this.$size = {\n        width: 0,\n        height: 0,\n        scrollerHeight: 0,\n        scrollerWidth: 0,\n        $dirty: true\n    };\n\n    this.layerConfig = {\n        width : 1,\n        padding : 0,\n        firstRow : 0,\n        firstRowScreen: 0,\n        lastRow : 0,\n        lineHeight : 0,\n        characterWidth : 0,\n        minHeight : 1,\n        maxHeight : 1,\n        offset : 0,\n        height : 1,\n        gutterOffset: 1\n    };\n    \n    this.scrollMargin = {\n        left: 0,\n        right: 0,\n        top: 0,\n        bottom: 0,\n        v: 0,\n        h: 0\n    };\n    \n    this.margin = {\n        left: 0,\n        right: 0,\n        top: 0,\n        bottom: 0,\n        v: 0,\n        h: 0\n    };\n    \n    this.$keepTextAreaAtCursor = !useragent.isIOS;\n\n    this.$loop = new RenderLoop(\n        this.$renderChanges.bind(this),\n        this.container.ownerDocument.defaultView\n    );\n    this.$loop.schedule(this.CHANGE_FULL);\n\n    this.updateCharacterSize();\n    this.setPadding(4);\n    config.resetOptions(this);\n    config._signal(\"renderer\", this);\n};\n\n(function() {\n\n    this.CHANGE_CURSOR = 1;\n    this.CHANGE_MARKER = 2;\n    this.CHANGE_GUTTER = 4;\n    this.CHANGE_SCROLL = 8;\n    this.CHANGE_LINES = 16;\n    this.CHANGE_TEXT = 32;\n    this.CHANGE_SIZE = 64;\n    this.CHANGE_MARKER_BACK = 128;\n    this.CHANGE_MARKER_FRONT = 256;\n    this.CHANGE_FULL = 512;\n    this.CHANGE_H_SCROLL = 1024;\n\n    oop.implement(this, EventEmitter);\n\n    this.updateCharacterSize = function() {\n        if (this.$textLayer.allowBoldFonts != this.$allowBoldFonts) {\n            this.$allowBoldFonts = this.$textLayer.allowBoldFonts;\n            this.setStyle(\"ace_nobold\", !this.$allowBoldFonts);\n        }\n\n        this.layerConfig.characterWidth =\n        this.characterWidth = this.$textLayer.getCharacterWidth();\n        this.layerConfig.lineHeight =\n        this.lineHeight = this.$textLayer.getLineHeight();\n        this.$updatePrintMargin();\n        dom.setStyle(this.scroller.style, \"line-height\", this.lineHeight + \"px\");\n    };\n    this.setSession = function(session) {\n        if (this.session)\n            this.session.doc.off(\"changeNewLineMode\", this.onChangeNewLineMode);\n            \n        this.session = session;\n        if (session && this.scrollMargin.top && session.getScrollTop() <= 0)\n            session.setScrollTop(-this.scrollMargin.top);\n\n        this.$cursorLayer.setSession(session);\n        this.$markerBack.setSession(session);\n        this.$markerFront.setSession(session);\n        this.$gutterLayer.setSession(session);\n        this.$textLayer.setSession(session);\n        if (!session)\n            return;\n        \n        this.$loop.schedule(this.CHANGE_FULL);\n        this.session.$setFontMetrics(this.$fontMetrics);\n        this.scrollBarH.scrollLeft = this.scrollBarV.scrollTop = null;\n        \n        this.onChangeNewLineMode = this.onChangeNewLineMode.bind(this);\n        this.onChangeNewLineMode();\n        this.session.doc.on(\"changeNewLineMode\", this.onChangeNewLineMode);\n    };\n    this.updateLines = function(firstRow, lastRow, force) {\n        if (lastRow === undefined)\n            lastRow = Infinity;\n\n        if (!this.$changedLines) {\n            this.$changedLines = {\n                firstRow: firstRow,\n                lastRow: lastRow\n            };\n        }\n        else {\n            if (this.$changedLines.firstRow > firstRow)\n                this.$changedLines.firstRow = firstRow;\n\n            if (this.$changedLines.lastRow < lastRow)\n                this.$changedLines.lastRow = lastRow;\n        }\n        if (this.$changedLines.lastRow < this.layerConfig.firstRow) {\n            if (force)\n                this.$changedLines.lastRow = this.layerConfig.lastRow;\n            else\n                return;\n        }\n        if (this.$changedLines.firstRow > this.layerConfig.lastRow)\n            return;\n        this.$loop.schedule(this.CHANGE_LINES);\n    };\n\n    this.onChangeNewLineMode = function() {\n        this.$loop.schedule(this.CHANGE_TEXT);\n        this.$textLayer.$updateEolChar();\n        this.session.$bidiHandler.setEolChar(this.$textLayer.EOL_CHAR);\n    };\n    \n    this.onChangeTabSize = function() {\n        this.$loop.schedule(this.CHANGE_TEXT | this.CHANGE_MARKER);\n        this.$textLayer.onChangeTabSize();\n    };\n    this.updateText = function() {\n        this.$loop.schedule(this.CHANGE_TEXT);\n    };\n    this.updateFull = function(force) {\n        if (force)\n            this.$renderChanges(this.CHANGE_FULL, true);\n        else\n            this.$loop.schedule(this.CHANGE_FULL);\n    };\n    this.updateFontSize = function() {\n        this.$textLayer.checkForSizeChanges();\n    };\n\n    this.$changes = 0;\n    this.$updateSizeAsync = function() {\n        if (this.$loop.pending)\n            this.$size.$dirty = true;\n        else\n            this.onResize();\n    };\n    this.onResize = function(force, gutterWidth, width, height) {\n        if (this.resizing > 2)\n            return;\n        else if (this.resizing > 0)\n            this.resizing++;\n        else\n            this.resizing = force ? 1 : 0;\n        var el = this.container;\n        if (!height)\n            height = el.clientHeight || el.scrollHeight;\n        if (!width)\n            width = el.clientWidth || el.scrollWidth;\n        var changes = this.$updateCachedSize(force, gutterWidth, width, height);\n\n        \n        if (!this.$size.scrollerHeight || (!width && !height))\n            return this.resizing = 0;\n\n        if (force)\n            this.$gutterLayer.$padding = null;\n\n        if (force)\n            this.$renderChanges(changes | this.$changes, true);\n        else\n            this.$loop.schedule(changes | this.$changes);\n\n        if (this.resizing)\n            this.resizing = 0;\n        this.scrollBarV.scrollLeft = this.scrollBarV.scrollTop = null;\n    };\n    \n    this.$updateCachedSize = function(force, gutterWidth, width, height) {\n        height -= (this.$extraHeight || 0);\n        var changes = 0;\n        var size = this.$size;\n        var oldSize = {\n            width: size.width,\n            height: size.height,\n            scrollerHeight: size.scrollerHeight,\n            scrollerWidth: size.scrollerWidth\n        };\n        if (height && (force || size.height != height)) {\n            size.height = height;\n            changes |= this.CHANGE_SIZE;\n\n            size.scrollerHeight = size.height;\n            if (this.$horizScroll)\n                size.scrollerHeight -= this.scrollBarH.getHeight();\n            this.scrollBarV.element.style.bottom = this.scrollBarH.getHeight() + \"px\";\n\n            changes = changes | this.CHANGE_SCROLL;\n        }\n\n        if (width && (force || size.width != width)) {\n            changes |= this.CHANGE_SIZE;\n            size.width = width;\n            \n            if (gutterWidth == null)\n                gutterWidth = this.$showGutter ? this.$gutter.offsetWidth : 0;\n            \n            this.gutterWidth = gutterWidth;\n            \n            dom.setStyle(this.scrollBarH.element.style, \"left\", gutterWidth + \"px\");\n            dom.setStyle(this.scroller.style, \"left\", gutterWidth + this.margin.left + \"px\");\n            size.scrollerWidth = Math.max(0, width - gutterWidth - this.scrollBarV.getWidth() - this.margin.h);\n            dom.setStyle(this.$gutter.style, \"left\", this.margin.left + \"px\");\n            \n            var right = this.scrollBarV.getWidth() + \"px\";\n            dom.setStyle(this.scrollBarH.element.style, \"right\", right);\n            dom.setStyle(this.scroller.style, \"right\", right);\n            dom.setStyle(this.scroller.style, \"bottom\", this.scrollBarH.getHeight());\n\n            if (this.session && this.session.getUseWrapMode() && this.adjustWrapLimit() || force) {\n                changes |= this.CHANGE_FULL;\n            }\n        }\n        \n        size.$dirty = !width || !height;\n\n        if (changes)\n            this._signal(\"resize\", oldSize);\n\n        return changes;\n    };\n\n    this.onGutterResize = function(width) {\n        var gutterWidth = this.$showGutter ? width : 0;\n        if (gutterWidth != this.gutterWidth)\n            this.$changes |= this.$updateCachedSize(true, gutterWidth, this.$size.width, this.$size.height);\n\n        if (this.session.getUseWrapMode() && this.adjustWrapLimit()) {\n            this.$loop.schedule(this.CHANGE_FULL);\n        } else if (this.$size.$dirty) {\n            this.$loop.schedule(this.CHANGE_FULL);\n        } else {\n            this.$computeLayerConfig();\n        }\n    };\n    this.adjustWrapLimit = function() {\n        var availableWidth = this.$size.scrollerWidth - this.$padding * 2;\n        var limit = Math.floor(availableWidth / this.characterWidth);\n        return this.session.adjustWrapLimit(limit, this.$showPrintMargin && this.$printMarginColumn);\n    };\n    this.setAnimatedScroll = function(shouldAnimate){\n        this.setOption(\"animatedScroll\", shouldAnimate);\n    };\n    this.getAnimatedScroll = function() {\n        return this.$animatedScroll;\n    };\n    this.setShowInvisibles = function(showInvisibles) {\n        this.setOption(\"showInvisibles\", showInvisibles);\n        this.session.$bidiHandler.setShowInvisibles(showInvisibles);\n    };\n    this.getShowInvisibles = function() {\n        return this.getOption(\"showInvisibles\");\n    };\n    this.getDisplayIndentGuides = function() {\n        return this.getOption(\"displayIndentGuides\");\n    };\n\n    this.setDisplayIndentGuides = function(display) {\n        this.setOption(\"displayIndentGuides\", display);\n    };\n    this.setShowPrintMargin = function(showPrintMargin) {\n        this.setOption(\"showPrintMargin\", showPrintMargin);\n    };\n    this.getShowPrintMargin = function() {\n        return this.getOption(\"showPrintMargin\");\n    };\n    this.setPrintMarginColumn = function(showPrintMargin) {\n        this.setOption(\"printMarginColumn\", showPrintMargin);\n    };\n    this.getPrintMarginColumn = function() {\n        return this.getOption(\"printMarginColumn\");\n    };\n    this.getShowGutter = function(){\n        return this.getOption(\"showGutter\");\n    };\n    this.setShowGutter = function(show){\n        return this.setOption(\"showGutter\", show);\n    };\n\n    this.getFadeFoldWidgets = function(){\n        return this.getOption(\"fadeFoldWidgets\");\n    };\n\n    this.setFadeFoldWidgets = function(show) {\n        this.setOption(\"fadeFoldWidgets\", show);\n    };\n\n    this.setHighlightGutterLine = function(shouldHighlight) {\n        this.setOption(\"highlightGutterLine\", shouldHighlight);\n    };\n\n    this.getHighlightGutterLine = function() {\n        return this.getOption(\"highlightGutterLine\");\n    };\n\n    this.$updatePrintMargin = function() {\n        if (!this.$showPrintMargin && !this.$printMarginEl)\n            return;\n\n        if (!this.$printMarginEl) {\n            var containerEl = dom.createElement(\"div\");\n            containerEl.className = \"ace_layer ace_print-margin-layer\";\n            this.$printMarginEl = dom.createElement(\"div\");\n            this.$printMarginEl.className = \"ace_print-margin\";\n            containerEl.appendChild(this.$printMarginEl);\n            this.content.insertBefore(containerEl, this.content.firstChild);\n        }\n\n        var style = this.$printMarginEl.style;\n        style.left = Math.round(this.characterWidth * this.$printMarginColumn + this.$padding) + \"px\";\n        style.visibility = this.$showPrintMargin ? \"visible\" : \"hidden\";\n        \n        if (this.session && this.session.$wrap == -1)\n            this.adjustWrapLimit();\n    };\n    this.getContainerElement = function() {\n        return this.container;\n    };\n    this.getMouseEventTarget = function() {\n        return this.scroller;\n    };\n    this.getTextAreaContainer = function() {\n        return this.container;\n    };\n    this.$moveTextAreaToCursor = function() {\n        if (this.$isMousePressed) return;\n        var style = this.textarea.style;\n        var composition = this.$composition;\n        if (!this.$keepTextAreaAtCursor && !composition) {\n            dom.translate(this.textarea, -100, 0);\n            return;\n        }\n        var pixelPos = this.$cursorLayer.$pixelPos;\n        if (!pixelPos)\n            return;\n        if (composition && composition.markerRange)\n            pixelPos = this.$cursorLayer.getPixelPosition(composition.markerRange.start, true);\n        \n        var config = this.layerConfig;\n        var posTop = pixelPos.top;\n        var posLeft = pixelPos.left;\n        posTop -= config.offset;\n\n        var h = composition && composition.useTextareaForIME ? this.lineHeight : HIDE_TEXTAREA ? 0 : 1;\n        if (posTop < 0 || posTop > config.height - h) {\n            dom.translate(this.textarea, 0, 0);\n            return;\n        }\n\n        var w = 1;\n        var maxTop = this.$size.height - h;\n        if (!composition) {\n            posTop += this.lineHeight;\n        }\n        else {\n            if (composition.useTextareaForIME) {\n                var val = this.textarea.value;\n                w = this.characterWidth * (this.session.$getStringScreenWidth(val)[0]);\n            }\n            else {\n                posTop += this.lineHeight + 2;\n            }\n        }\n        \n        posLeft -= this.scrollLeft;\n        if (posLeft > this.$size.scrollerWidth - w)\n            posLeft = this.$size.scrollerWidth - w;\n\n        posLeft += this.gutterWidth + this.margin.left;\n\n        dom.setStyle(style, \"height\", h + \"px\");\n        dom.setStyle(style, \"width\", w + \"px\");\n        dom.translate(this.textarea, Math.min(posLeft, this.$size.scrollerWidth - w), Math.min(posTop, maxTop));\n    };\n    this.getFirstVisibleRow = function() {\n        return this.layerConfig.firstRow;\n    };\n    this.getFirstFullyVisibleRow = function() {\n        return this.layerConfig.firstRow + (this.layerConfig.offset === 0 ? 0 : 1);\n    };\n    this.getLastFullyVisibleRow = function() {\n        var config = this.layerConfig;\n        var lastRow = config.lastRow;\n        var top = this.session.documentToScreenRow(lastRow, 0) * config.lineHeight;\n        if (top - this.session.getScrollTop() > config.height - config.lineHeight)\n            return lastRow - 1;\n        return lastRow;\n    };\n    this.getLastVisibleRow = function() {\n        return this.layerConfig.lastRow;\n    };\n\n    this.$padding = null;\n    this.setPadding = function(padding) {\n        this.$padding = padding;\n        this.$textLayer.setPadding(padding);\n        this.$cursorLayer.setPadding(padding);\n        this.$markerFront.setPadding(padding);\n        this.$markerBack.setPadding(padding);\n        this.$loop.schedule(this.CHANGE_FULL);\n        this.$updatePrintMargin();\n    };\n    \n    this.setScrollMargin = function(top, bottom, left, right) {\n        var sm = this.scrollMargin;\n        sm.top = top|0;\n        sm.bottom = bottom|0;\n        sm.right = right|0;\n        sm.left = left|0;\n        sm.v = sm.top + sm.bottom;\n        sm.h = sm.left + sm.right;\n        if (sm.top && this.scrollTop <= 0 && this.session)\n            this.session.setScrollTop(-sm.top);\n        this.updateFull();\n    };\n    \n    this.setMargin = function(top, bottom, left, right) {\n        var sm = this.margin;\n        sm.top = top|0;\n        sm.bottom = bottom|0;\n        sm.right = right|0;\n        sm.left = left|0;\n        sm.v = sm.top + sm.bottom;\n        sm.h = sm.left + sm.right;\n        this.$updateCachedSize(true, this.gutterWidth, this.$size.width, this.$size.height);\n        this.updateFull();\n    };\n    this.getHScrollBarAlwaysVisible = function() {\n        return this.$hScrollBarAlwaysVisible;\n    };\n    this.setHScrollBarAlwaysVisible = function(alwaysVisible) {\n        this.setOption(\"hScrollBarAlwaysVisible\", alwaysVisible);\n    };\n    this.getVScrollBarAlwaysVisible = function() {\n        return this.$vScrollBarAlwaysVisible;\n    };\n    this.setVScrollBarAlwaysVisible = function(alwaysVisible) {\n        this.setOption(\"vScrollBarAlwaysVisible\", alwaysVisible);\n    };\n\n    this.$updateScrollBarV = function() {\n        var scrollHeight = this.layerConfig.maxHeight;\n        var scrollerHeight = this.$size.scrollerHeight;\n        if (!this.$maxLines && this.$scrollPastEnd) {\n            scrollHeight -= (scrollerHeight - this.lineHeight) * this.$scrollPastEnd;\n            if (this.scrollTop > scrollHeight - scrollerHeight) {\n                scrollHeight = this.scrollTop + scrollerHeight;\n                this.scrollBarV.scrollTop = null;\n            }\n        }\n        this.scrollBarV.setScrollHeight(scrollHeight + this.scrollMargin.v);\n        this.scrollBarV.setScrollTop(this.scrollTop + this.scrollMargin.top);\n    };\n    this.$updateScrollBarH = function() {\n        this.scrollBarH.setScrollWidth(this.layerConfig.width + 2 * this.$padding + this.scrollMargin.h);\n        this.scrollBarH.setScrollLeft(this.scrollLeft + this.scrollMargin.left);\n    };\n    \n    this.$frozen = false;\n    this.freeze = function() {\n        this.$frozen = true;\n    };\n    \n    this.unfreeze = function() {\n        this.$frozen = false;\n    };\n\n    this.$renderChanges = function(changes, force) {\n        if (this.$changes) {\n            changes |= this.$changes;\n            this.$changes = 0;\n        }\n        if ((!this.session || !this.container.offsetWidth || this.$frozen) || (!changes && !force)) {\n            this.$changes |= changes;\n            return; \n        } \n        if (this.$size.$dirty) {\n            this.$changes |= changes;\n            return this.onResize(true);\n        }\n        if (!this.lineHeight) {\n            this.$textLayer.checkForSizeChanges();\n        }\n        \n        this._signal(\"beforeRender\", changes);\n        \n        if (this.session && this.session.$bidiHandler)\n            this.session.$bidiHandler.updateCharacterWidths(this.$fontMetrics);\n\n        var config = this.layerConfig;\n        if (changes & this.CHANGE_FULL ||\n            changes & this.CHANGE_SIZE ||\n            changes & this.CHANGE_TEXT ||\n            changes & this.CHANGE_LINES ||\n            changes & this.CHANGE_SCROLL ||\n            changes & this.CHANGE_H_SCROLL\n        ) {\n            changes |= this.$computeLayerConfig() | this.$loop.clear();\n            if (config.firstRow != this.layerConfig.firstRow && config.firstRowScreen == this.layerConfig.firstRowScreen) {\n                var st = this.scrollTop + (config.firstRow - this.layerConfig.firstRow) * this.lineHeight;\n                if (st > 0) {\n                    this.scrollTop = st;\n                    changes = changes | this.CHANGE_SCROLL;\n                    changes |= this.$computeLayerConfig() | this.$loop.clear();\n                }\n            }\n            config = this.layerConfig;\n            this.$updateScrollBarV();\n            if (changes & this.CHANGE_H_SCROLL)\n                this.$updateScrollBarH();\n            \n            dom.translate(this.content, -this.scrollLeft, -config.offset);\n            \n            var width = config.width + 2 * this.$padding + \"px\";\n            var height = config.minHeight + \"px\";\n            \n            dom.setStyle(this.content.style, \"width\", width);\n            dom.setStyle(this.content.style, \"height\", height);\n        }\n        if (changes & this.CHANGE_H_SCROLL) {\n            dom.translate(this.content, -this.scrollLeft, -config.offset);\n            this.scroller.className = this.scrollLeft <= 0 ? \"ace_scroller\" : \"ace_scroller ace_scroll-left\";\n        }\n        if (changes & this.CHANGE_FULL) {\n            this.$changedLines = null;\n            this.$textLayer.update(config);\n            if (this.$showGutter)\n                this.$gutterLayer.update(config);\n            this.$markerBack.update(config);\n            this.$markerFront.update(config);\n            this.$cursorLayer.update(config);\n            this.$moveTextAreaToCursor();\n            this._signal(\"afterRender\", changes);\n            return;\n        }\n        if (changes & this.CHANGE_SCROLL) {\n            this.$changedLines = null;\n            if (changes & this.CHANGE_TEXT || changes & this.CHANGE_LINES)\n                this.$textLayer.update(config);\n            else\n                this.$textLayer.scrollLines(config);\n\n            if (this.$showGutter) {\n                if (changes & this.CHANGE_GUTTER || changes & this.CHANGE_LINES)\n                    this.$gutterLayer.update(config);\n                else\n                    this.$gutterLayer.scrollLines(config);\n            }\n            this.$markerBack.update(config);\n            this.$markerFront.update(config);\n            this.$cursorLayer.update(config);\n            this.$moveTextAreaToCursor();\n            this._signal(\"afterRender\", changes);\n            return;\n        }\n\n        if (changes & this.CHANGE_TEXT) {\n            this.$changedLines = null;\n            this.$textLayer.update(config);\n            if (this.$showGutter)\n                this.$gutterLayer.update(config);\n        }\n        else if (changes & this.CHANGE_LINES) {\n            if (this.$updateLines() || (changes & this.CHANGE_GUTTER) && this.$showGutter)\n                this.$gutterLayer.update(config);\n        }\n        else if (changes & this.CHANGE_TEXT || changes & this.CHANGE_GUTTER) {\n            if (this.$showGutter)\n                this.$gutterLayer.update(config);\n        }\n        else if (changes & this.CHANGE_CURSOR) {\n            if (this.$highlightGutterLine)\n                this.$gutterLayer.updateLineHighlight(config);\n        }\n\n        if (changes & this.CHANGE_CURSOR) {\n            this.$cursorLayer.update(config);\n            this.$moveTextAreaToCursor();\n        }\n\n        if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_FRONT)) {\n            this.$markerFront.update(config);\n        }\n\n        if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_BACK)) {\n            this.$markerBack.update(config);\n        }\n\n        this._signal(\"afterRender\", changes);\n    };\n\n    \n    this.$autosize = function() {\n        var height = this.session.getScreenLength() * this.lineHeight;\n        var maxHeight = this.$maxLines * this.lineHeight;\n        var desiredHeight = Math.min(maxHeight, \n            Math.max((this.$minLines || 1) * this.lineHeight, height)\n        ) + this.scrollMargin.v + (this.$extraHeight || 0);\n        if (this.$horizScroll)\n            desiredHeight += this.scrollBarH.getHeight();\n        if (this.$maxPixelHeight && desiredHeight > this.$maxPixelHeight)\n            desiredHeight = this.$maxPixelHeight;\n        \n        var hideScrollbars = desiredHeight <= 2 * this.lineHeight;\n        var vScroll = !hideScrollbars && height > maxHeight;\n        \n        if (desiredHeight != this.desiredHeight ||\n            this.$size.height != this.desiredHeight || vScroll != this.$vScroll) {\n            if (vScroll != this.$vScroll) {\n                this.$vScroll = vScroll;\n                this.scrollBarV.setVisible(vScroll);\n            }\n            \n            var w = this.container.clientWidth;\n            this.container.style.height = desiredHeight + \"px\";\n            this.$updateCachedSize(true, this.$gutterWidth, w, desiredHeight);\n            this.desiredHeight = desiredHeight;\n            \n            this._signal(\"autosize\");\n        }\n    };\n    \n    this.$computeLayerConfig = function() {\n        var session = this.session;\n        var size = this.$size;\n        \n        var hideScrollbars = size.height <= 2 * this.lineHeight;\n        var screenLines = this.session.getScreenLength();\n        var maxHeight = screenLines * this.lineHeight;\n\n        var longestLine = this.$getLongestLine();\n        \n        var horizScroll = !hideScrollbars && (this.$hScrollBarAlwaysVisible ||\n            size.scrollerWidth - longestLine - 2 * this.$padding < 0);\n\n        var hScrollChanged = this.$horizScroll !== horizScroll;\n        if (hScrollChanged) {\n            this.$horizScroll = horizScroll;\n            this.scrollBarH.setVisible(horizScroll);\n        }\n        var vScrollBefore = this.$vScroll; // autosize can change vscroll value in which case we need to update longestLine\n        if (this.$maxLines && this.lineHeight > 1)\n            this.$autosize();\n\n        var minHeight = size.scrollerHeight + this.lineHeight;\n        \n        var scrollPastEnd = !this.$maxLines && this.$scrollPastEnd\n            ? (size.scrollerHeight - this.lineHeight) * this.$scrollPastEnd\n            : 0;\n        maxHeight += scrollPastEnd;\n        \n        var sm = this.scrollMargin;\n        this.session.setScrollTop(Math.max(-sm.top,\n            Math.min(this.scrollTop, maxHeight - size.scrollerHeight + sm.bottom)));\n\n        this.session.setScrollLeft(Math.max(-sm.left, Math.min(this.scrollLeft, \n            longestLine + 2 * this.$padding - size.scrollerWidth + sm.right)));\n        \n        var vScroll = !hideScrollbars && (this.$vScrollBarAlwaysVisible ||\n            size.scrollerHeight - maxHeight + scrollPastEnd < 0 || this.scrollTop > sm.top);\n        var vScrollChanged = vScrollBefore !== vScroll;\n        if (vScrollChanged) {\n            this.$vScroll = vScroll;\n            this.scrollBarV.setVisible(vScroll);\n        }\n\n        var offset = this.scrollTop % this.lineHeight;\n        var lineCount = Math.ceil(minHeight / this.lineHeight) - 1;\n        var firstRow = Math.max(0, Math.round((this.scrollTop - offset) / this.lineHeight));\n        var lastRow = firstRow + lineCount;\n        var firstRowScreen, firstRowHeight;\n        var lineHeight = this.lineHeight;\n        firstRow = session.screenToDocumentRow(firstRow, 0);\n        var foldLine = session.getFoldLine(firstRow);\n        if (foldLine) {\n            firstRow = foldLine.start.row;\n        }\n\n        firstRowScreen = session.documentToScreenRow(firstRow, 0);\n        firstRowHeight = session.getRowLength(firstRow) * lineHeight;\n\n        lastRow = Math.min(session.screenToDocumentRow(lastRow, 0), session.getLength() - 1);\n        minHeight = size.scrollerHeight + session.getRowLength(lastRow) * lineHeight +\n                                                firstRowHeight;\n\n        offset = this.scrollTop - firstRowScreen * lineHeight;\n\n        var changes = 0;\n        if (this.layerConfig.width != longestLine || hScrollChanged) \n            changes = this.CHANGE_H_SCROLL;\n        if (hScrollChanged || vScrollChanged) {\n            changes |= this.$updateCachedSize(true, this.gutterWidth, size.width, size.height);\n            this._signal(\"scrollbarVisibilityChanged\");\n            if (vScrollChanged)\n                longestLine = this.$getLongestLine();\n        }\n        \n        this.layerConfig = {\n            width : longestLine,\n            padding : this.$padding,\n            firstRow : firstRow,\n            firstRowScreen: firstRowScreen,\n            lastRow : lastRow,\n            lineHeight : lineHeight,\n            characterWidth : this.characterWidth,\n            minHeight : minHeight,\n            maxHeight : maxHeight,\n            offset : offset,\n            gutterOffset : lineHeight ? Math.max(0, Math.ceil((offset + size.height - size.scrollerHeight) / lineHeight)) : 0,\n            height : this.$size.scrollerHeight\n        };\n\n        if (this.session.$bidiHandler)\n            this.session.$bidiHandler.setContentWidth(longestLine - this.$padding);\n\n        return changes;\n    };\n\n    this.$updateLines = function() {\n        if (!this.$changedLines) return;\n        var firstRow = this.$changedLines.firstRow;\n        var lastRow = this.$changedLines.lastRow;\n        this.$changedLines = null;\n\n        var layerConfig = this.layerConfig;\n\n        if (firstRow > layerConfig.lastRow + 1) { return; }\n        if (lastRow < layerConfig.firstRow) { return; }\n        if (lastRow === Infinity) {\n            if (this.$showGutter)\n                this.$gutterLayer.update(layerConfig);\n            this.$textLayer.update(layerConfig);\n            return;\n        }\n        this.$textLayer.updateLines(layerConfig, firstRow, lastRow);\n        return true;\n    };\n\n    this.$getLongestLine = function() {\n        var charCount = this.session.getScreenWidth();\n        if (this.showInvisibles && !this.session.$useWrapMode)\n            charCount += 1;\n            \n        if (this.$textLayer && charCount > this.$textLayer.MAX_LINE_LENGTH)\n            charCount = this.$textLayer.MAX_LINE_LENGTH + 30;\n\n        return Math.max(this.$size.scrollerWidth - 2 * this.$padding, Math.round(charCount * this.characterWidth));\n    };\n    this.updateFrontMarkers = function() {\n        this.$markerFront.setMarkers(this.session.getMarkers(true));\n        this.$loop.schedule(this.CHANGE_MARKER_FRONT);\n    };\n    this.updateBackMarkers = function() {\n        this.$markerBack.setMarkers(this.session.getMarkers());\n        this.$loop.schedule(this.CHANGE_MARKER_BACK);\n    };\n    this.addGutterDecoration = function(row, className){\n        this.$gutterLayer.addGutterDecoration(row, className);\n    };\n    this.removeGutterDecoration = function(row, className){\n        this.$gutterLayer.removeGutterDecoration(row, className);\n    };\n    this.updateBreakpoints = function(rows) {\n        this.$loop.schedule(this.CHANGE_GUTTER);\n    };\n    this.setAnnotations = function(annotations) {\n        this.$gutterLayer.setAnnotations(annotations);\n        this.$loop.schedule(this.CHANGE_GUTTER);\n    };\n    this.updateCursor = function() {\n        this.$loop.schedule(this.CHANGE_CURSOR);\n    };\n    this.hideCursor = function() {\n        this.$cursorLayer.hideCursor();\n    };\n    this.showCursor = function() {\n        this.$cursorLayer.showCursor();\n    };\n\n    this.scrollSelectionIntoView = function(anchor, lead, offset) {\n        this.scrollCursorIntoView(anchor, offset);\n        this.scrollCursorIntoView(lead, offset);\n    };\n    this.scrollCursorIntoView = function(cursor, offset, $viewMargin) {\n        if (this.$size.scrollerHeight === 0)\n            return;\n\n        var pos = this.$cursorLayer.getPixelPosition(cursor);\n\n        var left = pos.left;\n        var top = pos.top;\n        \n        var topMargin = $viewMargin && $viewMargin.top || 0;\n        var bottomMargin = $viewMargin && $viewMargin.bottom || 0;\n        \n        var scrollTop = this.$scrollAnimation ? this.session.getScrollTop() : this.scrollTop;\n        \n        if (scrollTop + topMargin > top) {\n            if (offset && scrollTop + topMargin > top + this.lineHeight)\n                top -= offset * this.$size.scrollerHeight;\n            if (top === 0)\n                top = -this.scrollMargin.top;\n            this.session.setScrollTop(top);\n        } else if (scrollTop + this.$size.scrollerHeight - bottomMargin < top + this.lineHeight) {\n            if (offset && scrollTop + this.$size.scrollerHeight - bottomMargin < top -  this.lineHeight)\n                top += offset * this.$size.scrollerHeight;\n            this.session.setScrollTop(top + this.lineHeight + bottomMargin - this.$size.scrollerHeight);\n        }\n\n        var scrollLeft = this.scrollLeft;\n\n        if (scrollLeft > left) {\n            if (left < this.$padding + 2 * this.layerConfig.characterWidth)\n                left = -this.scrollMargin.left;\n            this.session.setScrollLeft(left);\n        } else if (scrollLeft + this.$size.scrollerWidth < left + this.characterWidth) {\n            this.session.setScrollLeft(Math.round(left + this.characterWidth - this.$size.scrollerWidth));\n        } else if (scrollLeft <= this.$padding && left - scrollLeft < this.characterWidth) {\n            this.session.setScrollLeft(0);\n        }\n    };\n    this.getScrollTop = function() {\n        return this.session.getScrollTop();\n    };\n    this.getScrollLeft = function() {\n        return this.session.getScrollLeft();\n    };\n    this.getScrollTopRow = function() {\n        return this.scrollTop / this.lineHeight;\n    };\n    this.getScrollBottomRow = function() {\n        return Math.max(0, Math.floor((this.scrollTop + this.$size.scrollerHeight) / this.lineHeight) - 1);\n    };\n    this.scrollToRow = function(row) {\n        this.session.setScrollTop(row * this.lineHeight);\n    };\n\n    this.alignCursor = function(cursor, alignment) {\n        if (typeof cursor == \"number\")\n            cursor = {row: cursor, column: 0};\n\n        var pos = this.$cursorLayer.getPixelPosition(cursor);\n        var h = this.$size.scrollerHeight - this.lineHeight;\n        var offset = pos.top - h * (alignment || 0);\n\n        this.session.setScrollTop(offset);\n        return offset;\n    };\n\n    this.STEPS = 8;\n    this.$calcSteps = function(fromValue, toValue){\n        var i = 0;\n        var l = this.STEPS;\n        var steps = [];\n\n        var func  = function(t, x_min, dx) {\n            return dx * (Math.pow(t - 1, 3) + 1) + x_min;\n        };\n\n        for (i = 0; i < l; ++i)\n            steps.push(func(i / this.STEPS, fromValue, toValue - fromValue));\n\n        return steps;\n    };\n    this.scrollToLine = function(line, center, animate, callback) {\n        var pos = this.$cursorLayer.getPixelPosition({row: line, column: 0});\n        var offset = pos.top;\n        if (center)\n            offset -= this.$size.scrollerHeight / 2;\n\n        var initialScroll = this.scrollTop;\n        this.session.setScrollTop(offset);\n        if (animate !== false)\n            this.animateScrolling(initialScroll, callback);\n    };\n\n    this.animateScrolling = function(fromValue, callback) {\n        var toValue = this.scrollTop;\n        if (!this.$animatedScroll)\n            return;\n        var _self = this;\n        \n        if (fromValue == toValue)\n            return;\n        \n        if (this.$scrollAnimation) {\n            var oldSteps = this.$scrollAnimation.steps;\n            if (oldSteps.length) {\n                fromValue = oldSteps[0];\n                if (fromValue == toValue)\n                    return;\n            }\n        }\n        \n        var steps = _self.$calcSteps(fromValue, toValue);\n        this.$scrollAnimation = {from: fromValue, to: toValue, steps: steps};\n\n        clearInterval(this.$timer);\n\n        _self.session.setScrollTop(steps.shift());\n        _self.session.$scrollTop = toValue;\n        this.$timer = setInterval(function() {\n            if (steps.length) {\n                _self.session.setScrollTop(steps.shift());\n                _self.session.$scrollTop = toValue;\n            } else if (toValue != null) {\n                _self.session.$scrollTop = -1;\n                _self.session.setScrollTop(toValue);\n                toValue = null;\n            } else {\n                _self.$timer = clearInterval(_self.$timer);\n                _self.$scrollAnimation = null;\n                callback && callback();\n            }\n        }, 10);\n    };\n    this.scrollToY = function(scrollTop) {\n        if (this.scrollTop !== scrollTop) {\n            this.$loop.schedule(this.CHANGE_SCROLL);\n            this.scrollTop = scrollTop;\n        }\n    };\n    this.scrollToX = function(scrollLeft) {\n        if (this.scrollLeft !== scrollLeft)\n            this.scrollLeft = scrollLeft;\n        this.$loop.schedule(this.CHANGE_H_SCROLL);\n    };\n    this.scrollTo = function(x, y) {\n        this.session.setScrollTop(y);\n        this.session.setScrollLeft(y);\n    };\n    this.scrollBy = function(deltaX, deltaY) {\n        deltaY && this.session.setScrollTop(this.session.getScrollTop() + deltaY);\n        deltaX && this.session.setScrollLeft(this.session.getScrollLeft() + deltaX);\n    };\n    this.isScrollableBy = function(deltaX, deltaY) {\n        if (deltaY < 0 && this.session.getScrollTop() >= 1 - this.scrollMargin.top)\n           return true;\n        if (deltaY > 0 && this.session.getScrollTop() + this.$size.scrollerHeight\n            - this.layerConfig.maxHeight < -1 + this.scrollMargin.bottom)\n           return true;\n        if (deltaX < 0 && this.session.getScrollLeft() >= 1 - this.scrollMargin.left)\n            return true;\n        if (deltaX > 0 && this.session.getScrollLeft() + this.$size.scrollerWidth\n            - this.layerConfig.width < -1 + this.scrollMargin.right)\n           return true;\n    };\n\n    this.pixelToScreenCoordinates = function(x, y) {\n        var canvasPos;\n        if (this.$hasCssTransforms) {\n            canvasPos = {top:0, left: 0};\n            var p = this.$fontMetrics.transformCoordinates([x, y]);\n            x = p[1] - this.gutterWidth - this.margin.left;\n            y = p[0];\n        } else {\n            canvasPos = this.scroller.getBoundingClientRect();\n        }\n        \n        var offsetX = x + this.scrollLeft - canvasPos.left - this.$padding;\n        var offset = offsetX / this.characterWidth;\n        var row = Math.floor((y + this.scrollTop - canvasPos.top) / this.lineHeight);\n        var col = this.$blockCursor ? Math.floor(offset) : Math.round(offset);\n\n        return {row: row, column: col, side: offset - col > 0 ? 1 : -1, offsetX:  offsetX};\n    };\n\n    this.screenToTextCoordinates = function(x, y) {\n        var canvasPos;\n        if (this.$hasCssTransforms) {\n            canvasPos = {top:0, left: 0};\n            var p = this.$fontMetrics.transformCoordinates([x, y]);\n            x = p[1] - this.gutterWidth - this.margin.left;\n            y = p[0];\n        } else {\n            canvasPos = this.scroller.getBoundingClientRect();\n        }\n\n        var offsetX = x + this.scrollLeft - canvasPos.left - this.$padding;\n        var offset = offsetX / this.characterWidth;\n        var col = this.$blockCursor ? Math.floor(offset) : Math.round(offset);\n\n        var row = Math.floor((y + this.scrollTop - canvasPos.top) / this.lineHeight);\n\n        return this.session.screenToDocumentPosition(row, Math.max(col, 0), offsetX);\n    };\n    this.textToScreenCoordinates = function(row, column) {\n        var canvasPos = this.scroller.getBoundingClientRect();\n        var pos = this.session.documentToScreenPosition(row, column);\n\n        var x = this.$padding + (this.session.$bidiHandler.isBidiRow(pos.row, row)\n             ? this.session.$bidiHandler.getPosLeft(pos.column)\n             : Math.round(pos.column * this.characterWidth));\n        \n        var y = pos.row * this.lineHeight;\n\n        return {\n            pageX: canvasPos.left + x - this.scrollLeft,\n            pageY: canvasPos.top + y - this.scrollTop\n        };\n    };\n    this.visualizeFocus = function() {\n        dom.addCssClass(this.container, \"ace_focus\");\n    };\n    this.visualizeBlur = function() {\n        dom.removeCssClass(this.container, \"ace_focus\");\n    };\n    this.showComposition = function(composition) {\n        this.$composition = composition;\n        if (!composition.cssText) {\n            composition.cssText = this.textarea.style.cssText;\n        }\n        composition.useTextareaForIME = this.$useTextareaForIME;\n        \n        if (this.$useTextareaForIME) {\n            dom.addCssClass(this.textarea, \"ace_composition\");\n            this.textarea.style.cssText = \"\";\n            this.$moveTextAreaToCursor();\n            this.$cursorLayer.element.style.display = \"none\";\n        }\n        else {\n            composition.markerId = this.session.addMarker(composition.markerRange, \"ace_composition_marker\", \"text\");\n        }\n    };\n    this.setCompositionText = function(text) {\n        var cursor = this.session.selection.cursor;\n        this.addToken(text, \"composition_placeholder\", cursor.row, cursor.column);\n        this.$moveTextAreaToCursor();\n    };\n    this.hideComposition = function() {\n        if (!this.$composition)\n            return;\n        \n        if (this.$composition.markerId)\n            this.session.removeMarker(this.$composition.markerId);\n\n        dom.removeCssClass(this.textarea, \"ace_composition\");\n        this.textarea.style.cssText = this.$composition.cssText;\n        this.$composition = null;\n        this.$cursorLayer.element.style.display = \"\";\n    };\n    \n    this.addToken = function(text, type, row, column) {\n        var session = this.session;\n        session.bgTokenizer.lines[row] = null;\n        var newToken = {type: type, value: text};\n        var tokens = session.getTokens(row);\n        if (column == null) {\n            tokens.push(newToken);\n        } else {\n            var l = 0;\n            for (var i =0; i < tokens.length; i++) {\n                var token = tokens[i];\n                l += token.value.length;\n                if (column <= l) {\n                    var diff = token.value.length - (l - column);\n                    var before = token.value.slice(0, diff);\n                    var after = token.value.slice(diff);\n    \n                    tokens.splice(i, 1, {type: token.type, value: before},  newToken,  {type: token.type, value: after});\n                    break;\n                }\n            }\n        }\n        this.updateLines(row, row);\n    };\n    this.setTheme = function(theme, cb) {\n        var _self = this;\n        this.$themeId = theme;\n        _self._dispatchEvent('themeChange',{theme:theme});\n\n        if (!theme || typeof theme == \"string\") {\n            var moduleName = theme || this.$options.theme.initialValue;\n            config.loadModule([\"theme\", moduleName], afterLoad);\n        } else {\n            afterLoad(theme);\n        }\n\n        function afterLoad(module) {\n            if (_self.$themeId != theme)\n                return cb && cb();\n            if (!module || !module.cssClass)\n                throw new Error(\"couldn't load module \" + theme + \" or it didn't call define\");\n            if (module.$id)\n                _self.$themeId = module.$id;\n            dom.importCssString(\n                module.cssText,\n                module.cssClass,\n                _self.container\n            );\n\n            if (_self.theme)\n                dom.removeCssClass(_self.container, _self.theme.cssClass);\n\n            var padding = \"padding\" in module ? module.padding \n                : \"padding\" in (_self.theme || {}) ? 4 : _self.$padding;\n            if (_self.$padding && padding != _self.$padding)\n                _self.setPadding(padding);\n            _self.$theme = module.cssClass;\n\n            _self.theme = module;\n            dom.addCssClass(_self.container, module.cssClass);\n            dom.setCssClass(_self.container, \"ace_dark\", module.isDark);\n            if (_self.$size) {\n                _self.$size.width = 0;\n                _self.$updateSizeAsync();\n            }\n\n            _self._dispatchEvent('themeLoaded', {theme:module});\n            cb && cb();\n        }\n    };\n    this.getTheme = function() {\n        return this.$themeId;\n    };\n    this.setStyle = function(style, include) {\n        dom.setCssClass(this.container, style, include !== false);\n    };\n    this.unsetStyle = function(style) {\n        dom.removeCssClass(this.container, style);\n    };\n    \n    this.setCursorStyle = function(style) {\n        dom.setStyle(this.scroller.style, \"cursor\", style);\n    };\n    this.setMouseCursor = function(cursorStyle) {\n        dom.setStyle(this.scroller.style, \"cursor\", cursorStyle);\n    };\n    \n    this.attachToShadowRoot = function() {\n        dom.importCssString(editorCss, \"ace_editor.css\", this.container);\n    };\n    this.destroy = function() {\n        this.freeze();\n        this.$fontMetrics.destroy();\n        this.$cursorLayer.destroy();\n    };\n\n}).call(VirtualRenderer.prototype);\n\n\nconfig.defineOptions(VirtualRenderer.prototype, \"renderer\", {\n    animatedScroll: {initialValue: false},\n    showInvisibles: {\n        set: function(value) {\n            if (this.$textLayer.setShowInvisibles(value))\n                this.$loop.schedule(this.CHANGE_TEXT);\n        },\n        initialValue: false\n    },\n    showPrintMargin: {\n        set: function() { this.$updatePrintMargin(); },\n        initialValue: true\n    },\n    printMarginColumn: {\n        set: function() { this.$updatePrintMargin(); },\n        initialValue: 80\n    },\n    printMargin: {\n        set: function(val) {\n            if (typeof val == \"number\")\n                this.$printMarginColumn = val;\n            this.$showPrintMargin = !!val;\n            this.$updatePrintMargin();\n        },\n        get: function() {\n            return this.$showPrintMargin && this.$printMarginColumn; \n        }\n    },\n    showGutter: {\n        set: function(show){\n            this.$gutter.style.display = show ? \"block\" : \"none\";\n            this.$loop.schedule(this.CHANGE_FULL);\n            this.onGutterResize();\n        },\n        initialValue: true\n    },\n    fadeFoldWidgets: {\n        set: function(show) {\n            dom.setCssClass(this.$gutter, \"ace_fade-fold-widgets\", show);\n        },\n        initialValue: false\n    },\n    showFoldWidgets: {\n        set: function(show) {\n            this.$gutterLayer.setShowFoldWidgets(show);\n            this.$loop.schedule(this.CHANGE_GUTTER);\n        },\n        initialValue: true\n    },\n    displayIndentGuides: {\n        set: function(show) {\n            if (this.$textLayer.setDisplayIndentGuides(show))\n                this.$loop.schedule(this.CHANGE_TEXT);\n        },\n        initialValue: true\n    },\n    highlightGutterLine: {\n        set: function(shouldHighlight) {\n            this.$gutterLayer.setHighlightGutterLine(shouldHighlight);\n            this.$loop.schedule(this.CHANGE_GUTTER);\n        },\n        initialValue: true\n    },\n    hScrollBarAlwaysVisible: {\n        set: function(val) {\n            if (!this.$hScrollBarAlwaysVisible || !this.$horizScroll)\n                this.$loop.schedule(this.CHANGE_SCROLL);\n        },\n        initialValue: false\n    },\n    vScrollBarAlwaysVisible: {\n        set: function(val) {\n            if (!this.$vScrollBarAlwaysVisible || !this.$vScroll)\n                this.$loop.schedule(this.CHANGE_SCROLL);\n        },\n        initialValue: false\n    },\n    fontSize: {\n        set: function(size) {\n            if (typeof size == \"number\")\n                size = size + \"px\";\n            this.container.style.fontSize = size;\n            this.updateFontSize();\n        },\n        initialValue: 12\n    },\n    fontFamily: {\n        set: function(name) {\n            this.container.style.fontFamily = name;\n            this.updateFontSize();\n        }\n    },\n    maxLines: {\n        set: function(val) {\n            this.updateFull();\n        }\n    },\n    minLines: {\n        set: function(val) {\n            if (!(this.$minLines < 0x1ffffffffffff))\n                this.$minLines = 0;\n            this.updateFull();\n        }\n    },\n    maxPixelHeight: {\n        set: function(val) {\n            this.updateFull();\n        },\n        initialValue: 0\n    },\n    scrollPastEnd: {\n        set: function(val) {\n            val = +val || 0;\n            if (this.$scrollPastEnd == val)\n                return;\n            this.$scrollPastEnd = val;\n            this.$loop.schedule(this.CHANGE_SCROLL);\n        },\n        initialValue: 0,\n        handlesSet: true\n    },\n    fixedWidthGutter: {\n        set: function(val) {\n            this.$gutterLayer.$fixedWidth = !!val;\n            this.$loop.schedule(this.CHANGE_GUTTER);\n        }\n    },\n    theme: {\n        set: function(val) { this.setTheme(val); },\n        get: function() { return this.$themeId || this.theme; },\n        initialValue: \"./theme/textmate\",\n        handlesSet: true\n    },\n    hasCssTransforms: {\n    },\n    useTextareaForIME: {\n        initialValue: !useragent.isMobile && !useragent.isIE\n    }\n});\n\nexports.VirtualRenderer = VirtualRenderer;\n});\n\nace.define(\"ace/worker/worker_client\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/net\",\"ace/lib/event_emitter\",\"ace/config\"], function(require, exports, module) {\n\"use strict\";\n\nvar oop = require(\"../lib/oop\");\nvar net = require(\"../lib/net\");\nvar EventEmitter = require(\"../lib/event_emitter\").EventEmitter;\nvar config = require(\"../config\");\n\nfunction $workerBlob(workerUrl) {\n    var script = \"importScripts('\" + net.qualifyURL(workerUrl) + \"');\";\n    try {\n        return new Blob([script], {\"type\": \"application/javascript\"});\n    } catch (e) { // Backwards-compatibility\n        var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder;\n        var blobBuilder = new BlobBuilder();\n        blobBuilder.append(script);\n        return blobBuilder.getBlob(\"application/javascript\");\n    }\n}\n\nfunction createWorker(workerUrl) {\n    if (typeof Worker == \"undefined\")\n        return { postMessage: function() {}, terminate: function() {} };\n    if (config.get(\"loadWorkerFromBlob\")) {\n        var blob = $workerBlob(workerUrl);\n        var URL = window.URL || window.webkitURL;\n        var blobURL = URL.createObjectURL(blob);\n        return new Worker(blobURL);\n    }\n    return new Worker(workerUrl);\n}\n\nvar WorkerClient = function(worker) {\n    if (!worker.postMessage)\n        worker = this.$createWorkerFromOldConfig.apply(this, arguments);\n\n    this.$worker = worker;\n    this.$sendDeltaQueue = this.$sendDeltaQueue.bind(this);\n    this.changeListener = this.changeListener.bind(this);\n    this.onMessage = this.onMessage.bind(this);\n\n    this.callbackId = 1;\n    this.callbacks = {};\n\n    this.$worker.onmessage = this.onMessage;\n};\n\n(function(){\n\n    oop.implement(this, EventEmitter);\n\n    this.$createWorkerFromOldConfig = function(topLevelNamespaces, mod, classname, workerUrl, importScripts) {\n        if (require.nameToUrl && !require.toUrl)\n            require.toUrl = require.nameToUrl;\n\n        if (config.get(\"packaged\") || !require.toUrl) {\n            workerUrl = workerUrl || config.moduleUrl(mod, \"worker\");\n        } else {\n            var normalizePath = this.$normalizePath;\n            workerUrl = workerUrl || normalizePath(require.toUrl(\"ace/worker/worker.js\", null, \"_\"));\n\n            var tlns = {};\n            topLevelNamespaces.forEach(function(ns) {\n                tlns[ns] = normalizePath(require.toUrl(ns, null, \"_\").replace(/(\\.js)?(\\?.*)?$/, \"\"));\n            });\n        }\n\n        this.$worker = createWorker(workerUrl);\n        if (importScripts) {\n            this.send(\"importScripts\", importScripts);\n        }\n        this.$worker.postMessage({\n            init : true,\n            tlns : tlns,\n            module : mod,\n            classname : classname\n        });\n        return this.$worker;\n    };\n\n    this.onMessage = function(e) {\n        var msg = e.data;\n        switch (msg.type) {\n            case \"event\":\n                this._signal(msg.name, {data: msg.data});\n                break;\n            case \"call\":\n                var callback = this.callbacks[msg.id];\n                if (callback) {\n                    callback(msg.data);\n                    delete this.callbacks[msg.id];\n                }\n                break;\n            case \"error\":\n                this.reportError(msg.data);\n                break;\n            case \"log\":\n                window.console && console.log && console.log.apply(console, msg.data);\n                break;\n        }\n    };\n    \n    this.reportError = function(err) {\n        window.console && console.error && console.error(err);\n    };\n\n    this.$normalizePath = function(path) {\n        return net.qualifyURL(path);\n    };\n\n    this.terminate = function() {\n        this._signal(\"terminate\", {});\n        this.deltaQueue = null;\n        this.$worker.terminate();\n        this.$worker = null;\n        if (this.$doc)\n            this.$doc.off(\"change\", this.changeListener);\n        this.$doc = null;\n    };\n\n    this.send = function(cmd, args) {\n        this.$worker.postMessage({command: cmd, args: args});\n    };\n\n    this.call = function(cmd, args, callback) {\n        if (callback) {\n            var id = this.callbackId++;\n            this.callbacks[id] = callback;\n            args.push(id);\n        }\n        this.send(cmd, args);\n    };\n\n    this.emit = function(event, data) {\n        try {\n            if (data.data && data.data.err)\n                data.data.err = {message: data.data.err.message, stack: data.data.err.stack, code: data.data.err.code};\n            this.$worker.postMessage({event: event, data: {data: data.data}});\n        }\n        catch(ex) {\n            console.error(ex.stack);\n        }\n    };\n\n    this.attachToDocument = function(doc) {\n        if (this.$doc)\n            this.terminate();\n\n        this.$doc = doc;\n        this.call(\"setValue\", [doc.getValue()]);\n        doc.on(\"change\", this.changeListener);\n    };\n\n    this.changeListener = function(delta) {\n        if (!this.deltaQueue) {\n            this.deltaQueue = [];\n            setTimeout(this.$sendDeltaQueue, 0);\n        }\n        if (delta.action == \"insert\")\n            this.deltaQueue.push(delta.start, delta.lines);\n        else\n            this.deltaQueue.push(delta.start, delta.end);\n    };\n\n    this.$sendDeltaQueue = function() {\n        var q = this.deltaQueue;\n        if (!q) return;\n        this.deltaQueue = null;\n        if (q.length > 50 && q.length > this.$doc.getLength() >> 1) {\n            this.call(\"setValue\", [this.$doc.getValue()]);\n        } else\n            this.emit(\"change\", {data: q});\n    };\n\n}).call(WorkerClient.prototype);\n\n\nvar UIWorkerClient = function(topLevelNamespaces, mod, classname) {\n    var main = null;\n    var emitSync = false;\n    var sender = Object.create(EventEmitter);\n\n    var messageBuffer = [];\n    var workerClient = new WorkerClient({\n        messageBuffer: messageBuffer,\n        terminate: function() {},\n        postMessage: function(e) {\n            messageBuffer.push(e);\n            if (!main) return;\n            if (emitSync)\n                setTimeout(processNext);\n            else\n                processNext();\n        }\n    });\n\n    workerClient.setEmitSync = function(val) { emitSync = val; };\n\n    var processNext = function() {\n        var msg = messageBuffer.shift();\n        if (msg.command)\n            main[msg.command].apply(main, msg.args);\n        else if (msg.event)\n            sender._signal(msg.event, msg.data);\n    };\n\n    sender.postMessage = function(msg) {\n        workerClient.onMessage({data: msg});\n    };\n    sender.callback = function(data, callbackId) {\n        this.postMessage({type: \"call\", id: callbackId, data: data});\n    };\n    sender.emit = function(name, data) {\n        this.postMessage({type: \"event\", name: name, data: data});\n    };\n\n    config.loadModule([\"worker\", mod], function(Main) {\n        main = new Main[classname](sender);\n        while (messageBuffer.length)\n            processNext();\n    });\n\n    return workerClient;\n};\n\nexports.UIWorkerClient = UIWorkerClient;\nexports.WorkerClient = WorkerClient;\nexports.createWorker = createWorker;\n\n\n});\n\nace.define(\"ace/placeholder\",[\"require\",\"exports\",\"module\",\"ace/range\",\"ace/lib/event_emitter\",\"ace/lib/oop\"], function(require, exports, module) {\n\"use strict\";\n\nvar Range = require(\"./range\").Range;\nvar EventEmitter = require(\"./lib/event_emitter\").EventEmitter;\nvar oop = require(\"./lib/oop\");\n\nvar PlaceHolder = function(session, length, pos, others, mainClass, othersClass) {\n    var _self = this;\n    this.length = length;\n    this.session = session;\n    this.doc = session.getDocument();\n    this.mainClass = mainClass;\n    this.othersClass = othersClass;\n    this.$onUpdate = this.onUpdate.bind(this);\n    this.doc.on(\"change\", this.$onUpdate);\n    this.$others = others;\n    \n    this.$onCursorChange = function() {\n        setTimeout(function() {\n            _self.onCursorChange();\n        });\n    };\n    \n    this.$pos = pos;\n    var undoStack = session.getUndoManager().$undoStack || session.getUndoManager().$undostack || {length: -1};\n    this.$undoStackDepth = undoStack.length;\n    this.setup();\n\n    session.selection.on(\"changeCursor\", this.$onCursorChange);\n};\n\n(function() {\n\n    oop.implement(this, EventEmitter);\n    this.setup = function() {\n        var _self = this;\n        var doc = this.doc;\n        var session = this.session;\n        \n        this.selectionBefore = session.selection.toJSON();\n        if (session.selection.inMultiSelectMode)\n            session.selection.toSingleRange();\n\n        this.pos = doc.createAnchor(this.$pos.row, this.$pos.column);\n        var pos = this.pos;\n        pos.$insertRight = true;\n        pos.detach();\n        pos.markerId = session.addMarker(new Range(pos.row, pos.column, pos.row, pos.column + this.length), this.mainClass, null, false);\n        this.others = [];\n        this.$others.forEach(function(other) {\n            var anchor = doc.createAnchor(other.row, other.column);\n            anchor.$insertRight = true;\n            anchor.detach();\n            _self.others.push(anchor);\n        });\n        session.setUndoSelect(false);\n    };\n    this.showOtherMarkers = function() {\n        if (this.othersActive) return;\n        var session = this.session;\n        var _self = this;\n        this.othersActive = true;\n        this.others.forEach(function(anchor) {\n            anchor.markerId = session.addMarker(new Range(anchor.row, anchor.column, anchor.row, anchor.column+_self.length), _self.othersClass, null, false);\n        });\n    };\n    this.hideOtherMarkers = function() {\n        if (!this.othersActive) return;\n        this.othersActive = false;\n        for (var i = 0; i < this.others.length; i++) {\n            this.session.removeMarker(this.others[i].markerId);\n        }\n    };\n    this.onUpdate = function(delta) {\n        if (this.$updating)\n            return this.updateAnchors(delta);\n            \n        var range = delta;\n        if (range.start.row !== range.end.row) return;\n        if (range.start.row !== this.pos.row) return;\n        this.$updating = true;\n        var lengthDiff = delta.action === \"insert\" ? range.end.column - range.start.column : range.start.column - range.end.column;\n        var inMainRange = range.start.column >= this.pos.column && range.start.column <= this.pos.column + this.length + 1;\n        var distanceFromStart = range.start.column - this.pos.column;\n        \n        this.updateAnchors(delta);\n        \n        if (inMainRange)\n            this.length += lengthDiff;\n\n        if (inMainRange && !this.session.$fromUndo) {\n            if (delta.action === 'insert') {\n                for (var i = this.others.length - 1; i >= 0; i--) {\n                    var otherPos = this.others[i];\n                    var newPos = {row: otherPos.row, column: otherPos.column + distanceFromStart};\n                    this.doc.insertMergedLines(newPos, delta.lines);\n                }\n            } else if (delta.action === 'remove') {\n                for (var i = this.others.length - 1; i >= 0; i--) {\n                    var otherPos = this.others[i];\n                    var newPos = {row: otherPos.row, column: otherPos.column + distanceFromStart};\n                    this.doc.remove(new Range(newPos.row, newPos.column, newPos.row, newPos.column - lengthDiff));\n                }\n            }\n        }\n        \n        this.$updating = false;\n        this.updateMarkers();\n    };\n    \n    this.updateAnchors = function(delta) {\n        this.pos.onChange(delta);\n        for (var i = this.others.length; i--;)\n            this.others[i].onChange(delta);\n        this.updateMarkers();\n    };\n    \n    this.updateMarkers = function() {\n        if (this.$updating)\n            return;\n        var _self = this;\n        var session = this.session;\n        var updateMarker = function(pos, className) {\n            session.removeMarker(pos.markerId);\n            pos.markerId = session.addMarker(new Range(pos.row, pos.column, pos.row, pos.column+_self.length), className, null, false);\n        };\n        updateMarker(this.pos, this.mainClass);\n        for (var i = this.others.length; i--;)\n            updateMarker(this.others[i], this.othersClass);\n    };\n\n    this.onCursorChange = function(event) {\n        if (this.$updating || !this.session) return;\n        var pos = this.session.selection.getCursor();\n        if (pos.row === this.pos.row && pos.column >= this.pos.column && pos.column <= this.pos.column + this.length) {\n            this.showOtherMarkers();\n            this._emit(\"cursorEnter\", event);\n        } else {\n            this.hideOtherMarkers();\n            this._emit(\"cursorLeave\", event);\n        }\n    };    \n    this.detach = function() {\n        this.session.removeMarker(this.pos && this.pos.markerId);\n        this.hideOtherMarkers();\n        this.doc.removeEventListener(\"change\", this.$onUpdate);\n        this.session.selection.removeEventListener(\"changeCursor\", this.$onCursorChange);\n        this.session.setUndoSelect(true);\n        this.session = null;\n    };\n    this.cancel = function() {\n        if (this.$undoStackDepth === -1)\n            return;\n        var undoManager = this.session.getUndoManager();\n        var undosRequired = (undoManager.$undoStack || undoManager.$undostack).length - this.$undoStackDepth;\n        for (var i = 0; i < undosRequired; i++) {\n            undoManager.undo(this.session, true);\n        }\n        if (this.selectionBefore)\n            this.session.selection.fromJSON(this.selectionBefore);\n    };\n}).call(PlaceHolder.prototype);\n\n\nexports.PlaceHolder = PlaceHolder;\n});\n\nace.define(\"ace/mouse/multi_select_handler\",[\"require\",\"exports\",\"module\",\"ace/lib/event\",\"ace/lib/useragent\"], function(require, exports, module) {\n\nvar event = require(\"../lib/event\");\nvar useragent = require(\"../lib/useragent\");\nfunction isSamePoint(p1, p2) {\n    return p1.row == p2.row && p1.column == p2.column;\n}\n\nfunction onMouseDown(e) {\n    var ev = e.domEvent;\n    var alt = ev.altKey;\n    var shift = ev.shiftKey;\n    var ctrl = ev.ctrlKey;\n    var accel = e.getAccelKey();\n    var button = e.getButton();\n    \n    if (ctrl && useragent.isMac)\n        button = ev.button;\n\n    if (e.editor.inMultiSelectMode && button == 2) {\n        e.editor.textInput.onContextMenu(e.domEvent);\n        return;\n    }\n    \n    if (!ctrl && !alt && !accel) {\n        if (button === 0 && e.editor.inMultiSelectMode)\n            e.editor.exitMultiSelectMode();\n        return;\n    }\n    \n    if (button !== 0)\n        return;\n\n    var editor = e.editor;\n    var selection = editor.selection;\n    var isMultiSelect = editor.inMultiSelectMode;\n    var pos = e.getDocumentPosition();\n    var cursor = selection.getCursor();\n    var inSelection = e.inSelection() || (selection.isEmpty() && isSamePoint(pos, cursor));\n\n    var mouseX = e.x, mouseY = e.y;\n    var onMouseSelection = function(e) {\n        mouseX = e.clientX;\n        mouseY = e.clientY;\n    };\n    \n    var session = editor.session;\n    var screenAnchor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY);\n    var screenCursor = screenAnchor;\n    \n    var selectionMode;\n    if (editor.$mouseHandler.$enableJumpToDef) {\n        if (ctrl && alt || accel && alt)\n            selectionMode = shift ? \"block\" : \"add\";\n        else if (alt && editor.$blockSelectEnabled)\n            selectionMode = \"block\";\n    } else {\n        if (accel && !alt) {\n            selectionMode = \"add\";\n            if (!isMultiSelect && shift)\n                return;\n        } else if (alt && editor.$blockSelectEnabled) {\n            selectionMode = \"block\";\n        }\n    }\n    \n    if (selectionMode && useragent.isMac && ev.ctrlKey) {\n        editor.$mouseHandler.cancelContextMenu();\n    }\n\n    if (selectionMode == \"add\") {\n        if (!isMultiSelect && inSelection)\n            return; // dragging\n\n        if (!isMultiSelect) {\n            var range = selection.toOrientedRange();\n            editor.addSelectionMarker(range);\n        }\n\n        var oldRange = selection.rangeList.rangeAtPoint(pos);\n        \n        editor.inVirtualSelectionMode = true;\n        \n        if (shift) {\n            oldRange = null;\n            range = selection.ranges[0] || range;\n            editor.removeSelectionMarker(range);\n        }\n        editor.once(\"mouseup\", function() {\n            var tmpSel = selection.toOrientedRange();\n\n            if (oldRange && tmpSel.isEmpty() && isSamePoint(oldRange.cursor, tmpSel.cursor))\n                selection.substractPoint(tmpSel.cursor);\n            else {\n                if (shift) {\n                    selection.substractPoint(range.cursor);\n                } else if (range) {\n                    editor.removeSelectionMarker(range);\n                    selection.addRange(range);\n                }\n                selection.addRange(tmpSel);\n            }\n            editor.inVirtualSelectionMode = false;\n        });\n\n    } else if (selectionMode == \"block\") {\n        e.stop();\n        editor.inVirtualSelectionMode = true;        \n        var initialRange;\n        var rectSel = [];\n        var blockSelect = function() {\n            var newCursor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY);\n            var cursor = session.screenToDocumentPosition(newCursor.row, newCursor.column, newCursor.offsetX);\n\n            if (isSamePoint(screenCursor, newCursor) && isSamePoint(cursor, selection.lead))\n                return;\n            screenCursor = newCursor;\n            \n            editor.selection.moveToPosition(cursor);\n            editor.renderer.scrollCursorIntoView();\n\n            editor.removeSelectionMarkers(rectSel);\n            rectSel = selection.rectangularRangeBlock(screenCursor, screenAnchor);\n            if (editor.$mouseHandler.$clickSelection && rectSel.length == 1 && rectSel[0].isEmpty())\n                rectSel[0] = editor.$mouseHandler.$clickSelection.clone();\n            rectSel.forEach(editor.addSelectionMarker, editor);\n            editor.updateSelectionMarkers();\n        };\n        if (isMultiSelect && !accel) {\n            selection.toSingleRange();\n        } else if (!isMultiSelect && accel) {\n            initialRange = selection.toOrientedRange();\n            editor.addSelectionMarker(initialRange);\n        }\n        \n        if (shift)\n            screenAnchor = session.documentToScreenPosition(selection.lead);            \n        else\n            selection.moveToPosition(pos);\n        \n        screenCursor = {row: -1, column: -1};\n\n        var onMouseSelectionEnd = function(e) {\n            blockSelect();\n            clearInterval(timerId);\n            editor.removeSelectionMarkers(rectSel);\n            if (!rectSel.length)\n                rectSel = [selection.toOrientedRange()];\n            if (initialRange) {\n                editor.removeSelectionMarker(initialRange);\n                selection.toSingleRange(initialRange);\n            }\n            for (var i = 0; i < rectSel.length; i++)\n                selection.addRange(rectSel[i]);\n            editor.inVirtualSelectionMode = false;\n            editor.$mouseHandler.$clickSelection = null;\n        };\n\n        var onSelectionInterval = blockSelect;\n\n        event.capture(editor.container, onMouseSelection, onMouseSelectionEnd);\n        var timerId = setInterval(function() {onSelectionInterval();}, 20);\n\n        return e.preventDefault();\n    }\n}\n\n\nexports.onMouseDown = onMouseDown;\n\n});\n\nace.define(\"ace/commands/multi_select_commands\",[\"require\",\"exports\",\"module\",\"ace/keyboard/hash_handler\"], function(require, exports, module) {\nexports.defaultCommands = [{\n    name: \"addCursorAbove\",\n    description: \"Add cursor above\",\n    exec: function(editor) { editor.selectMoreLines(-1); },\n    bindKey: {win: \"Ctrl-Alt-Up\", mac: \"Ctrl-Alt-Up\"},\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"addCursorBelow\",\n    description: \"Add cursor below\",\n    exec: function(editor) { editor.selectMoreLines(1); },\n    bindKey: {win: \"Ctrl-Alt-Down\", mac: \"Ctrl-Alt-Down\"},\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"addCursorAboveSkipCurrent\",\n    description: \"Add cursor above (skip current)\",\n    exec: function(editor) { editor.selectMoreLines(-1, true); },\n    bindKey: {win: \"Ctrl-Alt-Shift-Up\", mac: \"Ctrl-Alt-Shift-Up\"},\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"addCursorBelowSkipCurrent\",\n    description: \"Add cursor below (skip current)\",\n    exec: function(editor) { editor.selectMoreLines(1, true); },\n    bindKey: {win: \"Ctrl-Alt-Shift-Down\", mac: \"Ctrl-Alt-Shift-Down\"},\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"selectMoreBefore\",\n    description: \"Select more before\",\n    exec: function(editor) { editor.selectMore(-1); },\n    bindKey: {win: \"Ctrl-Alt-Left\", mac: \"Ctrl-Alt-Left\"},\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"selectMoreAfter\",\n    description: \"Select more after\",\n    exec: function(editor) { editor.selectMore(1); },\n    bindKey: {win: \"Ctrl-Alt-Right\", mac: \"Ctrl-Alt-Right\"},\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"selectNextBefore\",\n    description: \"Select next before\",\n    exec: function(editor) { editor.selectMore(-1, true); },\n    bindKey: {win: \"Ctrl-Alt-Shift-Left\", mac: \"Ctrl-Alt-Shift-Left\"},\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"selectNextAfter\",\n    description: \"Select next after\",\n    exec: function(editor) { editor.selectMore(1, true); },\n    bindKey: {win: \"Ctrl-Alt-Shift-Right\", mac: \"Ctrl-Alt-Shift-Right\"},\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}, {\n    name: \"toggleSplitSelectionIntoLines\",\n    description: \"Split into lines\",\n    exec: function(editor) {\n        if (editor.multiSelect.rangeCount > 1)\n            editor.multiSelect.joinSelections();\n        else\n            editor.multiSelect.splitIntoLines();\n    },\n    bindKey: {win: \"Ctrl-Alt-L\", mac: \"Ctrl-Alt-L\"},\n    readOnly: true\n}, {\n    name: \"splitSelectionIntoLines\",\n    description: \"Split into lines\",\n    exec: function(editor) { editor.multiSelect.splitIntoLines(); },\n    readOnly: true\n}, {\n    name: \"alignCursors\",\n    description: \"Align cursors\",\n    exec: function(editor) { editor.alignCursors(); },\n    bindKey: {win: \"Ctrl-Alt-A\", mac: \"Ctrl-Alt-A\"},\n    scrollIntoView: \"cursor\"\n}, {\n    name: \"findAll\",\n    description: \"Find all\",\n    exec: function(editor) { editor.findAll(); },\n    bindKey: {win: \"Ctrl-Alt-K\", mac: \"Ctrl-Alt-G\"},\n    scrollIntoView: \"cursor\",\n    readOnly: true\n}];\nexports.multiSelectCommands = [{\n    name: \"singleSelection\",\n    description: \"Single selection\",\n    bindKey: \"esc\",\n    exec: function(editor) { editor.exitMultiSelectMode(); },\n    scrollIntoView: \"cursor\",\n    readOnly: true,\n    isAvailable: function(editor) {return editor && editor.inMultiSelectMode;}\n}];\n\nvar HashHandler = require(\"../keyboard/hash_handler\").HashHandler;\nexports.keyboardHandler = new HashHandler(exports.multiSelectCommands);\n\n});\n\nace.define(\"ace/multi_select\",[\"require\",\"exports\",\"module\",\"ace/range_list\",\"ace/range\",\"ace/selection\",\"ace/mouse/multi_select_handler\",\"ace/lib/event\",\"ace/lib/lang\",\"ace/commands/multi_select_commands\",\"ace/search\",\"ace/edit_session\",\"ace/editor\",\"ace/config\"], function(require, exports, module) {\n\nvar RangeList = require(\"./range_list\").RangeList;\nvar Range = require(\"./range\").Range;\nvar Selection = require(\"./selection\").Selection;\nvar onMouseDown = require(\"./mouse/multi_select_handler\").onMouseDown;\nvar event = require(\"./lib/event\");\nvar lang = require(\"./lib/lang\");\nvar commands = require(\"./commands/multi_select_commands\");\nexports.commands = commands.defaultCommands.concat(commands.multiSelectCommands);\nvar Search = require(\"./search\").Search;\nvar search = new Search();\n\nfunction find(session, needle, dir) {\n    search.$options.wrap = true;\n    search.$options.needle = needle;\n    search.$options.backwards = dir == -1;\n    return search.find(session);\n}\nvar EditSession = require(\"./edit_session\").EditSession;\n(function() {\n    this.getSelectionMarkers = function() {\n        return this.$selectionMarkers;\n    };\n}).call(EditSession.prototype);\n(function() {\n    this.ranges = null;\n    this.rangeList = null;\n    this.addRange = function(range, $blockChangeEvents) {\n        if (!range)\n            return;\n\n        if (!this.inMultiSelectMode && this.rangeCount === 0) {\n            var oldRange = this.toOrientedRange();\n            this.rangeList.add(oldRange);\n            this.rangeList.add(range);\n            if (this.rangeList.ranges.length != 2) {\n                this.rangeList.removeAll();\n                return $blockChangeEvents || this.fromOrientedRange(range);\n            }\n            this.rangeList.removeAll();\n            this.rangeList.add(oldRange);\n            this.$onAddRange(oldRange);\n        }\n\n        if (!range.cursor)\n            range.cursor = range.end;\n\n        var removed = this.rangeList.add(range);\n\n        this.$onAddRange(range);\n\n        if (removed.length)\n            this.$onRemoveRange(removed);\n\n        if (this.rangeCount > 1 && !this.inMultiSelectMode) {\n            this._signal(\"multiSelect\");\n            this.inMultiSelectMode = true;\n            this.session.$undoSelect = false;\n            this.rangeList.attach(this.session);\n        }\n\n        return $blockChangeEvents || this.fromOrientedRange(range);\n    };\n    this.toSingleRange = function(range) {\n        range = range || this.ranges[0];\n        var removed = this.rangeList.removeAll();\n        if (removed.length)\n            this.$onRemoveRange(removed);\n\n        range && this.fromOrientedRange(range);\n    };\n    this.substractPoint = function(pos) {\n        var removed = this.rangeList.substractPoint(pos);\n        if (removed) {\n            this.$onRemoveRange(removed);\n            return removed[0];\n        }\n    };\n    this.mergeOverlappingRanges = function() {\n        var removed = this.rangeList.merge();\n        if (removed.length)\n            this.$onRemoveRange(removed);\n    };\n\n    this.$onAddRange = function(range) {\n        this.rangeCount = this.rangeList.ranges.length;\n        this.ranges.unshift(range);\n        this._signal(\"addRange\", {range: range});\n    };\n\n    this.$onRemoveRange = function(removed) {\n        this.rangeCount = this.rangeList.ranges.length;\n        if (this.rangeCount == 1 && this.inMultiSelectMode) {\n            var lastRange = this.rangeList.ranges.pop();\n            removed.push(lastRange);\n            this.rangeCount = 0;\n        }\n\n        for (var i = removed.length; i--; ) {\n            var index = this.ranges.indexOf(removed[i]);\n            this.ranges.splice(index, 1);\n        }\n\n        this._signal(\"removeRange\", {ranges: removed});\n\n        if (this.rangeCount === 0 && this.inMultiSelectMode) {\n            this.inMultiSelectMode = false;\n            this._signal(\"singleSelect\");\n            this.session.$undoSelect = true;\n            this.rangeList.detach(this.session);\n        }\n\n        lastRange = lastRange || this.ranges[0];\n        if (lastRange && !lastRange.isEqual(this.getRange()))\n            this.fromOrientedRange(lastRange);\n    };\n    this.$initRangeList = function() {\n        if (this.rangeList)\n            return;\n\n        this.rangeList = new RangeList();\n        this.ranges = [];\n        this.rangeCount = 0;\n    };\n    this.getAllRanges = function() {\n        return this.rangeCount ? this.rangeList.ranges.concat() : [this.getRange()];\n    };\n    this.splitIntoLines = function () {\n        var ranges = this.ranges.length ? this.ranges : [this.getRange()];\n        var newRanges = [];\n        for (var i = 0; i < ranges.length; i++) {\n            var range = ranges[i];\n            var row = range.start.row;\n            var endRow = range.end.row;\n            if (row === endRow) {\n                newRanges.push(range.clone());\n            } else {\n                newRanges.push(new Range(row, range.start.column, row, this.session.getLine(row).length));\n                while (++row < endRow)\n                    newRanges.push(this.getLineRange(row, true));\n                newRanges.push(new Range(endRow, 0, endRow, range.end.column));\n            }\n            if (i == 0 && !this.isBackwards())\n                newRanges = newRanges.reverse();\n        }\n        this.toSingleRange();\n        for (var i = newRanges.length; i--;)\n            this.addRange(newRanges[i]);\n    };\n    \n    this.joinSelections = function () {\n        var ranges = this.rangeList.ranges;\n        var lastRange = ranges[ranges.length - 1];\n        var range = Range.fromPoints(ranges[0].start, lastRange.end);\n\n        this.toSingleRange();\n        this.setSelectionRange(range, lastRange.cursor == lastRange.start);\n    };\n    this.toggleBlockSelection = function () {\n        if (this.rangeCount > 1) {\n            var ranges = this.rangeList.ranges;\n            var lastRange = ranges[ranges.length - 1];\n            var range = Range.fromPoints(ranges[0].start, lastRange.end);\n\n            this.toSingleRange();\n            this.setSelectionRange(range, lastRange.cursor == lastRange.start);\n        } else {\n            var cursor = this.session.documentToScreenPosition(this.cursor);\n            var anchor = this.session.documentToScreenPosition(this.anchor);\n\n            var rectSel = this.rectangularRangeBlock(cursor, anchor);\n            rectSel.forEach(this.addRange, this);\n        }\n    };\n    this.rectangularRangeBlock = function(screenCursor, screenAnchor, includeEmptyLines) {\n        var rectSel = [];\n\n        var xBackwards = screenCursor.column < screenAnchor.column;\n        if (xBackwards) {\n            var startColumn = screenCursor.column;\n            var endColumn = screenAnchor.column;\n            var startOffsetX = screenCursor.offsetX;\n            var endOffsetX = screenAnchor.offsetX;\n        } else {\n            var startColumn = screenAnchor.column;\n            var endColumn = screenCursor.column;\n            var startOffsetX = screenAnchor.offsetX;\n            var endOffsetX = screenCursor.offsetX;\n        }\n\n        var yBackwards = screenCursor.row < screenAnchor.row;\n        if (yBackwards) {\n            var startRow = screenCursor.row;\n            var endRow = screenAnchor.row;\n        } else {\n            var startRow = screenAnchor.row;\n            var endRow = screenCursor.row;\n        }\n\n        if (startColumn < 0)\n            startColumn = 0;\n        if (startRow < 0)\n            startRow = 0;\n\n        if (startRow == endRow)\n            includeEmptyLines = true;\n\n        var docEnd;\n        for (var row = startRow; row <= endRow; row++) {\n            var range = Range.fromPoints(\n                this.session.screenToDocumentPosition(row, startColumn, startOffsetX),\n                this.session.screenToDocumentPosition(row, endColumn, endOffsetX)\n            );\n            if (range.isEmpty()) {\n                if (docEnd && isSamePoint(range.end, docEnd))\n                    break;\n                docEnd = range.end;\n            }\n            range.cursor = xBackwards ? range.start : range.end;\n            rectSel.push(range);\n        }\n\n        if (yBackwards)\n            rectSel.reverse();\n\n        if (!includeEmptyLines) {\n            var end = rectSel.length - 1;\n            while (rectSel[end].isEmpty() && end > 0)\n                end--;\n            if (end > 0) {\n                var start = 0;\n                while (rectSel[start].isEmpty())\n                    start++;\n            }\n            for (var i = end; i >= start; i--) {\n                if (rectSel[i].isEmpty())\n                    rectSel.splice(i, 1);\n            }\n        }\n\n        return rectSel;\n    };\n}).call(Selection.prototype);\nvar Editor = require(\"./editor\").Editor;\n(function() {\n    this.updateSelectionMarkers = function() {\n        this.renderer.updateCursor();\n        this.renderer.updateBackMarkers();\n    };\n    this.addSelectionMarker = function(orientedRange) {\n        if (!orientedRange.cursor)\n            orientedRange.cursor = orientedRange.end;\n\n        var style = this.getSelectionStyle();\n        orientedRange.marker = this.session.addMarker(orientedRange, \"ace_selection\", style);\n\n        this.session.$selectionMarkers.push(orientedRange);\n        this.session.selectionMarkerCount = this.session.$selectionMarkers.length;\n        return orientedRange;\n    };\n    this.removeSelectionMarker = function(range) {\n        if (!range.marker)\n            return;\n        this.session.removeMarker(range.marker);\n        var index = this.session.$selectionMarkers.indexOf(range);\n        if (index != -1)\n            this.session.$selectionMarkers.splice(index, 1);\n        this.session.selectionMarkerCount = this.session.$selectionMarkers.length;\n    };\n\n    this.removeSelectionMarkers = function(ranges) {\n        var markerList = this.session.$selectionMarkers;\n        for (var i = ranges.length; i--; ) {\n            var range = ranges[i];\n            if (!range.marker)\n                continue;\n            this.session.removeMarker(range.marker);\n            var index = markerList.indexOf(range);\n            if (index != -1)\n                markerList.splice(index, 1);\n        }\n        this.session.selectionMarkerCount = markerList.length;\n    };\n\n    this.$onAddRange = function(e) {\n        this.addSelectionMarker(e.range);\n        this.renderer.updateCursor();\n        this.renderer.updateBackMarkers();\n    };\n\n    this.$onRemoveRange = function(e) {\n        this.removeSelectionMarkers(e.ranges);\n        this.renderer.updateCursor();\n        this.renderer.updateBackMarkers();\n    };\n\n    this.$onMultiSelect = function(e) {\n        if (this.inMultiSelectMode)\n            return;\n        this.inMultiSelectMode = true;\n\n        this.setStyle(\"ace_multiselect\");\n        this.keyBinding.addKeyboardHandler(commands.keyboardHandler);\n        this.commands.setDefaultHandler(\"exec\", this.$onMultiSelectExec);\n\n        this.renderer.updateCursor();\n        this.renderer.updateBackMarkers();\n    };\n\n    this.$onSingleSelect = function(e) {\n        if (this.session.multiSelect.inVirtualMode)\n            return;\n        this.inMultiSelectMode = false;\n\n        this.unsetStyle(\"ace_multiselect\");\n        this.keyBinding.removeKeyboardHandler(commands.keyboardHandler);\n\n        this.commands.removeDefaultHandler(\"exec\", this.$onMultiSelectExec);\n        this.renderer.updateCursor();\n        this.renderer.updateBackMarkers();\n        this._emit(\"changeSelection\");\n    };\n\n    this.$onMultiSelectExec = function(e) {\n        var command = e.command;\n        var editor = e.editor;\n        if (!editor.multiSelect)\n            return;\n        if (!command.multiSelectAction) {\n            var result = command.exec(editor, e.args || {});\n            editor.multiSelect.addRange(editor.multiSelect.toOrientedRange());\n            editor.multiSelect.mergeOverlappingRanges();\n        } else if (command.multiSelectAction == \"forEach\") {\n            result = editor.forEachSelection(command, e.args);\n        } else if (command.multiSelectAction == \"forEachLine\") {\n            result = editor.forEachSelection(command, e.args, true);\n        } else if (command.multiSelectAction == \"single\") {\n            editor.exitMultiSelectMode();\n            result = command.exec(editor, e.args || {});\n        } else {\n            result = command.multiSelectAction(editor, e.args || {});\n        }\n        return result;\n    }; \n    this.forEachSelection = function(cmd, args, options) {\n        if (this.inVirtualSelectionMode)\n            return;\n        var keepOrder = options && options.keepOrder;\n        var $byLines = options == true || options && options.$byLines;\n        var session = this.session;\n        var selection = this.selection;\n        var rangeList = selection.rangeList;\n        var ranges = (keepOrder ? selection : rangeList).ranges;\n        var result;\n        \n        if (!ranges.length)\n            return cmd.exec ? cmd.exec(this, args || {}) : cmd(this, args || {});\n        \n        var reg = selection._eventRegistry;\n        selection._eventRegistry = {};\n\n        var tmpSel = new Selection(session);\n        this.inVirtualSelectionMode = true;\n        for (var i = ranges.length; i--;) {\n            if ($byLines) {\n                while (i > 0 && ranges[i].start.row == ranges[i - 1].end.row)\n                    i--;\n            }\n            tmpSel.fromOrientedRange(ranges[i]);\n            tmpSel.index = i;\n            this.selection = session.selection = tmpSel;\n            var cmdResult = cmd.exec ? cmd.exec(this, args || {}) : cmd(this, args || {});\n            if (!result && cmdResult !== undefined)\n                result = cmdResult;\n            tmpSel.toOrientedRange(ranges[i]);\n        }\n        tmpSel.detach();\n\n        this.selection = session.selection = selection;\n        this.inVirtualSelectionMode = false;\n        selection._eventRegistry = reg;\n        selection.mergeOverlappingRanges();\n        if (selection.ranges[0])\n            selection.fromOrientedRange(selection.ranges[0]);\n        \n        var anim = this.renderer.$scrollAnimation;\n        this.onCursorChange();\n        this.onSelectionChange();\n        if (anim && anim.from == anim.to)\n            this.renderer.animateScrolling(anim.from);\n        \n        return result;\n    };\n    this.exitMultiSelectMode = function() {\n        if (!this.inMultiSelectMode || this.inVirtualSelectionMode)\n            return;\n        this.multiSelect.toSingleRange();\n    };\n\n    this.getSelectedText = function() {\n        var text = \"\";\n        if (this.inMultiSelectMode && !this.inVirtualSelectionMode) {\n            var ranges = this.multiSelect.rangeList.ranges;\n            var buf = [];\n            for (var i = 0; i < ranges.length; i++) {\n                buf.push(this.session.getTextRange(ranges[i]));\n            }\n            var nl = this.session.getDocument().getNewLineCharacter();\n            text = buf.join(nl);\n            if (text.length == (buf.length - 1) * nl.length)\n                text = \"\";\n        } else if (!this.selection.isEmpty()) {\n            text = this.session.getTextRange(this.getSelectionRange());\n        }\n        return text;\n    };\n    \n    this.$checkMultiselectChange = function(e, anchor) {\n        if (this.inMultiSelectMode && !this.inVirtualSelectionMode) {\n            var range = this.multiSelect.ranges[0];\n            if (this.multiSelect.isEmpty() && anchor == this.multiSelect.anchor)\n                return;\n            var pos = anchor == this.multiSelect.anchor\n                ? range.cursor == range.start ? range.end : range.start\n                : range.cursor;\n            if (pos.row != anchor.row \n                || this.session.$clipPositionToDocument(pos.row, pos.column).column != anchor.column)\n                this.multiSelect.toSingleRange(this.multiSelect.toOrientedRange());\n            else\n                this.multiSelect.mergeOverlappingRanges();\n        }\n    };\n    this.findAll = function(needle, options, additive) {\n        options = options || {};\n        options.needle = needle || options.needle;\n        if (options.needle == undefined) {\n            var range = this.selection.isEmpty()\n                ? this.selection.getWordRange()\n                : this.selection.getRange();\n            options.needle = this.session.getTextRange(range);\n        }    \n        this.$search.set(options);\n        \n        var ranges = this.$search.findAll(this.session);\n        if (!ranges.length)\n            return 0;\n\n        var selection = this.multiSelect;\n\n        if (!additive)\n            selection.toSingleRange(ranges[0]);\n\n        for (var i = ranges.length; i--; )\n            selection.addRange(ranges[i], true);\n        if (range && selection.rangeList.rangeAtPoint(range.start))\n            selection.addRange(range, true);\n        \n        return ranges.length;\n    };\n    this.selectMoreLines = function(dir, skip) {\n        var range = this.selection.toOrientedRange();\n        var isBackwards = range.cursor == range.end;\n\n        var screenLead = this.session.documentToScreenPosition(range.cursor);\n        if (this.selection.$desiredColumn)\n            screenLead.column = this.selection.$desiredColumn;\n\n        var lead = this.session.screenToDocumentPosition(screenLead.row + dir, screenLead.column);\n\n        if (!range.isEmpty()) {\n            var screenAnchor = this.session.documentToScreenPosition(isBackwards ? range.end : range.start);\n            var anchor = this.session.screenToDocumentPosition(screenAnchor.row + dir, screenAnchor.column);\n        } else {\n            var anchor = lead;\n        }\n\n        if (isBackwards) {\n            var newRange = Range.fromPoints(lead, anchor);\n            newRange.cursor = newRange.start;\n        } else {\n            var newRange = Range.fromPoints(anchor, lead);\n            newRange.cursor = newRange.end;\n        }\n\n        newRange.desiredColumn = screenLead.column;\n        if (!this.selection.inMultiSelectMode) {\n            this.selection.addRange(range);\n        } else {\n            if (skip)\n                var toRemove = range.cursor;\n        }\n\n        this.selection.addRange(newRange);\n        if (toRemove)\n            this.selection.substractPoint(toRemove);\n    };\n    this.transposeSelections = function(dir) {\n        var session = this.session;\n        var sel = session.multiSelect;\n        var all = sel.ranges;\n\n        for (var i = all.length; i--; ) {\n            var range = all[i];\n            if (range.isEmpty()) {\n                var tmp = session.getWordRange(range.start.row, range.start.column);\n                range.start.row = tmp.start.row;\n                range.start.column = tmp.start.column;\n                range.end.row = tmp.end.row;\n                range.end.column = tmp.end.column;\n            }\n        }\n        sel.mergeOverlappingRanges();\n\n        var words = [];\n        for (var i = all.length; i--; ) {\n            var range = all[i];\n            words.unshift(session.getTextRange(range));\n        }\n\n        if (dir < 0)\n            words.unshift(words.pop());\n        else\n            words.push(words.shift());\n\n        for (var i = all.length; i--; ) {\n            var range = all[i];\n            var tmp = range.clone();\n            session.replace(range, words[i]);\n            range.start.row = tmp.start.row;\n            range.start.column = tmp.start.column;\n        }\n        sel.fromOrientedRange(sel.ranges[0]);\n    };\n    this.selectMore = function(dir, skip, stopAtFirst) {\n        var session = this.session;\n        var sel = session.multiSelect;\n\n        var range = sel.toOrientedRange();\n        if (range.isEmpty()) {\n            range = session.getWordRange(range.start.row, range.start.column);\n            range.cursor = dir == -1 ? range.start : range.end;\n            this.multiSelect.addRange(range);\n            if (stopAtFirst)\n                return;\n        }\n        var needle = session.getTextRange(range);\n\n        var newRange = find(session, needle, dir);\n        if (newRange) {\n            newRange.cursor = dir == -1 ? newRange.start : newRange.end;\n            this.session.unfold(newRange);\n            this.multiSelect.addRange(newRange);\n            this.renderer.scrollCursorIntoView(null, 0.5);\n        }\n        if (skip)\n            this.multiSelect.substractPoint(range.cursor);\n    };\n    this.alignCursors = function() {\n        var session = this.session;\n        var sel = session.multiSelect;\n        var ranges = sel.ranges;\n        var row = -1;\n        var sameRowRanges = ranges.filter(function(r) {\n            if (r.cursor.row == row)\n                return true;\n            row = r.cursor.row;\n        });\n        \n        if (!ranges.length || sameRowRanges.length == ranges.length - 1) {\n            var range = this.selection.getRange();\n            var fr = range.start.row, lr = range.end.row;\n            var guessRange = fr == lr;\n            if (guessRange) {\n                var max = this.session.getLength();\n                var line;\n                do {\n                    line = this.session.getLine(lr);\n                } while (/[=:]/.test(line) && ++lr < max);\n                do {\n                    line = this.session.getLine(fr);\n                } while (/[=:]/.test(line) && --fr > 0);\n                \n                if (fr < 0) fr = 0;\n                if (lr >= max) lr = max - 1;\n            }\n            var lines = this.session.removeFullLines(fr, lr);\n            lines = this.$reAlignText(lines, guessRange);\n            this.session.insert({row: fr, column: 0}, lines.join(\"\\n\") + \"\\n\");\n            if (!guessRange) {\n                range.start.column = 0;\n                range.end.column = lines[lines.length - 1].length;\n            }\n            this.selection.setRange(range);\n        } else {\n            sameRowRanges.forEach(function(r) {\n                sel.substractPoint(r.cursor);\n            });\n\n            var maxCol = 0;\n            var minSpace = Infinity;\n            var spaceOffsets = ranges.map(function(r) {\n                var p = r.cursor;\n                var line = session.getLine(p.row);\n                var spaceOffset = line.substr(p.column).search(/\\S/g);\n                if (spaceOffset == -1)\n                    spaceOffset = 0;\n\n                if (p.column > maxCol)\n                    maxCol = p.column;\n                if (spaceOffset < minSpace)\n                    minSpace = spaceOffset;\n                return spaceOffset;\n            });\n            ranges.forEach(function(r, i) {\n                var p = r.cursor;\n                var l = maxCol - p.column;\n                var d = spaceOffsets[i] - minSpace;\n                if (l > d)\n                    session.insert(p, lang.stringRepeat(\" \", l - d));\n                else\n                    session.remove(new Range(p.row, p.column, p.row, p.column - l + d));\n\n                r.start.column = r.end.column = maxCol;\n                r.start.row = r.end.row = p.row;\n                r.cursor = r.end;\n            });\n            sel.fromOrientedRange(ranges[0]);\n            this.renderer.updateCursor();\n            this.renderer.updateBackMarkers();\n        }\n    };\n\n    this.$reAlignText = function(lines, forceLeft) {\n        var isLeftAligned = true, isRightAligned = true;\n        var startW, textW, endW;\n\n        return lines.map(function(line) {\n            var m = line.match(/(\\s*)(.*?)(\\s*)([=:].*)/);\n            if (!m)\n                return [line];\n\n            if (startW == null) {\n                startW = m[1].length;\n                textW = m[2].length;\n                endW = m[3].length;\n                return m;\n            }\n\n            if (startW + textW + endW != m[1].length + m[2].length + m[3].length)\n                isRightAligned = false;\n            if (startW != m[1].length)\n                isLeftAligned = false;\n\n            if (startW > m[1].length)\n                startW = m[1].length;\n            if (textW < m[2].length)\n                textW = m[2].length;\n            if (endW > m[3].length)\n                endW = m[3].length;\n\n            return m;\n        }).map(forceLeft ? alignLeft :\n            isLeftAligned ? isRightAligned ? alignRight : alignLeft : unAlign);\n\n        function spaces(n) {\n            return lang.stringRepeat(\" \", n);\n        }\n\n        function alignLeft(m) {\n            return !m[2] ? m[0] : spaces(startW) + m[2]\n                + spaces(textW - m[2].length + endW)\n                + m[4].replace(/^([=:])\\s+/, \"$1 \");\n        }\n        function alignRight(m) {\n            return !m[2] ? m[0] : spaces(startW + textW - m[2].length) + m[2]\n                + spaces(endW)\n                + m[4].replace(/^([=:])\\s+/, \"$1 \");\n        }\n        function unAlign(m) {\n            return !m[2] ? m[0] : spaces(startW) + m[2]\n                + spaces(endW)\n                + m[4].replace(/^([=:])\\s+/, \"$1 \");\n        }\n    };\n}).call(Editor.prototype);\n\n\nfunction isSamePoint(p1, p2) {\n    return p1.row == p2.row && p1.column == p2.column;\n}\nexports.onSessionChange = function(e) {\n    var session = e.session;\n    if (session && !session.multiSelect) {\n        session.$selectionMarkers = [];\n        session.selection.$initRangeList();\n        session.multiSelect = session.selection;\n    }\n    this.multiSelect = session && session.multiSelect;\n\n    var oldSession = e.oldSession;\n    if (oldSession) {\n        oldSession.multiSelect.off(\"addRange\", this.$onAddRange);\n        oldSession.multiSelect.off(\"removeRange\", this.$onRemoveRange);\n        oldSession.multiSelect.off(\"multiSelect\", this.$onMultiSelect);\n        oldSession.multiSelect.off(\"singleSelect\", this.$onSingleSelect);\n        oldSession.multiSelect.lead.off(\"change\", this.$checkMultiselectChange);\n        oldSession.multiSelect.anchor.off(\"change\", this.$checkMultiselectChange);\n    }\n\n    if (session) {\n        session.multiSelect.on(\"addRange\", this.$onAddRange);\n        session.multiSelect.on(\"removeRange\", this.$onRemoveRange);\n        session.multiSelect.on(\"multiSelect\", this.$onMultiSelect);\n        session.multiSelect.on(\"singleSelect\", this.$onSingleSelect);\n        session.multiSelect.lead.on(\"change\", this.$checkMultiselectChange);\n        session.multiSelect.anchor.on(\"change\", this.$checkMultiselectChange);\n    }\n\n    if (session && this.inMultiSelectMode != session.selection.inMultiSelectMode) {\n        if (session.selection.inMultiSelectMode)\n            this.$onMultiSelect();\n        else\n            this.$onSingleSelect();\n    }\n};\nfunction MultiSelect(editor) {\n    if (editor.$multiselectOnSessionChange)\n        return;\n    editor.$onAddRange = editor.$onAddRange.bind(editor);\n    editor.$onRemoveRange = editor.$onRemoveRange.bind(editor);\n    editor.$onMultiSelect = editor.$onMultiSelect.bind(editor);\n    editor.$onSingleSelect = editor.$onSingleSelect.bind(editor);\n    editor.$multiselectOnSessionChange = exports.onSessionChange.bind(editor);\n    editor.$checkMultiselectChange = editor.$checkMultiselectChange.bind(editor);\n\n    editor.$multiselectOnSessionChange(editor);\n    editor.on(\"changeSession\", editor.$multiselectOnSessionChange);\n\n    editor.on(\"mousedown\", onMouseDown);\n    editor.commands.addCommands(commands.defaultCommands);\n\n    addAltCursorListeners(editor);\n}\n\nfunction addAltCursorListeners(editor){\n    if (!editor.textInput) return;\n    var el = editor.textInput.getElement();\n    var altCursor = false;\n    event.addListener(el, \"keydown\", function(e) {\n        var altDown = e.keyCode == 18 && !(e.ctrlKey || e.shiftKey || e.metaKey);\n        if (editor.$blockSelectEnabled && altDown) {\n            if (!altCursor) {\n                editor.renderer.setMouseCursor(\"crosshair\");\n                altCursor = true;\n            }\n        } else if (altCursor) {\n            reset();\n        }\n    });\n\n    event.addListener(el, \"keyup\", reset);\n    event.addListener(el, \"blur\", reset);\n    function reset(e) {\n        if (altCursor) {\n            editor.renderer.setMouseCursor(\"\");\n            altCursor = false;\n        }\n    }\n}\n\nexports.MultiSelect = MultiSelect;\n\n\nrequire(\"./config\").defineOptions(Editor.prototype, \"editor\", {\n    enableMultiselect: {\n        set: function(val) {\n            MultiSelect(this);\n            if (val) {\n                this.on(\"changeSession\", this.$multiselectOnSessionChange);\n                this.on(\"mousedown\", onMouseDown);\n            } else {\n                this.off(\"changeSession\", this.$multiselectOnSessionChange);\n                this.off(\"mousedown\", onMouseDown);\n            }\n        },\n        value: true\n    },\n    enableBlockSelect: {\n        set: function(val) {\n            this.$blockSelectEnabled = val;\n        },\n        value: true\n    }\n});\n\n\n\n});\n\nace.define(\"ace/mode/folding/fold_mode\",[\"require\",\"exports\",\"module\",\"ace/range\"], function(require, exports, module) {\n\"use strict\";\n\nvar Range = require(\"../../range\").Range;\n\nvar FoldMode = exports.FoldMode = function() {};\n\n(function() {\n\n    this.foldingStartMarker = null;\n    this.foldingStopMarker = null;\n    this.getFoldWidget = function(session, foldStyle, row) {\n        var line = session.getLine(row);\n        if (this.foldingStartMarker.test(line))\n            return \"start\";\n        if (foldStyle == \"markbeginend\"\n                && this.foldingStopMarker\n                && this.foldingStopMarker.test(line))\n            return \"end\";\n        return \"\";\n    };\n\n    this.getFoldWidgetRange = function(session, foldStyle, row) {\n        return null;\n    };\n\n    this.indentationBlock = function(session, row, column) {\n        var re = /\\S/;\n        var line = session.getLine(row);\n        var startLevel = line.search(re);\n        if (startLevel == -1)\n            return;\n\n        var startColumn = column || line.length;\n        var maxRow = session.getLength();\n        var startRow = row;\n        var endRow = row;\n\n        while (++row < maxRow) {\n            var level = session.getLine(row).search(re);\n\n            if (level == -1)\n                continue;\n\n            if (level <= startLevel) {\n                var token = session.getTokenAt(row, 0);\n                if (!token || token.type !== \"string\")\n                    break;\n            }\n\n            endRow = row;\n        }\n\n        if (endRow > startRow) {\n            var endColumn = session.getLine(endRow).length;\n            return new Range(startRow, startColumn, endRow, endColumn);\n        }\n    };\n\n    this.openingBracketBlock = function(session, bracket, row, column, typeRe) {\n        var start = {row: row, column: column + 1};\n        var end = session.$findClosingBracket(bracket, start, typeRe);\n        if (!end)\n            return;\n\n        var fw = session.foldWidgets[end.row];\n        if (fw == null)\n            fw = session.getFoldWidget(end.row);\n\n        if (fw == \"start\" && end.row > start.row) {\n            end.row --;\n            end.column = session.getLine(end.row).length;\n        }\n        return Range.fromPoints(start, end);\n    };\n\n    this.closingBracketBlock = function(session, bracket, row, column, typeRe) {\n        var end = {row: row, column: column};\n        var start = session.$findOpeningBracket(bracket, end);\n\n        if (!start)\n            return;\n\n        start.column++;\n        end.column--;\n\n        return  Range.fromPoints(start, end);\n    };\n}).call(FoldMode.prototype);\n\n});\n\nace.define(\"ace/theme/textmate\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\"], function(require, exports, module) {\n\"use strict\";\n\nexports.isDark = false;\nexports.cssClass = \"ace-tm\";\nexports.cssText = \".ace-tm .ace_gutter {\\\nbackground: #f0f0f0;\\\ncolor: #333;\\\n}\\\n.ace-tm .ace_print-margin {\\\nwidth: 1px;\\\nbackground: #e8e8e8;\\\n}\\\n.ace-tm .ace_fold {\\\nbackground-color: #6B72E6;\\\n}\\\n.ace-tm {\\\nbackground-color: #FFFFFF;\\\ncolor: black;\\\n}\\\n.ace-tm .ace_cursor {\\\ncolor: black;\\\n}\\\n.ace-tm .ace_invisible {\\\ncolor: rgb(191, 191, 191);\\\n}\\\n.ace-tm .ace_storage,\\\n.ace-tm .ace_keyword {\\\ncolor: blue;\\\n}\\\n.ace-tm .ace_constant {\\\ncolor: rgb(197, 6, 11);\\\n}\\\n.ace-tm .ace_constant.ace_buildin {\\\ncolor: rgb(88, 72, 246);\\\n}\\\n.ace-tm .ace_constant.ace_language {\\\ncolor: rgb(88, 92, 246);\\\n}\\\n.ace-tm .ace_constant.ace_library {\\\ncolor: rgb(6, 150, 14);\\\n}\\\n.ace-tm .ace_invalid {\\\nbackground-color: rgba(255, 0, 0, 0.1);\\\ncolor: red;\\\n}\\\n.ace-tm .ace_support.ace_function {\\\ncolor: rgb(60, 76, 114);\\\n}\\\n.ace-tm .ace_support.ace_constant {\\\ncolor: rgb(6, 150, 14);\\\n}\\\n.ace-tm .ace_support.ace_type,\\\n.ace-tm .ace_support.ace_class {\\\ncolor: rgb(109, 121, 222);\\\n}\\\n.ace-tm .ace_keyword.ace_operator {\\\ncolor: rgb(104, 118, 135);\\\n}\\\n.ace-tm .ace_string {\\\ncolor: rgb(3, 106, 7);\\\n}\\\n.ace-tm .ace_comment {\\\ncolor: rgb(76, 136, 107);\\\n}\\\n.ace-tm .ace_comment.ace_doc {\\\ncolor: rgb(0, 102, 255);\\\n}\\\n.ace-tm .ace_comment.ace_doc.ace_tag {\\\ncolor: rgb(128, 159, 191);\\\n}\\\n.ace-tm .ace_constant.ace_numeric {\\\ncolor: rgb(0, 0, 205);\\\n}\\\n.ace-tm .ace_variable {\\\ncolor: rgb(49, 132, 149);\\\n}\\\n.ace-tm .ace_xml-pe {\\\ncolor: rgb(104, 104, 91);\\\n}\\\n.ace-tm .ace_entity.ace_name.ace_function {\\\ncolor: #0000A2;\\\n}\\\n.ace-tm .ace_heading {\\\ncolor: rgb(12, 7, 255);\\\n}\\\n.ace-tm .ace_list {\\\ncolor:rgb(185, 6, 144);\\\n}\\\n.ace-tm .ace_meta.ace_tag {\\\ncolor:rgb(0, 22, 142);\\\n}\\\n.ace-tm .ace_string.ace_regex {\\\ncolor: rgb(255, 0, 0)\\\n}\\\n.ace-tm .ace_marker-layer .ace_selection {\\\nbackground: rgb(181, 213, 255);\\\n}\\\n.ace-tm.ace_multiselect .ace_selection.ace_start {\\\nbox-shadow: 0 0 3px 0px white;\\\n}\\\n.ace-tm .ace_marker-layer .ace_step {\\\nbackground: rgb(252, 255, 0);\\\n}\\\n.ace-tm .ace_marker-layer .ace_stack {\\\nbackground: rgb(164, 229, 101);\\\n}\\\n.ace-tm .ace_marker-layer .ace_bracket {\\\nmargin: -1px 0 0 -1px;\\\nborder: 1px solid rgb(192, 192, 192);\\\n}\\\n.ace-tm .ace_marker-layer .ace_active-line {\\\nbackground: rgba(0, 0, 0, 0.07);\\\n}\\\n.ace-tm .ace_gutter-active-line {\\\nbackground-color : #dcdcdc;\\\n}\\\n.ace-tm .ace_marker-layer .ace_selected-word {\\\nbackground: rgb(250, 250, 255);\\\nborder: 1px solid rgb(200, 200, 250);\\\n}\\\n.ace-tm .ace_indent-guide {\\\nbackground: url(\\\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\\\") right repeat-y;\\\n}\\\n\";\nexports.$id = \"ace/theme/textmate\";\n\nvar dom = require(\"../lib/dom\");\ndom.importCssString(exports.cssText, exports.cssClass);\n});\n\nace.define(\"ace/line_widgets\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\"], function(require, exports, module) {\n\"use strict\";\n\nvar dom = require(\"./lib/dom\");\n\nfunction LineWidgets(session) {\n    this.session = session;\n    this.session.widgetManager = this;\n    this.session.getRowLength = this.getRowLength;\n    this.session.$getWidgetScreenLength = this.$getWidgetScreenLength;\n    this.updateOnChange = this.updateOnChange.bind(this);\n    this.renderWidgets = this.renderWidgets.bind(this);\n    this.measureWidgets = this.measureWidgets.bind(this);\n    this.session._changedWidgets = [];\n    this.$onChangeEditor = this.$onChangeEditor.bind(this);\n    \n    this.session.on(\"change\", this.updateOnChange);\n    this.session.on(\"changeFold\", this.updateOnFold);\n    this.session.on(\"changeEditor\", this.$onChangeEditor);\n}\n\n(function() {\n    this.getRowLength = function(row) {\n        var h;\n        if (this.lineWidgets)\n            h = this.lineWidgets[row] && this.lineWidgets[row].rowCount || 0;\n        else \n            h = 0;\n        if (!this.$useWrapMode || !this.$wrapData[row]) {\n            return 1 + h;\n        } else {\n            return this.$wrapData[row].length + 1 + h;\n        }\n    };\n\n    this.$getWidgetScreenLength = function() {\n        var screenRows = 0;\n        this.lineWidgets.forEach(function(w){\n            if (w && w.rowCount && !w.hidden)\n                screenRows += w.rowCount;\n        });\n        return screenRows;\n    };    \n    \n    this.$onChangeEditor = function(e) {\n        this.attach(e.editor);\n    };\n    \n    this.attach = function(editor) {\n        if (editor  && editor.widgetManager && editor.widgetManager != this)\n            editor.widgetManager.detach();\n\n        if (this.editor == editor)\n            return;\n\n        this.detach();\n        this.editor = editor;\n        \n        if (editor) {\n            editor.widgetManager = this;\n            editor.renderer.on(\"beforeRender\", this.measureWidgets);\n            editor.renderer.on(\"afterRender\", this.renderWidgets);\n        }\n    };\n    this.detach = function(e) {\n        var editor = this.editor;\n        if (!editor)\n            return;\n        \n        this.editor = null;\n        editor.widgetManager = null;\n        \n        editor.renderer.off(\"beforeRender\", this.measureWidgets);\n        editor.renderer.off(\"afterRender\", this.renderWidgets);\n        var lineWidgets = this.session.lineWidgets;\n        lineWidgets && lineWidgets.forEach(function(w) {\n            if (w && w.el && w.el.parentNode) {\n                w._inDocument = false;\n                w.el.parentNode.removeChild(w.el);\n            }\n        });\n    };\n\n    this.updateOnFold = function(e, session) {\n        var lineWidgets = session.lineWidgets;\n        if (!lineWidgets || !e.action)\n            return;\n        var fold = e.data;\n        var start = fold.start.row;\n        var end = fold.end.row;\n        var hide = e.action == \"add\";\n        for (var i = start + 1; i < end; i++) {\n            if (lineWidgets[i])\n                lineWidgets[i].hidden = hide;\n        }\n        if (lineWidgets[end]) {\n            if (hide) {\n                if (!lineWidgets[start])\n                    lineWidgets[start] = lineWidgets[end];\n                else\n                    lineWidgets[end].hidden = hide;\n            } else {\n                if (lineWidgets[start] == lineWidgets[end])\n                    lineWidgets[start] = undefined;\n                lineWidgets[end].hidden = hide;\n            }\n        }\n    };\n    \n    this.updateOnChange = function(delta) {\n        var lineWidgets = this.session.lineWidgets;\n        if (!lineWidgets) return;\n        \n        var startRow = delta.start.row;\n        var len = delta.end.row - startRow;\n\n        if (len === 0) {\n        } else if (delta.action == \"remove\") {\n            var removed = lineWidgets.splice(startRow + 1, len);\n            if (!lineWidgets[startRow] && removed[removed.length - 1]) {\n                lineWidgets[startRow] = removed.pop();\n            }\n            removed.forEach(function(w) {\n                w && this.removeLineWidget(w);\n            }, this);\n            this.$updateRows();\n        } else {\n            var args = new Array(len);\n            if (lineWidgets[startRow] && lineWidgets[startRow].column != null) {\n                if (delta.start.column > lineWidgets[startRow].column)\n                    startRow++;\n            }\n            args.unshift(startRow, 0);\n            lineWidgets.splice.apply(lineWidgets, args);\n            this.$updateRows();\n        }\n    };\n    \n    this.$updateRows = function() {\n        var lineWidgets = this.session.lineWidgets;\n        if (!lineWidgets) return;\n        var noWidgets = true;\n        lineWidgets.forEach(function(w, i) {\n            if (w) {\n                noWidgets = false;\n                w.row = i;\n                while (w.$oldWidget) {\n                    w.$oldWidget.row = i;\n                    w = w.$oldWidget;\n                }\n            }\n        });\n        if (noWidgets)\n            this.session.lineWidgets = null;\n    };\n\n    this.$registerLineWidget = function(w) {\n        if (!this.session.lineWidgets)\n            this.session.lineWidgets = new Array(this.session.getLength());\n        \n        var old = this.session.lineWidgets[w.row];\n        if (old) {\n            w.$oldWidget = old;\n            if (old.el && old.el.parentNode) {\n                old.el.parentNode.removeChild(old.el);\n                old._inDocument = false;\n            }\n        }\n            \n        this.session.lineWidgets[w.row] = w;\n        return w;\n    };\n    \n    this.addLineWidget = function(w) {\n        this.$registerLineWidget(w);\n        w.session = this.session;\n        \n        if (!this.editor) return w;\n        \n        var renderer = this.editor.renderer;\n        if (w.html && !w.el) {\n            w.el = dom.createElement(\"div\");\n            w.el.innerHTML = w.html;\n        }\n        if (w.el) {\n            dom.addCssClass(w.el, \"ace_lineWidgetContainer\");\n            w.el.style.position = \"absolute\";\n            w.el.style.zIndex = 5;\n            renderer.container.appendChild(w.el);\n            w._inDocument = true;\n            \n            if (!w.coverGutter) {\n                w.el.style.zIndex = 3;\n            }\n            if (w.pixelHeight == null) {\n                w.pixelHeight = w.el.offsetHeight;\n            }\n        }\n        if (w.rowCount == null) {\n            w.rowCount = w.pixelHeight / renderer.layerConfig.lineHeight;\n        }\n        \n        var fold = this.session.getFoldAt(w.row, 0);\n        w.$fold = fold;\n        if (fold) {\n            var lineWidgets = this.session.lineWidgets;\n            if (w.row == fold.end.row && !lineWidgets[fold.start.row])\n                lineWidgets[fold.start.row] = w;\n            else\n                w.hidden = true;\n        }\n            \n        this.session._emit(\"changeFold\", {data:{start:{row: w.row}}});\n        \n        this.$updateRows();\n        this.renderWidgets(null, renderer);\n        this.onWidgetChanged(w);\n        return w;\n    };\n    \n    this.removeLineWidget = function(w) {\n        w._inDocument = false;\n        w.session = null;\n        if (w.el && w.el.parentNode)\n            w.el.parentNode.removeChild(w.el);\n        if (w.editor && w.editor.destroy) try {\n            w.editor.destroy();\n        } catch(e){}\n        if (this.session.lineWidgets) {\n            var w1 = this.session.lineWidgets[w.row];\n            if (w1 == w) {\n                this.session.lineWidgets[w.row] = w.$oldWidget;\n                if (w.$oldWidget)\n                    this.onWidgetChanged(w.$oldWidget);\n            } else {\n                while (w1) {\n                    if (w1.$oldWidget == w) {\n                        w1.$oldWidget = w.$oldWidget;\n                        break;\n                    }\n                    w1 = w1.$oldWidget;\n                }\n            }\n        }\n        this.session._emit(\"changeFold\", {data:{start:{row: w.row}}});\n        this.$updateRows();\n    };\n    \n    this.getWidgetsAtRow = function(row) {\n        var lineWidgets = this.session.lineWidgets;\n        var w = lineWidgets && lineWidgets[row];\n        var list = [];\n        while (w) {\n            list.push(w);\n            w = w.$oldWidget;\n        }\n        return list;\n    };\n    \n    this.onWidgetChanged = function(w) {\n        this.session._changedWidgets.push(w);\n        this.editor && this.editor.renderer.updateFull();\n    };\n    \n    this.measureWidgets = function(e, renderer) {\n        var changedWidgets = this.session._changedWidgets;\n        var config = renderer.layerConfig;\n        \n        if (!changedWidgets || !changedWidgets.length) return;\n        var min = Infinity;\n        for (var i = 0; i < changedWidgets.length; i++) {\n            var w = changedWidgets[i];\n            if (!w || !w.el) continue;\n            if (w.session != this.session) continue;\n            if (!w._inDocument) {\n                if (this.session.lineWidgets[w.row] != w)\n                    continue;\n                w._inDocument = true;\n                renderer.container.appendChild(w.el);\n            }\n            \n            w.h = w.el.offsetHeight;\n            \n            if (!w.fixedWidth) {\n                w.w = w.el.offsetWidth;\n                w.screenWidth = Math.ceil(w.w / config.characterWidth);\n            }\n            \n            var rowCount = w.h / config.lineHeight;\n            if (w.coverLine) {\n                rowCount -= this.session.getRowLineCount(w.row);\n                if (rowCount < 0)\n                    rowCount = 0;\n            }\n            if (w.rowCount != rowCount) {\n                w.rowCount = rowCount;\n                if (w.row < min)\n                    min = w.row;\n            }\n        }\n        if (min != Infinity) {\n            this.session._emit(\"changeFold\", {data:{start:{row: min}}});\n            this.session.lineWidgetWidth = null;\n        }\n        this.session._changedWidgets = [];\n    };\n    \n    this.renderWidgets = function(e, renderer) {\n        var config = renderer.layerConfig;\n        var lineWidgets = this.session.lineWidgets;\n        if (!lineWidgets)\n            return;\n        var first = Math.min(this.firstRow, config.firstRow);\n        var last = Math.max(this.lastRow, config.lastRow, lineWidgets.length);\n        \n        while (first > 0 && !lineWidgets[first])\n            first--;\n        \n        this.firstRow = config.firstRow;\n        this.lastRow = config.lastRow;\n\n        renderer.$cursorLayer.config = config;\n        for (var i = first; i <= last; i++) {\n            var w = lineWidgets[i];\n            if (!w || !w.el) continue;\n            if (w.hidden) {\n                w.el.style.top = -100 - (w.pixelHeight || 0) + \"px\";\n                continue;\n            }\n            if (!w._inDocument) {\n                w._inDocument = true;\n                renderer.container.appendChild(w.el);\n            }\n            var top = renderer.$cursorLayer.getPixelPosition({row: i, column:0}, true).top;\n            if (!w.coverLine)\n                top += config.lineHeight * this.session.getRowLineCount(w.row);\n            w.el.style.top = top - config.offset + \"px\";\n            \n            var left = w.coverGutter ? 0 : renderer.gutterWidth;\n            if (!w.fixedWidth)\n                left -= renderer.scrollLeft;\n            w.el.style.left = left + \"px\";\n            \n            if (w.fullWidth && w.screenWidth) {\n                w.el.style.minWidth = config.width + 2 * config.padding + \"px\";\n            }\n            \n            if (w.fixedWidth) {\n                w.el.style.right = renderer.scrollBar.getWidth() + \"px\";\n            } else {\n                w.el.style.right = \"\";\n            }\n        }\n    };\n    \n}).call(LineWidgets.prototype);\n\n\nexports.LineWidgets = LineWidgets;\n\n});\n\nace.define(\"ace/ext/error_marker\",[\"require\",\"exports\",\"module\",\"ace/line_widgets\",\"ace/lib/dom\",\"ace/range\"], function(require, exports, module) {\n\"use strict\";\nvar LineWidgets = require(\"../line_widgets\").LineWidgets;\nvar dom = require(\"../lib/dom\");\nvar Range = require(\"../range\").Range;\n\nfunction binarySearch(array, needle, comparator) {\n    var first = 0;\n    var last = array.length - 1;\n\n    while (first <= last) {\n        var mid = (first + last) >> 1;\n        var c = comparator(needle, array[mid]);\n        if (c > 0)\n            first = mid + 1;\n        else if (c < 0)\n            last = mid - 1;\n        else\n            return mid;\n    }\n    return -(first + 1);\n}\n\nfunction findAnnotations(session, row, dir) {\n    var annotations = session.getAnnotations().sort(Range.comparePoints);\n    if (!annotations.length)\n        return;\n    \n    var i = binarySearch(annotations, {row: row, column: -1}, Range.comparePoints);\n    if (i < 0)\n        i = -i - 1;\n    \n    if (i >= annotations.length)\n        i = dir > 0 ? 0 : annotations.length - 1;\n    else if (i === 0 && dir < 0)\n        i = annotations.length - 1;\n    \n    var annotation = annotations[i];\n    if (!annotation || !dir)\n        return;\n\n    if (annotation.row === row) {\n        do {\n            annotation = annotations[i += dir];\n        } while (annotation && annotation.row === row);\n        if (!annotation)\n            return annotations.slice();\n    }\n    \n    \n    var matched = [];\n    row = annotation.row;\n    do {\n        matched[dir < 0 ? \"unshift\" : \"push\"](annotation);\n        annotation = annotations[i += dir];\n    } while (annotation && annotation.row == row);\n    return matched.length && matched;\n}\n\nexports.showErrorMarker = function(editor, dir) {\n    var session = editor.session;\n    if (!session.widgetManager) {\n        session.widgetManager = new LineWidgets(session);\n        session.widgetManager.attach(editor);\n    }\n    \n    var pos = editor.getCursorPosition();\n    var row = pos.row;\n    var oldWidget = session.widgetManager.getWidgetsAtRow(row).filter(function(w) {\n        return w.type == \"errorMarker\";\n    })[0];\n    if (oldWidget) {\n        oldWidget.destroy();\n    } else {\n        row -= dir;\n    }\n    var annotations = findAnnotations(session, row, dir);\n    var gutterAnno;\n    if (annotations) {\n        var annotation = annotations[0];\n        pos.column = (annotation.pos && typeof annotation.column != \"number\"\n            ? annotation.pos.sc\n            : annotation.column) || 0;\n        pos.row = annotation.row;\n        gutterAnno = editor.renderer.$gutterLayer.$annotations[pos.row];\n    } else if (oldWidget) {\n        return;\n    } else {\n        gutterAnno = {\n            text: [\"Looks good!\"],\n            className: \"ace_ok\"\n        };\n    }\n    editor.session.unfold(pos.row);\n    editor.selection.moveToPosition(pos);\n    \n    var w = {\n        row: pos.row, \n        fixedWidth: true,\n        coverGutter: true,\n        el: dom.createElement(\"div\"),\n        type: \"errorMarker\"\n    };\n    var el = w.el.appendChild(dom.createElement(\"div\"));\n    var arrow = w.el.appendChild(dom.createElement(\"div\"));\n    arrow.className = \"error_widget_arrow \" + gutterAnno.className;\n    \n    var left = editor.renderer.$cursorLayer\n        .getPixelPosition(pos).left;\n    arrow.style.left = left + editor.renderer.gutterWidth - 5 + \"px\";\n    \n    w.el.className = \"error_widget_wrapper\";\n    el.className = \"error_widget \" + gutterAnno.className;\n    el.innerHTML = gutterAnno.text.join(\"<br>\");\n    \n    el.appendChild(dom.createElement(\"div\"));\n    \n    var kb = function(_, hashId, keyString) {\n        if (hashId === 0 && (keyString === \"esc\" || keyString === \"return\")) {\n            w.destroy();\n            return {command: \"null\"};\n        }\n    };\n    \n    w.destroy = function() {\n        if (editor.$mouseHandler.isMousePressed)\n            return;\n        editor.keyBinding.removeKeyboardHandler(kb);\n        session.widgetManager.removeLineWidget(w);\n        editor.off(\"changeSelection\", w.destroy);\n        editor.off(\"changeSession\", w.destroy);\n        editor.off(\"mouseup\", w.destroy);\n        editor.off(\"change\", w.destroy);\n    };\n    \n    editor.keyBinding.addKeyboardHandler(kb);\n    editor.on(\"changeSelection\", w.destroy);\n    editor.on(\"changeSession\", w.destroy);\n    editor.on(\"mouseup\", w.destroy);\n    editor.on(\"change\", w.destroy);\n    \n    editor.session.widgetManager.addLineWidget(w);\n    \n    w.el.onmousedown = editor.focus.bind(editor);\n    \n    editor.renderer.scrollCursorIntoView(null, 0.5, {bottom: w.el.offsetHeight});\n};\n\n\ndom.importCssString(\"\\\n    .error_widget_wrapper {\\\n        background: inherit;\\\n        color: inherit;\\\n        border:none\\\n    }\\\n    .error_widget {\\\n        border-top: solid 2px;\\\n        border-bottom: solid 2px;\\\n        margin: 5px 0;\\\n        padding: 10px 40px;\\\n        white-space: pre-wrap;\\\n    }\\\n    .error_widget.ace_error, .error_widget_arrow.ace_error{\\\n        border-color: #ff5a5a\\\n    }\\\n    .error_widget.ace_warning, .error_widget_arrow.ace_warning{\\\n        border-color: #F1D817\\\n    }\\\n    .error_widget.ace_info, .error_widget_arrow.ace_info{\\\n        border-color: #5a5a5a\\\n    }\\\n    .error_widget.ace_ok, .error_widget_arrow.ace_ok{\\\n        border-color: #5aaa5a\\\n    }\\\n    .error_widget_arrow {\\\n        position: absolute;\\\n        border: solid 5px;\\\n        border-top-color: transparent!important;\\\n        border-right-color: transparent!important;\\\n        border-left-color: transparent!important;\\\n        top: -5px;\\\n    }\\\n\", \"\");\n\n});\n\nace.define(\"ace/ace\",[\"require\",\"exports\",\"module\",\"ace/lib/fixoldbrowsers\",\"ace/lib/dom\",\"ace/lib/event\",\"ace/range\",\"ace/editor\",\"ace/edit_session\",\"ace/undomanager\",\"ace/virtual_renderer\",\"ace/worker/worker_client\",\"ace/keyboard/hash_handler\",\"ace/placeholder\",\"ace/multi_select\",\"ace/mode/folding/fold_mode\",\"ace/theme/textmate\",\"ace/ext/error_marker\",\"ace/config\"], function(require, exports, module) {\n\"use strict\";\n\nrequire(\"./lib/fixoldbrowsers\");\n\nvar dom = require(\"./lib/dom\");\nvar event = require(\"./lib/event\");\n\nvar Range = require(\"./range\").Range;\nvar Editor = require(\"./editor\").Editor;\nvar EditSession = require(\"./edit_session\").EditSession;\nvar UndoManager = require(\"./undomanager\").UndoManager;\nvar Renderer = require(\"./virtual_renderer\").VirtualRenderer;\nrequire(\"./worker/worker_client\");\nrequire(\"./keyboard/hash_handler\");\nrequire(\"./placeholder\");\nrequire(\"./multi_select\");\nrequire(\"./mode/folding/fold_mode\");\nrequire(\"./theme/textmate\");\nrequire(\"./ext/error_marker\");\n\nexports.config = require(\"./config\");\nexports.require = require;\n\nif (typeof define === \"function\")\n    exports.define = define;\nexports.edit = function(el, options) {\n    if (typeof el == \"string\") {\n        var _id = el;\n        el = document.getElementById(_id);\n        if (!el)\n            throw new Error(\"ace.edit can't find div #\" + _id);\n    }\n\n    if (el && el.env && el.env.editor instanceof Editor)\n        return el.env.editor;\n\n    var value = \"\";\n    if (el && /input|textarea/i.test(el.tagName)) {\n        var oldNode = el;\n        value = oldNode.value;\n        el = dom.createElement(\"pre\");\n        oldNode.parentNode.replaceChild(el, oldNode);\n    } else if (el) {\n        value = el.textContent;\n        el.innerHTML = \"\";\n    }\n\n    var doc = exports.createEditSession(value);\n\n    var editor = new Editor(new Renderer(el), doc, options);\n\n    var env = {\n        document: doc,\n        editor: editor,\n        onResize: editor.resize.bind(editor, null)\n    };\n    if (oldNode) env.textarea = oldNode;\n    event.addListener(window, \"resize\", env.onResize);\n    editor.on(\"destroy\", function() {\n        event.removeListener(window, \"resize\", env.onResize);\n        env.editor.container.env = null; // prevent memory leak on old ie\n    });\n    editor.container.env = editor.env = env;\n    return editor;\n};\nexports.createEditSession = function(text, mode) {\n    var doc = new EditSession(text, mode);\n    doc.setUndoManager(new UndoManager());\n    return doc;\n};\nexports.Range = Range;\nexports.Editor = Editor;\nexports.EditSession = EditSession;\nexports.UndoManager = UndoManager;\nexports.VirtualRenderer = Renderer;\nexports.version = exports.config.version;\n});            (function() {\n                ace.require([\"ace/ace\"], function(a) {\n                    if (a) {\n                        a.config.init(true);\n                        a.define = ace.define;\n                    }\n                    if (!window.ace)\n                        window.ace = a;\n                    for (var key in a) if (a.hasOwnProperty(key))\n                        window.ace[key] = a[key];\n                    window.ace[\"default\"] = window.ace;\n                    if (typeof module == \"object\" && typeof exports == \"object\" && module) {\n                        module.exports = window.ace;\n                    }\n                });\n            })();\n        "]}