{"version":3,"sources":["node_modules/brace/index.js","node_modules/ngx-ace-wrapper/fesm2020/ngx-ace-wrapper.mjs","node_modules/brace/theme/github.js","apps/vendasta-center-client/src/app/pages/the-loop/event-selector/event-selector.component.ts","apps/vendasta-center-client/src/app/pages/the-loop/event-selector/event-selector.component.html","node_modules/@vendasta/templates/fesm2020/vendasta-templates.mjs","node_modules/@vendasta/the-loop/fesm2020/vendasta-the-loop.mjs","apps/vendasta-center-client/src/app/pages/the-loop/post-type-editor/post-type-editor.component.ts","apps/vendasta-center-client/src/app/pages/the-loop/post-type-editor/post-type-editor.component.html","apps/vendasta-center-client/src/app/pages/the-loop/post-type-editor/post-type-filter-settings/post-type-filter-settings.component.ts","apps/vendasta-center-client/src/app/pages/the-loop/post-type-editor/post-type-filter-settings/post-type-filter-settings.component.html","apps/vendasta-center-client/src/app/pages/the-loop/post-type-editor/post-type-general-settings/post-type-general-settings.component.ts","apps/vendasta-center-client/src/app/pages/the-loop/post-type-editor/post-type-general-settings/post-type-general-settings.component.html","apps/vendasta-center-client/src/app/pages/the-loop/post-type-editor/post-type-icon-settings/post-type-icon-settings.component.ts","apps/vendasta-center-client/src/app/pages/the-loop/post-type-editor/post-type-icon-settings/post-type-icon-settings.component.html","apps/vendasta-center-client/src/app/pages/the-loop/post-type-editor/post-type-templates-settings/post-type-templates-settings.component.ts","apps/vendasta-center-client/src/app/pages/the-loop/post-type-editor/post-type-templates-settings/post-type-templates-settings.component.html","node_modules/autolinker/dist/es2015/version.js","node_modules/autolinker/dist/es2015/utils.js","node_modules/autolinker/dist/es2015/regex-lib.js","node_modules/autolinker/dist/es2015/html-tag.js","node_modules/autolinker/dist/es2015/truncate/truncate-smart.js","node_modules/autolinker/dist/es2015/truncate/truncate-middle.js","node_modules/autolinker/dist/es2015/truncate/truncate-end.js","node_modules/autolinker/dist/es2015/anchor-tag-builder.js","node_modules/autolinker/dist/es2015/match/abstract-match.js","node_modules/autolinker/dist/es2015/parser/tld-regex.js","node_modules/autolinker/dist/es2015/parser/uri-utils.js","node_modules/autolinker/dist/es2015/match/url-match.js","node_modules/autolinker/dist/es2015/parser/email-utils.js","node_modules/autolinker/dist/es2015/match/email-match.js","node_modules/autolinker/dist/es2015/parser/hashtag-utils.js","node_modules/autolinker/dist/es2015/match/hashtag-match.js","node_modules/autolinker/dist/es2015/parser/mention-utils.js","node_modules/autolinker/dist/es2015/match/mention-match.js","node_modules/autolinker/dist/es2015/parser/phone-number-utils.js","node_modules/autolinker/dist/es2015/match/phone-match.js","node_modules/autolinker/dist/es2015/parser/parse-matches.js","node_modules/autolinker/dist/es2015/htmlParser/parse-html.js","node_modules/autolinker/dist/es2015/autolinker.js","node_modules/autolinker/dist/es2015/index.js","apps/vendasta-center-client/src/app/pages/the-loop/post-types-table/post-types-table.component.ts","apps/vendasta-center-client/src/app/pages/the-loop/post-types-table/post-types-table.component.html","apps/vendasta-center-client/src/app/pages/the-loop/the-loop.routing.module.ts","apps/vendasta-center-client/src/app/pages/the-loop/the-loop.module.ts"],"sourcesContent":["/* ***** 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 (acequire, exports, module) params\n */\n\n(function () {\n var ACE_NAMESPACE = \"ace\";\n var global = function () {\n return this;\n }();\n if (!global && typeof window != \"undefined\") global = window; // strict mode\n\n if (!ACE_NAMESPACE && typeof acequirejs !== \"undefined\") return;\n var define = function (module, deps, payload) {\n if (typeof module !== \"string\") {\n if (define.original) define.original.apply(this, arguments);else {\n console.error(\"dropping module because define wasn\\'t a string.\");\n console.trace();\n }\n return;\n }\n if (arguments.length == 2) payload = deps;\n if (!define.modules[module]) {\n define.payloads[module] = payload;\n define.modules[module] = null;\n }\n };\n define.modules = {};\n define.payloads = {};\n\n /**\n * Get at functionality define()ed using the function above\n */\n var _acequire = 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 && acequire.original) return;\n params.push(dep);\n }\n return callback && callback.apply(null, params) || true;\n }\n };\n var acequire = function (module, callback) {\n var packagedModule = _acequire(\"\", module, callback);\n if (packagedModule == undefined && acequire.original) return acequire.original.apply(this, arguments);\n return packagedModule;\n };\n var normalizeModule = function (parentId, moduleName) {\n // normalize plugin acequires\n if (moduleName.indexOf(\"!\") !== -1) {\n var chunks = moduleName.split(\"!\");\n return normalizeModule(parentId, chunks[0]) + \"!\" + normalizeModule(parentId, chunks[1]);\n }\n // normalize relative acequires\n if (moduleName.charAt(0) == \".\") {\n var base = parentId.split(\"/\").slice(0, -1).join(\"/\");\n moduleName = base + \"/\" + moduleName;\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 */\n var lookup = function (parentId, moduleName) {\n moduleName = normalizeModule(parentId, moduleName);\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 var req = function (module, callback) {\n return _acequire(moduleName, module, callback);\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 function exportAce(ns) {\n var root = global;\n if (ns) {\n if (!global[ns]) global[ns] = {};\n root = global[ns];\n }\n if (!root.define || !root.define.packaged) {\n define.original = root.define;\n root.define = define;\n root.define.packaged = true;\n }\n if (!root.acequire || !root.acequire.packaged) {\n acequire.original = root.acequire;\n root.acequire = acequire;\n root.acequire.packaged = true;\n }\n }\n exportAce(ACE_NAMESPACE);\n})();\nace.define(\"ace/lib/regexp\", [\"require\", \"exports\", \"module\"], function (acequire, 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,\n // 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 if (compliantLastIndexIncrement && compliantExecNpcg) return;\n RegExp.prototype.exec = function (str) {\n var match = real.exec.apply(this, arguments),\n name,\n 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) 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) match[name] = match[i];\n }\n }\n if (!compliantLastIndexIncrement && this.global && !match[0].length && this.lastIndex > match.index) 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) this.lastIndex--;\n return !!match;\n };\n }\n function getNativeFlags(regex) {\n return (regex.global ? \"g\" : \"\") + (regex.ignoreCase ? \"i\" : \"\") + (regex.multiline ? \"m\" : \"\") + (regex.extended ? \"x\" : \"\") + (\n // Proposed for ES4; included in AS3\n regex.sticky ? \"y\" : \"\");\n }\n function indexOf(array, item, from) {\n if (Array.prototype.indexOf)\n // 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) return i;\n }\n return -1;\n }\n});\nace.define(\"ace/lib/es5-shim\", [\"require\", \"exports\", \"module\"], function (acequire, exports, module) {\n function Empty() {}\n if (!Function.prototype.bind) {\n Function.prototype.bind = function bind(that) {\n // .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 if (this instanceof bound) {\n var result = target.apply(this, args.concat(slice.call(arguments)));\n if (Object(result) === result) {\n return result;\n }\n return this;\n } else {\n return target.apply(that, args.concat(slice.call(arguments)));\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 }\n var call = Function.prototype.call;\n var prototypeOfArray = Array.prototype;\n var prototypeOfObject = Object.prototype;\n var slice = prototypeOfArray.slice;\n var _toString = call.bind(prototypeOfObject.toString);\n var owns = call.bind(prototypeOfObject.hasOwnProperty);\n var defineGetter;\n var defineSetter;\n var lookupGetter;\n var lookupSetter;\n var supportsAccessors;\n if (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 }\n if ([1, 2].splice(0).length != 2) {\n if (function () {\n // 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 = [],\n lengthBefore;\n array.splice.apply(array, makeArray(20));\n array.splice.apply(array, makeArray(26));\n lengthBefore = array.length; //46\n array.splice(5, 0, \"XXX\"); // add one element\n\n lengthBefore + 1 == array.length;\n if (lengthBefore + 1 == array.length) {\n return true; // has right splice implementation without bugs\n }\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, [start === void 0 ? 0 : start, deleteCount === void 0 ? this.length - start : deleteCount].concat(slice.call(arguments, 2)));\n }\n };\n } else {\n //IE8\n Array.prototype.splice = function (pos, removeCount) {\n var length = this.length;\n if (pos > 0) {\n if (pos > length) 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 if (!(pos + removeCount < length)) removeCount = length - pos;\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 if (tailNewPos < tailOldPos) {\n // case A\n for (var i = 0; i < tailCount; ++i) {\n this[tailNewPos + i] = this[tailOldPos + i];\n }\n } else if (tailNewPos > tailOldPos) {\n // 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 }\n if (!Array.isArray) {\n Array.isArray = function isArray(obj) {\n return _toString(obj) == \"[object Array]\";\n };\n }\n var boxedString = Object(\"a\"),\n splitString = boxedString[0] != \"a\" || !(0 in boxedString);\n if (!Array.prototype.forEach) {\n Array.prototype.forEach = function forEach(fun /*, thisp*/) {\n var object = toObject(this),\n self = splitString && _toString(this) == \"[object String]\" ? this.split(\"\") : 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 while (++i < length) {\n if (i in self) {\n fun.call(thisp, self[i], i, object);\n }\n }\n };\n }\n if (!Array.prototype.map) {\n Array.prototype.map = function map(fun /*, thisp*/) {\n var object = toObject(this),\n self = splitString && _toString(this) == \"[object String]\" ? this.split(\"\") : 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 for (var i = 0; i < length; i++) {\n if (i in self) result[i] = fun.call(thisp, self[i], i, object);\n }\n return result;\n };\n }\n if (!Array.prototype.filter) {\n Array.prototype.filter = function filter(fun /*, thisp */) {\n var object = toObject(this),\n self = splitString && _toString(this) == \"[object String]\" ? this.split(\"\") : 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 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 }\n if (!Array.prototype.every) {\n Array.prototype.every = function every(fun /*, thisp */) {\n var object = toObject(this),\n self = splitString && _toString(this) == \"[object String]\" ? this.split(\"\") : 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 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 }\n if (!Array.prototype.some) {\n Array.prototype.some = function some(fun /*, thisp */) {\n var object = toObject(this),\n self = splitString && _toString(this) == \"[object String]\" ? this.split(\"\") : 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 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 }\n if (!Array.prototype.reduce) {\n Array.prototype.reduce = function reduce(fun /*, initial*/) {\n var object = toObject(this),\n self = splitString && _toString(this) == \"[object String]\" ? this.split(\"\") : 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 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 for (; i < length; i++) {\n if (i in self) {\n result = fun.call(void 0, result, self[i], i, object);\n }\n }\n return result;\n };\n }\n if (!Array.prototype.reduceRight) {\n Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) {\n var object = toObject(this),\n self = splitString && _toString(this) == \"[object String]\" ? this.split(\"\") : 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 var result,\n 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 do {\n if (i in this) {\n result = fun.call(void 0, result, self[i], i, object);\n }\n } while (i--);\n return result;\n };\n }\n if (!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]\" ? this.split(\"\") : toObject(this),\n length = self.length >>> 0;\n if (!length) {\n return -1;\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 }\n if (!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]\" ? this.split(\"\") : toObject(this),\n length = self.length >>> 0;\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 }\n if (!Object.getPrototypeOf) {\n Object.getPrototypeOf = function getPrototypeOf(object) {\n return object.__proto__ || (object.constructor ? object.constructor.prototype : prototypeOfObject);\n };\n }\n if (!Object.getOwnPropertyDescriptor) {\n var ERR_NON_OBJECT = \"Object.getOwnPropertyDescriptor called on a \" + \"non-object: \";\n Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) {\n if (typeof object != \"object\" && typeof object != \"function\" || object === null) throw new TypeError(ERR_NON_OBJECT + object);\n if (!owns(object, property)) return;\n var descriptor, getter, setter;\n descriptor = {\n enumerable: true,\n configurable: true\n };\n if (supportsAccessors) {\n var prototype = object.__proto__;\n object.__proto__ = prototypeOfObject;\n var getter = lookupGetter(object, property);\n var setter = lookupSetter(object, property);\n object.__proto__ = prototype;\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 }\n if (!Object.getOwnPropertyNames) {\n Object.getOwnPropertyNames = function getOwnPropertyNames(object) {\n return Object.keys(object);\n };\n }\n if (!Object.create) {\n var createEmpty;\n if (Object.prototype.__proto__ === null) {\n createEmpty = function () {\n return {\n \"__proto__\": null\n };\n };\n } else {\n createEmpty = function () {\n var empty = {};\n for (var i in empty) empty[i] = null;\n empty.constructor = empty.hasOwnProperty = empty.propertyIsEnumerable = empty.isPrototypeOf = empty.toLocaleString = empty.toString = empty.valueOf = empty.__proto__ = null;\n return empty;\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\") 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) Object.defineProperties(object, properties);\n return object;\n };\n }\n function doesDefinePropertyWork(object) {\n try {\n Object.defineProperty(object, \"sentinel\", {});\n return \"sentinel\" in object;\n } catch (exception) {}\n }\n if (Object.defineProperty) {\n var definePropertyWorksOnObject = doesDefinePropertyWork({});\n var definePropertyWorksOnDom = typeof document == \"undefined\" || doesDefinePropertyWork(document.createElement(\"div\"));\n if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) {\n var definePropertyFallback = Object.defineProperty;\n }\n }\n if (!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 \" + \"on this javascript engine\";\n Object.defineProperty = function defineProperty(object, property, descriptor) {\n if (typeof object != \"object\" && typeof object != \"function\" || object === null) throw new TypeError(ERR_NON_OBJECT_TARGET + object);\n if (typeof descriptor != \"object\" && typeof descriptor != \"function\" || descriptor === null) 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 if (owns(descriptor, \"value\")) {\n if (supportsAccessors && (lookupGetter(object, property) || lookupSetter(object, property))) {\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) throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);\n if (owns(descriptor, \"get\")) defineGetter(object, property, descriptor.get);\n if (owns(descriptor, \"set\")) defineSetter(object, property, descriptor.set);\n }\n return object;\n };\n }\n if (!Object.defineProperties) {\n Object.defineProperties = function defineProperties(object, properties) {\n for (var property in properties) {\n if (owns(properties, property)) Object.defineProperty(object, property, properties[property]);\n }\n return object;\n };\n }\n if (!Object.seal) {\n Object.seal = function seal(object) {\n return object;\n };\n }\n if (!Object.freeze) {\n Object.freeze = function freeze(object) {\n return object;\n };\n }\n try {\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 }\n if (!Object.preventExtensions) {\n Object.preventExtensions = function preventExtensions(object) {\n return object;\n };\n }\n if (!Object.isSealed) {\n Object.isSealed = function isSealed(object) {\n return false;\n };\n }\n if (!Object.isFrozen) {\n Object.isFrozen = function isFrozen(object) {\n return false;\n };\n }\n if (!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 }\n if (!Object.keys) {\n var hasDontEnumBug = true,\n dontEnums = [\"toString\", \"toLocaleString\", \"valueOf\", \"hasOwnProperty\", \"isPrototypeOf\", \"propertyIsEnumerable\", \"constructor\"],\n dontEnumsLength = dontEnums.length;\n for (var key in {\n \"toString\": null\n }) {\n hasDontEnumBug = false;\n }\n Object.keys = function keys(object) {\n if (typeof object != \"object\" && typeof object != \"function\" || object === null) {\n throw new TypeError(\"Object.keys called on a non-object\");\n }\n var keys = [];\n for (var name in object) {\n if (owns(object, name)) {\n keys.push(name);\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 if (!Date.now) {\n Date.now = function now() {\n return new Date().getTime();\n };\n }\n var ws = \"\\x09\\x0A\\x0B\\x0C\\x0D\\x20\\xA0\\u1680\\u180E\\u2000\\u2001\\u2002\\u2003\" + \"\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\u2028\" + \"\\u2029\\uFEFF\";\n if (!String.prototype.trim || ws.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 function toInteger(n) {\n n = +n;\n if (n !== 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 function isPrimitive(input) {\n var type = typeof input;\n return input === null || type === \"undefined\" || type === \"boolean\" || type === \"number\" || type === \"string\";\n }\n function 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 }\n var toObject = function (o) {\n if (o == null) {\n // this matches both null and undefined\n throw new TypeError(\"can't convert \" + o + \" to object\");\n }\n return Object(o);\n };\n});\nace.define(\"ace/lib/fixoldbrowsers\", [\"require\", \"exports\", \"module\", \"ace/lib/regexp\", \"ace/lib/es5-shim\"], function (acequire, exports, module) {\n \"use strict\";\n\n acequire(\"./regexp\");\n acequire(\"./es5-shim\");\n});\nace.define(\"ace/lib/dom\", [\"require\", \"exports\", \"module\"], function (acequire, exports, module) {\n \"use strict\";\n\n var XHTML_NS = \"http://www.w3.org/1999/xhtml\";\n exports.getDocumentHead = function (doc) {\n if (!doc) doc = document;\n return doc.head || doc.getElementsByTagName(\"head\")[0] || doc.documentElement;\n };\n exports.createElement = function (tag, ns) {\n return document.createElementNS ? document.createElementNS(ns || XHTML_NS, tag) : document.createElement(tag);\n };\n exports.hasCssClass = function (el, name) {\n var classes = (el.className + \"\").split(/\\s+/g);\n return classes.indexOf(name) !== -1;\n };\n exports.addCssClass = function (el, name) {\n if (!exports.hasCssClass(el, name)) {\n el.className += \" \" + name;\n }\n };\n exports.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 exports.toggleCssClass = function (el, name) {\n var classes = el.className.split(/\\s+/g),\n 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) classes.push(name);\n el.className = classes.join(\" \");\n return add;\n };\n exports.setCssClass = function (node, className, include) {\n if (include) {\n exports.addCssClass(node, className);\n } else {\n exports.removeCssClass(node, className);\n }\n };\n exports.hasCssString = function (id, doc) {\n var index = 0,\n sheets;\n doc = doc || document;\n if (doc.createStyleSheet && (sheets = doc.styleSheets)) {\n while (index < sheets.length) if (sheets[index++].owningElement.id === id) return true;\n } else if (sheets = doc.getElementsByTagName(\"style\")) {\n while (index < sheets.length) if (sheets[index++].id === id) return true;\n }\n return false;\n };\n exports.importCssString = function importCssString(cssText, id, doc) {\n doc = doc || document;\n if (id && exports.hasCssString(id, doc)) return null;\n var style;\n if (id) cssText += \"\\n/*# sourceURL=ace/css/\" + id + \" */\";\n if (doc.createStyleSheet) {\n style = doc.createStyleSheet();\n style.cssText = cssText;\n if (id) style.owningElement.id = id;\n } else {\n style = exports.createElement(\"style\");\n style.appendChild(doc.createTextNode(cssText));\n if (id) style.id = id;\n exports.getDocumentHead(doc).appendChild(style);\n }\n };\n exports.importCssStylsheet = function (uri, doc) {\n if (doc.createStyleSheet) {\n doc.createStyleSheet(uri);\n } else {\n var link = exports.createElement('link');\n link.rel = 'stylesheet';\n link.href = uri;\n exports.getDocumentHead(doc).appendChild(link);\n }\n };\n exports.getInnerWidth = function (element) {\n return parseInt(exports.computedStyle(element, \"paddingLeft\"), 10) + parseInt(exports.computedStyle(element, \"paddingRight\"), 10) + element.clientWidth;\n };\n exports.getInnerHeight = function (element) {\n return parseInt(exports.computedStyle(element, \"paddingTop\"), 10) + parseInt(exports.computedStyle(element, \"paddingBottom\"), 10) + element.clientHeight;\n };\n exports.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 var outer = exports.createElement(\"ace_outer\");\n var style = outer.style;\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 outer.appendChild(inner);\n var body = document.documentElement;\n body.appendChild(outer);\n var noScrollbar = inner.offsetWidth;\n style.overflow = \"scroll\";\n var withScrollbar = inner.offsetWidth;\n if (noScrollbar == withScrollbar) {\n withScrollbar = outer.clientWidth;\n }\n body.removeChild(outer);\n return noScrollbar - withScrollbar;\n };\n if (typeof document == \"undefined\") {\n exports.importCssString = function () {};\n return;\n }\n if (window.pageYOffset !== undefined) {\n exports.getPageScrollTop = function () {\n return window.pageYOffset;\n };\n exports.getPageScrollLeft = function () {\n return window.pageXOffset;\n };\n } else {\n exports.getPageScrollTop = function () {\n return document.body.scrollTop;\n };\n exports.getPageScrollLeft = function () {\n return document.body.scrollLeft;\n };\n }\n if (window.getComputedStyle) exports.computedStyle = function (element, style) {\n if (style) return (window.getComputedStyle(element, \"\") || {})[style] || \"\";\n return window.getComputedStyle(element, \"\") || {};\n };else exports.computedStyle = function (element, style) {\n if (style) return element.currentStyle[style];\n return element.currentStyle;\n };\n exports.setInnerHtml = function (el, innerHtml) {\n var element = el.cloneNode(false); //document.createElement(\"div\");\n element.innerHTML = innerHtml;\n el.parentNode.replaceChild(element, el);\n return element;\n };\n if (\"textContent\" in document.documentElement) {\n exports.setInnerText = function (el, innerText) {\n el.textContent = innerText;\n };\n exports.getInnerText = function (el) {\n return el.textContent;\n };\n } else {\n exports.setInnerText = function (el, innerText) {\n el.innerText = innerText;\n };\n exports.getInnerText = function (el) {\n return el.innerText;\n };\n }\n exports.getParentWindow = function (document) {\n return document.defaultView || document.parentWindow;\n };\n});\nace.define(\"ace/lib/oop\", [\"require\", \"exports\", \"module\"], function (acequire, exports, module) {\n \"use strict\";\n\n exports.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 exports.mixin = function (obj, mixin) {\n for (var key in mixin) {\n obj[key] = mixin[key];\n }\n return obj;\n };\n exports.implement = function (proto, mixin) {\n exports.mixin(proto, mixin);\n };\n});\nace.define(\"ace/lib/keys\", [\"require\", \"exports\", \"module\", \"ace/lib/fixoldbrowsers\", \"ace/lib/oop\"], function (acequire, exports, module) {\n \"use strict\";\n\n acequire(\"./fixoldbrowsers\");\n var oop = acequire(\"./oop\");\n var Keys = function () {\n var ret = {\n MODIFIER_KEYS: {\n 16: 'Shift',\n 17: 'Ctrl',\n 18: 'Alt',\n 224: 'Meta'\n },\n KEY_MODS: {\n \"ctrl\": 1,\n \"alt\": 2,\n \"option\": 2,\n \"shift\": 4,\n \"super\": 8,\n \"meta\": 8,\n \"command\": 8,\n \"cmd\": 8\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 PRINTABLE_KEYS: {\n 32: ' ',\n 48: '0',\n 49: '1',\n 50: '2',\n 51: '3',\n 52: '4',\n 53: '5',\n 54: '6',\n 55: '7',\n 56: '8',\n 57: '9',\n 59: ';',\n 61: '=',\n 65: 'a',\n 66: 'b',\n 67: 'c',\n 68: 'd',\n 69: 'e',\n 70: 'f',\n 71: 'g',\n 72: 'h',\n 73: 'i',\n 74: 'j',\n 75: 'k',\n 76: 'l',\n 77: 'm',\n 78: 'n',\n 79: 'o',\n 80: 'p',\n 81: 'q',\n 82: 'r',\n 83: 's',\n 84: 't',\n 85: 'u',\n 86: 'v',\n 87: 'w',\n 88: 'x',\n 89: 'y',\n 90: 'z',\n 107: '+',\n 109: '-',\n 110: '.',\n 186: ';',\n 187: '=',\n 188: ',',\n 189: '-',\n 190: '.',\n 191: '/',\n 192: '`',\n 219: '[',\n 220: '\\\\',\n 221: ']',\n 222: \"'\",\n 111: '/',\n 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 (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 ret.KEY_MODS[0] = \"\";\n ret.KEY_MODS[-1] = \"input-\";\n return ret;\n }();\n oop.mixin(exports, Keys);\n exports.keyCodeToString = function (keyCode) {\n var keyString = Keys[keyCode];\n if (typeof keyString != \"string\") keyString = String.fromCharCode(keyCode);\n return keyString.toLowerCase();\n };\n});\nace.define(\"ace/lib/useragent\", [\"require\", \"exports\", \"module\"], function (acequire, exports, module) {\n \"use strict\";\n\n exports.OS = {\n LINUX: \"LINUX\",\n MAC: \"MAC\",\n WINDOWS: \"WINDOWS\"\n };\n exports.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 };\n if (typeof navigator != \"object\") return;\n var os = (navigator.platform.match(/mac|win|linux/i) || [\"other\"])[0].toLowerCase();\n var ua = navigator.userAgent;\n exports.isWin = os == \"win\";\n exports.isMac = os == \"mac\";\n exports.isLinux = os == \"linux\";\n exports.isIE = navigator.appName == \"Microsoft Internet Explorer\" || navigator.appName.indexOf(\"MSAppHost\") >= 0 ? parseFloat((ua.match(/(?:MSIE |Trident\\/[0-9]+[\\.0-9]+;.*rv:)([0-9]+[\\.0-9]+)/) || [])[1]) : parseFloat((ua.match(/(?:Trident\\/[0-9]+[\\.0-9]+;.*rv:)([0-9]+[\\.0-9]+)/) || [])[1]); // for ie\n\n exports.isOldIE = exports.isIE && exports.isIE < 9;\n exports.isGecko = exports.isMozilla = (window.Controllers || window.controllers) && window.navigator.product === \"Gecko\";\n exports.isOldGecko = exports.isGecko && parseInt((ua.match(/rv:(\\d+)/) || [])[1], 10) < 4;\n exports.isOpera = window.opera && Object.prototype.toString.call(window.opera) == \"[object Opera]\";\n exports.isWebKit = parseFloat(ua.split(\"WebKit/\")[1]) || undefined;\n exports.isChrome = parseFloat(ua.split(\" Chrome/\")[1]) || undefined;\n exports.isAIR = ua.indexOf(\"AdobeAIR\") >= 0;\n exports.isIPad = ua.indexOf(\"iPad\") >= 0;\n exports.isChromeOS = ua.indexOf(\" CrOS \") >= 0;\n exports.isIOS = /iPad|iPhone|iPod/.test(ua) && !window.MSStream;\n if (exports.isIOS) exports.isMac = true;\n});\nace.define(\"ace/lib/event\", [\"require\", \"exports\", \"module\", \"ace/lib/keys\", \"ace/lib/useragent\"], function (acequire, exports, module) {\n \"use strict\";\n\n var keys = acequire(\"./keys\");\n var useragent = acequire(\"./useragent\");\n var pressedKeys = null;\n var ts = 0;\n exports.addListener = function (elem, type, callback) {\n if (elem.addEventListener) {\n return elem.addEventListener(type, callback, false);\n }\n if (elem.attachEvent) {\n var wrapper = function () {\n callback.call(elem, window.event);\n };\n callback._wrapper = wrapper;\n elem.attachEvent(\"on\" + type, wrapper);\n }\n };\n exports.removeListener = function (elem, type, callback) {\n if (elem.removeEventListener) {\n return elem.removeEventListener(type, callback, false);\n }\n if (elem.detachEvent) {\n elem.detachEvent(\"on\" + type, callback._wrapper || callback);\n }\n };\n exports.stopEvent = function (e) {\n exports.stopPropagation(e);\n exports.preventDefault(e);\n return false;\n };\n exports.stopPropagation = function (e) {\n if (e.stopPropagation) e.stopPropagation();else e.cancelBubble = true;\n };\n exports.preventDefault = function (e) {\n if (e.preventDefault) e.preventDefault();else e.returnValue = false;\n };\n exports.getButton = function (e) {\n if (e.type == \"dblclick\") return 0;\n if (e.type == \"contextmenu\" || useragent.isMac && e.ctrlKey && !e.altKey && !e.shiftKey) return 2;\n if (e.preventDefault) {\n return e.button;\n } else {\n return {\n 1: 0,\n 2: 2,\n 4: 1\n }[e.button];\n }\n };\n exports.capture = function (el, eventHandler, releaseCaptureHandler) {\n function onMouseUp(e) {\n eventHandler && eventHandler(e);\n releaseCaptureHandler && releaseCaptureHandler(e);\n exports.removeListener(document, \"mousemove\", eventHandler, true);\n exports.removeListener(document, \"mouseup\", onMouseUp, true);\n exports.removeListener(document, \"dragstart\", onMouseUp, true);\n }\n exports.addListener(document, \"mousemove\", eventHandler, true);\n exports.addListener(document, \"mouseup\", onMouseUp, true);\n exports.addListener(document, \"dragstart\", onMouseUp, true);\n return onMouseUp;\n };\n exports.addTouchMoveListener = function (el, callback) {\n var startx, starty;\n exports.addListener(el, \"touchstart\", function (e) {\n var touches = e.touches;\n var touchObj = touches[0];\n startx = touchObj.clientX;\n starty = touchObj.clientY;\n });\n exports.addListener(el, \"touchmove\", function (e) {\n var touches = e.touches;\n if (touches.length > 1) return;\n var touchObj = touches[0];\n e.wheelX = startx - touchObj.clientX;\n e.wheelY = starty - touchObj.clientY;\n startx = touchObj.clientX;\n starty = touchObj.clientY;\n callback(e);\n });\n };\n exports.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 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 exports.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 function onMousedown(e) {\n if (exports.getButton(e) !== 0) {\n clicks = 0;\n } else if (e.detail > 1) {\n clicks++;\n if (clicks > 4) 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) clicks = 1;\n if (timer) clearTimeout(timer);\n timer = setTimeout(function () {\n timer = null;\n }, timeouts[clicks - 1] || 600);\n if (clicks == 1) {\n startX = e.clientX;\n startY = e.clientY;\n }\n }\n e._clicks = clicks;\n eventHandler[callbackName](\"mousedown\", e);\n if (clicks > 4) clicks = 0;else if (clicks > 1) return eventHandler[callbackName](eventNames[clicks], e);\n }\n function onDblclick(e) {\n clicks = 2;\n if (timer) clearTimeout(timer);\n timer = setTimeout(function () {\n timer = null;\n }, timeouts[clicks - 1] || 600);\n eventHandler[callbackName](\"mousedown\", e);\n eventHandler[callbackName](eventNames[clicks], e);\n }\n if (!Array.isArray(elements)) elements = [elements];\n elements.forEach(function (el) {\n exports.addListener(el, \"mousedown\", onMousedown);\n if (useragent.isOldIE) exports.addListener(el, \"dblclick\", onDblclick);\n });\n };\n var getModifierHash = useragent.isMac && useragent.isOpera && !(\"KeyboardEvent\" in window) ? function (e) {\n return 0 | (e.metaKey ? 1 : 0) | (e.altKey ? 2 : 0) | (e.shiftKey ? 4 : 0) | (e.ctrlKey ? 8 : 0);\n } : function (e) {\n return 0 | (e.ctrlKey ? 1 : 0) | (e.altKey ? 2 : 0) | (e.shiftKey ? 4 : 0) | (e.metaKey ? 8 : 0);\n };\n exports.getModifierString = function (e) {\n return keys.KEY_MODS[getModifierHash(e)];\n };\n function normalizeCommandKeys(callback, e, keyCode) {\n var hashId = getModifierHash(e);\n if (!useragent.isMac && pressedKeys) {\n if (e.getModifierState && (e.getModifierState(\"OS\") || e.getModifierState(\"Win\"))) hashId |= 8;\n if (pressedKeys.altGr) {\n if ((3 & hashId) != 3) pressedKeys.altGr = 0;else 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) ts = e.timeStamp;\n } else if (keyCode === 18 && hashId === 3 && location === 2) {\n var dt = e.timeStamp - ts;\n if (dt < 50) pressedKeys.altGr = true;\n }\n }\n }\n if (keyCode in keys.MODIFIER_KEYS) {\n keyCode = -1;\n }\n if (hashId & 8 && keyCode >= 91 && keyCode <= 93) {\n keyCode = -1;\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) return;\n }\n }\n if (useragent.isChromeOS && hashId & 8) {\n callback(e, hashId, keyCode);\n if (e.defaultPrevented) return;else hashId &= ~8;\n }\n if (!hashId && !(keyCode in keys.FUNCTION_KEYS) && !(keyCode in keys.PRINTABLE_KEYS)) {\n return false;\n }\n return callback(e, hashId, keyCode);\n }\n exports.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 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 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 addListener(el, \"keyup\", function (e) {\n pressedKeys[e.keyCode] = null;\n });\n if (!pressedKeys) {\n resetPressedKeys();\n addListener(window, \"focus\", resetPressedKeys);\n }\n }\n };\n function resetPressedKeys() {\n pressedKeys = Object.create(null);\n }\n if (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 exports.addListener(win, \"message\", function listener(e) {\n if (e.data == messageName) {\n exports.stopPropagation(e);\n exports.removeListener(win, \"message\", listener);\n callback();\n }\n });\n win.postMessage(messageName, \"*\");\n };\n }\n exports.nextFrame = typeof window == \"object\" && (window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame || window.oRequestAnimationFrame);\n if (exports.nextFrame) exports.nextFrame = exports.nextFrame.bind(window);else exports.nextFrame = function (callback) {\n setTimeout(callback, 17);\n };\n});\nace.define(\"ace/lib/lang\", [\"require\", \"exports\", \"module\"], function (acequire, exports, module) {\n \"use strict\";\n\n exports.last = function (a) {\n return a[a.length - 1];\n };\n exports.stringReverse = function (string) {\n return string.split(\"\").reverse().join(\"\");\n };\n exports.stringRepeat = function (string, count) {\n var result = '';\n while (count > 0) {\n if (count & 1) result += string;\n if (count >>= 1) string += string;\n }\n return result;\n };\n var trimBeginRegexp = /^\\s\\s*/;\n var trimEndRegexp = /\\s\\s*$/;\n exports.stringTrimLeft = function (string) {\n return string.replace(trimBeginRegexp, '');\n };\n exports.stringTrimRight = function (string) {\n return string.replace(trimEndRegexp, '');\n };\n exports.copyObject = function (obj) {\n var copy = {};\n for (var key in obj) {\n copy[key] = obj[key];\n }\n return copy;\n };\n exports.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\") copy[i] = this.copyObject(array[i]);else copy[i] = array[i];\n }\n return copy;\n };\n exports.deepCopy = function deepCopy(obj) {\n if (typeof obj !== \"object\" || !obj) 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]\") return obj;\n copy = {};\n for (var key in obj) copy[key] = deepCopy(obj[key]);\n return copy;\n };\n exports.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 exports.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 };\n exports.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 exports.escapeRegExp = function (str) {\n return str.replace(/([.*+?^${}()|[\\]\\/\\\\])/g, '\\\\$1');\n };\n exports.escapeHTML = function (str) {\n return str.replace(/&/g, \"&\").replace(/\"/g, \""\").replace(/'/g, \"'\").replace(/ PLACEHOLDER.length) data = data.substr(9);else if (data.substr(0, 4) == PLACEHOLDER.substr(0, 4)) data = data.substr(4, data.length - PLACEHOLDER.length + 1);else if (data.charAt(data.length - 1) == PLACEHOLDER.charAt(0)) data = data.slice(0, -1);\n if (data == PLACEHOLDER.charAt(0)) {} else if (data.charAt(data.length - 1) == PLACEHOLDER.charAt(0)) data = data.slice(0, -1);\n if (data) host.onTextInput(data);\n }\n if (copied) {\n copied = false;\n }\n if (afterContextMenu) afterContextMenu = false;\n };\n var onInput = function (e) {\n if (inComposition) return;\n var data = text.value;\n sendText(data);\n resetValue();\n };\n var handleClipboardData = function (e, data, forceIEMime) {\n var clipboardData = e.clipboardData || window.clipboardData;\n if (!clipboardData || BROKEN_SETDATA) 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) return handleClipboardData(e, data, true);\n }\n };\n var doCopy = function (e, isCut) {\n var data = host.getCopyText();\n if (!data) return event.preventDefault(e);\n if (handleClipboardData(e, data)) {\n if (useragent.isIOS) {\n cut = isCut;\n text.value = \"\\n aa\" + data + \"a a\\n\";\n text.setSelectionRange(4, 4 + data.length);\n copied = {\n value: data\n };\n }\n isCut ? host.onCut() : host.onCopy();\n if (!useragent.isIOS) event.preventDefault(e);\n } else {\n copied = true;\n text.value = data;\n text.select();\n setTimeout(function () {\n copied = false;\n resetValue();\n resetSelection();\n isCut ? host.onCut() : host.onCopy();\n });\n }\n };\n var onCut = function (e) {\n doCopy(e, true);\n };\n var onCopy = function (e) {\n doCopy(e, false);\n };\n var onPaste = function (e) {\n var data = handleClipboardData(e);\n if (typeof data == \"string\") {\n if (data) host.onPaste(data, e);\n if (useragent.isIE) setTimeout(resetSelection);\n event.preventDefault(e);\n } else {\n text.value = \"\";\n pasted = true;\n }\n };\n event.addCommandKeyListener(text, host.onCommandKey.bind(host));\n event.addListener(text, \"select\", onSelect);\n event.addListener(text, \"input\", onInput);\n event.addListener(text, \"cut\", onCut);\n event.addListener(text, \"copy\", onCopy);\n event.addListener(text, \"paste\", onPaste);\n var onCompositionStart = function (e) {\n if (inComposition || !host.onCompositionStart || host.$readOnly) return;\n inComposition = {};\n inComposition.canUndo = host.session.$undoManager;\n host.onCompositionStart();\n setTimeout(onCompositionUpdate, 0);\n host.on(\"mousedown\", onCompositionEnd);\n if (inComposition.canUndo && !host.selection.isEmpty()) {\n host.insert(\"\");\n host.session.markUndoGroup();\n host.selection.clearSelection();\n }\n host.session.markUndoGroup();\n };\n var onCompositionUpdate = function () {\n if (!inComposition || !host.onCompositionUpdate || host.$readOnly) return;\n var val = text.value.replace(/\\x01/g, \"\");\n if (inComposition.lastValue === val) return;\n host.onCompositionUpdate(val);\n if (inComposition.lastValue) host.undo();\n if (inComposition.canUndo) inComposition.lastValue = val;\n if (inComposition.lastValue) {\n var r = host.selection.getRange();\n host.insert(inComposition.lastValue);\n host.session.markUndoGroup();\n inComposition.range = host.selection.getRange();\n host.selection.setRange(r);\n host.selection.clearSelection();\n }\n };\n var onCompositionEnd = function (e) {\n if (!host.onCompositionEnd || host.$readOnly) return;\n var c = inComposition;\n inComposition = false;\n var timer = setTimeout(function () {\n timer = null;\n var str = text.value.replace(/\\x01/g, \"\");\n if (inComposition) return;else if (str == c.lastValue) resetValue();else if (!c.lastValue && str) {\n resetValue();\n sendText(str);\n }\n });\n inputHandler = function compositionInputHandler(str) {\n if (timer) clearTimeout(timer);\n str = str.replace(/\\x01/g, \"\");\n if (str == c.lastValue) return \"\";\n if (c.lastValue && timer) host.undo();\n return str;\n };\n host.onCompositionEnd();\n host.removeListener(\"mousedown\", onCompositionEnd);\n if (e.type == \"compositionend\" && c.range) {\n host.selection.setRange(c.range);\n }\n var needsOnInput = !!useragent.isChrome && useragent.isChrome >= 53 || !!useragent.isWebKit && useragent.isWebKit >= 603;\n if (needsOnInput) {\n onInput();\n }\n };\n var syncComposition = lang.delayedCall(onCompositionUpdate, 50);\n event.addListener(text, \"compositionstart\", onCompositionStart);\n if (useragent.isGecko) {\n event.addListener(text, \"text\", function () {\n syncComposition.schedule();\n });\n } else {\n event.addListener(text, \"keyup\", function () {\n syncComposition.schedule();\n });\n event.addListener(text, \"keydown\", function () {\n syncComposition.schedule();\n });\n }\n event.addListener(text, \"compositionend\", onCompositionEnd);\n this.getElement = function () {\n return text;\n };\n this.setReadOnly = function (readOnly) {\n text.readOnly = readOnly;\n };\n this.onContextMenu = function (e) {\n afterContextMenu = true;\n resetSelection(host.selection.isEmpty());\n host._emit(\"nativecontextmenu\", {\n target: host,\n domEvent: e\n });\n this.moveToMouse(e, true);\n };\n this.moveToMouse = function (e, bringToFront) {\n if (!tempStyle) tempStyle = text.style.cssText;\n text.style.cssText = (bringToFront ? \"z-index:100000;\" : \"\") + \"height:\" + text.style.height + \";\" + (useragent.isIE ? \"opacity:0.1;\" : \"\");\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 text.style.left = e.clientX - left - 2 + \"px\";\n text.style.top = Math.min(e.clientY - top - 2, maxTop) + \"px\";\n };\n move(e);\n if (e.type != \"mousedown\") return;\n if (host.renderer.$keepTextAreaAtCursor) host.renderer.$keepTextAreaAtCursor = null;\n clearTimeout(closeTimeout);\n if (useragent.isWin) event.capture(host.container, move, onContextMenuClose);\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 if (host.renderer.$keepTextAreaAtCursor == null) {\n host.renderer.$keepTextAreaAtCursor = true;\n host.renderer.$moveTextAreaToCursor();\n }\n }, 0);\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 if (useragent.isIOS) {\n var typingResetTimeout = null;\n var typing = false;\n parentNode.addEventListener(\"keydown\", function (e) {\n if (typingResetTimeout) clearTimeout(typingResetTimeout);\n typing = true;\n });\n parentNode.addEventListener(\"keyup\", function (e) {\n typingResetTimeout = setTimeout(function () {\n typing = false;\n }, 100);\n });\n var detectArrowKeys = function (e) {\n if (document.activeElement !== text) return;\n if (typing) return;\n if (cut) {\n return setTimeout(function () {\n cut = false;\n }, 100);\n }\n var selectionStart = text.selectionStart;\n var selectionEnd = text.selectionEnd;\n text.setSelectionRange(4, 5);\n if (selectionStart == selectionEnd) {\n switch (selectionStart) {\n case 0:\n host.onCommandKey(null, 0, KEYS.up);\n break;\n case 1:\n host.onCommandKey(null, 0, KEYS.home);\n break;\n case 2:\n host.onCommandKey(null, MODS.option, KEYS.left);\n break;\n case 4:\n host.onCommandKey(null, 0, KEYS.left);\n break;\n case 5:\n host.onCommandKey(null, 0, KEYS.right);\n break;\n case 7:\n host.onCommandKey(null, MODS.option, KEYS.right);\n break;\n case 8:\n host.onCommandKey(null, 0, KEYS.end);\n break;\n case 9:\n host.onCommandKey(null, 0, KEYS.down);\n break;\n }\n } else {\n switch (selectionEnd) {\n case 6:\n host.onCommandKey(null, MODS.shift, KEYS.right);\n break;\n case 7:\n host.onCommandKey(null, MODS.shift | MODS.option, KEYS.right);\n break;\n case 8:\n host.onCommandKey(null, MODS.shift, KEYS.end);\n break;\n case 9:\n host.onCommandKey(null, MODS.shift, KEYS.down);\n break;\n }\n switch (selectionStart) {\n case 0:\n host.onCommandKey(null, MODS.shift, KEYS.up);\n break;\n case 1:\n host.onCommandKey(null, MODS.shift, KEYS.home);\n break;\n case 2:\n host.onCommandKey(null, MODS.shift | MODS.option, KEYS.left);\n break;\n case 3:\n host.onCommandKey(null, MODS.shift, KEYS.left);\n break;\n }\n }\n };\n document.addEventListener(\"selectionchange\", detectArrowKeys);\n host.on(\"destroy\", function () {\n document.removeEventListener(\"selectionchange\", detectArrowKeys);\n });\n }\n };\n exports.TextInput = TextInput;\n});\nace.define(\"ace/keyboard/textinput\", [\"require\", \"exports\", \"module\", \"ace/lib/event\", \"ace/lib/useragent\", \"ace/lib/dom\", \"ace/lib/lang\", \"ace/keyboard/textinput_ios\"], function (acequire, exports, module) {\n \"use strict\";\n\n var event = acequire(\"../lib/event\");\n var useragent = acequire(\"../lib/useragent\");\n var dom = acequire(\"../lib/dom\");\n var lang = acequire(\"../lib/lang\");\n var BROKEN_SETDATA = useragent.isChrome < 18;\n var USE_IE_MIME_TYPE = useragent.isIE;\n var TextInputIOS = acequire(\"./textinput_ios\").TextInput;\n var TextInput = function (parentNode, host) {\n if (useragent.isIOS) return TextInputIOS.call(this, parentNode, host);\n var text = dom.createElement(\"textarea\");\n text.className = \"ace_text-input\";\n text.setAttribute(\"wrap\", \"off\");\n text.setAttribute(\"autocorrect\", \"off\");\n text.setAttribute(\"autocapitalize\", \"off\");\n text.setAttribute(\"spellcheck\", false);\n text.style.opacity = \"0\";\n parentNode.insertBefore(text, parentNode.firstChild);\n var PLACEHOLDER = \"\\u2028\\u2028\";\n var copied = false;\n var pasted = false;\n var inComposition = false;\n var tempStyle = '';\n var isSelectionEmpty = true;\n try {\n var isFocused = document.activeElement === text;\n } catch (e) {}\n event.addListener(text, \"blur\", function (e) {\n host.onBlur(e);\n isFocused = false;\n });\n event.addListener(text, \"focus\", function (e) {\n isFocused = true;\n host.onFocus(e);\n resetSelection();\n });\n this.focus = function () {\n if (tempStyle) return text.focus();\n var top = text.style.top;\n text.style.position = \"fixed\";\n text.style.top = \"0px\";\n text.focus();\n setTimeout(function () {\n text.style.position = \"\";\n if (text.style.top == \"0px\") text.style.top = top;\n }, 0);\n };\n this.blur = function () {\n text.blur();\n };\n this.isFocused = function () {\n return isFocused;\n };\n var syncSelection = lang.delayedCall(function () {\n isFocused && resetSelection(isSelectionEmpty);\n });\n var syncValue = lang.delayedCall(function () {\n if (!inComposition) {\n text.value = PLACEHOLDER;\n isFocused && resetSelection();\n }\n });\n function resetSelection(isEmpty) {\n if (inComposition) return;\n inComposition = true;\n if (inputHandler) {\n var selectionStart = 0;\n var selectionEnd = isEmpty ? 0 : text.value.length - 1;\n } else {\n var selectionStart = isEmpty ? 2 : 1;\n var selectionEnd = 2;\n }\n try {\n text.setSelectionRange(selectionStart, selectionEnd);\n } catch (e) {}\n inComposition = false;\n }\n function resetValue() {\n if (inComposition) return;\n text.value = PLACEHOLDER;\n if (useragent.isWebKit) syncValue.schedule();\n }\n useragent.isWebKit || host.addEventListener('changeSelection', function () {\n if (host.selection.isEmpty() != isSelectionEmpty) {\n isSelectionEmpty = !isSelectionEmpty;\n syncSelection.schedule();\n }\n });\n resetValue();\n if (isFocused) host.onFocus();\n var isAllSelected = function (text) {\n return text.selectionStart === 0 && text.selectionEnd === text.value.length;\n };\n var onSelect = function (e) {\n if (copied) {\n copied = false;\n } else if (isAllSelected(text)) {\n host.selectAll();\n resetSelection();\n } else if (inputHandler) {\n resetSelection(host.selection.isEmpty());\n }\n };\n var inputHandler = null;\n this.setInputHandler = function (cb) {\n inputHandler = cb;\n };\n this.getInputHandler = function () {\n return inputHandler;\n };\n var afterContextMenu = false;\n var sendText = function (data) {\n if (inputHandler) {\n data = inputHandler(data);\n inputHandler = null;\n }\n if (pasted) {\n resetSelection();\n if (data) host.onPaste(data);\n pasted = false;\n } else if (data == PLACEHOLDER.charAt(0)) {\n if (afterContextMenu) host.execCommand(\"del\", {\n source: \"ace\"\n });else\n // some versions of android do not fire keydown when pressing backspace\n host.execCommand(\"backspace\", {\n source: \"ace\"\n });\n } else {\n if (data.substring(0, 2) == PLACEHOLDER) data = data.substr(2);else if (data.charAt(0) == PLACEHOLDER.charAt(0)) data = data.substr(1);else if (data.charAt(data.length - 1) == PLACEHOLDER.charAt(0)) data = data.slice(0, -1);\n if (data.charAt(data.length - 1) == PLACEHOLDER.charAt(0)) data = data.slice(0, -1);\n if (data) host.onTextInput(data);\n }\n if (afterContextMenu) afterContextMenu = false;\n };\n var onInput = function (e) {\n if (inComposition) return;\n var data = text.value;\n sendText(data);\n resetValue();\n };\n var handleClipboardData = function (e, data, forceIEMime) {\n var clipboardData = e.clipboardData || window.clipboardData;\n if (!clipboardData || BROKEN_SETDATA) 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) return handleClipboardData(e, data, true);\n }\n };\n var doCopy = function (e, isCut) {\n var data = host.getCopyText();\n if (!data) return event.preventDefault(e);\n if (handleClipboardData(e, data)) {\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 resetValue();\n resetSelection();\n isCut ? host.onCut() : host.onCopy();\n });\n }\n };\n var onCut = function (e) {\n doCopy(e, true);\n };\n var onCopy = function (e) {\n doCopy(e, false);\n };\n var onPaste = function (e) {\n var data = handleClipboardData(e);\n if (typeof data == \"string\") {\n if (data) host.onPaste(data, e);\n if (useragent.isIE) setTimeout(resetSelection);\n event.preventDefault(e);\n } else {\n text.value = \"\";\n pasted = true;\n }\n };\n event.addCommandKeyListener(text, host.onCommandKey.bind(host));\n event.addListener(text, \"select\", onSelect);\n event.addListener(text, \"input\", onInput);\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) return;\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) return;\n inComposition = {};\n inComposition.canUndo = host.session.$undoManager;\n host.onCompositionStart();\n setTimeout(onCompositionUpdate, 0);\n host.on(\"mousedown\", onCompositionEnd);\n if (inComposition.canUndo && !host.selection.isEmpty()) {\n host.insert(\"\");\n host.session.markUndoGroup();\n host.selection.clearSelection();\n }\n host.session.markUndoGroup();\n };\n var onCompositionUpdate = function () {\n if (!inComposition || !host.onCompositionUpdate || host.$readOnly) return;\n var val = text.value.replace(/\\u2028/g, \"\");\n if (inComposition.lastValue === val) return;\n host.onCompositionUpdate(val);\n if (inComposition.lastValue) host.undo();\n if (inComposition.canUndo) inComposition.lastValue = val;\n if (inComposition.lastValue) {\n var r = host.selection.getRange();\n host.insert(inComposition.lastValue);\n host.session.markUndoGroup();\n inComposition.range = host.selection.getRange();\n host.selection.setRange(r);\n host.selection.clearSelection();\n }\n };\n var onCompositionEnd = function (e) {\n if (!host.onCompositionEnd || host.$readOnly) return;\n var c = inComposition;\n inComposition = false;\n var timer = setTimeout(function () {\n timer = null;\n var str = text.value.replace(/\\u2028/g, \"\");\n if (inComposition) return;else if (str == c.lastValue) resetValue();else if (!c.lastValue && str) {\n resetValue();\n sendText(str);\n }\n });\n inputHandler = function compositionInputHandler(str) {\n if (timer) clearTimeout(timer);\n str = str.replace(/\\u2028/g, \"\");\n if (str == c.lastValue) return \"\";\n if (c.lastValue && timer) host.undo();\n return str;\n };\n host.onCompositionEnd();\n host.removeListener(\"mousedown\", onCompositionEnd);\n if (e.type == \"compositionend\" && c.range) {\n host.selection.setRange(c.range);\n }\n var needsOnInput = !!useragent.isChrome && useragent.isChrome >= 53 || !!useragent.isWebKit && useragent.isWebKit >= 603;\n if (needsOnInput) {\n onInput();\n }\n };\n var syncComposition = lang.delayedCall(onCompositionUpdate, 50);\n event.addListener(text, \"compositionstart\", onCompositionStart);\n if (useragent.isGecko) {\n event.addListener(text, \"text\", function () {\n syncComposition.schedule();\n });\n } else {\n event.addListener(text, \"keyup\", function () {\n syncComposition.schedule();\n });\n event.addListener(text, \"keydown\", function () {\n syncComposition.schedule();\n });\n }\n event.addListener(text, \"compositionend\", onCompositionEnd);\n this.getElement = function () {\n return text;\n };\n this.setReadOnly = function (readOnly) {\n text.readOnly = readOnly;\n };\n this.onContextMenu = function (e) {\n afterContextMenu = true;\n resetSelection(host.selection.isEmpty());\n host._emit(\"nativecontextmenu\", {\n target: host,\n domEvent: e\n });\n this.moveToMouse(e, true);\n };\n this.moveToMouse = function (e, bringToFront) {\n if (!tempStyle) tempStyle = text.style.cssText;\n text.style.cssText = (bringToFront ? \"z-index:100000;\" : \"\") + \"height:\" + text.style.height + \";\" + (useragent.isIE ? \"opacity:0.1;\" : \"\");\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 text.style.left = e.clientX - left - 2 + \"px\";\n text.style.top = Math.min(e.clientY - top - 2, maxTop) + \"px\";\n };\n move(e);\n if (e.type != \"mousedown\") return;\n if (host.renderer.$keepTextAreaAtCursor) host.renderer.$keepTextAreaAtCursor = null;\n clearTimeout(closeTimeout);\n if (useragent.isWin) event.capture(host.container, move, onContextMenuClose);\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 if (host.renderer.$keepTextAreaAtCursor == null) {\n host.renderer.$keepTextAreaAtCursor = true;\n host.renderer.$moveTextAreaToCursor();\n }\n }, 0);\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 exports.TextInput = TextInput;\n});\nace.define(\"ace/mouse/default_handlers\", [\"require\", \"exports\", \"module\", \"ace/lib/dom\", \"ace/lib/event\", \"ace/lib/useragent\"], function (acequire, exports, module) {\n \"use strict\";\n\n var dom = acequire(\"../lib/dom\");\n var event = acequire(\"../lib/event\");\n var useragent = acequire(\"../lib/useragent\");\n var DRAG_OFFSET = 0; // pixels\n var SCROLL_COOLDOWN_T = 250; // milliseconds\n\n function DefaultHandlers(mouseHandler) {\n mouseHandler.$clickSelection = null;\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 editor.setDefaultHandler(\"touchmove\", this.onTouchMove.bind(mouseHandler));\n var exports = [\"select\", \"startSelect\", \"selectEnd\", \"selectAllEnd\", \"selectByWordsEnd\", \"selectByLinesEnd\", \"dragWait\", \"dragWaitEnd\", \"focusWait\"];\n exports.forEach(function (x) {\n mouseHandler[x] = this[x];\n }, this);\n mouseHandler.selectByLines = this.extendSelectionBy.bind(mouseHandler, \"getLineRange\");\n mouseHandler.selectByWords = this.extendSelectionBy.bind(mouseHandler, \"getWordRange\");\n }\n (function () {\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 var button = ev.getButton();\n if (button !== 0) {\n var selectionRange = editor.getSelectionRange();\n var selectionEmpty = selectionRange.isEmpty();\n editor.$blockScrolling++;\n if (selectionEmpty || button == 1) editor.selection.moveToPosition(pos);\n editor.$blockScrolling--;\n if (button == 2) {\n editor.textInput.onContextMenu(ev.domEvent);\n if (!useragent.isMozilla) ev.preventDefault();\n }\n return;\n }\n this.mousedownEvent.time = Date.now();\n if (inSelection && !editor.isFocused()) {\n editor.focus();\n if (this.$focusTimout && !this.$clickSelection && !editor.inMultiSelectMode) {\n this.setState(\"focusWait\");\n this.captureMouse(ev);\n return;\n }\n }\n this.captureMouse(ev);\n this.startSelect(pos, ev.domEvent._clicks > 1);\n return ev.preventDefault();\n };\n this.startSelect = function (pos, waitForClickSelection) {\n pos = pos || this.editor.renderer.screenToTextCoordinates(this.x, this.y);\n var editor = this.editor;\n editor.$blockScrolling++;\n if (this.mousedownEvent.getShiftKey()) editor.selection.selectToPosition(pos);else if (!waitForClickSelection) editor.selection.moveToPosition(pos);\n if (!waitForClickSelection) this.select();\n if (editor.renderer.scroller.setCapture) {\n editor.renderer.scroller.setCapture();\n }\n editor.setStyle(\"ace_selecting\");\n this.setState(\"select\");\n editor.$blockScrolling--;\n };\n this.select = function () {\n var anchor,\n editor = this.editor;\n var cursor = editor.renderer.screenToTextCoordinates(this.x, this.y);\n editor.$blockScrolling++;\n if (this.$clickSelection) {\n var cmp = this.$clickSelection.comparePoint(cursor);\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.$blockScrolling--;\n editor.renderer.scrollCursorIntoView();\n };\n this.extendSelectionBy = function (unitName) {\n var anchor,\n editor = this.editor;\n var cursor = editor.renderer.screenToTextCoordinates(this.x, this.y);\n var range = editor.selection[unitName](cursor.row, cursor.column);\n editor.$blockScrolling++;\n if (this.$clickSelection) {\n var cmpStart = this.$clickSelection.comparePoint(range.start);\n var cmpEnd = this.$clickSelection.comparePoint(range.end);\n if (cmpStart == -1 && cmpEnd <= 0) {\n anchor = this.$clickSelection.end;\n if (range.end.row != cursor.row || range.end.column != cursor.column) 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) 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.$blockScrolling--;\n editor.renderer.scrollCursorIntoView();\n };\n this.selectEnd = this.selectAllEnd = this.selectByWordsEnd = 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 this.focusWait = function () {\n var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y);\n var time = Date.now();\n if (distance > DRAG_OFFSET || time - this.mousedownEvent.time > this.$focusTimout) this.startSelect(this.mousedownEvent.getDocumentPosition());\n };\n this.onDoubleClick = function (ev) {\n var pos = ev.getDocumentPosition();\n var editor = this.editor;\n var session = editor.session;\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 this.onTripleClick = function (ev) {\n var pos = ev.getDocumentPosition();\n var editor = this.editor;\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 this.onQuadClick = function (ev) {\n var editor = this.editor;\n editor.selectAll();\n this.$clickSelection = editor.getSelectionRange();\n this.setState(\"selectAll\");\n };\n this.onMouseWheel = function (ev) {\n if (ev.getAccelKey()) return;\n if (ev.getShiftKey() && ev.wheelY && !ev.wheelX) {\n ev.wheelX = ev.wheelY;\n ev.wheelY = 0;\n }\n var editor = this.editor;\n if (!this.$lastScroll) this.$lastScroll = {\n t: 0,\n vx: 0,\n vy: 0,\n allowed: 0\n };\n var prevScroll = this.$lastScroll;\n var t = ev.domEvent.timeStamp;\n var dt = t - prevScroll.t;\n var vx = ev.wheelX / dt;\n var vy = ev.wheelY / dt;\n if (dt < SCROLL_COOLDOWN_T) {\n vx = (vx + prevScroll.vx) / 2;\n vy = (vy + prevScroll.vy) / 2;\n }\n var direction = Math.abs(vx / vy);\n var canScroll = false;\n if (direction >= 1 && editor.renderer.isScrollableBy(ev.wheelX * ev.speed, 0)) canScroll = true;\n if (direction <= 1 && editor.renderer.isScrollableBy(0, ev.wheelY * ev.speed)) canScroll = true;\n if (canScroll) {\n prevScroll.allowed = t;\n } else if (t - prevScroll.allowed < SCROLL_COOLDOWN_T) {\n var isSlower = Math.abs(vx) <= 1.1 * Math.abs(prevScroll.vx) && Math.abs(vy) <= 1.1 * Math.abs(prevScroll.vy);\n if (isSlower) {\n canScroll = true;\n prevScroll.allowed = t;\n } else {\n prevScroll.allowed = 0;\n }\n }\n prevScroll.t = t;\n prevScroll.vx = vx;\n prevScroll.vy = vy;\n if (canScroll) {\n editor.renderer.scrollBy(ev.wheelX * ev.speed, ev.wheelY * ev.speed);\n return ev.stop();\n }\n };\n this.onTouchMove = function (ev) {\n this.editor._emit(\"mousewheel\", ev);\n };\n }).call(DefaultHandlers.prototype);\n exports.DefaultHandlers = DefaultHandlers;\n function calcDistance(ax, ay, bx, by) {\n return Math.sqrt(Math.pow(bx - ax, 2) + Math.pow(by - ay, 2));\n }\n function calcRangeOrientation(range, cursor) {\n if (range.start.row == range.end.row) var cmp = 2 * cursor.column - range.start.column - range.end.column;else if (range.start.row == range.end.row - 1 && !range.start.column && !range.end.column) var cmp = cursor.column - 4;else var cmp = 2 * cursor.row - range.start.row - range.end.row;\n if (cmp < 0) return {\n cursor: range.start,\n anchor: range.end\n };else return {\n cursor: range.end,\n anchor: range.start\n };\n }\n});\nace.define(\"ace/tooltip\", [\"require\", \"exports\", \"module\", \"ace/lib/oop\", \"ace/lib/dom\"], function (acequire, exports, module) {\n \"use strict\";\n\n var oop = acequire(\"./lib/oop\");\n var dom = acequire(\"./lib/dom\");\n function Tooltip(parentNode) {\n this.isOpen = false;\n this.$element = null;\n this.$parentNode = parentNode;\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 dom.setInnerText(this.getElement(), 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) this.setText(text);\n if (x != null && y != null) this.setPosition(x, y);\n if (!this.isOpen) {\n this.getElement().style.display = \"block\";\n this.isOpen = true;\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 this.destroy = function () {\n this.isOpen = false;\n if (this.$element && this.$element.parentNode) {\n this.$element.parentNode.removeChild(this.$element);\n }\n };\n }).call(Tooltip.prototype);\n exports.Tooltip = Tooltip;\n});\nace.define(\"ace/mouse/default_gutter_handler\", [\"require\", \"exports\", \"module\", \"ace/lib/dom\", \"ace/lib/oop\", \"ace/lib/event\", \"ace/tooltip\"], function (acequire, exports, module) {\n \"use strict\";\n\n var dom = acequire(\"../lib/dom\");\n var oop = acequire(\"../lib/oop\");\n var event = acequire(\"../lib/event\");\n var Tooltip = acequire(\"../tooltip\").Tooltip;\n function GutterHandler(mouseHandler) {\n var editor = mouseHandler.editor;\n var gutter = editor.renderer.$gutterLayer;\n var tooltip = new GutterTooltip(editor.container);\n mouseHandler.editor.setDefaultHandler(\"guttermousedown\", function (e) {\n if (!editor.isFocused() || e.getButton() != 0) return;\n var gutterRegion = gutter.getRegion(e);\n if (gutterRegion == \"foldWidgets\") return;\n var row = e.getDocumentPosition().row;\n var selection = editor.session.selection;\n if (e.getShiftKey()) selection.selectTo(row, 0);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 var tooltipTimeout, mouseEvent, tooltipAnnotation;\n function showTooltip() {\n var row = mouseEvent.getDocumentPosition().row;\n var annotation = gutter.$annotations[row];\n if (!annotation) return hideTooltip();\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)) return hideTooltip();\n }\n if (tooltipAnnotation == annotation) return;\n tooltipAnnotation = annotation.text.join(\"
\");\n tooltip.setHtml(tooltipAnnotation);\n tooltip.show();\n editor._signal(\"showGutterTooltip\", tooltip);\n editor.on(\"mousewheel\", hideTooltip);\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 function hideTooltip() {\n if (tooltipTimeout) 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 function moveTooltip(e) {\n tooltip.setPosition(e.x, e.y);\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\")) return hideTooltip();\n if (tooltipAnnotation && mouseHandler.$tooltipFollowsMouse) moveTooltip(e);\n mouseEvent = e;\n if (tooltipTimeout) return;\n tooltipTimeout = setTimeout(function () {\n tooltipTimeout = null;\n if (mouseEvent && !mouseHandler.isMousePressed) showTooltip();else hideTooltip();\n }, 50);\n });\n event.addListener(editor.renderer.$gutter, \"mouseout\", function (e) {\n mouseEvent = null;\n if (!tooltipAnnotation || tooltipTimeout) return;\n tooltipTimeout = setTimeout(function () {\n tooltipTimeout = null;\n hideTooltip();\n }, 50);\n });\n editor.on(\"changeSession\", hideTooltip);\n }\n function GutterTooltip(parentNode) {\n Tooltip.call(this, parentNode);\n }\n oop.inherits(GutterTooltip, Tooltip);\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 }).call(GutterTooltip.prototype);\n exports.GutterHandler = GutterHandler;\n});\nace.define(\"ace/mouse/mouse_event\", [\"require\", \"exports\", \"module\", \"ace/lib/event\", \"ace/lib/useragent\"], function (acequire, exports, module) {\n \"use strict\";\n\n var event = acequire(\"../lib/event\");\n var useragent = acequire(\"../lib/useragent\");\n var MouseEvent = exports.MouseEvent = function (domEvent, editor) {\n this.domEvent = domEvent;\n this.editor = editor;\n this.x = this.clientX = domEvent.clientX;\n this.y = this.clientY = domEvent.clientY;\n this.$pos = null;\n this.$inSelection = null;\n this.propagationStopped = false;\n this.defaultPrevented = false;\n };\n (function () {\n this.stopPropagation = function () {\n event.stopPropagation(this.domEvent);\n this.propagationStopped = true;\n };\n this.preventDefault = function () {\n event.preventDefault(this.domEvent);\n this.defaultPrevented = true;\n };\n this.stop = function () {\n this.stopPropagation();\n this.preventDefault();\n };\n this.getDocumentPosition = function () {\n if (this.$pos) return this.$pos;\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) return this.$inSelection;\n var editor = this.editor;\n var selectionRange = editor.getSelectionRange();\n if (selectionRange.isEmpty()) this.$inSelection = false;else {\n var pos = this.getDocumentPosition();\n this.$inSelection = selectionRange.contains(pos.row, pos.column);\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 this.getAccelKey = useragent.isMac ? function () {\n return this.domEvent.metaKey;\n } : function () {\n return this.domEvent.ctrlKey;\n };\n }).call(MouseEvent.prototype);\n});\nace.define(\"ace/mouse/dragdrop_handler\", [\"require\", \"exports\", \"module\", \"ace/lib/dom\", \"ace/lib/event\", \"ace/lib/useragent\"], function (acequire, exports, module) {\n \"use strict\";\n\n var dom = acequire(\"../lib/dom\");\n var event = acequire(\"../lib/event\");\n var useragent = acequire(\"../lib/useragent\");\n var AUTOSCROLL_DELAY = 200;\n var SCROLL_CURSOR_DELAY = 200;\n var SCROLL_CURSOR_HYSTERESIS = 5;\n function DragdropHandler(mouseHandler) {\n var editor = mouseHandler.editor;\n var blankImage = dom.createElement(\"img\");\n blankImage.src = \"data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\";\n if (useragent.isOpera) blankImage.style.cssText = \"width:1px;height:1px;position:fixed;top:0;left:0;z-index:2147483647;opacity:0;\";\n var exports = [\"dragWait\", \"dragWaitEnd\", \"startDrag\", \"dragReadyEnd\", \"onMouseDrag\"];\n exports.forEach(function (x) {\n mouseHandler[x] = this[x];\n }, this);\n editor.addEventListener(\"mousedown\", this.onMouseDown.bind(mouseHandler));\n var mouseTarget = editor.container;\n var dragSelectionMarker, x, y;\n var timerId, range;\n var dragCursor,\n counter = 0;\n var dragOperation;\n var isInternal;\n var autoScrollStartTime;\n var cursorMovedTime;\n var cursorPointOnCaretMoved;\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 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 isInternal = true;\n this.setState(\"drag\");\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\") editor.session.remove(editor.getSelectionRange());\n editor.renderer.$cursorLayer.setBlinking(true);\n }\n this.editor.unsetStyle(\"ace_dragging\");\n this.editor.renderer.setCursorStyle(\"\");\n };\n this.onDragEnter = function (e) {\n if (editor.getReadOnly() || !canAccept(e.dataTransfer)) return;\n x = e.clientX;\n y = e.clientY;\n if (!dragSelectionMarker) addDragMarker();\n counter++;\n e.dataTransfer.dropEffect = dragOperation = getDropEffect(e);\n return event.preventDefault(e);\n };\n this.onDragOver = function (e) {\n if (editor.getReadOnly() || !canAccept(e.dataTransfer)) return;\n x = e.clientX;\n y = e.clientY;\n if (!dragSelectionMarker) {\n addDragMarker();\n counter++;\n }\n if (onMouseMoveTimer !== null) onMouseMoveTimer = null;\n e.dataTransfer.dropEffect = dragOperation = getDropEffect(e);\n return event.preventDefault(e);\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 this.onDrop = function (e) {\n if (!dragCursor) 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 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 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.$blockScrolling += 1;\n editor.moveCursorToPosition(cursor);\n editor.$blockScrolling -= 1;\n cursorMovedTime = now;\n cursorPointOnCaretMoved = {\n x: x,\n y: y\n };\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 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 = {\n row: cursor.row,\n column: cursor.column\n };\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) autoScrollStartTime = now;else if (now - autoScrollStartTime >= AUTOSCROLL_DELAY) editor.renderer.scrollCursorIntoView(scrollCursor);\n } else {\n autoScrollStartTime = null;\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 function addDragMarker() {\n range = editor.selection.toOrientedRange();\n dragSelectionMarker = editor.session.addMarker(range, \"ace_selection\", editor.getSelectionStyle());\n editor.clearSelection();\n if (editor.isFocused()) 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 function clearDragMarker() {\n clearInterval(timerId);\n editor.session.removeMarker(dragSelectionMarker);\n dragSelectionMarker = null;\n editor.$blockScrolling += 1;\n editor.selection.fromOrientedRange(range);\n editor.$blockScrolling -= 1;\n if (editor.isFocused() && !isInternal) editor.renderer.$cursorLayer.setBlinking(!editor.getReadOnly());\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) clearDragMarker();\n }, 20);\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 function getDropEffect(e) {\n var copyAllowed = ['copy', 'copymove', 'all', 'uninitialized'];\n var moveAllowed = ['move', 'copymove', 'linkmove', 'all', 'uninitialized'];\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 if (copyModifierState && copyAllowed.indexOf(effectAllowed) >= 0) dropEffect = \"copy\";else if (moveAllowed.indexOf(effectAllowed) >= 0) dropEffect = \"move\";else if (copyAllowed.indexOf(effectAllowed) >= 0) dropEffect = \"copy\";\n return dropEffect;\n }\n }\n (function () {\n this.dragWait = function () {\n var interval = Date.now() - this.mousedownEvent.time;\n if (interval > this.editor.getDragDelay()) this.startDrag();\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 this.dragReadyEnd = function (e) {\n this.editor.renderer.$cursorLayer.setBlinking(!this.editor.getReadOnly());\n this.editor.unsetStyle(\"ace_dragging\");\n this.editor.renderer.setCursorStyle(\"\");\n this.dragWaitEnd();\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 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) 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 this.onMouseDown = function (e) {\n if (!this.$dragEnabled) return;\n this.mousedownEvent = e;\n var editor = this.editor;\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())) return;\n this.mousedownEvent.time = Date.now();\n var eventTarget = e.domEvent.target || e.domEvent.srcElement;\n if (\"unselectable\" in eventTarget) 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 }).call(DragdropHandler.prototype);\n function calcDistance(ax, ay, bx, by) {\n return Math.sqrt(Math.pow(bx - ax, 2) + Math.pow(by - ay, 2));\n }\n exports.DragdropHandler = DragdropHandler;\n});\nace.define(\"ace/lib/net\", [\"require\", \"exports\", \"module\", \"ace/lib/dom\"], function (acequire, exports, module) {\n \"use strict\";\n\n var dom = acequire(\"./dom\");\n exports.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 exports.loadScript = function (path, callback) {\n var head = dom.getDocumentHead();\n var s = document.createElement('script');\n s.src = path;\n head.appendChild(s);\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) callback();\n }\n };\n };\n exports.qualifyURL = function (url) {\n var a = document.createElement('a');\n a.href = url;\n return a.href;\n };\n});\nace.define(\"ace/lib/event_emitter\", [\"require\", \"exports\", \"module\"], function (acequire, exports, module) {\n \"use strict\";\n\n var EventEmitter = {};\n var stopPropagation = function () {\n this.propagationStopped = true;\n };\n var preventDefault = function () {\n this.defaultPrevented = true;\n };\n EventEmitter._emit = EventEmitter._dispatchEvent = function (eventName, e) {\n this._eventRegistry || (this._eventRegistry = {});\n this._defaultHandlers || (this._defaultHandlers = {});\n var listeners = this._eventRegistry[eventName] || [];\n var defaultHandler = this._defaultHandlers[eventName];\n if (!listeners.length && !defaultHandler) return;\n if (typeof e != \"object\" || !e) e = {};\n if (!e.type) e.type = eventName;\n if (!e.stopPropagation) e.stopPropagation = stopPropagation;\n if (!e.preventDefault) e.preventDefault = preventDefault;\n listeners = listeners.slice();\n for (var i = 0; i < listeners.length; i++) {\n listeners[i](e, this);\n if (e.propagationStopped) break;\n }\n if (defaultHandler && !e.defaultPrevented) return defaultHandler(e, this);\n };\n EventEmitter._signal = function (eventName, e) {\n var listeners = (this._eventRegistry || {})[eventName];\n if (!listeners) return;\n listeners = listeners.slice();\n for (var i = 0; i < listeners.length; i++) listeners[i](e, this);\n };\n EventEmitter.once = function (eventName, callback) {\n var _self = this;\n callback && this.addEventListener(eventName, function newCallback() {\n _self.removeEventListener(eventName, newCallback);\n callback.apply(null, arguments);\n });\n };\n EventEmitter.setDefaultHandler = function (eventName, callback) {\n var handlers = this._defaultHandlers;\n if (!handlers) handlers = this._defaultHandlers = {\n _disabled_: {}\n };\n if (handlers[eventName]) {\n var old = handlers[eventName];\n var disabled = handlers._disabled_[eventName];\n if (!disabled) handlers._disabled_[eventName] = disabled = [];\n disabled.push(old);\n var i = disabled.indexOf(callback);\n if (i != -1) disabled.splice(i, 1);\n }\n handlers[eventName] = callback;\n };\n EventEmitter.removeDefaultHandler = function (eventName, callback) {\n var handlers = this._defaultHandlers;\n if (!handlers) return;\n var disabled = handlers._disabled_[eventName];\n if (handlers[eventName] == callback) {\n var old = handlers[eventName];\n if (disabled) this.setDefaultHandler(eventName, disabled.pop());\n } else if (disabled) {\n var i = disabled.indexOf(callback);\n if (i != -1) disabled.splice(i, 1);\n }\n };\n EventEmitter.on = EventEmitter.addEventListener = function (eventName, callback, capturing) {\n this._eventRegistry = this._eventRegistry || {};\n var listeners = this._eventRegistry[eventName];\n if (!listeners) listeners = this._eventRegistry[eventName] = [];\n if (listeners.indexOf(callback) == -1) listeners[capturing ? \"unshift\" : \"push\"](callback);\n return callback;\n };\n EventEmitter.off = EventEmitter.removeListener = EventEmitter.removeEventListener = function (eventName, callback) {\n this._eventRegistry = this._eventRegistry || {};\n var listeners = this._eventRegistry[eventName];\n if (!listeners) return;\n var index = listeners.indexOf(callback);\n if (index !== -1) listeners.splice(index, 1);\n };\n EventEmitter.removeAllListeners = function (eventName) {\n if (this._eventRegistry) this._eventRegistry[eventName] = [];\n };\n exports.EventEmitter = EventEmitter;\n});\nace.define(\"ace/lib/app_config\", [\"require\", \"exports\", \"module\", \"ace/lib/oop\", \"ace/lib/event_emitter\"], function (acequire, exports, module) {\n \"no use strict\";\n\n var oop = acequire(\"./oop\");\n var EventEmitter = acequire(\"./event_emitter\").EventEmitter;\n var 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 optionNames = Object.keys(this.$options);\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) return;\n var opt = this.$options[name];\n if (!opt) {\n return warn('misspelled option \"' + name + '\"');\n }\n if (opt.forwardTo) return this[opt.forwardTo] && this[opt.forwardTo].setOption(name, value);\n if (!opt.handlesSet) this[\"$\" + name] = value;\n if (opt && opt.set) 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) return this[opt.forwardTo] && this[opt.forwardTo].getOption(name);\n return opt && opt.get ? opt.get.call(this) : this[\"$\" + name];\n }\n };\n function warn(message) {\n if (typeof console != \"undefined\" && console.warn) console.warn.apply(console, arguments);\n }\n function reportError(msg, data) {\n var e = new Error(msg);\n e.data = data;\n if (typeof console == \"object\" && console.error) console.error(e);\n setTimeout(function () {\n throw e;\n });\n }\n var AppConfig = function () {\n this.$defaultOptions = {};\n };\n (function () {\n oop.implement(this, EventEmitter);\n this.defineOptions = function (obj, path, options) {\n if (!obj.$options) this.$defaultOptions[path] = obj.$options = {};\n Object.keys(options).forEach(function (key) {\n var opt = options[key];\n if (typeof opt == \"string\") opt = {\n forwardTo: opt\n };\n opt.name || (opt.name = key);\n obj.$options[opt.name] = opt;\n if (\"initialValue\" in opt) obj[\"$\" + opt.name] = opt.initialValue;\n });\n oop.implement(obj, optionsProvider);\n return this;\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) obj.setOption(key, opt.value);\n });\n };\n this.setDefaultValue = function (path, name, value) {\n var opts = this.$defaultOptions[path] || (this.$defaultOptions[path] = {});\n if (opts[name]) {\n if (opts.forwardTo) this.setDefaultValue(opts.forwardTo, name, value);else opts[name].value = value;\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 this.warn = warn;\n this.reportError = reportError;\n }).call(AppConfig.prototype);\n exports.AppConfig = AppConfig;\n});\nace.define(\"ace/config\", [\"require\", \"exports\", \"module\", \"ace/lib/lang\", \"ace/lib/oop\", \"ace/lib/net\", \"ace/lib/app_config\"], function (acequire, exports, module) {\n \"no use strict\";\n\n var lang = acequire(\"./lib/lang\");\n var oop = acequire(\"./lib/oop\");\n var net = acequire(\"./lib/net\");\n var AppConfig = acequire(\"./lib/app_config\").AppConfig;\n module.exports = exports = new AppConfig();\n var global = function () {\n return this || typeof window != \"undefined\" && window;\n }();\n var options = {\n packaged: false,\n workerPath: null,\n modePath: null,\n themePath: null,\n basePath: \"\",\n suffix: \".js\",\n $moduleUrls: {}\n };\n exports.get = function (key) {\n if (!options.hasOwnProperty(key)) throw new Error(\"Unknown config key: \" + key);\n return options[key];\n };\n exports.set = function (key, value) {\n if (!options.hasOwnProperty(key)) throw new Error(\"Unknown config key: \" + key);\n options[key] = value;\n };\n exports.all = function () {\n return lang.copyObject(options);\n };\n exports.moduleUrl = function (name, component) {\n if (options.$moduleUrls[name]) return options.$moduleUrls[name];\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 if ((!base || base == component) && parts.length > 1) 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) != \"/\") path += \"/\";\n return path + component + sep + base + this.get(\"suffix\");\n };\n exports.setModuleUrl = function (name, subst) {\n return options.$moduleUrls[name] = subst;\n };\n exports.$loading = {};\n exports.loadModule = function (moduleName, onLoad) {\n var module, moduleType;\n if (Array.isArray(moduleName)) {\n moduleType = moduleName[0];\n moduleName = moduleName[1];\n }\n try {\n module = acequire(moduleName);\n } catch (e) {}\n if (module && !exports.$loading[moduleName]) return onLoad && onLoad(module);\n if (!exports.$loading[moduleName]) exports.$loading[moduleName] = [];\n exports.$loading[moduleName].push(onLoad);\n if (exports.$loading[moduleName].length > 1) return;\n var afterLoad = function () {\n acequire([moduleName], function (module) {\n exports._emit(\"load.module\", {\n name: moduleName,\n module: module\n });\n var listeners = exports.$loading[moduleName];\n exports.$loading[moduleName] = null;\n listeners.forEach(function (onLoad) {\n onLoad && onLoad(module);\n });\n });\n };\n if (!exports.get(\"packaged\")) return afterLoad();\n net.loadScript(exports.moduleUrl(moduleName, moduleType), afterLoad);\n };\n init(true);\n function init(packaged) {\n if (!global || !global.document) return;\n options.packaged = packaged || acequire.packaged || module.packaged || global.define && define.packaged;\n var scriptOptions = {};\n var scriptUrl = \"\";\n var currentScript = document.currentScript || document._currentScript; // native or polyfill\n var currentDocument = currentScript && currentScript.ownerDocument || document;\n var scripts = currentDocument.getElementsByTagName(\"script\");\n for (var i = 0; i < scripts.length; i++) {\n var script = scripts[i];\n var src = script.src || script.getAttribute(\"src\");\n if (!src) continue;\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 var m = src.match(/^(.*)\\/ace(\\-\\w+)?\\.js(\\?|$)/);\n if (m) scriptUrl = m[1];\n }\n if (scriptUrl) {\n scriptOptions.base = scriptOptions.base || scriptUrl;\n scriptOptions.packaged = true;\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 for (var key in scriptOptions) if (typeof scriptOptions[key] !== \"undefined\") exports.set(key, scriptOptions[key]);\n }\n exports.init = init;\n function deHyphenate(str) {\n return str.replace(/-(.)/g, function (m, m1) {\n return m1.toUpperCase();\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/config\"], function (acequire, exports, module) {\n \"use strict\";\n\n var event = acequire(\"../lib/event\");\n var useragent = acequire(\"../lib/useragent\");\n var DefaultHandlers = acequire(\"./default_handlers\").DefaultHandlers;\n var DefaultGutterHandler = acequire(\"./default_gutter_handler\").GutterHandler;\n var MouseEvent = acequire(\"./mouse_event\").MouseEvent;\n var DragdropHandler = acequire(\"./dragdrop_handler\").DragdropHandler;\n var config = acequire(\"../config\");\n var MouseHandler = function (editor) {\n var _self = this;\n this.editor = editor;\n new DefaultHandlers(this);\n new DefaultGutterHandler(this);\n new DragdropHandler(this);\n var focusEditor = function (e) {\n var windowBlurred = !document.hasFocus || !document.hasFocus() || !editor.isFocused() && document.activeElement == (editor.textInput && editor.textInput.getElement());\n if (windowBlurred) window.focus();\n editor.focus();\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([mouseTarget, editor.renderer.scrollBarV && editor.renderer.scrollBarV.inner, editor.renderer.scrollBarH && editor.renderer.scrollBarH.inner, editor.textInput && editor.textInput.getElement()].filter(Boolean), [400, 300, 250], this, \"onMouseEvent\");\n event.addMouseWheelListener(editor.container, this.onMouseWheel.bind(this, \"mousewheel\"));\n event.addTouchMoveListener(editor.container, this.onTouchMove.bind(this, \"touchmove\"));\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 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 editor.on(\"mousemove\", function (e) {\n if (_self.state || _self.$dragDelay || !_self.$dragEnabled) return;\n var character = editor.renderer.screenToTextCoordinates(e.x, e.y);\n var range = editor.session.selection.getRange();\n var renderer = editor.renderer;\n if (!range.isEmpty() && range.insideStart(character.row, character.column)) {\n renderer.setCursorStyle(\"default\");\n } else {\n renderer.setCursorStyle(\"\");\n }\n });\n };\n (function () {\n this.onMouseEvent = function (name, e) {\n this.editor._emit(name, new MouseEvent(e, this.editor));\n };\n this.onMouseMove = function (name, e) {\n var listeners = this.editor._eventRegistry && this.editor._eventRegistry.mousemove;\n if (!listeners || !listeners.length) return;\n this.editor._emit(name, new MouseEvent(e, this.editor));\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 this.editor._emit(name, mouseEvent);\n };\n this.onTouchMove = function (name, e) {\n var mouseEvent = new MouseEvent(e, this.editor);\n mouseEvent.speed = 1; //this.$scrollSpeed * 2;\n mouseEvent.wheelX = e.wheelX;\n mouseEvent.wheelY = e.wheelY;\n this.editor._emit(name, mouseEvent);\n };\n this.setState = function (state) {\n this.state = state;\n };\n this.captureMouse = function (ev, mouseMoveHandler) {\n this.x = ev.x;\n this.y = ev.y;\n this.isMousePressed = true;\n var renderer = this.editor.renderer;\n if (renderer.$keepTextAreaAtCursor) renderer.$keepTextAreaAtCursor = null;\n var self = this;\n var onMouseMove = function (e) {\n if (!e) return;\n if (useragent.isWebKit && !e.which && self.releaseMouse) return self.releaseMouse();\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 var onCaptureEnd = function (e) {\n clearInterval(timerId);\n onCaptureInterval();\n self[self.state + \"End\"] && self[self.state + \"End\"](e);\n self.state = \"\";\n if (renderer.$keepTextAreaAtCursor == null) {\n renderer.$keepTextAreaAtCursor = true;\n renderer.$moveTextAreaToCursor();\n }\n self.isMousePressed = false;\n self.$onCaptureMouseMove = self.releaseMouse = null;\n e && self.onMouseEvent(\"mouseup\", e);\n };\n var onCaptureInterval = function () {\n self[self.state] && self[self.state]();\n self.$mouseMoved = false;\n };\n if (useragent.isOldIE && ev.domEvent.type == \"dblclick\") {\n return setTimeout(function () {\n onCaptureEnd(ev);\n });\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\") return;\n this.editor.off(\"nativecontextmenu\", stop);\n if (e && e.domEvent) event.stopEvent(e.domEvent);\n }.bind(this);\n setTimeout(stop, 10);\n this.editor.on(\"nativecontextmenu\", stop);\n };\n }).call(MouseHandler.prototype);\n config.defineOptions(MouseHandler.prototype, \"mouseHandler\", {\n scrollSpeed: {\n initialValue: 2\n },\n dragDelay: {\n initialValue: useragent.isMac ? 150 : 0\n },\n dragEnabled: {\n initialValue: true\n },\n focusTimout: {\n initialValue: 0\n },\n tooltipFollowsMouse: {\n initialValue: true\n }\n });\n exports.MouseHandler = MouseHandler;\n});\nace.define(\"ace/mouse/fold_handler\", [\"require\", \"exports\", \"module\"], function (acequire, exports, module) {\n \"use strict\";\n\n function FoldHandler(editor) {\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()) session.removeFold(fold);else session.expandFold(fold);\n e.stop();\n }\n });\n editor.on(\"gutterclick\", function (e) {\n var gutterRegion = editor.renderer.$gutterLayer.getRegion(e);\n if (gutterRegion == \"foldWidgets\") {\n var row = e.getDocumentPosition().row;\n var session = editor.session;\n if (session.foldWidgets && session.foldWidgets[row]) editor.session.onFoldWidgetClick(row, e);\n if (!editor.isFocused()) editor.focus();\n e.stop();\n }\n });\n editor.on(\"gutterdblclick\", function (e) {\n var gutterRegion = editor.renderer.$gutterLayer.getRegion(e);\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 if (range) {\n row = range.start.row;\n var fold = session.getFoldAt(row, session.getLine(row).length, 1);\n if (fold) {\n session.removeFold(fold);\n } else {\n session.addFold(\"...\", range);\n editor.renderer.scrollCursorIntoView({\n row: range.start.row,\n column: 0\n });\n }\n }\n e.stop();\n }\n });\n }\n exports.FoldHandler = FoldHandler;\n});\nace.define(\"ace/keyboard/keybinding\", [\"require\", \"exports\", \"module\", \"ace/lib/keys\", \"ace/lib/event\"], function (acequire, exports, module) {\n \"use strict\";\n\n var keyUtil = acequire(\"../lib/keys\");\n var event = acequire(\"../lib/event\");\n var KeyBinding = function (editor) {\n this.$editor = editor;\n this.$data = {\n editor: editor\n };\n this.$handlers = [];\n this.setDefaultHandler(editor.commands);\n };\n (function () {\n this.setDefaultHandler = function (kb) {\n this.removeKeyboardHandler(this.$defaultHandler);\n this.$defaultHandler = kb;\n this.addKeyboardHandler(kb, 0);\n };\n this.setKeyboardHandler = function (kb) {\n var h = this.$handlers;\n if (h[h.length - 1] == kb) return;\n while (h[h.length - 1] && h[h.length - 1] != this.$defaultHandler) this.removeKeyboardHandler(h[h.length - 1]);\n this.addKeyboardHandler(kb, 1);\n };\n this.addKeyboardHandler = function (kb, pos) {\n if (!kb) return;\n if (typeof kb == \"function\" && !kb.handleKeyboard) kb.handleKeyboard = kb;\n var i = this.$handlers.indexOf(kb);\n if (i != -1) this.$handlers.splice(i, 1);\n if (pos == undefined) this.$handlers.push(kb);else this.$handlers.splice(pos, 0, kb);\n if (i == -1 && kb.attach) kb.attach(this.$editor);\n };\n this.removeKeyboardHandler = function (kb) {\n var i = this.$handlers.indexOf(kb);\n if (i == -1) return false;\n this.$handlers.splice(i, 1);\n kb.detach && kb.detach(this.$editor);\n return true;\n };\n this.getKeyboardHandler = function () {\n return this.$handlers[this.$handlers.length - 1];\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 this.$callKeyboardHandlers = function (hashId, keyString, keyCode, e) {\n var toExecute;\n var success = false;\n var commands = this.$editor.commands;\n for (var i = this.$handlers.length; i--;) {\n toExecute = this.$handlers[i].handleKeyboard(this.$data, hashId, keyString, keyCode, e);\n if (!toExecute || !toExecute.command) 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 && toExecute.passEvent != true && toExecute.command.passEvent != true) {\n event.stopEvent(e);\n }\n if (success) break;\n }\n if (!success && hashId == -1) {\n toExecute = {\n command: \"insertstring\"\n };\n success = commands.exec(\"insertstring\", this.$editor, keyString);\n }\n if (success && this.$editor._signal) this.$editor._signal(\"keyboardActivity\", toExecute);\n return success;\n };\n this.onCommandKey = function (e, hashId, keyCode) {\n var keyString = keyUtil.keyCodeToString(keyCode);\n this.$callKeyboardHandlers(hashId, keyString, keyCode, e);\n };\n this.onTextInput = function (text) {\n this.$callKeyboardHandlers(-1, text);\n };\n }).call(KeyBinding.prototype);\n exports.KeyBinding = KeyBinding;\n});\nace.define(\"ace/lib/bidiutil\", [\"require\", \"exports\", \"module\"], function (acequire, exports, module) {\n \"use strict\";\n\n var ArabicAlefBetIntervalsBegine = ['\\u0621', '\\u0641'];\n var ArabicAlefBetIntervalsEnd = ['\\u063A', '\\u064a'];\n var dir = 0,\n hiLevel = 0;\n var lastArabic = false,\n hasUBAT_AL = false,\n hasUBAT_B = false,\n hasUBAT_S = false,\n hasBlockSep = false,\n hasSegSep = false;\n var impTab_LTR = [[0, 3, 0, 1, 0, 0, 0], [0, 3, 0, 1, 2, 2, 0], [0, 3, 0, 0x11, 2, 0, 1], [0, 3, 5, 5, 4, 1, 0], [0, 3, 0x15, 0x15, 4, 0, 1], [0, 3, 5, 5, 4, 2, 0]];\n var impTab_RTL = [[2, 0, 1, 1, 0, 1, 0], [2, 0, 1, 1, 0, 2, 0], [2, 0, 2, 1, 3, 2, 0], [2, 0, 2, 0x21, 3, 1, 1]];\n var LTR = 0,\n RTL = 1;\n var L = 0;\n var R = 1;\n var EN = 2;\n var AN = 3;\n var ON = 4;\n var B = 5;\n var S = 6;\n var AL = 7;\n var WS = 8;\n var CS = 9;\n var ES = 10;\n var ET = 11;\n var NSM = 12;\n var LRE = 13;\n var RLE = 14;\n var PDF = 15;\n var LRO = 16;\n var RLO = 17;\n var BN = 18;\n var UnicodeTBL00 = [BN, BN, BN, BN, BN, BN, BN, BN, BN, S, B, S, WS, B, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, B, B, B, S, WS, ON, ON, ET, ET, ET, ON, ON, ON, ON, ON, ES, CS, ES, CS, CS, EN, EN, EN, EN, EN, EN, EN, EN, EN, EN, CS, ON, ON, ON, ON, ON, ON, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, ON, ON, ON, ON, ON, ON, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, ON, ON, ON, ON, BN, BN, BN, BN, BN, BN, B, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, CS, ON, ET, ET, ET, ET, ON, ON, ON, ON, L, ON, ON, BN, ON, ON, ET, ET, EN, EN, ON, L, ON, ON, ON, EN, L, ON, ON, ON, ON, ON];\n var UnicodeTBL20 = [WS, WS, WS, WS, WS, WS, WS, WS, WS, WS, WS, BN, BN, BN, L, R, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, WS, B, LRE, RLE, PDF, LRO, RLO, CS, ET, ET, ET, ET, ET, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, CS, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, WS];\n function _computeLevels(chars, levels, len, charTypes) {\n var impTab = dir ? impTab_RTL : impTab_LTR,\n prevState = null,\n newClass = null,\n newLevel = null,\n newState = 0,\n action = null,\n cond = null,\n condPos = -1,\n i = null,\n ix = null,\n classes = [];\n if (!charTypes) {\n for (i = 0, charTypes = []; i < len; i++) {\n charTypes[i] = _getCharacterType(chars[i]);\n }\n }\n hiLevel = dir;\n lastArabic = false;\n hasUBAT_AL = false;\n hasUBAT_B = false;\n hasUBAT_S = false;\n for (ix = 0; ix < len; ix++) {\n prevState = newState;\n classes[ix] = newClass = _getCharClass(chars, charTypes, classes, ix);\n newState = impTab[prevState][newClass];\n action = newState & 0xF0;\n newState &= 0x0F;\n levels[ix] = newLevel = impTab[newState][5];\n if (action > 0) {\n if (action == 0x10) {\n for (i = condPos; i < ix; i++) {\n levels[i] = 1;\n }\n condPos = -1;\n } else {\n condPos = -1;\n }\n }\n cond = impTab[newState][6];\n if (cond) {\n if (condPos == -1) {\n condPos = ix;\n }\n } else {\n if (condPos > -1) {\n for (i = condPos; i < ix; i++) {\n levels[i] = newLevel;\n }\n condPos = -1;\n }\n }\n if (charTypes[ix] == B) {\n levels[ix] = 0;\n }\n hiLevel |= newLevel;\n }\n if (hasUBAT_S) {\n for (i = 0; i < len; i++) {\n if (charTypes[i] == S) {\n levels[i] = dir;\n for (var j = i - 1; j >= 0; j--) {\n if (charTypes[j] == WS) {\n levels[j] = dir;\n } else {\n break;\n }\n }\n }\n }\n }\n }\n function _invertLevel(lev, levels, _array) {\n if (hiLevel < lev) {\n return;\n }\n if (lev == 1 && dir == RTL && !hasUBAT_B) {\n _array.reverse();\n return;\n }\n var len = _array.length,\n start = 0,\n end,\n lo,\n hi,\n tmp;\n while (start < len) {\n if (levels[start] >= lev) {\n end = start + 1;\n while (end < len && levels[end] >= lev) {\n end++;\n }\n for (lo = start, hi = end - 1; lo < hi; lo++, hi--) {\n tmp = _array[lo];\n _array[lo] = _array[hi];\n _array[hi] = tmp;\n }\n start = end;\n }\n start++;\n }\n }\n function _getCharClass(chars, types, classes, ix) {\n var cType = types[ix],\n wType,\n nType,\n len,\n i;\n switch (cType) {\n case L:\n case R:\n lastArabic = false;\n case ON:\n case AN:\n return cType;\n case EN:\n return lastArabic ? AN : EN;\n case AL:\n lastArabic = true;\n hasUBAT_AL = true;\n return R;\n case WS:\n return ON;\n case CS:\n if (ix < 1 || ix + 1 >= types.length || (wType = classes[ix - 1]) != EN && wType != AN || (nType = types[ix + 1]) != EN && nType != AN) {\n return ON;\n }\n if (lastArabic) {\n nType = AN;\n }\n return nType == wType ? nType : ON;\n case ES:\n wType = ix > 0 ? classes[ix - 1] : B;\n if (wType == EN && ix + 1 < types.length && types[ix + 1] == EN) {\n return EN;\n }\n return ON;\n case ET:\n if (ix > 0 && classes[ix - 1] == EN) {\n return EN;\n }\n if (lastArabic) {\n return ON;\n }\n i = ix + 1;\n len = types.length;\n while (i < len && types[i] == ET) {\n i++;\n }\n if (i < len && types[i] == EN) {\n return EN;\n }\n return ON;\n case NSM:\n len = types.length;\n i = ix + 1;\n while (i < len && types[i] == NSM) {\n i++;\n }\n if (i < len) {\n var c = chars[ix],\n rtlCandidate = c >= 0x0591 && c <= 0x08FF || c == 0xFB1E;\n wType = types[i];\n if (rtlCandidate && (wType == R || wType == AL)) {\n return R;\n }\n }\n if (ix < 1 || (wType = types[ix - 1]) == B) {\n return ON;\n }\n return classes[ix - 1];\n case B:\n lastArabic = false;\n hasUBAT_B = true;\n return dir;\n case S:\n hasUBAT_S = true;\n return ON;\n case LRE:\n case RLE:\n case LRO:\n case RLO:\n case PDF:\n lastArabic = false;\n case BN:\n return ON;\n }\n }\n function _getCharacterType(ch) {\n var uc = ch.charCodeAt(0),\n hi = uc >> 8;\n if (hi == 0) {\n return uc > 0x00BF ? L : UnicodeTBL00[uc];\n } else if (hi == 5) {\n return /[\\u0591-\\u05f4]/.test(ch) ? R : L;\n } else if (hi == 6) {\n if (/[\\u0610-\\u061a\\u064b-\\u065f\\u06d6-\\u06e4\\u06e7-\\u06ed]/.test(ch)) return NSM;else if (/[\\u0660-\\u0669\\u066b-\\u066c]/.test(ch)) return AN;else if (uc == 0x066A) return ET;else if (/[\\u06f0-\\u06f9]/.test(ch)) return EN;else return AL;\n } else if (hi == 0x20 && uc <= 0x205F) {\n return UnicodeTBL20[uc & 0xFF];\n } else if (hi == 0xFE) {\n return uc >= 0xFE70 ? AL : ON;\n }\n return ON;\n }\n function _isArabicDiacritics(ch) {\n return ch >= '\\u064b' && ch <= '\\u0655';\n }\n exports.L = L;\n exports.R = R;\n exports.EN = EN;\n exports.ON_R = 3;\n exports.AN = 4;\n exports.R_H = 5;\n exports.B = 6;\n exports.DOT = \"\\xB7\";\n exports.doBidiReorder = function (text, textCharTypes, isRtl) {\n if (text.length < 2) return {};\n var chars = text.split(\"\"),\n logicalFromVisual = new Array(chars.length),\n bidiLevels = new Array(chars.length),\n levels = [];\n dir = isRtl ? RTL : LTR;\n _computeLevels(chars, levels, chars.length, textCharTypes);\n for (var i = 0; i < logicalFromVisual.length; logicalFromVisual[i] = i, i++);\n _invertLevel(2, levels, logicalFromVisual);\n _invertLevel(1, levels, logicalFromVisual);\n for (var i = 0; i < logicalFromVisual.length - 1; i++) {\n //fix levels to reflect character width\n if (textCharTypes[i] === AN) {\n levels[i] = exports.AN;\n } else if (levels[i] === R && (textCharTypes[i] > AL && textCharTypes[i] < LRE || textCharTypes[i] === ON || textCharTypes[i] === BN)) {\n levels[i] = exports.ON_R;\n } else if (i > 0 && chars[i - 1] === '\\u0644' && /\\u0622|\\u0623|\\u0625|\\u0627/.test(chars[i])) {\n levels[i - 1] = levels[i] = exports.R_H;\n i++;\n }\n }\n if (chars[chars.length - 1] === exports.DOT) levels[chars.length - 1] = exports.B;\n for (var i = 0; i < logicalFromVisual.length; i++) {\n bidiLevels[i] = levels[logicalFromVisual[i]];\n }\n return {\n 'logicalFromVisual': logicalFromVisual,\n 'bidiLevels': bidiLevels\n };\n };\n exports.hasBidiCharacters = function (text, textCharTypes) {\n var ret = false;\n for (var i = 0; i < text.length; i++) {\n textCharTypes[i] = _getCharacterType(text.charAt(i));\n if (!ret && (textCharTypes[i] == R || textCharTypes[i] == AL)) ret = true;\n }\n return ret;\n };\n exports.getVisualFromLogicalIdx = function (logIdx, rowMap) {\n for (var i = 0; i < rowMap.logicalFromVisual.length; i++) {\n if (rowMap.logicalFromVisual[i] == logIdx) return i;\n }\n return 0;\n };\n});\nace.define(\"ace/bidihandler\", [\"require\", \"exports\", \"module\", \"ace/lib/bidiutil\", \"ace/lib/lang\", \"ace/lib/useragent\"], function (acequire, exports, module) {\n \"use strict\";\n\n var bidiUtil = acequire(\"./lib/bidiutil\");\n var lang = acequire(\"./lib/lang\");\n var useragent = acequire(\"./lib/useragent\");\n var bidiRE = /[\\u0590-\\u05f4\\u0600-\\u06ff\\u0700-\\u08ac]/;\n var 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.line = \"\";\n this.wrapIndent = 0;\n this.isLastRow = false;\n this.EOF = \"\\xB6\";\n this.seenBidi = false;\n };\n (function () {\n this.isBidiRow = function (screenRow, docRow, splitIndex) {\n if (!this.seenBidi) 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 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 } else {\n this.currentRow = null;\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) docRow = this.session.$docRowCache[index];\n }\n return docRow;\n };\n this.getSplitIndex = function () {\n var splitIndex = 0;\n var rowCache = this.session.$screenRowCache;\n if (rowCache.length) {\n var currentIndex,\n 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) break;\n prevIndex = currentIndex;\n splitIndex++;\n }\n }\n return splitIndex;\n };\n this.updateRowLine = function (docRow, splitIndex) {\n if (docRow === undefined) docRow = this.getDocumentRow();\n this.wrapIndent = 0;\n this.isLastRow = docRow === this.session.getLength() - 1;\n this.line = this.session.getLine(docRow);\n if (this.session.$useWrapMode) {\n var splits = this.session.$wrapData[docRow];\n if (splits) {\n if (splitIndex === undefined) splitIndex = this.getSplitIndex();\n if (splitIndex > 0 && splits.length) {\n this.wrapIndent = splits.indent;\n this.line = splitIndex < splits.length ? this.line.substring(splits[splitIndex - 1], splits[splits.length - 1]) : this.line.substring(splits[splits.length - 1]);\n } else {\n this.line = this.line.substring(0, splits[splitIndex]);\n }\n }\n }\n var session = this.session,\n shift = 0,\n 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 this.updateBidiMap = function () {\n var textCharTypes = [],\n endOfLine = this.isLastRow ? this.EOF : this.EOL;\n var line = this.line + (this.showInvisibles ? endOfLine : bidiUtil.DOT);\n if (bidiUtil.hasBidiCharacters(line, textCharTypes)) {\n this.bidiMap = bidiUtil.doBidiReorder(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.seenBidi) return;\n if (this.characterWidth === fontMetrics.$characterSize.width) return;\n var characterWidth = this.characterWidth = fontMetrics.$characterSize.width;\n var bidiCharWidth = fontMetrics.$measureCharWidth(\"\\u05d4\");\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] = useragent.isChrome ? bidiCharWidth : bidiCharWidth * 0.45;\n this.charWidths[bidiUtil.B] = 0;\n this.currentRow = null;\n };\n this.getShowInvisibles = function () {\n return this.showInvisibles;\n };\n this.setShowInvisibles = function (showInvisibles) {\n this.showInvisibles = showInvisibles;\n this.currentRow = null;\n };\n this.setEolChar = function (eolChar) {\n this.EOL = eolChar;\n };\n this.setTextDir = function (isRtlDir) {\n this.isRtlDir = isRtlDir;\n };\n this.getPosLeft = function (col) {\n col -= this.wrapIndent;\n var visualIdx = bidiUtil.getVisualFromLogicalIdx(col > 0 ? col - 1 : 0, this.bidiMap),\n levels = this.bidiMap.bidiLevels,\n left = 0;\n if (col === 0 && levels[visualIdx] % 2 !== 0) visualIdx++;\n for (var i = 0; i < visualIdx; i++) {\n left += this.charWidths[levels[i]];\n }\n if (col !== 0 && levels[visualIdx] % 2 === 0) left += this.charWidths[levels[visualIdx]];\n if (this.wrapIndent) left += this.wrapIndent * this.charWidths[bidiUtil.L];\n return left;\n };\n this.getSelections = function (startCol, endCol) {\n var map = this.bidiMap,\n levels = map.bidiLevels,\n level,\n offset = this.wrapIndent * this.charWidths[bidiUtil.L],\n selections = [],\n selColMin = Math.min(startCol, endCol) - this.wrapIndent,\n selColMax = Math.max(startCol, endCol) - this.wrapIndent,\n isSelected = false,\n isSelectedPrev = false,\n selectionStart = 0;\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({\n left: selectionStart,\n width: offset - selectionStart\n });\n }\n offset += this.charWidths[level];\n isSelectedPrev = isSelected;\n }\n if (isSelected && visIdx === levels.length) {\n selections.push({\n left: selectionStart,\n width: offset - selectionStart\n });\n }\n return selections;\n };\n this.offsetToCol = function (posX) {\n var logicalIdx = 0,\n posX = Math.max(posX, 0),\n offset = 0,\n visualIdx = 0,\n levels = this.bidiMap.bidiLevels,\n charWidth = this.charWidths[levels[visualIdx]];\n if (this.wrapIndent) {\n posX -= this.wrapIndent * this.charWidths[bidiUtil.L];\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 if (visualIdx > 0 && levels[visualIdx - 1] % 2 !== 0 && levels[visualIdx] % 2 === 0) {\n if (posX < offset) visualIdx--;\n logicalIdx = this.bidiMap.logicalFromVisual[visualIdx];\n } else if (visualIdx > 0 && levels[visualIdx - 1] % 2 === 0 && levels[visualIdx] % 2 !== 0) {\n logicalIdx = 1 + (posX > offset ? this.bidiMap.logicalFromVisual[visualIdx] : this.bidiMap.logicalFromVisual[visualIdx - 1]);\n } else if (this.isRtlDir && visualIdx === levels.length - 1 && charWidth === 0 && levels[visualIdx - 1] % 2 === 0 || !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) visualIdx--;\n logicalIdx = this.bidiMap.logicalFromVisual[visualIdx];\n }\n return logicalIdx + this.wrapIndent;\n };\n }).call(BidiHandler.prototype);\n exports.BidiHandler = BidiHandler;\n});\nace.define(\"ace/range\", [\"require\", \"exports\", \"module\"], function (acequire, exports, module) {\n \"use strict\";\n\n var comparePoints = function (p1, p2) {\n return p1.row - p2.row || p1.column - p2.column;\n };\n var Range = function (startRow, startColumn, endRow, endColumn) {\n this.start = {\n row: startRow,\n column: startColumn\n };\n this.end = {\n row: endRow,\n column: endColumn\n };\n };\n (function () {\n this.isEqual = function (range) {\n return this.start.row === range.start.row && this.end.row === range.end.row && this.start.column === range.start.column && this.end.column === range.end.column;\n };\n this.toString = function () {\n return \"Range: [\" + this.start.row + \"/\" + this.start.column + \"] -> [\" + this.end.row + \"/\" + this.end.column + \"]\";\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 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 if (row < this.start.row) return -1;\n if (row > this.end.row) return 1;\n if (this.start.row === row) return column >= this.start.column ? 0 : -1;\n if (this.end.row === row) return column <= this.end.column ? 0 : 1;\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) var end = {\n row: lastRow + 1,\n column: 0\n };else if (this.end.row < firstRow) var end = {\n row: firstRow,\n column: 0\n };\n if (this.start.row > lastRow) var start = {\n row: lastRow + 1,\n column: 0\n };else if (this.start.row < firstRow) var start = {\n row: firstRow,\n 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 if (cmp == 0) return this;else if (cmp == -1) var start = {\n row: row,\n column: column\n };else var end = {\n row: row,\n column: column\n };\n return Range.fromPoints(start || this.start, end || this.end);\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) return new Range(this.start.row, 0, Math.max(this.start.row, this.end.row - 1), 0);else 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 return new Range(screenPosStart.row, screenPosStart.column, screenPosEnd.row, screenPosEnd.column);\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 }).call(Range.prototype);\n Range.fromPoints = function (start, end) {\n return new Range(start.row, start.column, end.row, end.column);\n };\n Range.comparePoints = comparePoints;\n Range.comparePoints = function (p1, p2) {\n return p1.row - p2.row || p1.column - p2.column;\n };\n exports.Range = Range;\n});\nace.define(\"ace/selection\", [\"require\", \"exports\", \"module\", \"ace/lib/oop\", \"ace/lib/lang\", \"ace/lib/event_emitter\", \"ace/range\"], function (acequire, exports, module) {\n \"use strict\";\n\n var oop = acequire(\"./lib/oop\");\n var lang = acequire(\"./lib/lang\");\n var EventEmitter = acequire(\"./lib/event_emitter\").EventEmitter;\n var Range = acequire(\"./range\").Range;\n var Selection = function (session) {\n this.session = session;\n this.doc = session.getDocument();\n this.clearSelection();\n this.lead = this.selectionLead = this.doc.createAnchor(0, 0);\n this.anchor = this.selectionAnchor = this.doc.createAnchor(0, 0);\n var self = this;\n this.lead.on(\"change\", function (e) {\n self._emit(\"changeCursor\");\n if (!self.$isEmpty) self._emit(\"changeSelection\");\n if (!self.$keepDesiredColumnOnChange && e.old.column != e.value.column) self.$desiredColumn = null;\n });\n this.selectionAnchor.on(\"change\", function () {\n if (!self.$isEmpty) self._emit(\"changeSelection\");\n });\n };\n (function () {\n oop.implement(this, EventEmitter);\n this.isEmpty = function () {\n return this.$isEmpty || this.anchor.row == this.lead.row && this.anchor.column == this.lead.column;\n };\n this.isMultiLine = function () {\n if (this.isEmpty()) {\n return false;\n }\n return this.getRange().isMultiLine();\n };\n this.getCursor = function () {\n return this.lead.getPosition();\n };\n this.setSelectionAnchor = function (row, column) {\n this.anchor.setPosition(row, column);\n if (this.$isEmpty) {\n this.$isEmpty = false;\n this._emit(\"changeSelection\");\n }\n };\n this.getSelectionAnchor = function () {\n if (this.$isEmpty) return this.getSelectionLead();else return this.anchor.getPosition();\n };\n this.getSelectionLead = function () {\n return this.lead.getPosition();\n };\n this.shiftSelection = function (columns) {\n if (this.$isEmpty) {\n this.moveCursorTo(this.lead.row, this.lead.column + columns);\n return;\n }\n var anchor = this.getSelectionAnchor();\n var lead = this.getSelectionLead();\n var isBackwards = this.isBackwards();\n if (!isBackwards || anchor.column !== 0) this.setSelectionAnchor(anchor.row, anchor.column + columns);\n if (isBackwards || lead.column !== 0) {\n this.$moveSelection(function () {\n this.moveCursorTo(lead.row, lead.column + columns);\n });\n }\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 if (this.isEmpty()) return Range.fromPoints(lead, lead);\n if (this.isBackwards()) {\n return Range.fromPoints(lead, anchor);\n } else {\n return Range.fromPoints(anchor, lead);\n }\n };\n this.clearSelection = function () {\n if (!this.$isEmpty) {\n this.$isEmpty = true;\n this._emit(\"changeSelection\");\n }\n };\n this.selectAll = function () {\n var lastRow = this.doc.getLength() - 1;\n this.setSelectionAnchor(0, 0);\n this.moveCursorTo(lastRow, this.doc.getLine(lastRow).length);\n };\n this.setRange = this.setSelectionRange = function (range, reverse) {\n if (reverse) {\n this.setSelectionAnchor(range.end.row, range.end.column);\n this.selectTo(range.start.row, range.start.column);\n } else {\n this.setSelectionAnchor(range.start.row, range.start.column);\n this.selectTo(range.end.row, range.end.column);\n }\n if (this.getRange().isEmpty()) this.$isEmpty = true;\n this.$desiredColumn = null;\n };\n this.$moveSelection = function (mover) {\n var lead = this.lead;\n if (this.$isEmpty) this.setSelectionAnchor(lead.row, lead.column);\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 this.getLineRange = function (row, excludeLastChar) {\n var rowStart = typeof row == \"number\" ? row : this.lead.row;\n var rowEnd;\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) return new Range(rowStart, 0, rowEnd, this.session.getLine(rowEnd).length);else 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 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 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 } 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 } 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 } 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(row, null, firstColumnPosition.row, firstColumnPosition.column);\n var leadingSpace = beforeCursor.match(/^\\s*/);\n if (leadingSpace[0].length != column && !this.session.$useEmacsStyleLineStart) 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) lineEnd.column = textEnd;\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 var match;\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 (match = 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) this.moveCursorWordRight();\n return;\n }\n if (match = this.session.tokenRe.exec(rightOfCursor)) {\n column += this.session.tokenRe.lastIndex;\n this.session.tokenRe.lastIndex = 0;\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 var str = this.session.getFoldStringAt(row, column, -1);\n if (str == null) {\n str = this.doc.getLine(row).substring(0, column);\n }\n var leftOfCursor = lang.stringReverse(str);\n var match;\n this.session.nonTokenRe.lastIndex = 0;\n this.session.tokenRe.lastIndex = 0;\n if (match = 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) this.moveCursorWordLeft();\n return;\n }\n if (match = this.session.tokenRe.exec(leftOfCursor)) {\n column -= this.session.tokenRe.lastIndex;\n this.session.tokenRe.lastIndex = 0;\n }\n this.moveCursorTo(row, column);\n };\n this.$shortWordEndIndex = function (rightOfCursor) {\n var match,\n index = 0,\n ch;\n var whitespaceRe = /\\s/;\n var tokenRe = this.session.tokenRe;\n tokenRe.lastIndex = 0;\n if (match = this.session.tokenRe.exec(rightOfCursor)) {\n index = this.session.tokenRe.lastIndex;\n } else {\n while ((ch = rightOfCursor[index]) && whitespaceRe.test(ch)) index++;\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)) index++;\n if (index > 2) break;\n }\n }\n }\n }\n }\n tokenRe.lastIndex = 0;\n return index;\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 var fold = this.session.getFoldAt(row, column, 1);\n if (fold) return this.moveCursorTo(fold.end.row, fold.end.column);\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 if (!/^\\s+/.test(rightOfCursor)) rightOfCursor = \"\";\n column = 0;\n }\n var index = this.$shortWordEndIndex(rightOfCursor);\n this.moveCursorTo(row, column + index);\n };\n this.moveCursorShortWordLeft = 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)) return this.moveCursorTo(fold.start.row, fold.start.column);\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 column = line.length;\n if (!/\\s+$/.test(line)) line = \"\";\n }\n var leftOfCursor = lang.stringReverse(line);\n var index = this.$shortWordEndIndex(leftOfCursor);\n return this.moveCursorTo(row, column - index);\n };\n this.moveCursorWordRight = function () {\n if (this.session.$selectLongWords) this.moveCursorLongWordRight();else this.moveCursorShortWordRight();\n };\n this.moveCursorWordLeft = function () {\n if (this.session.$selectLongWords) this.moveCursorLongWordLeft();else this.moveCursorShortWordLeft();\n };\n this.moveCursorBy = function (rows, chars) {\n var screenPos = this.session.documentToScreenPosition(this.lead.row, this.lead.column);\n var offsetX;\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 if (this.$desiredColumn) screenPos.column = this.$desiredColumn;else this.$desiredColumn = screenPos.column;\n }\n var docPos = this.session.screenToDocumentPosition(screenPos.row + rows, screenPos.column, offsetX);\n if (rows !== 0 && chars === 0 && docPos.row === this.lead.row && docPos.column === this.lead.column) {\n if (this.session.lineWidgets && this.session.lineWidgets[docPos.row]) {\n if (docPos.row > 0 || rows > 0) docPos.row++;\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 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) column = column - 1;else column = column + 1;\n }\n this.lead.setPosition(row, column);\n this.$keepDesiredColumnOnChange = false;\n if (!keepDesiredColumn) 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 this.fromOrientedRange = function (range) {\n this.setSelectionRange(range, range.cursor == range.start);\n this.$desiredColumn = range.desiredColumn || this.$desiredColumn;\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 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 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 this.fromJSON = function (data) {\n if (data.start == undefined) {\n if (this.rangeList) {\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) r.cursor = r.start;\n this.addRange(r, true);\n }\n return;\n } else data = data[0];\n }\n if (this.rangeList) this.toSingleRange(data);\n this.setSelectionRange(data, data.isBackwards);\n };\n this.isEqual = function (data) {\n if ((data.length || this.rangeCount) && data.length != this.rangeCount) return false;\n if (!data.length || !this.ranges) return this.getRange().isEqual(data);\n for (var i = this.ranges.length; i--;) {\n if (!this.ranges[i].isEqual(data[i])) return false;\n }\n return true;\n };\n }).call(Selection.prototype);\n exports.Selection = Selection;\n});\nace.define(\"ace/tokenizer\", [\"require\", \"exports\", \"module\", \"ace/config\"], function (acequire, exports, module) {\n \"use strict\";\n\n var config = acequire(\"./config\");\n var MAX_TOKEN_COUNT = 2000;\n var Tokenizer = function (rules) {\n this.states = rules;\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] = {\n defaultToken: \"text\"\n };\n var flag = \"g\";\n var splitterRurles = [];\n for (var i = 0; i < state.length; i++) {\n var rule = state[i];\n if (rule.defaultToken) mapping.defaultToken = rule.defaultToken;\n if (rule.caseInsensitive) flag = \"gi\";\n if (rule.regex == null) continue;\n if (rule.regex instanceof RegExp) 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) rule.onMatch = this.$applyToken;else rule.onMatch = rule.token;\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\") splitterRurles.push(rule); // flag will be known only at the very end\n }\n mapping[matchTotal] = i;\n matchTotal += matchcount;\n ruleRegExps.push(adjustedregex);\n if (!rule.onMatch) rule.onMatch = null;\n }\n if (!ruleRegExps.length) {\n mapping[0] = 0;\n ruleRegExps.push(\"$\");\n }\n splitterRurles.forEach(function (rule) {\n rule.splitRegex = this.createSplitterRegexp(rule.regex, flag);\n }, this);\n this.regExps[key] = new RegExp(\"(\" + ruleRegExps.join(\")|(\") + \")|($)\", flag);\n }\n };\n (function () {\n this.$setMaxTokenCount = function (m) {\n MAX_TOKEN_COUNT = m | 0;\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\") return [{\n type: types,\n value: str\n }];\n var tokens = [];\n for (var i = 0, l = types.length; i < l; i++) {\n if (values[i]) tokens[tokens.length] = {\n type: types[i],\n value: values[i]\n };\n }\n return tokens;\n };\n this.$arrayTokens = function (str) {\n if (!str) return [];\n var values = this.splitRegex.exec(str);\n if (!values) 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]) tokens[tokens.length] = {\n type: types[i],\n value: values[i + 1]\n };\n }\n return tokens;\n };\n this.removeCapturingGroups = function (src) {\n var r = src.replace(/\\[(?:\\\\.|[^\\]])*?\\]|\\\\.|\\(\\?[:=!]|(\\()/g, function (x, y) {\n return y ? \"(?:\" : x;\n });\n return r;\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 (m, esc, parenOpen, parenClose, square, index) {\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 if (lastCapture.end != null && /^\\)*$/.test(src.substr(lastCapture.end))) 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 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 var stack = [];\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 var match,\n tokens = [];\n var lastIndex = 0;\n var matchAttempts = 0;\n var token = {\n type: null,\n 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 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) tokens.push(token);\n token = {\n type: type,\n value: skipped\n };\n }\n }\n for (var i = 0; i < match.length - 2; i++) {\n if (match[i + 1] === undefined) continue;\n rule = state[mapping[i]];\n if (rule.onMatch) type = rule.onMatch(value, currentState, stack, line);else type = rule.token;\n if (rule.next) {\n if (typeof rule.next == \"string\") {\n currentState = rule.next;\n } else {\n currentState = rule.next(currentState, stack);\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) lastIndex = index;\n break;\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) tokens.push(token);\n token = {\n type: type,\n value: value\n };\n }\n } else if (type) {\n if (token.type) tokens.push(token);\n token = {\n type: null,\n value: \"\"\n };\n for (var i = 0; i < type.length; i++) tokens.push(type[i]);\n }\n }\n if (lastIndex == line.length) break;\n lastIndex = index;\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) tokens.push(token);\n token = {\n value: line.substring(lastIndex, lastIndex += 2000),\n type: \"overflow\"\n };\n }\n currentState = \"start\";\n stack = [];\n break;\n }\n }\n if (token.type) tokens.push(token);\n if (stack.length > 1) {\n if (stack[0] !== currentState) stack.unshift(\"#tmp\", currentState);\n }\n return {\n tokens: tokens,\n state: stack.length ? stack : currentState\n };\n };\n this.reportError = config.reportError;\n }).call(Tokenizer.prototype);\n exports.Tokenizer = Tokenizer;\n});\nace.define(\"ace/mode/text_highlight_rules\", [\"require\", \"exports\", \"module\", \"ace/lib/lang\"], function (acequire, exports, module) {\n \"use strict\";\n\n var lang = acequire(\"../lib/lang\");\n var TextHighlightRules = function () {\n this.$rules = {\n \"start\": [{\n token: \"empty_line\",\n regex: '^$'\n }, {\n defaultToken: \"text\"\n }]\n };\n };\n (function () {\n this.addRules = function (rules, prefix) {\n if (!prefix) {\n for (var key in rules) 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) rule.next = prefix + rule.next;\n }\n if (rule.nextState && rule.nextState.indexOf(prefix) !== 0) rule.nextState = prefix + rule.nextState;\n }\n }\n this.$rules[prefix + key] = state;\n }\n };\n this.getRules = function () {\n return this.$rules;\n };\n this.embedRules = function (HighlightRules, prefix, escapeRules, states, append) {\n var embedRules = typeof HighlightRules == \"function\" ? new HighlightRules().getRules() : HighlightRules;\n if (states) {\n for (var i = 0; i < states.length; i++) states[i] = prefix + states[i];\n } else {\n states = [];\n for (var key in embedRules) states.push(prefix + key);\n }\n this.addRules(embedRules, prefix);\n if (escapeRules) {\n var addRules = Array.prototype[append ? \"push\" : \"unshift\"];\n for (var i = 0; i < states.length; i++) addRules.apply(this.$rules[states[i]], lang.deepCopy(escapeRules));\n }\n if (!this.$embeds) this.$embeds = [];\n this.$embeds.push(prefix);\n };\n this.getEmbeds = function () {\n return this.$embeds;\n };\n var pushState = function (currentState, stack) {\n if (currentState != \"start\" || stack.length) 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 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) 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\") stateName = stateName[0] || \"\";\n if (rules[stateName]) 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 if (rule.push) {\n rule.nextState = rule.next || rule.push;\n rule.next = pushState;\n delete rule.push;\n }\n if (rule.rules) {\n for (var r in rule.rules) {\n if (rules[r]) {\n if (rules[r].push) 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)) toInsert = includeName.map(function (x) {\n return rules[x];\n });else toInsert = rules[includeName];\n }\n if (toInsert) {\n var args = [i, 1].concat(toInsert);\n if (rule.noEscape) args = args.filter(function (x) {\n return !x.next;\n });\n state.splice.apply(state, args);\n i--;\n }\n if (rule.keywordMap) {\n rule.token = this.createKeywordMapper(rule.keywordMap, rule.defaultToken || \"text\", rule.caseInsensitive);\n delete rule.defaultToken;\n }\n }\n }\n Object.keys(rules).forEach(processState, this);\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) a = a.toLowerCase();\n var list = a.split(splitChar || \"|\");\n for (var i = list.length; i--;) 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 ? function (value) {\n return keywords[value.toLowerCase()] || defaultToken;\n } : function (value) {\n return keywords[value] || defaultToken;\n };\n };\n this.getKeywords = function () {\n return this.$keywords;\n };\n }).call(TextHighlightRules.prototype);\n exports.TextHighlightRules = TextHighlightRules;\n});\nace.define(\"ace/mode/behaviour\", [\"require\", \"exports\", \"module\"], function (acequire, exports, module) {\n \"use strict\";\n\n var Behaviour = function () {\n this.$behaviours = {};\n };\n (function () {\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 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 this.remove = function (name) {\n if (this.$behaviours && this.$behaviours[name]) {\n delete this.$behaviours[name];\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 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 }).call(Behaviour.prototype);\n exports.Behaviour = Behaviour;\n});\nace.define(\"ace/token_iterator\", [\"require\", \"exports\", \"module\", \"ace/range\"], function (acequire, exports, module) {\n \"use strict\";\n\n var Range = acequire(\"./range\").Range;\n var TokenIterator = function (session, initialRow, initialColumn) {\n this.$session = session;\n this.$row = initialRow;\n this.$rowTokens = session.getTokens(initialRow);\n var token = session.getTokenAt(initialRow, initialColumn);\n this.$tokenIndex = token ? token.index : -1;\n };\n (function () {\n this.stepBackward = function () {\n this.$tokenIndex -= 1;\n while (this.$tokenIndex < 0) {\n this.$row -= 1;\n if (this.$row < 0) {\n this.$row = 0;\n return null;\n }\n this.$rowTokens = this.$session.getTokens(this.$row);\n this.$tokenIndex = this.$rowTokens.length - 1;\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) rowCount = this.$session.getLength();\n if (this.$row >= rowCount) {\n this.$row = rowCount - 1;\n return null;\n }\n this.$rowTokens = this.$session.getTokens(this.$row);\n this.$tokenIndex = 0;\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) return column;\n column = 0;\n while (tokenIndex > 0) {\n tokenIndex -= 1;\n column += rowTokens[tokenIndex].value.length;\n }\n return column;\n };\n this.getCurrentTokenPosition = function () {\n return {\n row: this.$row,\n column: this.getCurrentTokenColumn()\n };\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 }).call(TokenIterator.prototype);\n exports.TokenIterator = TokenIterator;\n});\nace.define(\"ace/mode/behaviour/cstyle\", [\"require\", \"exports\", \"module\", \"ace/lib/oop\", \"ace/mode/behaviour\", \"ace/token_iterator\", \"ace/lib/lang\"], function (acequire, exports, module) {\n \"use strict\";\n\n var oop = acequire(\"../../lib/oop\");\n var Behaviour = acequire(\"../behaviour\").Behaviour;\n var TokenIterator = acequire(\"../../token_iterator\").TokenIterator;\n var lang = acequire(\"../../lib/lang\");\n var SAFE_INSERT_IN_TOKENS = [\"text\", \"paren.rparen\", \"punctuation.operator\"];\n var SAFE_INSERT_BEFORE_TOKENS = [\"text\", \"paren.rparen\", \"punctuation.operator\", \"comment\"];\n var context;\n var contextCache = {};\n var defaultQuotes = {\n '\"': '\"',\n \"'\": \"'\"\n };\n var initContext = function (editor) {\n var id = -1;\n if (editor.multiSelect) {\n id = editor.selection.index;\n if (contextCache.rangeCount != editor.multiSelect.rangeCount) contextCache = {\n rangeCount: editor.multiSelect.rangeCount\n };\n }\n if (contextCache[id]) 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 var getWrapped = function (selection, selected, opening, closing) {\n var rowDiff = selection.end.row - selection.start.row;\n return {\n text: opening + selected + closing,\n selection: [0, selection.start.column + 1, rowDiff, selection.end.column + (rowDiff ? 0 : 1)]\n };\n };\n var 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('}', {\n column: cursor.column + 1,\n row: cursor.row\n });\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({\n row: cursor.row,\n column: cursor.column + 1\n }, '}');\n if (!openBracePos) 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 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 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 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(')', {\n column: cursor.column + 1,\n row: cursor.row\n });\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 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 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(']', {\n column: cursor.column + 1,\n row: cursor.row\n });\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 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 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) 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 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)) return null;\n var stringBefore = token && /string|escape/.test(token.type);\n var stringAfter = !rightToken || /string|escape/.test(rightToken.type);\n var pair;\n if (rightChar == quote) {\n pair = stringBefore !== stringAfter;\n if (pair && /string\\.end/.test(rightToken.type)) pair = false;\n } else {\n if (stringBefore && !stringAfter) return null; // wrap string with different quote\n if (stringBefore && stringAfter) 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) return null; // before or after alphanumeric\n if (rightChar && !/[\\s;,.})\\]\\\\]/.test(rightChar)) return null; // there is rightChar and it isn't closing\n pair = true;\n }\n return {\n text: pair ? quote + quote : \"\",\n selection: [1, 1]\n };\n }\n }\n });\n this.add(\"string_dquotes\", \"deletion\", function (state, action, editor, session, range) {\n var selected = session.doc.getTextRange(range);\n if (!range.isMultiLine() && (selected == '\"' || 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 CstyleBehaviour.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 var iterator2 = new TokenIterator(session, cursor.row, cursor.column + 1);\n if (!this.$matchTokenType(iterator2.getCurrentToken() || \"text\", SAFE_INSERT_IN_TOKENS)) return false;\n }\n iterator.stepForward();\n return iterator.getCurrentTokenRow() !== cursor.row || this.$matchTokenType(iterator.getCurrentToken() || \"text\", SAFE_INSERT_BEFORE_TOKENS);\n };\n CstyleBehaviour.$matchTokenType = function (token, types) {\n return types.indexOf(token.type || token) > -1;\n };\n CstyleBehaviour.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])) context.autoInsertedBrackets = 0;\n context.autoInsertedRow = cursor.row;\n context.autoInsertedLineEnd = bracket + line.substr(cursor.column);\n context.autoInsertedBrackets++;\n };\n CstyleBehaviour.recordMaybeInsert = function (editor, session, bracket) {\n var cursor = editor.getCursorPosition();\n var line = session.doc.getLine(cursor.row);\n if (!this.isMaybeInsertedClosing(cursor, line)) 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 CstyleBehaviour.isAutoInsertedClosing = function (cursor, line, bracket) {\n return context.autoInsertedBrackets > 0 && cursor.row === context.autoInsertedRow && bracket === context.autoInsertedLineEnd[0] && line.substr(cursor.column) === context.autoInsertedLineEnd;\n };\n CstyleBehaviour.isMaybeInsertedClosing = function (cursor, line) {\n return context.maybeInsertedBrackets > 0 && cursor.row === context.maybeInsertedRow && line.substr(cursor.column) === context.maybeInsertedLineEnd && line.substr(0, cursor.column) == context.maybeInsertedLineStart;\n };\n CstyleBehaviour.popAutoInsertedClosing = function () {\n context.autoInsertedLineEnd = context.autoInsertedLineEnd.substr(1);\n context.autoInsertedBrackets--;\n };\n CstyleBehaviour.clearMaybeInsertedClosing = function () {\n if (context) {\n context.maybeInsertedBrackets = 0;\n context.maybeInsertedRow = -1;\n }\n };\n oop.inherits(CstyleBehaviour, Behaviour);\n exports.CstyleBehaviour = CstyleBehaviour;\n});\nace.define(\"ace/unicode\", [\"require\", \"exports\", \"module\"], function (acequire, exports, module) {\n \"use strict\";\n\n exports.packages = {};\n addUnicodePackage({\n L: \"0041-005A0061-007A00AA00B500BA00C0-00D600D8-00F600F8-02C102C6-02D102E0-02E402EC02EE0370-037403760377037A-037D03860388-038A038C038E-03A103A3-03F503F7-0481048A-05250531-055605590561-058705D0-05EA05F0-05F20621-064A066E066F0671-06D306D506E506E606EE06EF06FA-06FC06FF07100712-072F074D-07A507B107CA-07EA07F407F507FA0800-0815081A082408280904-0939093D09500958-0961097109720979-097F0985-098C098F09900993-09A809AA-09B009B209B6-09B909BD09CE09DC09DD09DF-09E109F009F10A05-0A0A0A0F0A100A13-0A280A2A-0A300A320A330A350A360A380A390A59-0A5C0A5E0A72-0A740A85-0A8D0A8F-0A910A93-0AA80AAA-0AB00AB20AB30AB5-0AB90ABD0AD00AE00AE10B05-0B0C0B0F0B100B13-0B280B2A-0B300B320B330B35-0B390B3D0B5C0B5D0B5F-0B610B710B830B85-0B8A0B8E-0B900B92-0B950B990B9A0B9C0B9E0B9F0BA30BA40BA8-0BAA0BAE-0BB90BD00C05-0C0C0C0E-0C100C12-0C280C2A-0C330C35-0C390C3D0C580C590C600C610C85-0C8C0C8E-0C900C92-0CA80CAA-0CB30CB5-0CB90CBD0CDE0CE00CE10D05-0D0C0D0E-0D100D12-0D280D2A-0D390D3D0D600D610D7A-0D7F0D85-0D960D9A-0DB10DB3-0DBB0DBD0DC0-0DC60E01-0E300E320E330E40-0E460E810E820E840E870E880E8A0E8D0E94-0E970E99-0E9F0EA1-0EA30EA50EA70EAA0EAB0EAD-0EB00EB20EB30EBD0EC0-0EC40EC60EDC0EDD0F000F40-0F470F49-0F6C0F88-0F8B1000-102A103F1050-1055105A-105D106110651066106E-10701075-1081108E10A0-10C510D0-10FA10FC1100-1248124A-124D1250-12561258125A-125D1260-1288128A-128D1290-12B012B2-12B512B8-12BE12C012C2-12C512C8-12D612D8-13101312-13151318-135A1380-138F13A0-13F41401-166C166F-167F1681-169A16A0-16EA1700-170C170E-17111720-17311740-17511760-176C176E-17701780-17B317D717DC1820-18771880-18A818AA18B0-18F51900-191C1950-196D1970-19741980-19AB19C1-19C71A00-1A161A20-1A541AA71B05-1B331B45-1B4B1B83-1BA01BAE1BAF1C00-1C231C4D-1C4F1C5A-1C7D1CE9-1CEC1CEE-1CF11D00-1DBF1E00-1F151F18-1F1D1F20-1F451F48-1F4D1F50-1F571F591F5B1F5D1F5F-1F7D1F80-1FB41FB6-1FBC1FBE1FC2-1FC41FC6-1FCC1FD0-1FD31FD6-1FDB1FE0-1FEC1FF2-1FF41FF6-1FFC2071207F2090-209421022107210A-211321152119-211D212421262128212A-212D212F-2139213C-213F2145-2149214E218321842C00-2C2E2C30-2C5E2C60-2CE42CEB-2CEE2D00-2D252D30-2D652D6F2D80-2D962DA0-2DA62DA8-2DAE2DB0-2DB62DB8-2DBE2DC0-2DC62DC8-2DCE2DD0-2DD62DD8-2DDE2E2F300530063031-3035303B303C3041-3096309D-309F30A1-30FA30FC-30FF3105-312D3131-318E31A0-31B731F0-31FF3400-4DB54E00-9FCBA000-A48CA4D0-A4FDA500-A60CA610-A61FA62AA62BA640-A65FA662-A66EA67F-A697A6A0-A6E5A717-A71FA722-A788A78BA78CA7FB-A801A803-A805A807-A80AA80C-A822A840-A873A882-A8B3A8F2-A8F7A8FBA90A-A925A930-A946A960-A97CA984-A9B2A9CFAA00-AA28AA40-AA42AA44-AA4BAA60-AA76AA7AAA80-AAAFAAB1AAB5AAB6AAB9-AABDAAC0AAC2AADB-AADDABC0-ABE2AC00-D7A3D7B0-D7C6D7CB-D7FBF900-FA2DFA30-FA6DFA70-FAD9FB00-FB06FB13-FB17FB1DFB1F-FB28FB2A-FB36FB38-FB3CFB3EFB40FB41FB43FB44FB46-FBB1FBD3-FD3DFD50-FD8FFD92-FDC7FDF0-FDFBFE70-FE74FE76-FEFCFF21-FF3AFF41-FF5AFF66-FFBEFFC2-FFC7FFCA-FFCFFFD2-FFD7FFDA-FFDC\",\n Ll: \"0061-007A00AA00B500BA00DF-00F600F8-00FF01010103010501070109010B010D010F01110113011501170119011B011D011F01210123012501270129012B012D012F01310133013501370138013A013C013E014001420144014601480149014B014D014F01510153015501570159015B015D015F01610163016501670169016B016D016F0171017301750177017A017C017E-0180018301850188018C018D019201950199-019B019E01A101A301A501A801AA01AB01AD01B001B401B601B901BA01BD-01BF01C601C901CC01CE01D001D201D401D601D801DA01DC01DD01DF01E101E301E501E701E901EB01ED01EF01F001F301F501F901FB01FD01FF02010203020502070209020B020D020F02110213021502170219021B021D021F02210223022502270229022B022D022F02310233-0239023C023F0240024202470249024B024D024F-02930295-02AF037103730377037B-037D039003AC-03CE03D003D103D5-03D703D903DB03DD03DF03E103E303E503E703E903EB03ED03EF-03F303F503F803FB03FC0430-045F04610463046504670469046B046D046F04710473047504770479047B047D047F0481048B048D048F04910493049504970499049B049D049F04A104A304A504A704A904AB04AD04AF04B104B304B504B704B904BB04BD04BF04C204C404C604C804CA04CC04CE04CF04D104D304D504D704D904DB04DD04DF04E104E304E504E704E904EB04ED04EF04F104F304F504F704F904FB04FD04FF05010503050505070509050B050D050F05110513051505170519051B051D051F0521052305250561-05871D00-1D2B1D62-1D771D79-1D9A1E011E031E051E071E091E0B1E0D1E0F1E111E131E151E171E191E1B1E1D1E1F1E211E231E251E271E291E2B1E2D1E2F1E311E331E351E371E391E3B1E3D1E3F1E411E431E451E471E491E4B1E4D1E4F1E511E531E551E571E591E5B1E5D1E5F1E611E631E651E671E691E6B1E6D1E6F1E711E731E751E771E791E7B1E7D1E7F1E811E831E851E871E891E8B1E8D1E8F1E911E931E95-1E9D1E9F1EA11EA31EA51EA71EA91EAB1EAD1EAF1EB11EB31EB51EB71EB91EBB1EBD1EBF1EC11EC31EC51EC71EC91ECB1ECD1ECF1ED11ED31ED51ED71ED91EDB1EDD1EDF1EE11EE31EE51EE71EE91EEB1EED1EEF1EF11EF31EF51EF71EF91EFB1EFD1EFF-1F071F10-1F151F20-1F271F30-1F371F40-1F451F50-1F571F60-1F671F70-1F7D1F80-1F871F90-1F971FA0-1FA71FB0-1FB41FB61FB71FBE1FC2-1FC41FC61FC71FD0-1FD31FD61FD71FE0-1FE71FF2-1FF41FF61FF7210A210E210F2113212F21342139213C213D2146-2149214E21842C30-2C5E2C612C652C662C682C6A2C6C2C712C732C742C76-2C7C2C812C832C852C872C892C8B2C8D2C8F2C912C932C952C972C992C9B2C9D2C9F2CA12CA32CA52CA72CA92CAB2CAD2CAF2CB12CB32CB52CB72CB92CBB2CBD2CBF2CC12CC32CC52CC72CC92CCB2CCD2CCF2CD12CD32CD52CD72CD92CDB2CDD2CDF2CE12CE32CE42CEC2CEE2D00-2D25A641A643A645A647A649A64BA64DA64FA651A653A655A657A659A65BA65DA65FA663A665A667A669A66BA66DA681A683A685A687A689A68BA68DA68FA691A693A695A697A723A725A727A729A72BA72DA72F-A731A733A735A737A739A73BA73DA73FA741A743A745A747A749A74BA74DA74FA751A753A755A757A759A75BA75DA75FA761A763A765A767A769A76BA76DA76FA771-A778A77AA77CA77FA781A783A785A787A78CFB00-FB06FB13-FB17FF41-FF5A\",\n Lu: \"0041-005A00C0-00D600D8-00DE01000102010401060108010A010C010E01100112011401160118011A011C011E01200122012401260128012A012C012E01300132013401360139013B013D013F0141014301450147014A014C014E01500152015401560158015A015C015E01600162016401660168016A016C016E017001720174017601780179017B017D018101820184018601870189-018B018E-0191019301940196-0198019C019D019F01A001A201A401A601A701A901AC01AE01AF01B1-01B301B501B701B801BC01C401C701CA01CD01CF01D101D301D501D701D901DB01DE01E001E201E401E601E801EA01EC01EE01F101F401F6-01F801FA01FC01FE02000202020402060208020A020C020E02100212021402160218021A021C021E02200222022402260228022A022C022E02300232023A023B023D023E02410243-02460248024A024C024E03700372037603860388-038A038C038E038F0391-03A103A3-03AB03CF03D2-03D403D803DA03DC03DE03E003E203E403E603E803EA03EC03EE03F403F703F903FA03FD-042F04600462046404660468046A046C046E04700472047404760478047A047C047E0480048A048C048E04900492049404960498049A049C049E04A004A204A404A604A804AA04AC04AE04B004B204B404B604B804BA04BC04BE04C004C104C304C504C704C904CB04CD04D004D204D404D604D804DA04DC04DE04E004E204E404E604E804EA04EC04EE04F004F204F404F604F804FA04FC04FE05000502050405060508050A050C050E05100512051405160518051A051C051E0520052205240531-055610A0-10C51E001E021E041E061E081E0A1E0C1E0E1E101E121E141E161E181E1A1E1C1E1E1E201E221E241E261E281E2A1E2C1E2E1E301E321E341E361E381E3A1E3C1E3E1E401E421E441E461E481E4A1E4C1E4E1E501E521E541E561E581E5A1E5C1E5E1E601E621E641E661E681E6A1E6C1E6E1E701E721E741E761E781E7A1E7C1E7E1E801E821E841E861E881E8A1E8C1E8E1E901E921E941E9E1EA01EA21EA41EA61EA81EAA1EAC1EAE1EB01EB21EB41EB61EB81EBA1EBC1EBE1EC01EC21EC41EC61EC81ECA1ECC1ECE1ED01ED21ED41ED61ED81EDA1EDC1EDE1EE01EE21EE41EE61EE81EEA1EEC1EEE1EF01EF21EF41EF61EF81EFA1EFC1EFE1F08-1F0F1F18-1F1D1F28-1F2F1F38-1F3F1F48-1F4D1F591F5B1F5D1F5F1F68-1F6F1FB8-1FBB1FC8-1FCB1FD8-1FDB1FE8-1FEC1FF8-1FFB21022107210B-210D2110-211221152119-211D212421262128212A-212D2130-2133213E213F214521832C00-2C2E2C602C62-2C642C672C692C6B2C6D-2C702C722C752C7E-2C802C822C842C862C882C8A2C8C2C8E2C902C922C942C962C982C9A2C9C2C9E2CA02CA22CA42CA62CA82CAA2CAC2CAE2CB02CB22CB42CB62CB82CBA2CBC2CBE2CC02CC22CC42CC62CC82CCA2CCC2CCE2CD02CD22CD42CD62CD82CDA2CDC2CDE2CE02CE22CEB2CEDA640A642A644A646A648A64AA64CA64EA650A652A654A656A658A65AA65CA65EA662A664A666A668A66AA66CA680A682A684A686A688A68AA68CA68EA690A692A694A696A722A724A726A728A72AA72CA72EA732A734A736A738A73AA73CA73EA740A742A744A746A748A74AA74CA74EA750A752A754A756A758A75AA75CA75EA760A762A764A766A768A76AA76CA76EA779A77BA77DA77EA780A782A784A786A78BFF21-FF3A\",\n Lt: \"01C501C801CB01F21F88-1F8F1F98-1F9F1FA8-1FAF1FBC1FCC1FFC\",\n Lm: \"02B0-02C102C6-02D102E0-02E402EC02EE0374037A0559064006E506E607F407F507FA081A0824082809710E460EC610FC17D718431AA71C78-1C7D1D2C-1D611D781D9B-1DBF2071207F2090-20942C7D2D6F2E2F30053031-3035303B309D309E30FC-30FEA015A4F8-A4FDA60CA67FA717-A71FA770A788A9CFAA70AADDFF70FF9EFF9F\",\n Lo: \"01BB01C0-01C3029405D0-05EA05F0-05F20621-063F0641-064A066E066F0671-06D306D506EE06EF06FA-06FC06FF07100712-072F074D-07A507B107CA-07EA0800-08150904-0939093D09500958-096109720979-097F0985-098C098F09900993-09A809AA-09B009B209B6-09B909BD09CE09DC09DD09DF-09E109F009F10A05-0A0A0A0F0A100A13-0A280A2A-0A300A320A330A350A360A380A390A59-0A5C0A5E0A72-0A740A85-0A8D0A8F-0A910A93-0AA80AAA-0AB00AB20AB30AB5-0AB90ABD0AD00AE00AE10B05-0B0C0B0F0B100B13-0B280B2A-0B300B320B330B35-0B390B3D0B5C0B5D0B5F-0B610B710B830B85-0B8A0B8E-0B900B92-0B950B990B9A0B9C0B9E0B9F0BA30BA40BA8-0BAA0BAE-0BB90BD00C05-0C0C0C0E-0C100C12-0C280C2A-0C330C35-0C390C3D0C580C590C600C610C85-0C8C0C8E-0C900C92-0CA80CAA-0CB30CB5-0CB90CBD0CDE0CE00CE10D05-0D0C0D0E-0D100D12-0D280D2A-0D390D3D0D600D610D7A-0D7F0D85-0D960D9A-0DB10DB3-0DBB0DBD0DC0-0DC60E01-0E300E320E330E40-0E450E810E820E840E870E880E8A0E8D0E94-0E970E99-0E9F0EA1-0EA30EA50EA70EAA0EAB0EAD-0EB00EB20EB30EBD0EC0-0EC40EDC0EDD0F000F40-0F470F49-0F6C0F88-0F8B1000-102A103F1050-1055105A-105D106110651066106E-10701075-1081108E10D0-10FA1100-1248124A-124D1250-12561258125A-125D1260-1288128A-128D1290-12B012B2-12B512B8-12BE12C012C2-12C512C8-12D612D8-13101312-13151318-135A1380-138F13A0-13F41401-166C166F-167F1681-169A16A0-16EA1700-170C170E-17111720-17311740-17511760-176C176E-17701780-17B317DC1820-18421844-18771880-18A818AA18B0-18F51900-191C1950-196D1970-19741980-19AB19C1-19C71A00-1A161A20-1A541B05-1B331B45-1B4B1B83-1BA01BAE1BAF1C00-1C231C4D-1C4F1C5A-1C771CE9-1CEC1CEE-1CF12135-21382D30-2D652D80-2D962DA0-2DA62DA8-2DAE2DB0-2DB62DB8-2DBE2DC0-2DC62DC8-2DCE2DD0-2DD62DD8-2DDE3006303C3041-3096309F30A1-30FA30FF3105-312D3131-318E31A0-31B731F0-31FF3400-4DB54E00-9FCBA000-A014A016-A48CA4D0-A4F7A500-A60BA610-A61FA62AA62BA66EA6A0-A6E5A7FB-A801A803-A805A807-A80AA80C-A822A840-A873A882-A8B3A8F2-A8F7A8FBA90A-A925A930-A946A960-A97CA984-A9B2AA00-AA28AA40-AA42AA44-AA4BAA60-AA6FAA71-AA76AA7AAA80-AAAFAAB1AAB5AAB6AAB9-AABDAAC0AAC2AADBAADCABC0-ABE2AC00-D7A3D7B0-D7C6D7CB-D7FBF900-FA2DFA30-FA6DFA70-FAD9FB1DFB1F-FB28FB2A-FB36FB38-FB3CFB3EFB40FB41FB43FB44FB46-FBB1FBD3-FD3DFD50-FD8FFD92-FDC7FDF0-FDFBFE70-FE74FE76-FEFCFF66-FF6FFF71-FF9DFFA0-FFBEFFC2-FFC7FFCA-FFCFFFD2-FFD7FFDA-FFDC\",\n M: \"0300-036F0483-04890591-05BD05BF05C105C205C405C505C70610-061A064B-065E067006D6-06DC06DE-06E406E706E806EA-06ED07110730-074A07A6-07B007EB-07F30816-0819081B-08230825-08270829-082D0900-0903093C093E-094E0951-0955096209630981-098309BC09BE-09C409C709C809CB-09CD09D709E209E30A01-0A030A3C0A3E-0A420A470A480A4B-0A4D0A510A700A710A750A81-0A830ABC0ABE-0AC50AC7-0AC90ACB-0ACD0AE20AE30B01-0B030B3C0B3E-0B440B470B480B4B-0B4D0B560B570B620B630B820BBE-0BC20BC6-0BC80BCA-0BCD0BD70C01-0C030C3E-0C440C46-0C480C4A-0C4D0C550C560C620C630C820C830CBC0CBE-0CC40CC6-0CC80CCA-0CCD0CD50CD60CE20CE30D020D030D3E-0D440D46-0D480D4A-0D4D0D570D620D630D820D830DCA0DCF-0DD40DD60DD8-0DDF0DF20DF30E310E34-0E3A0E47-0E4E0EB10EB4-0EB90EBB0EBC0EC8-0ECD0F180F190F350F370F390F3E0F3F0F71-0F840F860F870F90-0F970F99-0FBC0FC6102B-103E1056-1059105E-10601062-10641067-106D1071-10741082-108D108F109A-109D135F1712-17141732-1734175217531772177317B6-17D317DD180B-180D18A91920-192B1930-193B19B0-19C019C819C91A17-1A1B1A55-1A5E1A60-1A7C1A7F1B00-1B041B34-1B441B6B-1B731B80-1B821BA1-1BAA1C24-1C371CD0-1CD21CD4-1CE81CED1CF21DC0-1DE61DFD-1DFF20D0-20F02CEF-2CF12DE0-2DFF302A-302F3099309AA66F-A672A67CA67DA6F0A6F1A802A806A80BA823-A827A880A881A8B4-A8C4A8E0-A8F1A926-A92DA947-A953A980-A983A9B3-A9C0AA29-AA36AA43AA4CAA4DAA7BAAB0AAB2-AAB4AAB7AAB8AABEAABFAAC1ABE3-ABEAABECABEDFB1EFE00-FE0FFE20-FE26\",\n Mn: \"0300-036F0483-04870591-05BD05BF05C105C205C405C505C70610-061A064B-065E067006D6-06DC06DF-06E406E706E806EA-06ED07110730-074A07A6-07B007EB-07F30816-0819081B-08230825-08270829-082D0900-0902093C0941-0948094D0951-095509620963098109BC09C1-09C409CD09E209E30A010A020A3C0A410A420A470A480A4B-0A4D0A510A700A710A750A810A820ABC0AC1-0AC50AC70AC80ACD0AE20AE30B010B3C0B3F0B41-0B440B4D0B560B620B630B820BC00BCD0C3E-0C400C46-0C480C4A-0C4D0C550C560C620C630CBC0CBF0CC60CCC0CCD0CE20CE30D41-0D440D4D0D620D630DCA0DD2-0DD40DD60E310E34-0E3A0E47-0E4E0EB10EB4-0EB90EBB0EBC0EC8-0ECD0F180F190F350F370F390F71-0F7E0F80-0F840F860F870F90-0F970F99-0FBC0FC6102D-10301032-10371039103A103D103E10581059105E-10601071-1074108210851086108D109D135F1712-17141732-1734175217531772177317B7-17BD17C617C9-17D317DD180B-180D18A91920-19221927192819321939-193B1A171A181A561A58-1A5E1A601A621A65-1A6C1A73-1A7C1A7F1B00-1B031B341B36-1B3A1B3C1B421B6B-1B731B801B811BA2-1BA51BA81BA91C2C-1C331C361C371CD0-1CD21CD4-1CE01CE2-1CE81CED1DC0-1DE61DFD-1DFF20D0-20DC20E120E5-20F02CEF-2CF12DE0-2DFF302A-302F3099309AA66FA67CA67DA6F0A6F1A802A806A80BA825A826A8C4A8E0-A8F1A926-A92DA947-A951A980-A982A9B3A9B6-A9B9A9BCAA29-AA2EAA31AA32AA35AA36AA43AA4CAAB0AAB2-AAB4AAB7AAB8AABEAABFAAC1ABE5ABE8ABEDFB1EFE00-FE0FFE20-FE26\",\n Mc: \"0903093E-09400949-094C094E0982098309BE-09C009C709C809CB09CC09D70A030A3E-0A400A830ABE-0AC00AC90ACB0ACC0B020B030B3E0B400B470B480B4B0B4C0B570BBE0BBF0BC10BC20BC6-0BC80BCA-0BCC0BD70C01-0C030C41-0C440C820C830CBE0CC0-0CC40CC70CC80CCA0CCB0CD50CD60D020D030D3E-0D400D46-0D480D4A-0D4C0D570D820D830DCF-0DD10DD8-0DDF0DF20DF30F3E0F3F0F7F102B102C10311038103B103C105610571062-10641067-106D108310841087-108C108F109A-109C17B617BE-17C517C717C81923-19261929-192B193019311933-193819B0-19C019C819C91A19-1A1B1A551A571A611A631A641A6D-1A721B041B351B3B1B3D-1B411B431B441B821BA11BA61BA71BAA1C24-1C2B1C341C351CE11CF2A823A824A827A880A881A8B4-A8C3A952A953A983A9B4A9B5A9BAA9BBA9BD-A9C0AA2FAA30AA33AA34AA4DAA7BABE3ABE4ABE6ABE7ABE9ABEAABEC\",\n Me: \"0488048906DE20DD-20E020E2-20E4A670-A672\",\n N: \"0030-003900B200B300B900BC-00BE0660-066906F0-06F907C0-07C90966-096F09E6-09EF09F4-09F90A66-0A6F0AE6-0AEF0B66-0B6F0BE6-0BF20C66-0C6F0C78-0C7E0CE6-0CEF0D66-0D750E50-0E590ED0-0ED90F20-0F331040-10491090-10991369-137C16EE-16F017E0-17E917F0-17F91810-18191946-194F19D0-19DA1A80-1A891A90-1A991B50-1B591BB0-1BB91C40-1C491C50-1C5920702074-20792080-20892150-21822185-21892460-249B24EA-24FF2776-27932CFD30073021-30293038-303A3192-31953220-32293251-325F3280-328932B1-32BFA620-A629A6E6-A6EFA830-A835A8D0-A8D9A900-A909A9D0-A9D9AA50-AA59ABF0-ABF9FF10-FF19\",\n Nd: \"0030-00390660-066906F0-06F907C0-07C90966-096F09E6-09EF0A66-0A6F0AE6-0AEF0B66-0B6F0BE6-0BEF0C66-0C6F0CE6-0CEF0D66-0D6F0E50-0E590ED0-0ED90F20-0F291040-10491090-109917E0-17E91810-18191946-194F19D0-19DA1A80-1A891A90-1A991B50-1B591BB0-1BB91C40-1C491C50-1C59A620-A629A8D0-A8D9A900-A909A9D0-A9D9AA50-AA59ABF0-ABF9FF10-FF19\",\n Nl: \"16EE-16F02160-21822185-218830073021-30293038-303AA6E6-A6EF\",\n No: \"00B200B300B900BC-00BE09F4-09F90BF0-0BF20C78-0C7E0D70-0D750F2A-0F331369-137C17F0-17F920702074-20792080-20892150-215F21892460-249B24EA-24FF2776-27932CFD3192-31953220-32293251-325F3280-328932B1-32BFA830-A835\",\n P: \"0021-00230025-002A002C-002F003A003B003F0040005B-005D005F007B007D00A100AB00B700BB00BF037E0387055A-055F0589058A05BE05C005C305C605F305F40609060A060C060D061B061E061F066A-066D06D40700-070D07F7-07F90830-083E0964096509700DF40E4F0E5A0E5B0F04-0F120F3A-0F3D0F850FD0-0FD4104A-104F10FB1361-13681400166D166E169B169C16EB-16ED1735173617D4-17D617D8-17DA1800-180A1944194519DE19DF1A1E1A1F1AA0-1AA61AA8-1AAD1B5A-1B601C3B-1C3F1C7E1C7F1CD32010-20272030-20432045-20512053-205E207D207E208D208E2329232A2768-277527C527C627E6-27EF2983-299829D8-29DB29FC29FD2CF9-2CFC2CFE2CFF2E00-2E2E2E302E313001-30033008-30113014-301F3030303D30A030FBA4FEA4FFA60D-A60FA673A67EA6F2-A6F7A874-A877A8CEA8CFA8F8-A8FAA92EA92FA95FA9C1-A9CDA9DEA9DFAA5C-AA5FAADEAADFABEBFD3EFD3FFE10-FE19FE30-FE52FE54-FE61FE63FE68FE6AFE6BFF01-FF03FF05-FF0AFF0C-FF0FFF1AFF1BFF1FFF20FF3B-FF3DFF3FFF5BFF5DFF5F-FF65\",\n Pd: \"002D058A05BE140018062010-20152E172E1A301C303030A0FE31FE32FE58FE63FF0D\",\n Ps: \"0028005B007B0F3A0F3C169B201A201E2045207D208D23292768276A276C276E27702772277427C527E627E827EA27EC27EE2983298529872989298B298D298F299129932995299729D829DA29FC2E222E242E262E283008300A300C300E3010301430163018301A301DFD3EFE17FE35FE37FE39FE3BFE3DFE3FFE41FE43FE47FE59FE5BFE5DFF08FF3BFF5BFF5FFF62\",\n Pe: \"0029005D007D0F3B0F3D169C2046207E208E232A2769276B276D276F27712773277527C627E727E927EB27ED27EF298429862988298A298C298E2990299229942996299829D929DB29FD2E232E252E272E293009300B300D300F3011301530173019301B301E301FFD3FFE18FE36FE38FE3AFE3CFE3EFE40FE42FE44FE48FE5AFE5CFE5EFF09FF3DFF5DFF60FF63\",\n Pi: \"00AB2018201B201C201F20392E022E042E092E0C2E1C2E20\",\n Pf: \"00BB2019201D203A2E032E052E0A2E0D2E1D2E21\",\n Pc: \"005F203F20402054FE33FE34FE4D-FE4FFF3F\",\n Po: \"0021-00230025-0027002A002C002E002F003A003B003F0040005C00A100B700BF037E0387055A-055F058905C005C305C605F305F40609060A060C060D061B061E061F066A-066D06D40700-070D07F7-07F90830-083E0964096509700DF40E4F0E5A0E5B0F04-0F120F850FD0-0FD4104A-104F10FB1361-1368166D166E16EB-16ED1735173617D4-17D617D8-17DA1800-18051807-180A1944194519DE19DF1A1E1A1F1AA0-1AA61AA8-1AAD1B5A-1B601C3B-1C3F1C7E1C7F1CD3201620172020-20272030-2038203B-203E2041-20432047-205120532055-205E2CF9-2CFC2CFE2CFF2E002E012E06-2E082E0B2E0E-2E162E182E192E1B2E1E2E1F2E2A-2E2E2E302E313001-3003303D30FBA4FEA4FFA60D-A60FA673A67EA6F2-A6F7A874-A877A8CEA8CFA8F8-A8FAA92EA92FA95FA9C1-A9CDA9DEA9DFAA5C-AA5FAADEAADFABEBFE10-FE16FE19FE30FE45FE46FE49-FE4CFE50-FE52FE54-FE57FE5F-FE61FE68FE6AFE6BFF01-FF03FF05-FF07FF0AFF0CFF0EFF0FFF1AFF1BFF1FFF20FF3CFF61FF64FF65\",\n S: \"0024002B003C-003E005E0060007C007E00A2-00A900AC00AE-00B100B400B600B800D700F702C2-02C502D2-02DF02E5-02EB02ED02EF-02FF03750384038503F604820606-0608060B060E060F06E906FD06FE07F609F209F309FA09FB0AF10B700BF3-0BFA0C7F0CF10CF20D790E3F0F01-0F030F13-0F170F1A-0F1F0F340F360F380FBE-0FC50FC7-0FCC0FCE0FCF0FD5-0FD8109E109F13601390-139917DB194019E0-19FF1B61-1B6A1B74-1B7C1FBD1FBF-1FC11FCD-1FCF1FDD-1FDF1FED-1FEF1FFD1FFE20442052207A-207C208A-208C20A0-20B8210021012103-21062108210921142116-2118211E-2123212521272129212E213A213B2140-2144214A-214D214F2190-2328232B-23E82400-24262440-244A249C-24E92500-26CD26CF-26E126E326E8-26FF2701-27042706-2709270C-27272729-274B274D274F-27522756-275E2761-276727942798-27AF27B1-27BE27C0-27C427C7-27CA27CC27D0-27E527F0-29822999-29D729DC-29FB29FE-2B4C2B50-2B592CE5-2CEA2E80-2E992E9B-2EF32F00-2FD52FF0-2FFB300430123013302030363037303E303F309B309C319031913196-319F31C0-31E33200-321E322A-32503260-327F328A-32B032C0-32FE3300-33FF4DC0-4DFFA490-A4C6A700-A716A720A721A789A78AA828-A82BA836-A839AA77-AA79FB29FDFCFDFDFE62FE64-FE66FE69FF04FF0BFF1C-FF1EFF3EFF40FF5CFF5EFFE0-FFE6FFE8-FFEEFFFCFFFD\",\n Sm: \"002B003C-003E007C007E00AC00B100D700F703F60606-060820442052207A-207C208A-208C2140-2144214B2190-2194219A219B21A021A321A621AE21CE21CF21D221D421F4-22FF2308-230B23202321237C239B-23B323DC-23E125B725C125F8-25FF266F27C0-27C427C7-27CA27CC27D0-27E527F0-27FF2900-29822999-29D729DC-29FB29FE-2AFF2B30-2B442B47-2B4CFB29FE62FE64-FE66FF0BFF1C-FF1EFF5CFF5EFFE2FFE9-FFEC\",\n Sc: \"002400A2-00A5060B09F209F309FB0AF10BF90E3F17DB20A0-20B8A838FDFCFE69FF04FFE0FFE1FFE5FFE6\",\n Sk: \"005E006000A800AF00B400B802C2-02C502D2-02DF02E5-02EB02ED02EF-02FF0375038403851FBD1FBF-1FC11FCD-1FCF1FDD-1FDF1FED-1FEF1FFD1FFE309B309CA700-A716A720A721A789A78AFF3EFF40FFE3\",\n So: \"00A600A700A900AE00B000B60482060E060F06E906FD06FE07F609FA0B700BF3-0BF80BFA0C7F0CF10CF20D790F01-0F030F13-0F170F1A-0F1F0F340F360F380FBE-0FC50FC7-0FCC0FCE0FCF0FD5-0FD8109E109F13601390-1399194019E0-19FF1B61-1B6A1B74-1B7C210021012103-21062108210921142116-2118211E-2123212521272129212E213A213B214A214C214D214F2195-2199219C-219F21A121A221A421A521A7-21AD21AF-21CD21D021D121D321D5-21F32300-2307230C-231F2322-2328232B-237B237D-239A23B4-23DB23E2-23E82400-24262440-244A249C-24E92500-25B625B8-25C025C2-25F72600-266E2670-26CD26CF-26E126E326E8-26FF2701-27042706-2709270C-27272729-274B274D274F-27522756-275E2761-276727942798-27AF27B1-27BE2800-28FF2B00-2B2F2B452B462B50-2B592CE5-2CEA2E80-2E992E9B-2EF32F00-2FD52FF0-2FFB300430123013302030363037303E303F319031913196-319F31C0-31E33200-321E322A-32503260-327F328A-32B032C0-32FE3300-33FF4DC0-4DFFA490-A4C6A828-A82BA836A837A839AA77-AA79FDFDFFE4FFE8FFEDFFEEFFFCFFFD\",\n Z: \"002000A01680180E2000-200A20282029202F205F3000\",\n Zs: \"002000A01680180E2000-200A202F205F3000\",\n Zl: \"2028\",\n Zp: \"2029\",\n C: \"0000-001F007F-009F00AD03780379037F-0383038B038D03A20526-05300557055805600588058B-059005C8-05CF05EB-05EF05F5-0605061C061D0620065F06DD070E070F074B074C07B2-07BF07FB-07FF082E082F083F-08FF093A093B094F095609570973-097809800984098D098E0991099209A909B109B3-09B509BA09BB09C509C609C909CA09CF-09D609D8-09DB09DE09E409E509FC-0A000A040A0B-0A0E0A110A120A290A310A340A370A3A0A3B0A3D0A43-0A460A490A4A0A4E-0A500A52-0A580A5D0A5F-0A650A76-0A800A840A8E0A920AA90AB10AB40ABA0ABB0AC60ACA0ACE0ACF0AD1-0ADF0AE40AE50AF00AF2-0B000B040B0D0B0E0B110B120B290B310B340B3A0B3B0B450B460B490B4A0B4E-0B550B58-0B5B0B5E0B640B650B72-0B810B840B8B-0B8D0B910B96-0B980B9B0B9D0BA0-0BA20BA5-0BA70BAB-0BAD0BBA-0BBD0BC3-0BC50BC90BCE0BCF0BD1-0BD60BD8-0BE50BFB-0C000C040C0D0C110C290C340C3A-0C3C0C450C490C4E-0C540C570C5A-0C5F0C640C650C70-0C770C800C810C840C8D0C910CA90CB40CBA0CBB0CC50CC90CCE-0CD40CD7-0CDD0CDF0CE40CE50CF00CF3-0D010D040D0D0D110D290D3A-0D3C0D450D490D4E-0D560D58-0D5F0D640D650D76-0D780D800D810D840D97-0D990DB20DBC0DBE0DBF0DC7-0DC90DCB-0DCE0DD50DD70DE0-0DF10DF5-0E000E3B-0E3E0E5C-0E800E830E850E860E890E8B0E8C0E8E-0E930E980EA00EA40EA60EA80EA90EAC0EBA0EBE0EBF0EC50EC70ECE0ECF0EDA0EDB0EDE-0EFF0F480F6D-0F700F8C-0F8F0F980FBD0FCD0FD9-0FFF10C6-10CF10FD-10FF1249124E124F12571259125E125F1289128E128F12B112B612B712BF12C112C612C712D7131113161317135B-135E137D-137F139A-139F13F5-13FF169D-169F16F1-16FF170D1715-171F1737-173F1754-175F176D17711774-177F17B417B517DE17DF17EA-17EF17FA-17FF180F181A-181F1878-187F18AB-18AF18F6-18FF191D-191F192C-192F193C-193F1941-1943196E196F1975-197F19AC-19AF19CA-19CF19DB-19DD1A1C1A1D1A5F1A7D1A7E1A8A-1A8F1A9A-1A9F1AAE-1AFF1B4C-1B4F1B7D-1B7F1BAB-1BAD1BBA-1BFF1C38-1C3A1C4A-1C4C1C80-1CCF1CF3-1CFF1DE7-1DFC1F161F171F1E1F1F1F461F471F4E1F4F1F581F5A1F5C1F5E1F7E1F7F1FB51FC51FD41FD51FDC1FF01FF11FF51FFF200B-200F202A-202E2060-206F20722073208F2095-209F20B9-20CF20F1-20FF218A-218F23E9-23FF2427-243F244B-245F26CE26E226E4-26E727002705270A270B2728274C274E2753-2755275F27602795-279727B027BF27CB27CD-27CF2B4D-2B4F2B5A-2BFF2C2F2C5F2CF2-2CF82D26-2D2F2D66-2D6E2D70-2D7F2D97-2D9F2DA72DAF2DB72DBF2DC72DCF2DD72DDF2E32-2E7F2E9A2EF4-2EFF2FD6-2FEF2FFC-2FFF3040309730983100-3104312E-3130318F31B8-31BF31E4-31EF321F32FF4DB6-4DBF9FCC-9FFFA48D-A48FA4C7-A4CFA62C-A63FA660A661A674-A67BA698-A69FA6F8-A6FFA78D-A7FAA82C-A82FA83A-A83FA878-A87FA8C5-A8CDA8DA-A8DFA8FC-A8FFA954-A95EA97D-A97FA9CEA9DA-A9DDA9E0-A9FFAA37-AA3FAA4EAA4FAA5AAA5BAA7C-AA7FAAC3-AADAAAE0-ABBFABEEABEFABFA-ABFFD7A4-D7AFD7C7-D7CAD7FC-F8FFFA2EFA2FFA6EFA6FFADA-FAFFFB07-FB12FB18-FB1CFB37FB3DFB3FFB42FB45FBB2-FBD2FD40-FD4FFD90FD91FDC8-FDEFFDFEFDFFFE1A-FE1FFE27-FE2FFE53FE67FE6C-FE6FFE75FEFD-FF00FFBF-FFC1FFC8FFC9FFD0FFD1FFD8FFD9FFDD-FFDFFFE7FFEF-FFFBFFFEFFFF\",\n Cc: \"0000-001F007F-009F\",\n Cf: \"00AD0600-060306DD070F17B417B5200B-200F202A-202E2060-2064206A-206FFEFFFFF9-FFFB\",\n Co: \"E000-F8FF\",\n Cs: \"D800-DFFF\",\n Cn: \"03780379037F-0383038B038D03A20526-05300557055805600588058B-059005C8-05CF05EB-05EF05F5-05FF06040605061C061D0620065F070E074B074C07B2-07BF07FB-07FF082E082F083F-08FF093A093B094F095609570973-097809800984098D098E0991099209A909B109B3-09B509BA09BB09C509C609C909CA09CF-09D609D8-09DB09DE09E409E509FC-0A000A040A0B-0A0E0A110A120A290A310A340A370A3A0A3B0A3D0A43-0A460A490A4A0A4E-0A500A52-0A580A5D0A5F-0A650A76-0A800A840A8E0A920AA90AB10AB40ABA0ABB0AC60ACA0ACE0ACF0AD1-0ADF0AE40AE50AF00AF2-0B000B040B0D0B0E0B110B120B290B310B340B3A0B3B0B450B460B490B4A0B4E-0B550B58-0B5B0B5E0B640B650B72-0B810B840B8B-0B8D0B910B96-0B980B9B0B9D0BA0-0BA20BA5-0BA70BAB-0BAD0BBA-0BBD0BC3-0BC50BC90BCE0BCF0BD1-0BD60BD8-0BE50BFB-0C000C040C0D0C110C290C340C3A-0C3C0C450C490C4E-0C540C570C5A-0C5F0C640C650C70-0C770C800C810C840C8D0C910CA90CB40CBA0CBB0CC50CC90CCE-0CD40CD7-0CDD0CDF0CE40CE50CF00CF3-0D010D040D0D0D110D290D3A-0D3C0D450D490D4E-0D560D58-0D5F0D640D650D76-0D780D800D810D840D97-0D990DB20DBC0DBE0DBF0DC7-0DC90DCB-0DCE0DD50DD70DE0-0DF10DF5-0E000E3B-0E3E0E5C-0E800E830E850E860E890E8B0E8C0E8E-0E930E980EA00EA40EA60EA80EA90EAC0EBA0EBE0EBF0EC50EC70ECE0ECF0EDA0EDB0EDE-0EFF0F480F6D-0F700F8C-0F8F0F980FBD0FCD0FD9-0FFF10C6-10CF10FD-10FF1249124E124F12571259125E125F1289128E128F12B112B612B712BF12C112C612C712D7131113161317135B-135E137D-137F139A-139F13F5-13FF169D-169F16F1-16FF170D1715-171F1737-173F1754-175F176D17711774-177F17DE17DF17EA-17EF17FA-17FF180F181A-181F1878-187F18AB-18AF18F6-18FF191D-191F192C-192F193C-193F1941-1943196E196F1975-197F19AC-19AF19CA-19CF19DB-19DD1A1C1A1D1A5F1A7D1A7E1A8A-1A8F1A9A-1A9F1AAE-1AFF1B4C-1B4F1B7D-1B7F1BAB-1BAD1BBA-1BFF1C38-1C3A1C4A-1C4C1C80-1CCF1CF3-1CFF1DE7-1DFC1F161F171F1E1F1F1F461F471F4E1F4F1F581F5A1F5C1F5E1F7E1F7F1FB51FC51FD41FD51FDC1FF01FF11FF51FFF2065-206920722073208F2095-209F20B9-20CF20F1-20FF218A-218F23E9-23FF2427-243F244B-245F26CE26E226E4-26E727002705270A270B2728274C274E2753-2755275F27602795-279727B027BF27CB27CD-27CF2B4D-2B4F2B5A-2BFF2C2F2C5F2CF2-2CF82D26-2D2F2D66-2D6E2D70-2D7F2D97-2D9F2DA72DAF2DB72DBF2DC72DCF2DD72DDF2E32-2E7F2E9A2EF4-2EFF2FD6-2FEF2FFC-2FFF3040309730983100-3104312E-3130318F31B8-31BF31E4-31EF321F32FF4DB6-4DBF9FCC-9FFFA48D-A48FA4C7-A4CFA62C-A63FA660A661A674-A67BA698-A69FA6F8-A6FFA78D-A7FAA82C-A82FA83A-A83FA878-A87FA8C5-A8CDA8DA-A8DFA8FC-A8FFA954-A95EA97D-A97FA9CEA9DA-A9DDA9E0-A9FFAA37-AA3FAA4EAA4FAA5AAA5BAA7C-AA7FAAC3-AADAAAE0-ABBFABEEABEFABFA-ABFFD7A4-D7AFD7C7-D7CAD7FC-D7FFFA2EFA2FFA6EFA6FFADA-FAFFFB07-FB12FB18-FB1CFB37FB3DFB3FFB42FB45FBB2-FBD2FD40-FD4FFD90FD91FDC8-FDEFFDFEFDFFFE1A-FE1FFE27-FE2FFE53FE67FE6C-FE6FFE75FEFDFEFEFF00FFBF-FFC1FFC8FFC9FFD0FFD1FFD8FFD9FFDD-FFDFFFE7FFEF-FFF8FFFEFFFF\"\n });\n function addUnicodePackage(pack) {\n var codePoint = /\\w{4}/g;\n for (var name in pack) exports.packages[name] = pack[name].replace(codePoint, \"\\\\u$&\");\n }\n});\nace.define(\"ace/mode/text\", [\"require\", \"exports\", \"module\", \"ace/tokenizer\", \"ace/mode/text_highlight_rules\", \"ace/mode/behaviour/cstyle\", \"ace/unicode\", \"ace/lib/lang\", \"ace/token_iterator\", \"ace/range\"], function (acequire, exports, module) {\n \"use strict\";\n\n var Tokenizer = acequire(\"../tokenizer\").Tokenizer;\n var TextHighlightRules = acequire(\"./text_highlight_rules\").TextHighlightRules;\n var CstyleBehaviour = acequire(\"./behaviour/cstyle\").CstyleBehaviour;\n var unicode = acequire(\"../unicode\");\n var lang = acequire(\"../lib/lang\");\n var TokenIterator = acequire(\"../token_iterator\").TokenIterator;\n var Range = acequire(\"../range\").Range;\n var Mode = function () {\n this.HighlightRules = TextHighlightRules;\n };\n (function () {\n this.$defaultBehaviour = new CstyleBehaviour();\n this.tokenRe = new RegExp(\"^[\" + unicode.packages.L + unicode.packages.Mn + unicode.packages.Mc + unicode.packages.Nd + unicode.packages.Pc + \"\\\\$_]+\", \"g\");\n this.nonTokenRe = new RegExp(\"^(?:[^\" + unicode.packages.L + unicode.packages.Mn + unicode.packages.Mc + unicode.packages.Nd + unicode.packages.Pc + \"\\\\$_]|\\\\s])+\", \"g\");\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 this.lineCommentStart = \"\";\n this.blockComment = \"\";\n this.toggleCommentLines = function (state, session, startRow, endRow) {\n var doc = session.doc;\n var ignoreBlankLines = true;\n var shouldRemove = true;\n var minIndent = Infinity;\n var tabSize = session.getTabSize();\n var insertAtTabStop = false;\n if (!this.lineCommentStart) {\n if (!this.blockComment) 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 var comment = function (line, i) {\n if (testRemove(line, i)) return;\n if (!ignoreBlankLines || /\\S/.test(line)) {\n doc.insertInLine({\n row: i,\n column: line.length\n }, lineCommentEnd);\n doc.insertInLine({\n row: i,\n column: minIndent\n }, lineCommentStart);\n }\n };\n var uncomment = function (line, i) {\n var m;\n if (m = line.match(regexpEnd)) doc.removeInLine(i, line.length - m[0].length, line.length);\n if (m = line.match(regexpStart)) doc.removeInLine(i, m[1].length, m[0].length);\n };\n var testRemove = function (line, row) {\n if (regexpStart.test(line)) return true;\n var tokens = session.getTokens(row);\n for (var i = 0; i < tokens.length; i++) {\n if (tokens[i].type === \"comment\") 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 insertAtTabStop = session.getUseSoftTabs();\n var uncomment = function (line, i) {\n var m = line.match(regexpStart);\n if (!m) return;\n var start = m[1].length,\n end = m[0].length;\n if (!shouldInsertSpace(line, start, end) && m[0][end - 1] == \" \") 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)) doc.insertInLine({\n row: i,\n column: minIndent\n }, commentWithSpace);else doc.insertInLine({\n row: i,\n column: minIndent\n }, lineCommentStart);\n }\n };\n var testRemove = function (line, i) {\n return regexpStart.test(line);\n };\n var shouldInsertSpace = function (line, before, after) {\n var spaces = 0;\n while (before-- && line.charAt(before) == \" \") spaces++;\n if (spaces % tabSize != 0) return false;\n var spaces = 0;\n while (line.charAt(after++) == \" \") spaces++;\n if (tabSize > 2) return spaces % tabSize != tabSize - 1;else return spaces % tabSize == 0;\n return true;\n };\n }\n function iter(fun) {\n for (var i = startRow; i <= endRow; i++) fun(doc.getLine(i), i);\n }\n var minEmptyLength = Infinity;\n iter(function (line, i) {\n var indent = line.search(/\\S/);\n if (indent !== -1) {\n if (indent < minIndent) minIndent = indent;\n if (shouldRemove && !testRemove(line, i)) shouldRemove = false;\n } else if (minEmptyLength > line.length) {\n minEmptyLength = line.length;\n }\n });\n if (minIndent == Infinity) {\n minIndent = minEmptyLength;\n ignoreBlankLines = false;\n shouldRemove = false;\n }\n if (insertAtTabStop && minIndent % tabSize != 0) minIndent = Math.floor(minIndent / tabSize) * tabSize;\n iter(shouldRemove ? uncomment : comment);\n };\n this.toggleBlockComment = function (state, session, range, cursor) {\n var comment = this.blockComment;\n if (!comment) return;\n if (!comment.start && comment[0]) comment = comment[0];\n var iterator = new TokenIterator(session, cursor.row, cursor.column);\n var token = iterator.getCurrentToken();\n var sel = session.selection;\n var initialRange = session.selection.toOrientedRange();\n var startRow, colDiff;\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 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) 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) initialRange.start.column += colDiff;\n if (initialRange.end.row == startRow) initialRange.end.column += colDiff;\n session.selection.fromOrientedRange(initialRange);\n };\n this.getNextLineIndent = function (state, line, tab) {\n return this.$getIndent(line);\n };\n this.checkOutdent = function (state, line, input) {\n return false;\n };\n this.autoOutdent = function (state, doc, row) {};\n this.$getIndent = function (line) {\n return line.match(/^\\s*/)[0];\n };\n this.createWorker = function (session) {\n return null;\n };\n this.createModeDelegates = function (mapping) {\n this.$embeds = [];\n this.$modes = {};\n for (var i in mapping) {\n if (mapping[i]) {\n this.$embeds.push(i);\n this.$modes[i] = new mapping[i]();\n }\n }\n var delegations = [\"toggleBlockComment\", \"toggleCommentLines\", \"getNextLineIndent\", \"checkOutdent\", \"autoOutdent\", \"transformAction\", \"getCompletions\"];\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 this.$delegator = function (method, args, defaultHandler) {\n var state = args[0];\n if (typeof state != \"string\") state = state[0];\n for (var i = 0; i < this.$embeds.length; i++) {\n if (!this.$modes[this.$embeds[i]]) continue;\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 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 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)) completionKeywords.push(ruleItr[r].regex);\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) return this.$keywordList;\n return completionKeywords.concat(this.$keywordList || []);\n };\n this.$createKeywordList = function () {\n if (!this.$highlightRules) this.getTokenizer();\n return this.$keywordList = this.$highlightRules.$keywordList || [];\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 this.$id = \"ace/mode/text\";\n }).call(Mode.prototype);\n exports.Mode = Mode;\n});\nace.define(\"ace/apply_delta\", [\"require\", \"exports\", \"module\"], function (acequire, exports, module) {\n \"use strict\";\n\n function throwDeltaError(delta, errorText) {\n console.log(\"Invalid Delta:\", delta);\n throw \"Invalid Delta: \" + errorText;\n }\n function positionInDocument(docLines, position) {\n return position.row >= 0 && position.row < docLines.length && position.column >= 0 && position.column <= docLines[position.row].length;\n }\n function validateDelta(docLines, delta) {\n if (delta.action != \"insert\" && delta.action != \"remove\") throwDeltaError(delta, \"delta.action must be 'insert' or 'remove'\");\n if (!(delta.lines instanceof Array)) throwDeltaError(delta, \"delta.lines must be an Array\");\n if (!delta.start || !delta.end) throwDeltaError(delta, \"delta.start/end must be an present\");\n var start = delta.start;\n if (!positionInDocument(docLines, delta.start)) throwDeltaError(delta, \"delta.start must be contained in document\");\n var end = delta.end;\n if (delta.action == \"remove\" && !positionInDocument(docLines, end)) 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) throwDeltaError(delta, \"delta.range must match delta lines\");\n }\n exports.applyDelta = function (docLines, delta, doNotValidate) {\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(row, endRow - row + 1, line.substring(0, startColumn) + docLines[endRow].substring(endColumn));\n }\n break;\n }\n };\n});\nace.define(\"ace/anchor\", [\"require\", \"exports\", \"module\", \"ace/lib/oop\", \"ace/lib/event_emitter\"], function (acequire, exports, module) {\n \"use strict\";\n\n var oop = acequire(\"./lib/oop\");\n var EventEmitter = acequire(\"./lib/event_emitter\").EventEmitter;\n var Anchor = exports.Anchor = function (doc, row, column) {\n this.$onChange = this.onChange.bind(this);\n this.attach(doc);\n if (typeof column == \"undefined\") this.setPosition(row.row, row.column);else this.setPosition(row, column);\n };\n (function () {\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) return;\n if (delta.start.row > this.row) return;\n var point = $getTransformedPoint(delta, {\n row: this.row,\n column: this.column\n }, this.$insertRight);\n this.setPosition(point.row, point.column, true);\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 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 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 if (this.row == pos.row && this.column == pos.column) return;\n var old = {\n row: this.row,\n column: this.column\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 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 } else if (row < 0) {\n pos.row = 0;\n pos.column = 0;\n } else {\n pos.row = row;\n pos.column = Math.min(this.document.getLine(pos.row).length, Math.max(0, column));\n }\n if (column < 0) pos.column = 0;\n return pos;\n };\n }).call(Anchor.prototype);\n});\nace.define(\"ace/document\", [\"require\", \"exports\", \"module\", \"ace/lib/oop\", \"ace/apply_delta\", \"ace/lib/event_emitter\", \"ace/range\", \"ace/anchor\"], function (acequire, exports, module) {\n \"use strict\";\n\n var oop = acequire(\"./lib/oop\");\n var applyDelta = acequire(\"./apply_delta\").applyDelta;\n var EventEmitter = acequire(\"./lib/event_emitter\").EventEmitter;\n var Range = acequire(\"./range\").Range;\n var Anchor = acequire(\"./anchor\").Anchor;\n var Document = function (textOrLines) {\n this.$lines = [\"\"];\n if (textOrLines.length === 0) {\n this.$lines = [\"\"];\n } else if (Array.isArray(textOrLines)) {\n this.insertMergedLines({\n row: 0,\n column: 0\n }, textOrLines);\n } else {\n this.insert({\n row: 0,\n column: 0\n }, textOrLines);\n }\n };\n (function () {\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({\n row: 0,\n column: 0\n }, 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 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 this.$autoNewLine = \"\";\n this.$newLineMode = \"auto\";\n this.setNewLineMode = function (newLineMode) {\n if (this.$newLineMode === newLineMode) return;\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) 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) this.$detectNewLine(text);\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 this.applyDelta({\n start: start,\n end: end,\n action: \"insert\",\n lines: [text]\n }, true);\n return this.clonePos(end);\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) column = line.length;\n column = Math.min(Math.max(column, 0), line.length);\n return {\n row: row,\n column: column\n };\n };\n this.clonePos = function (pos) {\n return {\n row: pos.row,\n column: pos.column\n };\n };\n this.pos = function (row, column) {\n return {\n row: row,\n 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({\n row: row,\n column: column\n }, 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 this.applyDelta({\n start: start,\n end: end,\n action: \"insert\",\n lines: lines\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({\n start: start,\n end: end\n })\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 this.applyDelta({\n start: start,\n end: end,\n action: \"remove\",\n lines: this.getLinesForRange({\n start: start,\n end: end\n })\n }, true);\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 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)) range = Range.fromPoints(range.start, range.end);\n if (text.length === 0 && range.isEmpty()) return range.start;\n if (text == this.getTextRange(range)) return range.end;\n this.remove(range);\n var end;\n if (text) {\n end = this.insert(range.start, text);\n } else {\n end = range.start;\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] : !Range.comparePoints(delta.start, delta.end)) {\n return;\n }\n if (isInsert && delta.lines.length > 20000) this.$splitAndapplyLargeDelta(delta, 20000);\n applyDelta(this.$lines, delta, doNotValidate);\n this._signal(\"change\", delta);\n };\n this.$splitAndapplyLargeDelta = function (delta, MAX) {\n var lines = delta.lines;\n var l = lines.length;\n var row = delta.start.row;\n var column = delta.start.column;\n var from = 0,\n to = 0;\n do {\n from = to;\n to += MAX - 1;\n var chunk = lines.slice(from, to);\n if (to > l) {\n delta.lines = chunk;\n delta.start.row = row + from;\n delta.start.column = column;\n break;\n }\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 } while (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) return {\n row: i,\n column: index + lines[i].length + newlineLength\n };\n }\n return {\n row: l - 1,\n column: lines[l - 1].length\n };\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) index += lines[i].length + newlineLength;\n return index + pos.column;\n };\n }).call(Document.prototype);\n exports.Document = Document;\n});\nace.define(\"ace/background_tokenizer\", [\"require\", \"exports\", \"module\", \"ace/lib/oop\", \"ace/lib/event_emitter\"], function (acequire, exports, module) {\n \"use strict\";\n\n var oop = acequire(\"./lib/oop\");\n var EventEmitter = acequire(\"./lib/event_emitter\").EventEmitter;\n var BackgroundTokenizer = function (tokenizer, editor) {\n this.running = false;\n this.lines = [];\n this.states = [];\n this.currentLine = 0;\n this.tokenizer = tokenizer;\n var self = this;\n this.$worker = function () {\n if (!self.running) {\n return;\n }\n var workerStart = new Date();\n var currentLine = self.currentLine;\n var endLine = -1;\n var doc = self.doc;\n var startLine = currentLine;\n while (self.lines[currentLine]) currentLine++;\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 if (endLine == -1) endLine = currentLine;\n if (startLine <= endLine) self.fireUpdateEvent(startLine, endLine);\n };\n };\n (function () {\n oop.implement(this, EventEmitter);\n this.setTokenizer = function (tokenizer) {\n this.tokenizer = tokenizer;\n this.lines = [];\n this.states = [];\n this.start(0);\n };\n this.setDocument = function (doc) {\n this.doc = doc;\n this.lines = [];\n this.states = [];\n this.stop();\n };\n this.fireUpdateEvent = function (firstRow, lastRow) {\n var data = {\n first: firstRow,\n last: lastRow\n };\n this._signal(\"update\", {\n data: data\n });\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 this.stop();\n this.running = setTimeout(this.$worker, 700);\n };\n this.scheduleStart = function () {\n if (!this.running) this.running = setTimeout(this.$worker, 700);\n };\n this.$updateOnChange = function (delta) {\n var startRow = delta.start.row;\n var len = delta.end.row - startRow;\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 this.currentLine = Math.min(startRow, this.currentLine, this.doc.getLength());\n this.stop();\n };\n this.stop = function () {\n if (this.running) 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) this.$tokenizeRow(row);\n return this.states[row] || \"start\";\n };\n this.$tokenizeRow = function (row) {\n var line = this.doc.getLine(row);\n var state = this.states[row - 1];\n var data = this.tokenizer.getLineTokens(line, state, row);\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) this.currentLine = row + 1;\n } else if (this.currentLine == row) {\n this.currentLine = row + 1;\n }\n return this.lines[row] = data.tokens;\n };\n }).call(BackgroundTokenizer.prototype);\n exports.BackgroundTokenizer = BackgroundTokenizer;\n});\nace.define(\"ace/search_highlight\", [\"require\", \"exports\", \"module\", \"ace/lib/lang\", \"ace/lib/oop\", \"ace/range\"], function (acequire, exports, module) {\n \"use strict\";\n\n var lang = acequire(\"./lib/lang\");\n var oop = acequire(\"./lib/oop\");\n var Range = acequire(\"./range\").Range;\n var SearchHighlight = function (regExp, clazz, type) {\n this.setRegexp(regExp);\n this.clazz = clazz;\n this.type = type || \"text\";\n };\n (function () {\n this.MAX_RANGES = 500;\n this.setRegexp = function (regExp) {\n if (this.regExp + \"\" == regExp + \"\") return;\n this.regExp = regExp;\n this.cache = [];\n };\n this.update = function (html, markerLayer, session, config) {\n if (!this.regExp) return;\n var start = config.firstRow,\n end = config.lastRow;\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) 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 for (var j = ranges.length; j--;) {\n markerLayer.drawSingleLineMarker(html, ranges[j].toScreenRange(session), this.clazz, config);\n }\n }\n };\n }).call(SearchHighlight.prototype);\n exports.SearchHighlight = SearchHighlight;\n});\nace.define(\"ace/edit_session/fold_line\", [\"require\", \"exports\", \"module\", \"ace/range\"], function (acequire, exports, module) {\n \"use strict\";\n\n var Range = acequire(\"../range\").Range;\n function 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 var last = folds[folds.length - 1];\n this.range = new Range(folds[0].start.row, folds[0].start.column, last.end.row, last.end.column);\n this.start = this.range.start;\n this.end = this.range.end;\n this.folds.forEach(function (fold) {\n fold.setFoldLine(this);\n }, this);\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 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 this.containsRow = function (row) {\n return row >= this.start.row && row <= this.end.row;\n };\n this.walk = function (callback, endRow, endColumn) {\n var lastEnd = 0,\n folds = this.folds,\n fold,\n cmp,\n stop,\n isNewRow = true;\n if (endRow == null) {\n endRow = this.end.row;\n endColumn = this.end.column;\n }\n for (var i = 0; i < folds.length; i++) {\n fold = folds[i];\n cmp = fold.range.compareStart(endRow, endColumn);\n if (cmp == -1) {\n callback(null, endRow, endColumn, lastEnd, isNewRow);\n return;\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 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 this.addRemoveChars = function (row, column, len) {\n var ret = this.getNextFoldTo(row, column),\n fold,\n folds;\n if (ret) {\n fold = ret.fold;\n if (ret.kind == \"inside\" && fold.start.column != column && fold.start.row != row) {\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 this.split = function (row, column) {\n var pos = this.getNextFoldTo(row, column);\n if (!pos || pos.kind == \"inside\") return null;\n var fold = pos.fold;\n var folds = this.folds;\n var foldData = this.foldData;\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 var newFoldLine = new FoldLine(foldData, folds);\n foldData.splice(foldData.indexOf(this) + 1, 0, newFoldLine);\n return newFoldLine;\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 this.toString = function () {\n var ret = [this.range.toString() + \": [\"];\n this.folds.forEach(function (fold) {\n ret.push(\" \" + fold.toString());\n });\n ret.push(\"]\");\n return ret.join(\"\\n\");\n };\n this.idxToPosition = function (idx) {\n var lastFoldEndColumn = 0;\n for (var i = 0; i < this.folds.length; i++) {\n var fold = this.folds[i];\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 idx -= fold.placeholder.length;\n if (idx < 0) {\n return fold.start;\n }\n lastFoldEndColumn = fold.end.column;\n }\n return {\n row: this.end.row,\n column: this.end.column + idx\n };\n };\n }).call(FoldLine.prototype);\n exports.FoldLine = FoldLine;\n});\nace.define(\"ace/range_list\", [\"require\", \"exports\", \"module\", \"ace/range\"], function (acequire, exports, module) {\n \"use strict\";\n\n var Range = acequire(\"./range\").Range;\n var comparePoints = Range.comparePoints;\n var RangeList = function () {\n this.ranges = [];\n };\n (function () {\n this.comparePoints = comparePoints;\n this.pointIndex = function (pos, excludeEdges, startIndex) {\n var list = this.ranges;\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) continue;\n var cmpStart = comparePoints(pos, range.start);\n if (cmpEnd === 0) return excludeEdges && cmpStart !== 0 ? -i - 2 : i;\n if (cmpStart > 0 || cmpStart === 0 && !excludeEdges) return i;\n return -i - 1;\n }\n return -i - 1;\n };\n this.add = function (range) {\n var excludeEdges = !range.isEmpty();\n var startIndex = this.pointIndex(range.start, excludeEdges);\n if (startIndex < 0) startIndex = -startIndex - 1;\n var endIndex = this.pointIndex(range.end, excludeEdges, startIndex);\n if (endIndex < 0) endIndex = -endIndex - 1;else endIndex++;\n return this.ranges.splice(startIndex, endIndex - startIndex, range);\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 this.substractPoint = function (pos) {\n var i = this.pointIndex(pos);\n if (i >= 0) return this.ranges.splice(i, 1);\n };\n this.merge = function () {\n var removed = [];\n var list = this.ranges;\n list = list.sort(function (a, b) {\n return comparePoints(a.start, b.start);\n });\n var next = list[0],\n 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) continue;\n if (cmp == 0 && !range.isEmpty() && !next.isEmpty()) continue;\n if (comparePoints(range.end, next.end) < 0) {\n range.end.row = next.end.row;\n range.end.column = next.end.column;\n }\n list.splice(i, 1);\n removed.push(next);\n next = range;\n i--;\n }\n this.ranges = list;\n return removed;\n };\n this.contains = function (row, column) {\n return this.pointIndex({\n row: row,\n column: column\n }) >= 0;\n };\n this.containsPoint = function (pos) {\n return this.pointIndex(pos) >= 0;\n };\n this.rangeAtPoint = function (pos) {\n var i = this.pointIndex(pos);\n if (i >= 0) return this.ranges[i];\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) return [];\n var startIndex = this.pointIndex({\n row: startRow,\n column: 0\n });\n if (startIndex < 0) startIndex = -startIndex - 1;\n var endIndex = this.pointIndex({\n row: endRow,\n column: 0\n }, startIndex);\n if (endIndex < 0) endIndex = -endIndex - 1;\n var clipped = [];\n for (var i = startIndex; i < endIndex; i++) {\n clipped.push(list[i]);\n }\n return clipped;\n };\n this.removeAll = function () {\n return this.ranges.splice(0, this.ranges.length);\n };\n this.attach = function (session) {\n if (this.session) this.detach();\n this.session = session;\n this.onChange = this.$onChange.bind(this);\n this.session.on('change', this.onChange);\n };\n this.detach = function () {\n if (!this.session) return;\n this.session.removeListener('change', this.onChange);\n this.session = null;\n };\n this.$onChange = function (delta) {\n if (delta.action == \"insert\") {\n var start = delta.start;\n var end = delta.end;\n } else {\n var end = delta.start;\n var start = delta.end;\n }\n var startRow = start.row;\n var endRow = end.row;\n var lineDif = endRow - startRow;\n var colDiff = -start.column + end.column;\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) continue;\n if (r.start.row > startRow) break;\n if (r.start.row == startRow && r.start.column >= start.column) {\n if (r.start.column == start.column && this.$insertRight) {} 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.$insertRight) {\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) r.end.column -= colDiff;\n }\n r.end.column += colDiff;\n r.end.row += lineDif;\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 }).call(RangeList.prototype);\n exports.RangeList = RangeList;\n});\nace.define(\"ace/edit_session/fold\", [\"require\", \"exports\", \"module\", \"ace/range\", \"ace/range_list\", \"ace/lib/oop\"], function (acequire, exports, module) {\n \"use strict\";\n\n var Range = acequire(\"../range\").Range;\n var RangeList = acequire(\"../range_list\").RangeList;\n var oop = acequire(\"../lib/oop\");\n var 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 this.sameRow = range.start.row == range.end.row;\n this.subFolds = this.ranges = [];\n };\n oop.inherits(Fold, RangeList);\n (function () {\n this.toString = function () {\n return '\"' + this.placeholder + '\" ' + this.range.toString();\n };\n this.setFoldLine = function (foldLine) {\n this.foldLine = foldLine;\n this.subFolds.forEach(function (fold) {\n fold.setFoldLine(foldLine);\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 this.addSubFold = function (fold) {\n if (this.range.isEqual(fold)) return;\n if (!this.range.containsRange(fold)) throw new Error(\"A fold can't intersect already existing fold\" + fold.range + this.range);\n consumeRange(fold, this.start);\n var row = fold.start.row,\n 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) break;\n }\n var afterStart = this.subFolds[i];\n if (cmp == 0) return afterStart.addSubFold(fold);\n var row = fold.range.end.row,\n 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) break;\n }\n var afterEnd = this.subFolds[j];\n if (cmp == 0) throw new Error(\"A fold can't intersect already existing fold\" + fold.range + this.range);\n var consumedFolds = this.subFolds.splice(i, j - i, fold);\n fold.setFoldLine(this.foldLine);\n return fold;\n };\n this.restoreRange = function (range) {\n return restoreRange(range, this.start);\n };\n }).call(Fold.prototype);\n function consumePoint(point, anchor) {\n point.row -= anchor.row;\n if (point.row == 0) point.column -= anchor.column;\n }\n function consumeRange(range, anchor) {\n consumePoint(range.start, anchor);\n consumePoint(range.end, anchor);\n }\n function restorePoint(point, anchor) {\n if (point.row == 0) point.column += anchor.column;\n point.row += anchor.row;\n }\n function restoreRange(range, anchor) {\n restorePoint(range.start, anchor);\n restorePoint(range.end, anchor);\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 (acequire, exports, module) {\n \"use strict\";\n\n var Range = acequire(\"../range\").Range;\n var FoldLine = acequire(\"./fold_line\").FoldLine;\n var Fold = acequire(\"./fold\").Fold;\n var TokenIterator = acequire(\"../token_iterator\").TokenIterator;\n function Folding() {\n this.getFoldAt = function (row, column, side) {\n var foldLine = this.getFoldLine(row);\n if (!foldLine) return null;\n var folds = foldLine.folds;\n for (var i = 0; i < folds.length; i++) {\n var fold = folds[i];\n if (fold.range.contains(row, column)) {\n if (side == 1 && fold.range.isEnd(row, column)) {\n continue;\n } else if (side == -1 && fold.range.isStart(row, column)) {\n continue;\n }\n return fold;\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 start.column += 1;\n end.column -= 1;\n for (var i = 0; i < foldLines.length; i++) {\n var cmp = foldLines[i].range.compareRange(range);\n if (cmp == 2) {\n continue;\n } else if (cmp == -2) {\n break;\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 if (cmp == 42) {\n break;\n }\n foundFolds.push(fold);\n }\n }\n start.column -= 1;\n end.column += 1;\n return foundFolds;\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 for (var i = 0; i < foldLines.length; i++) for (var j = 0; j < foldLines[i].folds.length; j++) folds.push(foldLines[i].folds[j]);\n return folds;\n };\n this.getFoldStringAt = function (row, column, trim, foldLine) {\n foldLine = foldLine || this.getFoldLine(row);\n if (!foldLine) return null;\n var lastFold = {\n end: {\n column: 0\n }\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.getLine(fold.start.row).substring(lastFold.end.column, fold.start.column);\n break;\n } else if (cmp === 0) {\n return null;\n }\n lastFold = fold;\n }\n if (!str) str = this.getLine(fold.start.row).substring(lastFold.end.column);\n if (trim == -1) return str.substring(0, column - lastFold.end.column);else if (trim == 1) return str.substring(column - lastFold.end.column);else return str;\n };\n this.getFoldLine = function (docRow, startFoldLine) {\n var foldData = this.$foldData;\n var i = 0;\n if (startFoldLine) i = foldData.indexOf(startFoldLine);\n if (i == -1) 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) i = foldData.indexOf(startFoldLine);\n if (i == -1) 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 this.getFoldedRowCount = function (first, last) {\n var foldData = this.$foldData,\n 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) rowCount -= last - start;else rowCount = 0; // in one fold\n }\n break;\n } else if (end >= first) {\n if (start >= first)\n // fold inside range\n rowCount -= end - start;else rowCount -= end - first + 1;\n }\n }\n return rowCount;\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 if (placeholder instanceof Fold) fold = placeholder;else {\n fold = new Fold(range, placeholder);\n fold.collapseChildren = range.collapseChildren;\n }\n this.$clipRangeToDocument(fold.range);\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 if (!(startRow < endRow || startRow == endRow && startColumn <= endColumn - 2)) throw new Error(\"The range has to be at least 2 characters width\");\n var startFold = this.getFoldAt(startRow, startColumn, 1);\n var endFold = this.getFoldAt(endRow, endColumn, -1);\n if (startFold && endFold == startFold) return startFold.addSubFold(fold);\n if (startFold && !startFold.range.isStart(startRow, startColumn)) this.removeFold(startFold);\n if (endFold && !endFold.range.isEnd(endRow, endColumn)) 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 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 if (!added) foldLine = this.$addFoldLine(new FoldLine(this.$foldData, fold));\n if (this.$useWrapMode) this.$updateWrapData(foldLine.start.row, foldLine.start.row);else this.$updateRowLengthCache(foldLine.start.row, foldLine.start.row);\n this.$modified = true;\n this._signal(\"changeFold\", {\n data: fold,\n action: \"add\"\n });\n return fold;\n };\n this.addFolds = function (folds) {\n folds.forEach(function (fold) {\n this.addFold(fold);\n }, this);\n };\n this.removeFold = function (fold) {\n var foldLine = fold.foldLine;\n var startRow = foldLine.start.row;\n var endRow = foldLine.end.row;\n var foldLines = this.$foldData;\n var folds = foldLine.folds;\n if (folds.length == 1) {\n foldLines.splice(foldLines.indexOf(foldLine), 1);\n } else 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 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 if (fold.sameRow) {\n folds.splice(folds.indexOf(fold), 1);\n } else {\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 if (!this.$updating) {\n if (this.$useWrapMode) this.$updateWrapData(startRow, endRow);else this.$updateRowLengthCache(startRow, endRow);\n }\n this.$modified = true;\n this._signal(\"changeFold\", {\n data: fold,\n 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 cloneFolds.forEach(function (fold) {\n this.removeFold(fold);\n }, this);\n this.$modified = true;\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 this.expandFolds = function (folds) {\n folds.forEach(function (fold) {\n this.expandFold(fold);\n }, this);\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\") range = new Range(location, 0, location, this.getLine(location).length);else if (\"row\" in location) range = Range.fromPoints(location, location);else range = location;\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) return folds;\n };\n this.isRowFolded = function (docRow, startFoldRow) {\n return !!this.getFoldLine(docRow, startFoldRow);\n };\n this.getRowFoldEnd = function (docRow, startFoldRow) {\n var foldLine = this.getFoldLine(docRow, startFoldRow);\n return foldLine ? foldLine.end.row : docRow;\n };\n this.getRowFoldStart = function (docRow, startFoldRow) {\n var foldLine = this.getFoldLine(docRow, startFoldRow);\n return foldLine ? foldLine.start.row : docRow;\n };\n this.getFoldDisplayLine = function (foldLine, endRow, endColumn, startRow, startColumn) {\n if (startRow == null) startRow = foldLine.start.row;\n if (startColumn == null) startColumn = 0;\n if (endRow == null) endRow = foldLine.end.row;\n if (endColumn == null) endColumn = this.getLine(endRow).length;\n var doc = this.doc;\n var textLine = \"\";\n foldLine.walk(function (placeholder, row, column, lastColumn) {\n if (row < startRow) return;\n if (row == startRow) {\n if (column < startColumn) return;\n lastColumn = Math.max(startColumn, lastColumn);\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 this.getDisplayLine = function (row, endColumn, startRow, startColumn) {\n var foldLine = this.getFoldLine(row);\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(foldLine, row, endColumn, startRow, startColumn);\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 return fd;\n };\n this.toggleFold = function (tryToUnfold) {\n var selection = this.selection;\n var range = selection.getRange();\n var fold;\n var bracketPos;\n if (range.isEmpty()) {\n var cursor = range.start;\n fold = this.getFoldAt(cursor.row, cursor.column);\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({\n row: cursor.row,\n column: cursor.column + 1\n })) {\n if (range.comparePoint(bracketPos) == 1) range.end = bracketPos;else range.start = bracketPos;\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 if (!fold) fold = this.getFoldAt(range.start.row, range.start.column);\n if (fold && fold.range.toString() == range.toString()) {\n this.expandFold(fold);\n return;\n }\n var placeholder = \"...\";\n if (!range.isMultiLine()) {\n placeholder = this.getTextRange(range);\n if (placeholder.length < 4) return;\n placeholder = placeholder.trim().substring(0, 2) + \"..\";\n }\n this.addFold(placeholder, range);\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\") 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 range.start.row = iterator.getCurrentTokenRow();\n range.start.column = iterator.getCurrentTokenColumn() + 2;\n iterator = new TokenIterator(this, row, column);\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)) 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 token = iterator.getCurrentToken();\n range.end.row = iterator.getCurrentTokenRow();\n range.end.column = iterator.getCurrentTokenColumn() + token.value.length - 2;\n return range;\n }\n };\n this.foldAll = function (startRow, endRow, depth) {\n if (depth == undefined) depth = 100000; // JSON.stringify doesn't hanle Infinity\n var foldWidgets = this.foldWidgets;\n if (!foldWidgets) 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) foldWidgets[row] = this.getFoldWidget(row);\n if (foldWidgets[row] != \"start\") continue;\n var range = this.getFoldWidgetRange(row);\n if (range && range.isMultiLine() && range.end.row <= endRow && range.start.row >= startRow) {\n row = range.end.row;\n try {\n var fold = this.addFold(\"...\", range);\n if (fold) 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]) throw new Error(\"invalid fold style: \" + style + \"[\" + Object.keys(this.$foldStyles).join(\", \") + \"]\");\n if (this.$foldStyle == style) return;\n this.$foldStyle = style;\n if (style == \"manual\") this.unfold();\n var mode = this.$foldMode;\n this.$setFolding(null);\n this.$setFolding(mode);\n };\n this.$setFolding = function (foldMode) {\n if (this.$foldMode == foldMode) return;\n this.$foldMode = foldMode;\n this.off('change', this.$updateFoldWidgets);\n this.off('tokenizerUpdate', this.$tokenizerUpdateFoldWidgets);\n this._signal(\"changeAnnotation\");\n if (!foldMode || this.$foldStyle == \"manual\") {\n this.foldWidgets = null;\n return;\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 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 this.getParentFoldRangeData = function (row, ignoreCurrent) {\n var fw = this.foldWidgets;\n if (!fw || ignoreCurrent && fw[row]) return {};\n var i = row - 1,\n firstRange;\n while (i >= 0) {\n var c = fw[i];\n if (c == null) c = fw[i] = this.getFoldWidget(i);\n if (c == \"start\") {\n var range = this.getFoldWidgetRange(i);\n if (!firstRange) firstRange = range;\n if (range && range.end.row >= row) break;\n }\n i--;\n }\n return {\n range: i !== -1 && range,\n firstRange: firstRange\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 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)) el.className += \" ace_invalid\";\n }\n };\n this.$toggleFoldWidget = function (row, options) {\n if (!this.getFoldWidget) return;\n var type = this.getFoldWidget(row);\n var line = this.getLine(row);\n var dir = type === \"end\" ? -1 : 1;\n var fold = this.getFoldAt(row, dir === -1 ? 0 : line.length, dir);\n if (fold) {\n if (options.children || options.all) this.removeFold(fold);else this.expandFold(fold);\n return fold;\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 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) range.collapseChildren = 10000;\n this.addFold(\"...\", range);\n }\n return range;\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 if (range) return;\n var data = this.getParentFoldRangeData(row, true);\n range = data.range || data.firstRange;\n if (range) {\n row = range.start.row;\n var fold = this.getFoldAt(row, this.getLine(row).length, 1);\n if (fold) {\n this.removeFold(fold);\n } else {\n this.addFold(\"...\", range);\n }\n }\n };\n this.updateFoldWidgets = function (delta) {\n var firstRow = delta.start.row;\n var len = delta.end.row - firstRow;\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) this.foldWidgets.splice(rows.first, this.foldWidgets.length);\n }\n };\n }\n exports.Folding = Folding;\n});\nace.define(\"ace/edit_session/bracket_match\", [\"require\", \"exports\", \"module\", \"ace/token_iterator\", \"ace/range\"], function (acequire, exports, module) {\n \"use strict\";\n\n var TokenIterator = acequire(\"../token_iterator\").TokenIterator;\n var Range = acequire(\"../range\").Range;\n function BracketMatch() {\n this.findMatchingBracket = function (position, chr) {\n if (position.column == 0) return null;\n var charBeforeCursor = chr || this.getLine(position.row).charAt(position.column - 1);\n if (charBeforeCursor == \"\") return null;\n var match = charBeforeCursor.match(/([\\(\\[\\{])|([\\)\\]\\}])/);\n if (!match) return null;\n if (match[1]) return this.$findClosingBracket(match[1], position);else return this.$findOpeningBracket(match[2], position);\n };\n this.getBracketRange = function (pos) {\n var line = this.getLine(pos.row);\n var before = true,\n range;\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 = {\n row: pos.row,\n column: pos.column + 1\n };\n match = chr && chr.match(/([\\(\\[\\{])|([\\)\\]\\}])/);\n before = false;\n }\n if (!match) return null;\n if (match[1]) {\n var bracketPos = this.$findClosingBracket(match[1], pos);\n if (!bracketPos) 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) 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 return range;\n };\n this.$brackets = {\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 var iterator = new TokenIterator(this, position.row, position.column);\n var token = iterator.getCurrentToken();\n if (!token) token = iterator.stepForward();\n if (!token) return;\n if (!typeRe) {\n typeRe = new RegExp(\"(\\\\.?\" + token.type.replace(\".\", \"\\\\.\").replace(\"rparen\", \".paren\").replace(/\\b(?:end)\\b/, \"(?:start|begin|end)\") + \")+\");\n }\n var valueIndex = position.column - iterator.getCurrentTokenColumn() - 2;\n var value = token.value;\n while (true) {\n while (valueIndex >= 0) {\n var chr = value.charAt(valueIndex);\n if (chr == openBracket) {\n depth -= 1;\n if (depth == 0) {\n return {\n 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 if (token == null) break;\n value = token.value;\n valueIndex = value.length - 1;\n }\n return null;\n };\n this.$findClosingBracket = function (bracket, position, typeRe) {\n var closingBracket = this.$brackets[bracket];\n var depth = 1;\n var iterator = new TokenIterator(this, position.row, position.column);\n var token = iterator.getCurrentToken();\n if (!token) token = iterator.stepForward();\n if (!token) return;\n if (!typeRe) {\n typeRe = new RegExp(\"(\\\\.?\" + token.type.replace(\".\", \"\\\\.\").replace(\"lparen\", \".paren\").replace(/\\b(?:start|begin)\\b/, \"(?:start|begin|end)\") + \")+\");\n }\n var valueIndex = position.column - iterator.getCurrentTokenColumn();\n while (true) {\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 {\n 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 if (token == null) break;\n valueIndex = 0;\n }\n return null;\n };\n }\n exports.BracketMatch = BracketMatch;\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 (acequire, exports, module) {\n \"use strict\";\n\n var oop = acequire(\"./lib/oop\");\n var lang = acequire(\"./lib/lang\");\n var BidiHandler = acequire(\"./bidihandler\").BidiHandler;\n var config = acequire(\"./config\");\n var EventEmitter = acequire(\"./lib/event_emitter\").EventEmitter;\n var Selection = acequire(\"./selection\").Selection;\n var TextMode = acequire(\"./mode/text\").Mode;\n var Range = acequire(\"./range\").Range;\n var Document = acequire(\"./document\").Document;\n var BackgroundTokenizer = acequire(\"./background_tokenizer\").BackgroundTokenizer;\n var SearchHighlight = acequire(\"./search_highlight\").SearchHighlight;\n var 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 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 if (typeof text != \"object\" || !text.getLine) text = new Document(text);\n this.$bidiHandler = new BidiHandler(this);\n this.setDocument(text);\n this.selection = new Selection(this);\n config.resetOptions(this);\n this.setMode(mode);\n config._signal(\"session\", this);\n };\n EditSession.$uid = 0;\n (function () {\n oop.implement(this, EventEmitter);\n this.setDocument = function (doc) {\n if (this.doc) this.doc.removeListener(\"change\", this.$onChange);\n this.doc = doc;\n doc.on(\"change\", this.$onChange);\n if (this.bgTokenizer) this.bgTokenizer.setDocument(this.getDocument());\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 this.$getRowCacheIndex = function (cacheArray, val) {\n var low = 0;\n var hi = cacheArray.length - 1;\n while (low <= hi) {\n var mid = low + hi >> 1;\n var c = cacheArray[mid];\n if (val > c) low = mid + 1;else if (val < c) hi = mid - 1;else return mid;\n }\n return low - 1;\n };\n this.resetCaches = function () {\n this.$modified = true;\n this.$wrapData = [];\n this.$rowLengthCache = [];\n this.$resetRowCache(0);\n if (this.bgTokenizer) this.bgTokenizer.start(0);\n };\n this.onChangeFold = function (e) {\n var fold = e.data;\n this.$resetRowCache(fold.start.row);\n };\n this.onChange = function (delta) {\n this.$modified = true;\n this.$bidiHandler.onChange(delta);\n this.$resetRowCache(delta.start.row);\n var removedFolds = this.$updateInternalDataOnChange(delta);\n if (!this.$fromUndo && this.$undoManager && !delta.ignore) {\n this.$deltasDoc.push(delta);\n if (removedFolds && removedFolds.length != 0) {\n this.$deltasFold.push({\n action: \"removeFolds\",\n folds: removedFolds\n });\n }\n this.$informUndoManager.schedule();\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 this.$resetRowCache(0);\n this.$deltas = [];\n this.$deltasDoc = [];\n this.$deltasFold = [];\n this.setUndoManager(this.$undoManager);\n this.getUndoManager().reset();\n };\n this.getValue = 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,\n 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) break;\n }\n }\n token = tokens[i];\n if (!token) 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 this.$deltas = [];\n this.$deltasDoc = [];\n this.$deltasFold = [];\n if (this.$informUndoManager) this.$informUndoManager.cancel();\n if (undoManager) {\n var self = this;\n this.$syncInformUndoManager = function () {\n self.$informUndoManager.cancel();\n if (self.$deltasFold.length) {\n self.$deltas.push({\n group: \"fold\",\n deltas: self.$deltasFold\n });\n self.$deltasFold = [];\n }\n if (self.$deltasDoc.length) {\n self.$deltas.push({\n group: \"doc\",\n deltas: self.$deltasDoc\n });\n self.$deltasDoc = [];\n }\n if (self.$deltas.length > 0) {\n undoManager.execute({\n action: \"aceupdate\",\n args: [self.$deltas, self],\n merge: self.mergeUndoDeltas\n });\n }\n self.mergeUndoDeltas = false;\n self.$deltas = [];\n };\n this.$informUndoManager = lang.delayedCall(this.$syncInformUndoManager);\n }\n };\n this.markUndoGroup = function () {\n if (this.$syncInformUndoManager) this.$syncInformUndoManager();\n };\n this.$defaultUndoManager = {\n undo: function () {},\n redo: function () {},\n reset: 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 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]) 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) className = \"ace_breakpoint\";\n if (className) this.$breakpoints[row] = className;else 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 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 if (inFront) {\n this.$frontMarkers[id] = marker;\n this._signal(\"changeFrontMarker\");\n } else {\n this.$backMarkers[id] = marker;\n this._signal(\"changeBackMarker\");\n }\n return id;\n };\n this.addDynamicMarker = function (marker, inFront) {\n if (!marker.update) return;\n var id = this.$markerId++;\n marker.id = id;\n marker.inFront = !!inFront;\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 return marker;\n };\n this.removeMarker = function (markerId) {\n var marker = this.$frontMarkers[markerId] || this.$backMarkers[markerId];\n if (!marker) return;\n var markers = marker.inFront ? this.$frontMarkers : this.$backMarkers;\n if (marker) {\n delete markers[markerId];\n this._signal(marker.inFront ? \"changeFrontMarker\" : \"changeBackMarker\");\n }\n };\n this.getMarkers = function (inFront) {\n return inFront ? this.$frontMarkers : this.$backMarkers;\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) clazz = \"ace_step\";\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 var inToken = false;\n if (column > 0) inToken = !!line.charAt(column - 1).match(this.tokenRe);\n if (!inToken) inToken = !!line.charAt(column).match(this.tokenRe);\n if (inToken) var re = this.tokenRe;else if (/^\\s+$/.test(line.slice(column - 1, column + 1))) var re = /\\s/;else var re = this.nonTokenRe;\n var start = column;\n if (start > 0) {\n do {\n start--;\n } while (start >= 0 && line.charAt(start).match(re));\n start++;\n }\n var end = column;\n while (end < line.length && line.charAt(end).match(re)) {\n end++;\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 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) {\n this.setOption(\"useWorker\", useWorker);\n };\n this.getUseWorker = function () {\n return this.$useWorker;\n };\n this.onReloadTokenizer = function (e) {\n var rows = e.data;\n this.bgTokenizer.start(rows.first);\n this._signal(\"tokenizerUpdate\", e);\n };\n this.$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) 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\"]) this.$modes[\"ace/mode/text\"] = new TextMode();\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) 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) this.$onChangeMode(this.$modes[\"ace/mode/text\"], true);\n };\n this.$onChangeMode = function (mode, $isPlaceholder) {\n if (!$isPlaceholder) this.$modeId = mode.$id;\n if (this.$mode === mode) return;\n this.$mode = mode;\n this.$stopWorker();\n if (this.$useWorker) this.$startWorker();\n var tokenizer = mode.getTokenizer();\n if (tokenizer.addEventListener !== undefined) {\n var onReloadTokenizer = this.onReloadTokenizer.bind(this);\n tokenizer.addEventListener(\"update\", onReloadTokenizer);\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 this.bgTokenizer.setDocument(this.getDocument());\n this.tokenRe = mode.tokenRe;\n this.nonTokenRe = mode.nonTokenRe;\n if (!$isPlaceholder) {\n if (mode.attachToSession) 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 this.$stopWorker = function () {\n if (this.$worker) {\n this.$worker.terminate();\n this.$worker = null;\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 this.$scrollTop = 0;\n this.setScrollTop = function (scrollTop) {\n if (this.$scrollTop === scrollTop || isNaN(scrollTop)) return;\n this.$scrollTop = scrollTop;\n this._signal(\"changeScrollTop\", scrollTop);\n };\n this.getScrollTop = function () {\n return this.$scrollTop;\n };\n this.$scrollLeft = 0;\n this.setScrollLeft = function (scrollLeft) {\n if (this.$scrollLeft === scrollLeft || isNaN(scrollLeft)) return;\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) return Math.max(this.getLineWidgetMaxWidth(), this.screenWidth);\n return this.screenWidth;\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) width = w.screenWidth;\n });\n return this.lineWidgetWidth = width;\n };\n this.$computeWidth = function (force) {\n if (this.$modified || force) {\n this.$modified = false;\n if (this.$useWrapMode) return this.screenWidth = this.$wrapLimit;\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 for (var i = 0; i < len; i++) {\n if (i > foldStart) {\n i = foldLine.end.row + 1;\n if (i >= len) break;\n foldLine = this.$foldData[foldIndex++];\n foldStart = foldLine ? foldLine.start.row : Infinity;\n }\n if (cache[i] == null) cache[i] = this.$getStringScreenWidth(lines[i])[0];\n if (cache[i] > longestScreenLine) 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) return;\n this.$fromUndo = true;\n var lastUndoRange = null;\n for (var i = deltas.length - 1; i != -1; i--) {\n var delta = deltas[i];\n if (delta.group == \"doc\") {\n this.doc.revertDeltas(delta.deltas);\n lastUndoRange = this.$getUndoSelection(delta.deltas, true, lastUndoRange);\n } else {\n delta.deltas.forEach(function (foldDelta) {\n this.addFolds(foldDelta.folds);\n }, this);\n }\n }\n this.$fromUndo = false;\n lastUndoRange && this.$undoSelect && !dontSelect && this.selection.setSelectionRange(lastUndoRange);\n return lastUndoRange;\n };\n this.redoChanges = function (deltas, dontSelect) {\n if (!deltas.length) return;\n this.$fromUndo = true;\n var lastUndoRange = null;\n for (var i = 0; i < deltas.length; i++) {\n var delta = deltas[i];\n if (delta.group == \"doc\") {\n this.doc.applyDeltas(delta.deltas);\n lastUndoRange = this.$getUndoSelection(delta.deltas, false, lastUndoRange);\n }\n }\n this.$fromUndo = false;\n lastUndoRange && this.$undoSelect && !dontSelect && this.selection.setSelectionRange(lastUndoRange);\n return lastUndoRange;\n };\n this.setUndoSelect = function (enable) {\n this.$undoSelect = enable;\n };\n this.$getUndoSelection = function (deltas, isUndo, lastUndoRange) {\n function isInsert(delta) {\n return isUndo ? delta.action !== \"insert\" : delta.action === \"insert\";\n }\n var delta = deltas[0];\n var range, point;\n var lastDeltaIsInsert = false;\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 for (var i = 1; i < deltas.length; i++) {\n delta = deltas[i];\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 if (lastUndoRange != null) {\n if (Range.comparePoints(lastUndoRange.start, range.start) === 0) {\n lastUndoRange.start.column += range.end.column - range.start.column;\n lastUndoRange.end.column += range.end.column - range.start.column;\n }\n var cmp = lastUndoRange.compareRange(range);\n if (cmp == 1) {\n range.setStart(lastUndoRange.start);\n } else if (cmp == -1) {\n range.setEnd(lastUndoRange.end);\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 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) toRange.start.column += collDiff;\n if (toRange.end.row == fromRange.end.row && toRange.end.column > fromRange.end.column) 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 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) x.start.column += collDiff;\n if (x.end.row == oldStart.row) x.end.column += collDiff;\n x.start.row += rowDiff;\n x.end.row += rowDiff;\n return x;\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++) this.doc.insertInLine({\n row: row,\n column: 0\n }, 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 for (var i = rowRange.start.row; i <= rowRange.end.row; ++i) {\n var line = this.getLine(i);\n deleteRange.start.row = i;\n deleteRange.end.row = i;\n for (var j = 0; j < size; ++j) if (line.charAt(j) != ' ') 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 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 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 var lines = dir == 0 ? this.doc.getLines(firstRow, lastRow) : 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 this.$clipRowToDocument = function (row) {\n return Math.max(0, Math.min(row, this.doc.getLength() - 1));\n };\n this.$clipColumnToRow = function (row, column) {\n if (column < 0) return 0;\n return Math.min(this.doc.getLine(row).length, column);\n };\n this.$clipPositionToDocument = function (row, column) {\n column = Math.max(0, column);\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 return {\n row: row,\n column: column\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(range.start.row, range.start.column);\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(range.end.row, range.end.column);\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 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 = {\n min: min,\n max: max\n };\n this.$modified = true;\n this.$bidiHandler.markAsDirty();\n if (this.$useWrapMode) this._signal(\"changeWrapMode\");\n }\n };\n this.adjustWrapLimit = function (desiredLimit, $printMargin) {\n var limits = this.$wrapLimitRange;\n if (limits.max < 0) limits = {\n min: $printMargin,\n max: $printMargin\n };\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 this.$constrainWrapLimit = function (wrapLimit, min, max) {\n if (min) wrapLimit = Math.max(min, wrapLimit);\n if (max) wrapLimit = Math.min(max, wrapLimit);\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 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 this.$updating = true;\n if (len != 0) {\n if (action === \"remove\") {\n this[useWrapMode ? \"$wrapData\" : \"$rowLengthCache\"].splice(firstRow, len);\n var foldLines = this.$foldData;\n removedFolds = this.getFoldsInRange(delta);\n this.removeFolds(removedFolds);\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 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 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 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 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 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 len = -len;\n }\n var foldLine = this.getFoldLine(firstRow);\n if (foldLine) {\n foldLine.addRemoveChars(firstRow, start.column, len);\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 if (useWrapMode) this.$updateWrapData(firstRow, lastRow);else this.$updateRowLengthCache(firstRow, lastRow);\n return removedFolds;\n };\n this.$updateRowLengthCache = function (firstRow, lastRow, b) {\n this.$rowLengthCache[firstRow] = null;\n this.$rowLengthCache[lastRow] = null;\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 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(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(lines[row].substring(lastColumn, column), tokens.length);\n }\n tokens = tokens.concat(walkTokens);\n }.bind(this), foldLine.end.row, lines[foldLine.end.row].length + 1);\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 this.$computeWrapSplits = function (tokens, wrapLimit, tabSize) {\n if (tokens.length == 0) {\n return [];\n }\n var splits = [];\n var displayLength = tokens.length;\n var lastSplit = 0,\n lastDocSplit = 0;\n var isCode = this.$wrapAsCode;\n var indentedSoftWrap = this.$indentedSoftWrap;\n var maxIndent = wrapLimit <= Math.max(2 * tabSize, 8) || indentedSoftWrap === false ? 0 : Math.floor(wrapLimit / 2);\n function getWrapIndent() {\n var indentation = 0;\n if (maxIndent === 0) return indentation;\n if (indentedSoftWrap) {\n for (var i = 0; i < tokens.length; i++) {\n var token = tokens[i];\n if (token == SPACE) indentation += 1;else if (token == TAB) indentation += tabSize;else if (token == TAB_SPACE) continue;else break;\n }\n }\n if (isCode && indentedSoftWrap !== false) indentation += tabSize;\n return Math.min(indentation, maxIndent);\n }\n function addSplit(screenPos) {\n var displayed = tokens.slice(lastSplit, screenPos);\n var len = displayed.length;\n displayed.join(\"\").replace(/12/g, function () {\n len -= 1;\n }).replace(/2/g, function () {\n len -= 1;\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) 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 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 } else if (c == 32) {\n arr.push(SPACE);\n } else if (c > 39 && c < 48 || c > 57 && c < 64) {\n arr.push(PUNCTUATION);\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) return [0, 0];\n if (maxScreenColumn == null) maxScreenColumn = Infinity;\n screenColumn = screenColumn || 0;\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 } else if (c >= 0x1100 && isFullWidth(c)) {\n screenColumn += 2;\n } else {\n screenColumn += 1;\n }\n if (screenColumn > maxScreenColumn) {\n break;\n }\n }\n return [screenColumn, column];\n };\n this.lineWidgets = null;\n this.getRowLength = function (row) {\n if (this.lineWidgets) var h = this.lineWidgets[row] && this.lineWidgets[row].rowCount || 0;else 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 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 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;\n };\n this.screenToDocumentRow = function (screenRow, screenColumn) {\n return this.screenToDocumentPosition(screenRow, screenColumn).row;\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) return {\n row: 0,\n 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 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 var maxRow = this.getLength() - 1;\n var foldLine = this.getNextFoldLine(docRow);\n var foldStart = foldLine ? foldLine.start.row : Infinity;\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 if (doCache) {\n this.$docRowCache.push(docRow);\n this.$screenRowCache.push(row);\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,\n 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 if (offsetX !== undefined && this.$bidiHandler.isBidiRow(row + splitIndex, docRow, splitIndex)) screenColumn = this.$bidiHandler.offsetToCol(offsetX);\n docColumn += this.$getStringScreenWidth(line, screenColumn - wrapIndent)[1];\n if (this.$useWrapMode && docColumn >= column) docColumn = column - 1;\n if (foldLine) return foldLine.idxToPosition(docColumn);\n return {\n row: docRow,\n column: docColumn\n };\n };\n this.documentToScreenPosition = function (docRow, docColumn) {\n if (typeof docColumn === \"undefined\") var pos = this.$clipPositionToDocument(docRow.row, docRow.column);else pos = this.$clipPositionToDocument(docRow, docColumn);\n docRow = pos.row;\n docColumn = pos.column;\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 var rowEnd,\n row = 0;\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 var foldLine = this.getNextFoldLine(row);\n var foldStart = foldLine ? foldLine.start.row : Infinity;\n while (row < docRow) {\n if (row >= foldStart) {\n rowEnd = foldLine.end.row + 1;\n if (rowEnd > docRow) break;\n foldLine = this.getNextFoldLine(rowEnd, foldLine);\n foldStart = foldLine ? foldLine.start.row : Infinity;\n } else {\n rowEnd = row + 1;\n }\n screenRow += this.getRowLength(row);\n row = rowEnd;\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(wrapRow[screenRowOffset - 1] || 0, textLine.length);\n wrapIndent = screenRowOffset > 0 ? wrapRow.indent : 0;\n }\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,\n i = 0;\n var fold = this.$foldData[i++];\n var foldStart = fold ? fold.start.row : Infinity;\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) screenRows += this.$getWidgetScreenLength();\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) return [0, 0];\n if (!maxScreenColumn) maxScreenColumn = Infinity;\n screenColumn = screenColumn || 0;\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 return [screenColumn, column];\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 this.isFullWidth = isFullWidth;\n function isFullWidth(c) {\n if (c < 0x1100) return false;\n return c >= 0x1100 && c <= 0x115F || c >= 0x11A3 && c <= 0x11A7 || c >= 0x11FA && c <= 0x11FF || c >= 0x2329 && c <= 0x232A || c >= 0x2E80 && c <= 0x2E99 || c >= 0x2E9B && c <= 0x2EF3 || c >= 0x2F00 && c <= 0x2FD5 || c >= 0x2FF0 && c <= 0x2FFB || c >= 0x3000 && c <= 0x303E || c >= 0x3041 && c <= 0x3096 || c >= 0x3099 && c <= 0x30FF || c >= 0x3105 && c <= 0x312D || c >= 0x3131 && c <= 0x318E || c >= 0x3190 && c <= 0x31BA || c >= 0x31C0 && c <= 0x31E3 || c >= 0x31F0 && c <= 0x321E || c >= 0x3220 && c <= 0x3247 || c >= 0x3250 && c <= 0x32FE || c >= 0x3300 && c <= 0x4DBF || c >= 0x4E00 && c <= 0xA48C || c >= 0xA490 && c <= 0xA4C6 || c >= 0xA960 && c <= 0xA97C || c >= 0xAC00 && c <= 0xD7A3 || c >= 0xD7B0 && c <= 0xD7C6 || c >= 0xD7CB && c <= 0xD7FB || c >= 0xF900 && c <= 0xFAFF || c >= 0xFE10 && c <= 0xFE19 || c >= 0xFE30 && c <= 0xFE52 || c >= 0xFE54 && c <= 0xFE66 || c >= 0xFE68 && c <= 0xFE6B || c >= 0xFF01 && c <= 0xFF60 || c >= 0xFFE0 && c <= 0xFFE6;\n }\n }).call(EditSession.prototype);\n acequire(\"./edit_session/folding\").Folding.call(EditSession.prototype);\n acequire(\"./edit_session/bracket_match\").BracketMatch.call(EditSession.prototype);\n config.defineOptions(EditSession.prototype, \"session\", {\n wrap: {\n set: function (value) {\n if (!value || value == \"off\") value = false;else if (value == \"free\") value = true;else if (value == \"printMargin\") value = -1;else if (typeof value == \"string\") value = parseInt(value, 10) || false;\n if (this.$wrap == value) 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) return \"printMargin\";\n if (!this.getWrapLimitRange().min) 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\" ? this.$mode.type != \"text\" : val != \"text\";\n if (val != this.$wrapAsCode) {\n this.$wrapAsCode = val;\n if (this.$useWrapMode) {\n this.$modified = true;\n this.$resetRowCache(0);\n this.$updateWrapData(0, this.getLength() - 1);\n }\n }\n },\n initialValue: \"auto\"\n },\n indentedSoftWrap: {\n initialValue: true\n },\n firstLineNumber: {\n set: function () {\n this._signal(\"changeBreakpoint\");\n },\n initialValue: 1\n },\n useWorker: {\n set: function (useWorker) {\n this.$useWorker = useWorker;\n this.$stopWorker();\n if (useWorker) this.$startWorker();\n },\n initialValue: true\n },\n useSoftTabs: {\n initialValue: true\n },\n tabSize: {\n set: function (tabSize) {\n if (isNaN(tabSize) || this.$tabSize === tabSize) return;\n this.$modified = true;\n this.$rowLengthCache = [];\n this.$tabSize = tabSize;\n this._signal(\"changeTabSize\");\n },\n initialValue: 4,\n handlesSet: true\n },\n navigateWithinSoftTabs: {\n initialValue: false\n },\n overwrite: {\n set: function (val) {\n this._signal(\"changeOverwrite\");\n },\n initialValue: false\n },\n newLineMode: {\n set: function (val) {\n this.doc.setNewLineMode(val);\n },\n get: function () {\n return this.doc.getNewLineMode();\n },\n handlesSet: true\n },\n mode: {\n set: function (val) {\n this.setMode(val);\n },\n get: function () {\n return this.$modeId;\n }\n }\n });\n exports.EditSession = EditSession;\n});\nace.define(\"ace/search\", [\"require\", \"exports\", \"module\", \"ace/lib/lang\", \"ace/lib/oop\", \"ace/range\"], function (acequire, exports, module) {\n \"use strict\";\n\n var lang = acequire(\"./lib/lang\");\n var oop = acequire(\"./lib/oop\");\n var Range = acequire(\"./range\").Range;\n var Search = function () {\n this.$options = {};\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) return false;\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 && options.skipCurrent != false && firstRange.isEqual(options.start)) {\n firstRange = null;\n return false;\n }\n return true;\n });\n return firstRange;\n };\n this.findAll = function (session) {\n var options = this.$options;\n if (!options.needle) return [];\n this.$assembleRegExp(options);\n var range = options.range;\n var lines = range ? session.getLines(range.start.row, range.end.row) : session.doc.getAllLines();\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++) if (lines[row + j].search(re[j]) == -1) continue outer;\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 if (prevRange && prevRange.end.row === row && prevRange.end.column > startIndex) {\n continue;\n }\n ranges.push(prevRange = new Range(row, startIndex, row + len - 1, endIndex));\n if (len > 2) 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 if (range) {\n var startColumn = range.start.column;\n var endColumn = range.start.column;\n var i = 0,\n j = ranges.length - 1;\n while (i < j && ranges[i].start.column < startColumn && ranges[i].start.row == range.start.row) i++;\n while (i < j && ranges[j].end.column > endColumn && ranges[j].end.row == range.end.row) j--;\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 return ranges;\n };\n this.replace = function (input, replacement) {\n var options = this.$options;\n var re = this.$assembleRegExp(options);\n if (options.$isMultiLine) return replacement;\n if (!re) return;\n var match = re.exec(input);\n if (!match || match[0].length != input.length) return null;\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) replacement[i] = replacement[i].toUpperCase();else replacement[i] = replacement[i].toLowerCase();\n }\n replacement = replacement.join(\"\");\n }\n return replacement;\n };\n this.$assembleRegExp = function (options, $disableFakeMultiline) {\n if (options.needle instanceof RegExp) return options.re = options.needle;\n var needle = options.needle;\n if (!options.needle) return options.re = false;\n if (!options.regExp) needle = lang.escapeRegExp(needle);\n if (options.wholeWord) needle = addWordBoundary(needle, options);\n var modifier = options.caseSensitive ? \"gm\" : \"gmi\";\n options.$isMultiLine = !$disableFakeMultiline && /[\\n\\r]/.test(needle);\n if (options.$isMultiLine) return options.re = this.$assembleMultilineRegExp(needle, modifier);\n try {\n var re = new RegExp(needle, modifier);\n } catch (e) {\n re = false;\n }\n return options.re = re;\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 this.$matchIterator = function (session, options) {\n var re = this.$assembleRegExp(options);\n if (!re) return false;\n var backwards = options.backwards == true;\n var skipCurrent = options.skipCurrent != false;\n var range = options.range;\n var start = options.start;\n if (!start) start = range ? range[backwards ? \"end\" : \"start\"] : session.selection.getRange();\n if (start.start) start = start[skipCurrent != backwards ? \"end\" : \"start\"];\n var firstRow = range ? range.start.row : 0;\n var lastRow = range ? range.end.row : session.getLength() - 1;\n if (backwards) {\n var forEach = function (callback) {\n var row = start.row;\n if (forEachInLine(row, start.column, callback)) return;\n for (row--; row >= firstRow; row--) if (forEachInLine(row, Number.MAX_VALUE, callback)) return;\n if (options.wrap == false) return;\n for (row = lastRow, firstRow = start.row; row >= firstRow; row--) if (forEachInLine(row, Number.MAX_VALUE, callback)) return;\n };\n } else {\n var forEach = function (callback) {\n var row = start.row;\n if (forEachInLine(row, start.column, callback)) return;\n for (row = row + 1; row <= lastRow; row++) if (forEachInLine(row, 0, callback)) return;\n if (options.wrap == false) return;\n for (row = firstRow, lastRow = start.row; row <= lastRow; row++) if (forEachInLine(row, 0, callback)) return;\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) 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)) return true;\n };\n } else if (backwards) {\n var forEachInLine = function (row, endIndex, callback) {\n var line = session.getLine(row);\n var matches = [];\n var m,\n 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) 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)) return true;\n }\n };\n } else {\n var forEachInLine = function (row, startIndex, callback) {\n var line = session.getLine(row);\n var m;\n var last = startIndex;\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)) return true;\n if (!length) {\n re.lastIndex = last += 1;\n if (last >= line.length) return false;\n }\n }\n };\n }\n return {\n forEach: forEach\n };\n };\n }).call(Search.prototype);\n function 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 + wordBoundary(needle[needle.length - 1]);\n }\n exports.Search = Search;\n});\nace.define(\"ace/keyboard/hash_handler\", [\"require\", \"exports\", \"module\", \"ace/lib/keys\", \"ace/lib/useragent\"], function (acequire, exports, module) {\n \"use strict\";\n\n var keyUtil = acequire(\"../lib/keys\");\n var useragent = acequire(\"../lib/useragent\");\n var KEY_MODS = keyUtil.KEY_MODS;\n function 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 function MultiHashHandler(config, platform) {\n HashHandler.call(this, config, platform);\n this.$singleCommand = false;\n }\n MultiHashHandler.prototype = HashHandler.prototype;\n (function () {\n this.addCommand = function (command) {\n if (this.commands[command.name]) this.removeCommand(command);\n this.commands[command.name] = command;\n if (command.bindKey) this._buildKeyHash(command);\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) 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) ckb[keyId] = cmdGroup[0];\n }\n }\n }\n };\n this.bindKey = function (key, command, position) {\n if (typeof key == \"object\" && key) {\n if (position == undefined) position = key.position;\n key = key[this.platform];\n }\n if (!key) return;\n if (typeof command == \"function\") return this.addCommand({\n exec: command,\n bindKey: key,\n 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 function getPosition(command) {\n return typeof command == \"object\" && command.bindKey && command.bindKey.position || (command.isDefault ? -100 : 0);\n }\n this._addCommandToBinding = function (keyId, command, position) {\n var ckb = this.commandKeyBinding,\n 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 if (typeof position != \"number\") {\n position = getPosition(command);\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) break;\n }\n commands.splice(i, 0, command);\n }\n };\n this.addCommands = function (commands) {\n commands && Object.keys(commands).forEach(function (name) {\n var command = commands[name];\n if (!command) return;\n if (typeof command === \"string\") return this.bindKey(command, name);\n if (typeof command === \"function\") command = {\n exec: command\n };\n if (typeof command !== \"object\") return;\n if (!command.name) command.name = name;\n this.addCommand(command);\n }, this);\n };\n this.removeCommands = function (commands) {\n Object.keys(commands).forEach(function (name) {\n this.removeCommand(commands[name]);\n }, this);\n };\n this.bindKeys = function (keyList) {\n Object.keys(keyList).forEach(function (key) {\n this.bindKey(key, keyList[key]);\n }, this);\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) {\n return x;\n });\n var key = parts.pop();\n var keyCode = keyUtil[key];\n if (keyUtil.FUNCTION_KEYS[keyCode]) key = keyUtil.FUNCTION_KEYS[keyCode].toLowerCase();else if (!parts.length) return {\n key: key,\n hashId: -1\n };else if (parts.length == 1 && parts[0] == \"shift\") return {\n key: key.toUpperCase(),\n 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\") console.error(\"invalid modifier \" + parts[i] + \" in \" + keys);\n return false;\n }\n hashId |= modifier;\n }\n return {\n key: key,\n 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 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 if (command) {\n if (command == \"chainKeys\" || command[command.length - 1] == \"chainKeys\") {\n data.$keyChain = data.$keyChain || key;\n return {\n command: \"null\"\n };\n }\n }\n if (data.$keyChain) {\n if ((!hashId || hashId == 4) && keyString.length == 1) data.$keyChain = data.$keyChain.slice(0, -key.length - 1); // wait for input\n else if (hashId == -1 || keyCode > 0) data.$keyChain = \"\"; // reset keyChain\n }\n return {\n command: command\n };\n };\n this.getStatusText = function (editor, data) {\n return data.$keyChain || \"\";\n };\n }).call(HashHandler.prototype);\n exports.HashHandler = HashHandler;\n exports.MultiHashHandler = MultiHashHandler;\n});\nace.define(\"ace/commands/command_manager\", [\"require\", \"exports\", \"module\", \"ace/lib/oop\", \"ace/keyboard/hash_handler\", \"ace/lib/event_emitter\"], function (acequire, exports, module) {\n \"use strict\";\n\n var oop = acequire(\"../lib/oop\");\n var MultiHashHandler = acequire(\"../keyboard/hash_handler\").MultiHashHandler;\n var EventEmitter = acequire(\"../lib/event_emitter\").EventEmitter;\n var 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 oop.inherits(CommandManager, MultiHashHandler);\n (function () {\n oop.implement(this, EventEmitter);\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 if (typeof command === \"string\") command = this.commands[command];\n if (!command) return false;\n if (editor && editor.$readOnly && !command.readOnly) return false;\n if (command.isAvailable && !command.isAvailable(editor)) return false;\n var e = {\n editor: editor,\n command: command,\n args: args\n };\n e.returnValue = this._emit(\"exec\", e);\n this._signal(\"afterExec\", e);\n return e.returnValue === false ? false : true;\n };\n this.toggleRecording = function (editor) {\n if (this.$inReplay) return;\n editor && editor._emit(\"changeStatus\");\n if (this.recording) {\n this.macro.pop();\n this.removeEventListener(\"exec\", this.$addCommandToMacro);\n if (!this.macro.length) this.macro = this.oldMacro;\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 this.oldMacro = this.macro;\n this.macro = [];\n this.on(\"exec\", this.$addCommandToMacro);\n return this.recording = true;\n };\n this.replay = function (editor) {\n if (this.$inReplay || !this.macro) return;\n if (this.recording) return this.toggleRecording(editor);\n try {\n this.$inReplay = true;\n this.macro.forEach(function (x) {\n if (typeof x == \"string\") this.exec(x, editor);else this.exec(x[0], editor, x[1]);\n }, this);\n } finally {\n this.$inReplay = false;\n }\n };\n this.trimMacro = function (m) {\n return m.map(function (x) {\n if (typeof x[0] != \"string\") x[0] = x[0].name;\n if (!x[1]) x = x[0];\n return x;\n });\n };\n }).call(CommandManager.prototype);\n exports.CommandManager = CommandManager;\n});\nace.define(\"ace/commands/default_commands\", [\"require\", \"exports\", \"module\", \"ace/lib/lang\", \"ace/config\", \"ace/range\"], function (acequire, exports, module) {\n \"use strict\";\n\n var lang = acequire(\"../lib/lang\");\n var config = acequire(\"../config\");\n var Range = acequire(\"../range\").Range;\n function bindKey(win, mac) {\n return {\n win: win,\n mac: mac\n };\n }\n exports.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(\"ace/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(\"ace/ext/error_marker\", function (module) {\n module.showErrorMarker(editor, -1);\n });\n },\n scrollIntoView: \"animate\",\n readOnly: true\n }, {\n name: \"selectall\",\n bindKey: bindKey(\"Ctrl-A\", \"Command-A\"),\n exec: function (editor) {\n editor.selectAll();\n },\n readOnly: true\n }, {\n name: \"centerselection\",\n bindKey: bindKey(null, \"Ctrl-L\"),\n exec: function (editor) {\n editor.centerSelection();\n },\n readOnly: true\n }, {\n name: \"gotoline\",\n bindKey: bindKey(\"Ctrl-L\", \"Command-L\"),\n exec: function (editor) {\n var line = parseInt(prompt(\"Enter line number:\"), 10);\n if (!isNaN(line)) {\n editor.gotoLine(line);\n }\n },\n readOnly: true\n }, {\n name: \"fold\",\n bindKey: bindKey(\"Alt-L|Ctrl-F1\", \"Command-Alt-L|Command-F1\"),\n exec: function (editor) {\n editor.session.toggleFold(false);\n },\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) {\n editor.session.toggleFold(true);\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"center\",\n readOnly: true\n }, {\n name: \"toggleFoldWidget\",\n bindKey: bindKey(\"F2\", \"F2\"),\n exec: function (editor) {\n editor.session.toggleFoldWidget();\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"center\",\n readOnly: true\n }, {\n name: \"toggleParentFoldWidget\",\n bindKey: bindKey(\"Alt-F2\", \"Alt-F2\"),\n exec: function (editor) {\n editor.session.toggleFoldWidget(true);\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"center\",\n readOnly: true\n }, {\n name: \"foldall\",\n bindKey: bindKey(null, \"Ctrl-Command-Option-0\"),\n exec: function (editor) {\n editor.session.foldAll();\n },\n scrollIntoView: \"center\",\n readOnly: true\n }, {\n name: \"foldOther\",\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 bindKey: bindKey(\"Alt-Shift-0\", \"Command-Option-Shift-0\"),\n exec: function (editor) {\n editor.session.unfold();\n },\n scrollIntoView: \"center\",\n readOnly: true\n }, {\n name: \"findnext\",\n bindKey: bindKey(\"Ctrl-K\", \"Command-G\"),\n exec: function (editor) {\n editor.findNext();\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"center\",\n readOnly: true\n }, {\n name: \"findprevious\",\n bindKey: bindKey(\"Ctrl-Shift-K\", \"Command-Shift-G\"),\n exec: function (editor) {\n editor.findPrevious();\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"center\",\n readOnly: true\n }, {\n name: \"selectOrFindNext\",\n bindKey: bindKey(\"Alt-K\", \"Ctrl-G\"),\n exec: function (editor) {\n if (editor.selection.isEmpty()) editor.selection.selectWord();else editor.findNext();\n },\n readOnly: true\n }, {\n name: \"selectOrFindPrevious\",\n bindKey: bindKey(\"Alt-Shift-K\", \"Ctrl-Shift-G\"),\n exec: function (editor) {\n if (editor.selection.isEmpty()) editor.selection.selectWord();else editor.findPrevious();\n },\n readOnly: true\n }, {\n name: \"find\",\n bindKey: bindKey(\"Ctrl-F\", \"Command-F\"),\n exec: function (editor) {\n config.loadModule(\"ace/ext/searchbox\", function (e) {\n e.Search(editor);\n });\n },\n readOnly: true\n }, {\n name: \"overwrite\",\n bindKey: \"Insert\",\n exec: function (editor) {\n editor.toggleOverwrite();\n },\n readOnly: true\n }, {\n name: \"selecttostart\",\n bindKey: bindKey(\"Ctrl-Shift-Home\", \"Command-Shift-Home|Command-Shift-Up\"),\n exec: function (editor) {\n editor.getSelection().selectFileStart();\n },\n multiSelectAction: \"forEach\",\n readOnly: true,\n scrollIntoView: \"animate\",\n aceCommandGroup: \"fileJump\"\n }, {\n name: \"gotostart\",\n bindKey: bindKey(\"Ctrl-Home\", \"Command-Home|Command-Up\"),\n exec: function (editor) {\n editor.navigateFileStart();\n },\n multiSelectAction: \"forEach\",\n readOnly: true,\n scrollIntoView: \"animate\",\n aceCommandGroup: \"fileJump\"\n }, {\n name: \"selectup\",\n bindKey: bindKey(\"Shift-Up\", \"Shift-Up|Ctrl-Shift-P\"),\n exec: function (editor) {\n editor.getSelection().selectUp();\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"cursor\",\n readOnly: true\n }, {\n name: \"golineup\",\n bindKey: bindKey(\"Up\", \"Up|Ctrl-P\"),\n exec: function (editor, args) {\n editor.navigateUp(args.times);\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"cursor\",\n readOnly: true\n }, {\n name: \"selecttoend\",\n bindKey: bindKey(\"Ctrl-Shift-End\", \"Command-Shift-End|Command-Shift-Down\"),\n exec: function (editor) {\n editor.getSelection().selectFileEnd();\n },\n multiSelectAction: \"forEach\",\n readOnly: true,\n scrollIntoView: \"animate\",\n aceCommandGroup: \"fileJump\"\n }, {\n name: \"gotoend\",\n bindKey: bindKey(\"Ctrl-End\", \"Command-End|Command-Down\"),\n exec: function (editor) {\n editor.navigateFileEnd();\n },\n multiSelectAction: \"forEach\",\n readOnly: true,\n scrollIntoView: \"animate\",\n aceCommandGroup: \"fileJump\"\n }, {\n name: \"selectdown\",\n bindKey: bindKey(\"Shift-Down\", \"Shift-Down|Ctrl-Shift-N\"),\n exec: function (editor) {\n editor.getSelection().selectDown();\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"cursor\",\n readOnly: true\n }, {\n name: \"golinedown\",\n bindKey: bindKey(\"Down\", \"Down|Ctrl-N\"),\n exec: function (editor, args) {\n editor.navigateDown(args.times);\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"cursor\",\n readOnly: true\n }, {\n name: \"selectwordleft\",\n bindKey: bindKey(\"Ctrl-Shift-Left\", \"Option-Shift-Left\"),\n exec: function (editor) {\n editor.getSelection().selectWordLeft();\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"cursor\",\n readOnly: true\n }, {\n name: \"gotowordleft\",\n bindKey: bindKey(\"Ctrl-Left\", \"Option-Left\"),\n exec: function (editor) {\n editor.navigateWordLeft();\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"cursor\",\n readOnly: true\n }, {\n name: \"selecttolinestart\",\n bindKey: bindKey(\"Alt-Shift-Left\", \"Command-Shift-Left|Ctrl-Shift-A\"),\n exec: function (editor) {\n editor.getSelection().selectLineStart();\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"cursor\",\n readOnly: true\n }, {\n name: \"gotolinestart\",\n bindKey: bindKey(\"Alt-Left|Home\", \"Command-Left|Home|Ctrl-A\"),\n exec: function (editor) {\n editor.navigateLineStart();\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"cursor\",\n readOnly: true\n }, {\n name: \"selectleft\",\n bindKey: bindKey(\"Shift-Left\", \"Shift-Left|Ctrl-Shift-B\"),\n exec: function (editor) {\n editor.getSelection().selectLeft();\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"cursor\",\n readOnly: true\n }, {\n name: \"gotoleft\",\n bindKey: bindKey(\"Left\", \"Left|Ctrl-B\"),\n exec: function (editor, args) {\n editor.navigateLeft(args.times);\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"cursor\",\n readOnly: true\n }, {\n name: \"selectwordright\",\n bindKey: bindKey(\"Ctrl-Shift-Right\", \"Option-Shift-Right\"),\n exec: function (editor) {\n editor.getSelection().selectWordRight();\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"cursor\",\n readOnly: true\n }, {\n name: \"gotowordright\",\n bindKey: bindKey(\"Ctrl-Right\", \"Option-Right\"),\n exec: function (editor) {\n editor.navigateWordRight();\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"cursor\",\n readOnly: true\n }, {\n name: \"selecttolineend\",\n bindKey: bindKey(\"Alt-Shift-Right\", \"Command-Shift-Right|Shift-End|Ctrl-Shift-E\"),\n exec: function (editor) {\n editor.getSelection().selectLineEnd();\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"cursor\",\n readOnly: true\n }, {\n name: \"gotolineend\",\n bindKey: bindKey(\"Alt-Right|End\", \"Command-Right|End|Ctrl-E\"),\n exec: function (editor) {\n editor.navigateLineEnd();\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"cursor\",\n readOnly: true\n }, {\n name: \"selectright\",\n bindKey: bindKey(\"Shift-Right\", \"Shift-Right\"),\n exec: function (editor) {\n editor.getSelection().selectRight();\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"cursor\",\n readOnly: true\n }, {\n name: \"gotoright\",\n bindKey: bindKey(\"Right\", \"Right|Ctrl-F\"),\n exec: function (editor, args) {\n editor.navigateRight(args.times);\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"cursor\",\n readOnly: true\n }, {\n name: \"selectpagedown\",\n bindKey: \"Shift-PageDown\",\n exec: function (editor) {\n editor.selectPageDown();\n },\n readOnly: true\n }, {\n name: \"pagedown\",\n bindKey: bindKey(null, \"Option-PageDown\"),\n exec: function (editor) {\n editor.scrollPageDown();\n },\n readOnly: true\n }, {\n name: \"gotopagedown\",\n bindKey: bindKey(\"PageDown\", \"PageDown|Ctrl-V\"),\n exec: function (editor) {\n editor.gotoPageDown();\n },\n readOnly: true\n }, {\n name: \"selectpageup\",\n bindKey: \"Shift-PageUp\",\n exec: function (editor) {\n editor.selectPageUp();\n },\n readOnly: true\n }, {\n name: \"pageup\",\n bindKey: bindKey(null, \"Option-PageUp\"),\n exec: function (editor) {\n editor.scrollPageUp();\n },\n readOnly: true\n }, {\n name: \"gotopageup\",\n bindKey: \"PageUp\",\n exec: function (editor) {\n editor.gotoPageUp();\n },\n readOnly: true\n }, {\n name: \"scrollup\",\n bindKey: bindKey(\"Ctrl-Up\", null),\n exec: function (e) {\n e.renderer.scrollBy(0, -2 * e.renderer.layerConfig.lineHeight);\n },\n readOnly: true\n }, {\n name: \"scrolldown\",\n bindKey: bindKey(\"Ctrl-Down\", null),\n exec: function (e) {\n e.renderer.scrollBy(0, 2 * e.renderer.layerConfig.lineHeight);\n },\n readOnly: true\n }, {\n name: \"selectlinestart\",\n bindKey: \"Shift-Home\",\n exec: function (editor) {\n editor.getSelection().selectLineStart();\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"cursor\",\n readOnly: true\n }, {\n name: \"selectlineend\",\n bindKey: \"Shift-End\",\n exec: function (editor) {\n editor.getSelection().selectLineEnd();\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"cursor\",\n readOnly: true\n }, {\n name: \"togglerecording\",\n bindKey: bindKey(\"Ctrl-Alt-E\", \"Command-Option-E\"),\n exec: function (editor) {\n editor.commands.toggleRecording(editor);\n },\n readOnly: true\n }, {\n name: \"replaymacro\",\n bindKey: bindKey(\"Ctrl-Shift-E\", \"Command-Shift-E\"),\n exec: function (editor) {\n editor.commands.replay(editor);\n },\n readOnly: true\n }, {\n name: \"jumptomatching\",\n bindKey: bindKey(\"Ctrl-P\", \"Ctrl-P\"),\n exec: function (editor) {\n editor.jumpToMatching();\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"animate\",\n readOnly: true\n }, {\n name: \"selecttomatching\",\n bindKey: bindKey(\"Ctrl-Shift-P\", \"Ctrl-Shift-P\"),\n exec: function (editor) {\n editor.jumpToMatching(true);\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"animate\",\n readOnly: true\n }, {\n name: \"expandToMatching\",\n bindKey: bindKey(\"Ctrl-Shift-M\", \"Ctrl-Shift-M\"),\n exec: function (editor) {\n editor.jumpToMatching(true, true);\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"animate\",\n readOnly: true\n }, {\n name: \"passKeysToBrowser\",\n bindKey: bindKey(null, null),\n exec: function () {},\n passEvent: true,\n readOnly: true\n }, {\n name: \"copy\",\n exec: function (editor) {},\n readOnly: true\n }, {\n name: \"cut\",\n exec: function (editor) {\n var range = editor.getSelectionRange();\n editor._emit(\"cut\", range);\n if (!editor.selection.isEmpty()) {\n editor.session.remove(range);\n editor.clearSelection();\n }\n },\n scrollIntoView: \"cursor\",\n multiSelectAction: \"forEach\"\n }, {\n name: \"paste\",\n exec: function (editor, args) {\n editor.$handlePaste(args);\n },\n scrollIntoView: \"cursor\"\n }, {\n name: \"removeline\",\n bindKey: bindKey(\"Ctrl-D\", \"Command-D\"),\n exec: function (editor) {\n editor.removeLines();\n },\n scrollIntoView: \"cursor\",\n multiSelectAction: \"forEachLine\"\n }, {\n name: \"duplicateSelection\",\n bindKey: bindKey(\"Ctrl-Shift-D\", \"Command-Shift-D\"),\n exec: function (editor) {\n editor.duplicateSelection();\n },\n scrollIntoView: \"cursor\",\n multiSelectAction: \"forEach\"\n }, {\n name: \"sortlines\",\n bindKey: bindKey(\"Ctrl-Alt-S\", \"Command-Alt-S\"),\n exec: function (editor) {\n editor.sortLines();\n },\n scrollIntoView: \"selection\",\n multiSelectAction: \"forEachLine\"\n }, {\n name: \"togglecomment\",\n bindKey: bindKey(\"Ctrl-/\", \"Command-/\"),\n exec: function (editor) {\n editor.toggleCommentLines();\n },\n multiSelectAction: \"forEachLine\",\n scrollIntoView: \"selectionPart\"\n }, {\n name: \"toggleBlockComment\",\n bindKey: bindKey(\"Ctrl-Shift-/\", \"Command-Shift-/\"),\n exec: function (editor) {\n editor.toggleBlockComment();\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"selectionPart\"\n }, {\n name: \"modifyNumberUp\",\n bindKey: bindKey(\"Ctrl-Shift-Up\", \"Alt-Shift-Up\"),\n exec: function (editor) {\n editor.modifyNumber(1);\n },\n scrollIntoView: \"cursor\",\n multiSelectAction: \"forEach\"\n }, {\n name: \"modifyNumberDown\",\n bindKey: bindKey(\"Ctrl-Shift-Down\", \"Alt-Shift-Down\"),\n exec: function (editor) {\n editor.modifyNumber(-1);\n },\n scrollIntoView: \"cursor\",\n multiSelectAction: \"forEach\"\n }, {\n name: \"replace\",\n bindKey: bindKey(\"Ctrl-H\", \"Command-Option-F\"),\n exec: function (editor) {\n config.loadModule(\"ace/ext/searchbox\", function (e) {\n e.Search(editor, true);\n });\n }\n }, {\n name: \"undo\",\n bindKey: bindKey(\"Ctrl-Z\", \"Command-Z\"),\n exec: function (editor) {\n editor.undo();\n }\n }, {\n name: \"redo\",\n bindKey: bindKey(\"Ctrl-Shift-Z|Ctrl-Y\", \"Command-Shift-Z|Command-Y\"),\n exec: function (editor) {\n editor.redo();\n }\n }, {\n name: \"copylinesup\",\n bindKey: bindKey(\"Alt-Shift-Up\", \"Command-Option-Up\"),\n exec: function (editor) {\n editor.copyLinesUp();\n },\n scrollIntoView: \"cursor\"\n }, {\n name: \"movelinesup\",\n bindKey: bindKey(\"Alt-Up\", \"Option-Up\"),\n exec: function (editor) {\n editor.moveLinesUp();\n },\n scrollIntoView: \"cursor\"\n }, {\n name: \"copylinesdown\",\n bindKey: bindKey(\"Alt-Shift-Down\", \"Command-Option-Down\"),\n exec: function (editor) {\n editor.copyLinesDown();\n },\n scrollIntoView: \"cursor\"\n }, {\n name: \"movelinesdown\",\n bindKey: bindKey(\"Alt-Down\", \"Option-Down\"),\n exec: function (editor) {\n editor.moveLinesDown();\n },\n scrollIntoView: \"cursor\"\n }, {\n name: \"del\",\n bindKey: bindKey(\"Delete\", \"Delete|Ctrl-D|Shift-Delete\"),\n exec: function (editor) {\n editor.remove(\"right\");\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"cursor\"\n }, {\n name: \"backspace\",\n bindKey: bindKey(\"Shift-Backspace|Backspace\", \"Ctrl-Backspace|Shift-Backspace|Backspace|Ctrl-H\"),\n exec: function (editor) {\n editor.remove(\"left\");\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"cursor\"\n }, {\n name: \"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 bindKey: bindKey(\"Alt-Backspace\", \"Command-Backspace\"),\n exec: function (editor) {\n editor.removeToLineStart();\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"cursor\"\n }, {\n name: \"removetolineend\",\n bindKey: bindKey(\"Alt-Delete\", \"Ctrl-K|Command-Delete\"),\n exec: function (editor) {\n editor.removeToLineEnd();\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"cursor\"\n }, {\n name: \"removetolinestarthard\",\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 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 bindKey: bindKey(\"Ctrl-Backspace\", \"Alt-Backspace|Ctrl-Alt-Backspace\"),\n exec: function (editor) {\n editor.removeWordLeft();\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"cursor\"\n }, {\n name: \"removewordright\",\n bindKey: bindKey(\"Ctrl-Delete\", \"Alt-Delete\"),\n exec: function (editor) {\n editor.removeWordRight();\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"cursor\"\n }, {\n name: \"outdent\",\n bindKey: bindKey(\"Shift-Tab\", \"Shift-Tab\"),\n exec: function (editor) {\n editor.blockOutdent();\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"selectionPart\"\n }, {\n name: \"indent\",\n bindKey: bindKey(\"Tab\", \"Tab\"),\n exec: function (editor) {\n editor.indent();\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"selectionPart\"\n }, {\n name: \"blockoutdent\",\n bindKey: bindKey(\"Ctrl-[\", \"Ctrl-[\"),\n exec: function (editor) {\n editor.blockOutdent();\n },\n multiSelectAction: \"forEachLine\",\n scrollIntoView: \"selectionPart\"\n }, {\n name: \"blockindent\",\n bindKey: bindKey(\"Ctrl-]\", \"Ctrl-]\"),\n exec: function (editor) {\n editor.blockIndent();\n },\n multiSelectAction: \"forEachLine\",\n scrollIntoView: \"selectionPart\"\n }, {\n name: \"insertstring\",\n exec: function (editor, str) {\n editor.insert(str);\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"cursor\"\n }, {\n name: \"inserttext\",\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 bindKey: bindKey(null, \"Ctrl-O\"),\n exec: function (editor) {\n editor.splitLine();\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"cursor\"\n }, {\n name: \"transposeletters\",\n bindKey: bindKey(\"Alt-Shift-X\", \"Ctrl-T\"),\n exec: function (editor) {\n editor.transposeLetters();\n },\n multiSelectAction: function (editor) {\n editor.transposeSelections(1);\n },\n scrollIntoView: \"cursor\"\n }, {\n name: \"touppercase\",\n bindKey: bindKey(\"Ctrl-U\", \"Ctrl-U\"),\n exec: function (editor) {\n editor.toUpperCase();\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"cursor\"\n }, {\n name: \"tolowercase\",\n bindKey: bindKey(\"Ctrl-Shift-U\", \"Ctrl-Shift-U\"),\n exec: function (editor) {\n editor.toLowerCase();\n },\n multiSelectAction: \"forEach\",\n scrollIntoView: \"cursor\"\n }, {\n name: \"expandtoline\",\n bindKey: bindKey(\"Ctrl-Shift-L\", \"Command-Shift-L\"),\n exec: function (editor) {\n var range = editor.selection.getRange();\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 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 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 if (selectionEnd.row + 1 < editor.session.doc.getLength() - 1) {\n insertLine += editor.session.doc.getNewLineCharacter();\n }\n editor.clearSelection();\n editor.session.doc.replace(new Range(selectionStart.row, 0, selectionEnd.row + 2, 0), insertLine);\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 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 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 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 editor.exitMultiSelectMode();\n editor.clearSelection();\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});\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\"], function (acequire, exports, module) {\n \"use strict\";\n\n acequire(\"./lib/fixoldbrowsers\");\n var oop = acequire(\"./lib/oop\");\n var dom = acequire(\"./lib/dom\");\n var lang = acequire(\"./lib/lang\");\n var useragent = acequire(\"./lib/useragent\");\n var TextInput = acequire(\"./keyboard/textinput\").TextInput;\n var MouseHandler = acequire(\"./mouse/mouse_handler\").MouseHandler;\n var FoldHandler = acequire(\"./mouse/fold_handler\").FoldHandler;\n var KeyBinding = acequire(\"./keyboard/keybinding\").KeyBinding;\n var EditSession = acequire(\"./edit_session\").EditSession;\n var Search = acequire(\"./search\").Search;\n var Range = acequire(\"./range\").Range;\n var EventEmitter = acequire(\"./lib/event_emitter\").EventEmitter;\n var CommandManager = acequire(\"./commands/command_manager\").CommandManager;\n var defaultCommands = acequire(\"./commands/default_commands\").commands;\n var config = acequire(\"./config\");\n var TokenIterator = acequire(\"./token_iterator\").TokenIterator;\n var Editor = function (renderer, session) {\n var container = renderer.getContainerElement();\n this.container = container;\n this.renderer = renderer;\n this.id = \"editor\" + ++Editor.$uid;\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 this.keyBinding = new KeyBinding(this);\n this.$blockScrolling = 0;\n this.$search = new Search().set({\n wrap: true\n });\n this.$historyTracker = this.$historyTracker.bind(this);\n this.commands.on(\"exec\", this.$historyTracker);\n this.$initOperationListeners();\n this._$emitInputEvent = lang.delayedCall(function () {\n this._signal(\"input\", {});\n if (this.session && this.session.bgTokenizer) this.session.bgTokenizer.scheduleStart();\n }.bind(this));\n this.on(\"change\", function (_, _self) {\n _self._$emitInputEvent.schedule(31);\n });\n this.setSession(session || new EditSession(\"\"));\n config.resetOptions(this);\n config._signal(\"editor\", this);\n };\n Editor.$uid = 0;\n (function () {\n oop.implement(this, EventEmitter);\n this.$initOperationListeners = function () {\n function last(a) {\n return a[a.length - 1];\n }\n this.selections = [];\n this.commands.on(\"exec\", this.startOperation.bind(this), true);\n this.commands.on(\"afterExec\", this.endOperation.bind(this), true);\n this.$opResetTimer = lang.delayedCall(this.endOperation.bind(this));\n this.on(\"change\", function () {\n this.curOp || this.startOperation();\n this.curOp.docChanged = true;\n }.bind(this), true);\n this.on(\"changeSelection\", function () {\n this.curOp || this.startOperation();\n this.curOp.selectionChanged = true;\n }.bind(this), true);\n };\n this.curOp = null;\n this.prevOp = {};\n this.startOperation = function (commadEvent) {\n if (this.curOp) {\n if (!commadEvent || this.curOp.command) return;\n this.prevOp = this.curOp;\n }\n if (!commadEvent) {\n this.previousCommand = null;\n commadEvent = {};\n }\n this.$opResetTimer.schedule();\n this.curOp = {\n command: commadEvent.command || {},\n args: commadEvent.args,\n scrollTop: this.renderer.scrollTop\n };\n if (this.curOp.command.name && this.curOp.command.scrollIntoView !== undefined) this.$blockScrolling++;\n };\n this.endOperation = function (e) {\n if (this.curOp) {\n if (e && e.returnValue === false) return this.curOp = null;\n this._signal(\"beforeEndOperation\");\n var command = this.curOp.command;\n if (command.name && this.$blockScrolling > 0) this.$blockScrolling--;\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\") this.renderer.animateScrolling(this.curOp.scrollTop);\n }\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) return;\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) this.mergeNextCommand = true;\n shouldMerge = shouldMerge && 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 && mergeableCommands.indexOf(e.command.name) !== -1; // the command is mergeable\n }\n if (this.$mergeUndoDeltas != \"always\" && Date.now() - this.sequenceStartTime > 2000) {\n shouldMerge = false; // the sequence is too long\n }\n if (shouldMerge) this.session.mergeUndoDeltas = true;else if (mergeableCommands.indexOf(e.command.name) !== -1) this.sequenceStartTime = Date.now();\n };\n this.setKeyboardHandler = function (keyboardHandler, cb) {\n if (keyboardHandler && typeof keyboardHandler === \"string\") {\n this.$keybindingId = keyboardHandler;\n var _self = this;\n config.loadModule([\"keybinding\", keyboardHandler], function (module) {\n if (_self.$keybindingId == keyboardHandler) _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) return;\n if (this.curOp) this.endOperation();\n this.curOp = {};\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 var selection = this.session.getSelection();\n selection.off(\"changeCursor\", this.$onCursorChange);\n selection.off(\"changeSelection\", this.$onSelectionChange);\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 this.$onChangeMode = this.onChangeMode.bind(this);\n session.on(\"changeMode\", this.$onChangeMode);\n this.$onTokenizerUpdate = this.onTokenizerUpdate.bind(this);\n session.on(\"tokenizerUpdate\", this.$onTokenizerUpdate);\n this.$onChangeTabSize = this.renderer.onChangeTabSize.bind(this.renderer);\n session.on(\"changeTabSize\", this.$onChangeTabSize);\n this.$onChangeWrapLimit = this.onChangeWrapLimit.bind(this);\n session.on(\"changeWrapLimit\", this.$onChangeWrapLimit);\n this.$onChangeWrapMode = this.onChangeWrapMode.bind(this);\n session.on(\"changeWrapMode\", this.$onChangeWrapMode);\n this.$onChangeFold = this.onChangeFold.bind(this);\n session.on(\"changeFold\", this.$onChangeFold);\n this.$onChangeFrontMarker = this.onChangeFrontMarker.bind(this);\n this.session.on(\"changeFrontMarker\", this.$onChangeFrontMarker);\n this.$onChangeBackMarker = this.onChangeBackMarker.bind(this);\n this.session.on(\"changeBackMarker\", this.$onChangeBackMarker);\n this.$onChangeBreakpoint = this.onChangeBreakpoint.bind(this);\n this.session.on(\"changeBreakpoint\", this.$onChangeBreakpoint);\n this.$onChangeAnnotation = this.onChangeAnnotation.bind(this);\n this.session.on(\"changeAnnotation\", this.$onChangeAnnotation);\n this.$onCursorChange = this.onCursorChange.bind(this);\n this.session.on(\"changeOverwrite\", this.$onCursorChange);\n this.$onScrollTopChange = this.onScrollTopChange.bind(this);\n this.session.on(\"changeScrollTop\", this.$onScrollTopChange);\n this.$onScrollLeftChange = this.onScrollLeftChange.bind(this);\n this.session.on(\"changeScrollLeft\", this.$onScrollLeftChange);\n this.selection = session.getSelection();\n this.selection.on(\"changeCursor\", this.$onCursorChange);\n this.$onSelectionChange = this.onSelectionChange.bind(this);\n this.selection.on(\"changeSelection\", this.$onSelectionChange);\n this.onChangeMode();\n this.$blockScrolling += 1;\n this.onCursorChange();\n this.$blockScrolling -= 1;\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 this._signal(\"changeSession\", {\n session: session,\n oldSession: oldSession\n });\n this.curOp = null;\n oldSession && oldSession._signal(\"changeEditor\", {\n oldEditor: this\n });\n session && session._signal(\"changeEditor\", {\n editor: this\n });\n if (session && session.bgTokenizer) 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 if (!cursorPos) this.selectAll();else if (cursorPos == 1) this.navigateFileEnd();else if (cursorPos == -1) this.navigateFileStart();\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\") || dom.computedStyle(this.container, \"fontSize\");\n };\n this.setFontSize = function (size) {\n this.setOption(\"fontSize\", size);\n };\n this.$highlightBrackets = function () {\n if (this.session.$bracketHighlight) {\n this.session.removeMarker(this.session.$bracketHighlight);\n this.session.$bracketHighlight = null;\n }\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 var pos = session.findMatchingBracket(self.getCursorPosition());\n if (pos) {\n var range = new Range(pos.row, pos.column, pos.row, pos.column + 1);\n } else if (session.$mode.getMatching) {\n var range = session.$mode.getMatching(self.session);\n }\n if (range) session.$bracketHighlight = session.addMarker(range, \"ace_bracket\", \"text\");\n }, 50);\n };\n this.$highlightTags = function () {\n if (this.$highlightTagPending) return;\n var self = this;\n this.$highlightTagPending = true;\n setTimeout(function () {\n self.$highlightTagPending = false;\n var session = self.session;\n if (!session || !session.bgTokenizer) return;\n var pos = self.getCursorPosition();\n var iterator = new TokenIterator(self.session, pos.row, pos.column);\n var token = iterator.getCurrentToken();\n if (!token || !/\\b(?:tag-open|tag-name)/.test(token.type)) {\n session.removeMarker(session.$tagHighlight);\n session.$tagHighlight = null;\n return;\n }\n if (token.type.indexOf(\"tag-open\") != -1) {\n token = iterator.stepForward();\n if (!token) return;\n }\n var tag = token.value;\n var depth = 0;\n var prevToken = iterator.stepBackward();\n if (prevToken.value == '<') {\n do {\n prevToken = token;\n token = iterator.stepForward();\n if (token && token.value === tag && token.type.indexOf('tag-name') !== -1) {\n if (prevToken.value === '<') {\n depth++;\n } else if (prevToken.value === '= 0);\n } else {\n do {\n token = prevToken;\n prevToken = iterator.stepBackward();\n if (token && token.value === tag && token.type.indexOf('tag-name') !== -1) {\n if (prevToken.value === '<') {\n depth++;\n } else if (prevToken.value === ' 1)) highlight = false;\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 this.onSelectionChange = function (e) {\n var session = this.session;\n if (session.$selectionMarker) {\n session.removeMarker(session.$selectionMarker);\n }\n session.$selectionMarker = null;\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 var re = this.$highlightSelectedWord && this.$getSelectionHighLightRegexp();\n this.session.highlight(re);\n this._signal(\"changeSelection\");\n };\n this.$getSelectionHighLightRegexp = function () {\n var session = this.session;\n var selection = this.getSelectionRange();\n if (selection.isEmpty() || selection.isMultiLine()) return;\n var startOuter = selection.start.column - 1;\n var endOuter = selection.end.column + 1;\n var line = session.getLine(selection.start.row);\n var lineCols = line.length;\n var needle = line.substring(Math.max(startOuter, 0), Math.min(endOuter, lineCols));\n if (startOuter >= 0 && /^[\\w\\d]/.test(needle) || endOuter <= lineCols && /[\\w\\d]$/.test(needle)) return;\n needle = line.substring(selection.start.column, selection.end.column);\n if (!/^[\\w\\d]+$/.test(needle)) return;\n var re = this.$search.$assembleRegExp({\n wholeWord: true,\n caseSensitive: true,\n needle: needle\n });\n return re;\n };\n this.onChangeFrontMarker = function () {\n this.renderer.updateFrontMarkers();\n };\n this.onChangeBackMarker = function () {\n this.renderer.updateBackMarkers();\n };\n this.onChangeBreakpoint = function () {\n this.renderer.updateBreakpoints();\n };\n this.onChangeAnnotation = function () {\n this.renderer.setAnnotations(this.session.getAnnotations());\n };\n this.onChangeMode = function (e) {\n this.renderer.updateText();\n this._emit(\"changeMode\", e);\n };\n this.onChangeWrapLimit = function () {\n this.renderer.updateFull();\n };\n this.onChangeWrapMode = function () {\n this.renderer.onResize(true);\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 this._signal(\"copy\", text);\n return 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 = {\n text: text,\n event: event\n };\n this.commands.exec(\"paste\", this, e);\n };\n this.$handlePaste = function (e) {\n if (typeof e == \"string\") e = {\n text: e\n };\n this._signal(\"paste\", e);\n var text = e.text;\n if (!this.inMultiSelectMode || this.inVirtualSelectionMode) {\n this.insert(text);\n } else {\n var lines = text.split(/\\r\\n|\\r|\\n/);\n var ranges = this.selection.rangeList.ranges;\n if (lines.length > ranges.length || lines.length < 2 || !lines[1]) return this.commands.exec(\"insertstring\", this, text);\n for (var i = ranges.length; i--;) {\n var range = ranges[i];\n if (!range.isEmpty()) this.session.remove(range);\n this.session.insert(range.start, lines[i]);\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 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 this.session.mergeUndoDeltas = false;\n this.$mergeNextCommand = false;\n }\n text = transform.text;\n }\n }\n if (text == \"\\t\") text = this.session.getTabString();\n if (!this.selection.isEmpty()) {\n var range = this.getSelectionRange();\n cursor = this.session.remove(range);\n this.clearSelection();\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 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 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 var end = session.insert(cursor, text);\n if (transform && transform.selection) {\n if (transform.selection.length == 2) {\n // Transform relative to the current column\n this.selection.setSelectionRange(new Range(cursor.row, start + transform.selection[0], cursor.row, start + transform.selection[1]));\n } else {\n // Transform relative to the current row.\n this.selection.setSelectionRange(new Range(cursor.row + transform.selection[0], transform.selection[1], cursor.row + transform.selection[2], transform.selection[3]));\n }\n }\n if (session.getDocument().isNewLine(text)) {\n var lineIndent = mode.getNextLineIndent(lineState, line.slice(0, cursor.column), session.getTabString());\n session.insert({\n row: cursor.row + 1,\n column: 0\n }, lineIndent);\n }\n if (shouldOutdent) mode.autoOutdent(lineState, session, cursor.row);\n };\n this.onTextInput = function (text) {\n this.keyBinding.onTextInput(text);\n };\n this.onCommandKey = function (e, hashId, keyCode) {\n 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 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 this.setAnimatedScroll = function (shouldAnimate) {\n this.renderer.setAnimatedScroll(shouldAnimate);\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 this.setDisplayIndentGuides = function (display) {\n this.renderer.setDisplayIndentGuides(display);\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 this.getShowFoldWidgets = function () {\n return this.getOption(\"showFoldWidgets\");\n };\n this.setFadeFoldWidgets = function (fade) {\n this.setOption(\"fadeFoldWidgets\", fade);\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\") this.selection.selectLeft();else this.selection.selectRight();\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 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) range = new_range;\n }\n this.session.remove(range);\n this.clearSelection();\n };\n this.removeWordRight = function () {\n if (this.selection.isEmpty()) this.selection.selectWordRight();\n this.session.remove(this.getSelectionRange());\n this.clearSelection();\n };\n this.removeWordLeft = function () {\n if (this.selection.isEmpty()) this.selection.selectWordLeft();\n this.session.remove(this.getSelectionRange());\n this.clearSelection();\n };\n this.removeToLineStart = function () {\n if (this.selection.isEmpty()) this.selection.selectLineStart();\n this.session.remove(this.getSelectionRange());\n this.clearSelection();\n };\n this.removeToLineEnd = function () {\n if (this.selection.isEmpty()) this.selection.selectLineEnd();\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 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 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 var cursor = this.getCursorPosition();\n var column = cursor.column;\n if (column === 0) return;\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 } 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 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 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 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 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 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 var lines = [];\n for (var i = rows.first; i <= rows.last; i++) lines.push(session.getLine(i));\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 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 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 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 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 var t = parseFloat(nr.value);\n t *= Math.pow(10, decimals);\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 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 };\n this.removeLines = function () {\n var rows = this.$getSelectedRows();\n this.session.removeFullLines(rows.first, rows.last);\n this.clearSelection();\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 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 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) break;else if (!copy && subRows.first > last + 1) 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 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 return {\n first: this.session.getRowFoldStart(range.start.row),\n last: this.session.getRowFoldEnd(range.end.row)\n };\n };\n this.onCompositionStart = function (text) {\n this.renderer.showComposition(this.getCursorPosition());\n };\n this.onCompositionUpdate = function (text) {\n this.renderer.setCompositionText(text);\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 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 this.$blockScrolling++;\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 this.$blockScrolling--;\n var scrollTop = renderer.scrollTop;\n renderer.scrollBy(0, rows * config.lineHeight);\n if (select != null) renderer.scrollCursorIntoView(null, 0.5);\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.$blockScrolling += 1;\n this.selection.selectAll();\n this.$blockScrolling -= 1;\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 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 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 bracketType = brackets[token.value[i]] + '.' + token.type.replace(\"rparen\", \"lparen\");\n if (isNaN(depth[bracketType])) {\n depth[bracketType] = 0;\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 if (depth[bracketType] === -1) {\n matchType = 'bracket';\n found = true;\n }\n break;\n }\n }\n } else if (token && token.type.indexOf('tag-name') !== -1) {\n if (isNaN(depth[token.value])) {\n depth[token.value] = 0;\n }\n if (prevToken.value === '<') {\n depth[token.value]++;\n } else if (prevToken.value === '= 0; --i) {\n if (this.$tryReplace(ranges[i], replacement)) {\n replaced++;\n }\n }\n this.selection.setSelectionRange(selection);\n this.$blockScrolling -= 1;\n return replaced;\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) options = {};\n if (typeof needle == \"string\" || needle instanceof RegExp) options.needle = needle;else if (typeof needle == \"object\") oop.mixin(options, needle);\n var range = this.selection.getRange();\n if (options.needle == null) {\n needle = this.session.getTextRange(range) || 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({\n needle: needle\n });\n }\n this.$search.set(options);\n if (!options.start) this.$search.set({\n start: range\n });\n var newRange = this.$search.find(this.session);\n if (options.preventScroll) return newRange;\n if (newRange) {\n this.revealRange(newRange, animate);\n return newRange;\n }\n if (options.backwards) range.start = range.end;else range.end = range.start;\n this.selection.setRange(range);\n };\n this.findNext = function (options, animate) {\n this.find({\n skipCurrent: true,\n backwards: false\n }, options, animate);\n };\n this.findPrevious = function (options, animate) {\n this.find(options, {\n skipCurrent: true,\n backwards: true\n }, animate);\n };\n this.revealRange = function (range, animate) {\n this.$blockScrolling += 1;\n this.session.unfold(range);\n this.selection.setSelectionRange(range);\n this.$blockScrolling -= 1;\n var scrollTop = this.renderer.scrollTop;\n this.renderer.scrollSelectionIntoView(range.start, range.end, 0.5);\n if (animate !== false) this.renderer.animateScrolling(scrollTop);\n };\n this.undo = function () {\n this.$blockScrolling++;\n this.session.getUndoManager().undo();\n this.$blockScrolling--;\n this.renderer.scrollCursorIntoView(null, 0.5);\n };\n this.redo = function () {\n this.$blockScrolling++;\n this.session.getUndoManager().redo();\n this.$blockScrolling--;\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 }\n };\n this.setAutoScrollEditorIntoView = function (enable) {\n if (!enable) return;\n var rect;\n var self = this;\n var shouldScroll = false;\n if (!this.$scrollAnchor) 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) rect = self.renderer.container.getBoundingClientRect();\n });\n var onAfterRender = this.renderer.on(\"afterRender\", function () {\n if (shouldScroll && rect && (self.isFocused() || self.searchBox && self.searchBox.isFocused())) {\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 && 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) 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 this.$resetCursorStyle = function () {\n var style = this.$cursorStyle || \"ace\";\n var cursorLayer = this.renderer.$cursorLayer;\n if (!cursorLayer) 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 }).call(Editor.prototype);\n config.defineOptions(Editor.prototype, \"editor\", {\n selectionStyle: {\n set: function (style) {\n this.onSelectionChange();\n this._signal(\"changeSelectionStyle\", {\n data: style\n });\n },\n initialValue: \"line\"\n },\n highlightActiveLine: {\n set: function () {\n this.$updateHighlightActiveLine();\n },\n initialValue: true\n },\n highlightSelectedWord: {\n set: function (shouldHighlight) {\n this.$onSelectionChange();\n },\n initialValue: true\n },\n readOnly: {\n set: function (readOnly) {\n this.$resetCursorStyle();\n },\n initialValue: false\n },\n cursorStyle: {\n set: function (val) {\n this.$resetCursorStyle();\n },\n values: [\"ace\", \"slim\", \"smooth\", \"wide\"],\n initialValue: \"ace\"\n },\n mergeUndoDeltas: {\n values: [false, true, \"always\"],\n initialValue: true\n },\n behavioursEnabled: {\n initialValue: true\n },\n wrapBehavioursEnabled: {\n initialValue: true\n },\n autoScrollEditorIntoView: {\n set: function (val) {\n this.setAutoScrollEditorIntoView(val);\n }\n },\n keyboardHandler: {\n set: function (val) {\n this.setKeyboardHandler(val);\n },\n get: function () {\n return this.keybindingId;\n },\n handlesSet: true\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 showLineNumbers: \"renderer\",\n showGutter: \"renderer\",\n displayIndentGuides: \"renderer\",\n fontSize: \"renderer\",\n fontFamily: \"renderer\",\n maxLines: \"renderer\",\n minLines: \"renderer\",\n scrollPastEnd: \"renderer\",\n fixedWidthGutter: \"renderer\",\n theme: \"renderer\",\n scrollSpeed: \"$mouseHandler\",\n dragDelay: \"$mouseHandler\",\n dragEnabled: \"$mouseHandler\",\n focusTimout: \"$mouseHandler\",\n tooltipFollowsMouse: \"$mouseHandler\",\n firstLineNumber: \"session\",\n overwrite: \"session\",\n newLineMode: \"session\",\n useWorker: \"session\",\n useSoftTabs: \"session\",\n tabSize: \"session\",\n wrap: \"session\",\n indentedSoftWrap: \"session\",\n foldStyle: \"session\",\n mode: \"session\"\n });\n exports.Editor = Editor;\n});\nace.define(\"ace/undomanager\", [\"require\", \"exports\", \"module\"], function (acequire, exports, module) {\n \"use strict\";\n\n var UndoManager = function () {\n this.reset();\n };\n (function () {\n this.execute = function (options) {\n var deltaSets = options.args[0];\n this.$doc = options.args[1];\n if (options.merge && this.hasUndo()) {\n this.dirtyCounter--;\n deltaSets = this.$undoStack.pop().concat(deltaSets);\n }\n this.$undoStack.push(deltaSets);\n this.$redoStack = [];\n if (this.dirtyCounter < 0) {\n this.dirtyCounter = NaN;\n }\n this.dirtyCounter++;\n };\n this.undo = function (dontSelect) {\n var deltaSets = this.$undoStack.pop();\n var undoSelectionRange = null;\n if (deltaSets) {\n undoSelectionRange = this.$doc.undoChanges(deltaSets, dontSelect);\n this.$redoStack.push(deltaSets);\n this.dirtyCounter--;\n }\n return undoSelectionRange;\n };\n this.redo = function (dontSelect) {\n var deltaSets = this.$redoStack.pop();\n var redoSelectionRange = null;\n if (deltaSets) {\n redoSelectionRange = this.$doc.redoChanges(this.$deserializeDeltas(deltaSets), dontSelect);\n this.$undoStack.push(deltaSets);\n this.dirtyCounter++;\n }\n return redoSelectionRange;\n };\n this.reset = function () {\n this.$undoStack = [];\n this.$redoStack = [];\n this.dirtyCounter = 0;\n };\n this.hasUndo = function () {\n return this.$undoStack.length > 0;\n };\n this.hasRedo = function () {\n return this.$redoStack.length > 0;\n };\n this.markClean = function () {\n this.dirtyCounter = 0;\n };\n this.isClean = function () {\n return this.dirtyCounter === 0;\n };\n this.$serializeDeltas = function (deltaSets) {\n return cloneDeltaSetsObj(deltaSets, $serializeDelta);\n };\n this.$deserializeDeltas = function (deltaSets) {\n return cloneDeltaSetsObj(deltaSets, $deserializeDelta);\n };\n function $serializeDelta(delta) {\n return {\n action: delta.action,\n start: delta.start,\n end: delta.end,\n lines: delta.lines.length == 1 ? null : delta.lines,\n text: delta.lines.length == 1 ? delta.lines[0] : null\n };\n }\n function $deserializeDelta(delta) {\n return {\n action: delta.action,\n start: delta.start,\n end: delta.end,\n lines: delta.lines || [delta.text]\n };\n }\n function cloneDeltaSetsObj(deltaSets_old, fnGetModifiedDelta) {\n var deltaSets_new = new Array(deltaSets_old.length);\n for (var i = 0; i < deltaSets_old.length; i++) {\n var deltaSet_old = deltaSets_old[i];\n var deltaSet_new = {\n group: deltaSet_old.group,\n deltas: new Array(deltaSet_old.length)\n };\n for (var j = 0; j < deltaSet_old.deltas.length; j++) {\n var delta_old = deltaSet_old.deltas[j];\n deltaSet_new.deltas[j] = fnGetModifiedDelta(delta_old);\n }\n deltaSets_new[i] = deltaSet_new;\n }\n return deltaSets_new;\n }\n }).call(UndoManager.prototype);\n exports.UndoManager = UndoManager;\n});\nace.define(\"ace/layer/gutter\", [\"require\", \"exports\", \"module\", \"ace/lib/dom\", \"ace/lib/oop\", \"ace/lib/lang\", \"ace/lib/event_emitter\"], function (acequire, exports, module) {\n \"use strict\";\n\n var dom = acequire(\"../lib/dom\");\n var oop = acequire(\"../lib/oop\");\n var lang = acequire(\"../lib/lang\");\n var EventEmitter = acequire(\"../lib/event_emitter\").EventEmitter;\n var 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 this.gutterWidth = 0;\n this.$annotations = [];\n this.$updateAnnotations = this.$updateAnnotations.bind(this);\n this.$cells = [];\n };\n (function () {\n oop.implement(this, EventEmitter);\n this.setSession = function (session) {\n if (this.session) this.session.removeEventListener(\"change\", this.$updateAnnotations);\n this.session = session;\n if (session) session.on(\"change\", this.$updateAnnotations);\n };\n this.addGutterDecoration = function (row, className) {\n if (window.console) console.warn && console.warn(\"deprecated use session.addGutterDecoration\");\n this.session.addGutterDecoration(row, className);\n };\n this.removeGutterDecoration = function (row, className) {\n if (window.console) console.warn && console.warn(\"deprecated use session.removeGutterDecoration\");\n this.session.removeGutterDecoration(row, className);\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) rowInfo = this.$annotations[row] = {\n text: []\n };\n var annoText = annotation.text;\n annoText = annoText ? lang.escapeHTML(annoText) : annotation.html || \"\";\n if (rowInfo.text.indexOf(annoText) === -1) rowInfo.text.push(annoText);\n var type = annotation.type;\n if (type == \"error\") rowInfo.className = \" ace_error\";else if (type == \"warning\" && rowInfo.className != \" ace_error\") rowInfo.className = \" ace_warning\";else if (type == \"info\" && !rowInfo.className) rowInfo.className = \" ace_info\";\n }\n };\n this.$updateAnnotations = function (delta) {\n if (!this.$annotations.length) return;\n var firstRow = delta.start.row;\n var len = delta.end.row - firstRow;\n if (len === 0) {} 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 this.update = function (config) {\n var session = this.session;\n var firstRow = config.firstRow;\n var lastRow = Math.min(config.lastRow + config.gutterOffset,\n // needed to compensate for hor scollbar\n session.getLength() - 1);\n var fold = session.getNextFoldLine(firstRow);\n var foldStart = fold ? fold.start.row : Infinity;\n var foldWidgets = this.$showFoldWidgets && session.foldWidgets;\n var breakpoints = session.$breakpoints;\n var decorations = session.$decorations;\n var firstLineNumber = session.$firstLineNumber;\n var lastLineNumber = 0;\n var gutterRenderer = session.gutterRenderer || this.$renderer;\n var cell = null;\n var index = -1;\n var row = firstRow;\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.$cells.length > index + 1) {\n cell = this.$cells.pop();\n this.element.removeChild(cell.element);\n }\n break;\n }\n cell = this.$cells[++index];\n if (!cell) {\n cell = {\n element: null,\n textNode: null,\n foldWidget: null\n };\n cell.element = dom.createElement(\"div\");\n cell.textNode = document.createTextNode('');\n cell.element.appendChild(cell.textNode);\n this.element.appendChild(cell.element);\n this.$cells[index] = cell;\n }\n var className = \"ace_gutter-cell \";\n if (breakpoints[row]) className += breakpoints[row];\n if (decorations[row]) className += decorations[row];\n if (this.$annotations[row]) className += this.$annotations[row].className;\n if (cell.element.className != className) cell.element.className = className;\n var height = session.getRowLength(row) * config.lineHeight + \"px\";\n if (height != cell.element.style.height) cell.element.style.height = height;\n if (foldWidgets) {\n var c = foldWidgets[row];\n if (c == null) c = foldWidgets[row] = session.getFoldWidget(row);\n }\n if (c) {\n if (!cell.foldWidget) {\n cell.foldWidget = dom.createElement(\"span\");\n cell.element.appendChild(cell.foldWidget);\n }\n var className = \"ace_fold-widget ace_\" + c;\n if (c == \"start\" && row == foldStart && row < fold.end.row) className += \" ace_closed\";else className += \" ace_open\";\n if (cell.foldWidget.className != className) cell.foldWidget.className = className;\n var height = config.lineHeight + \"px\";\n if (cell.foldWidget.style.height != height) cell.foldWidget.style.height = height;\n } else {\n if (cell.foldWidget) {\n cell.element.removeChild(cell.foldWidget);\n cell.foldWidget = null;\n }\n }\n var text = lastLineNumber = gutterRenderer ? gutterRenderer.getText(session, row) : row + firstLineNumber;\n if (text !== cell.textNode.data) cell.textNode.data = text;\n row++;\n }\n this.element.style.height = config.minHeight + \"px\";\n if (this.$fixedWidth || session.$useWrapMode) lastLineNumber = session.getLength() + firstLineNumber;\n var gutterWidth = gutterRenderer ? gutterRenderer.getWidth(session, lastLineNumber, config) : lastLineNumber.toString().length * config.characterWidth;\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.style.width = Math.ceil(this.gutterWidth) + \"px\";\n this._emit(\"changeGutterWidth\", gutterWidth);\n }\n };\n this.$fixedWidth = false;\n this.$showLineNumbers = true;\n this.$renderer = \"\";\n this.setShowLineNumbers = function (show) {\n this.$renderer = !show && {\n getWidth: function () {\n return \"\";\n },\n getText: function () {\n return \"\";\n }\n };\n };\n this.getShowLineNumbers = function () {\n return this.$showLineNumbers;\n };\n this.$showFoldWidgets = true;\n this.setShowFoldWidgets = function (show) {\n if (show) dom.addCssClass(this.element, \"ace_folding-enabled\");else dom.removeCssClass(this.element, \"ace_folding-enabled\");\n this.$showFoldWidgets = show;\n this.$padding = null;\n };\n this.getShowFoldWidgets = function () {\n return this.$showFoldWidgets;\n };\n this.$computePadding = function () {\n if (!this.element.firstChild) return {\n left: 0,\n right: 0\n };\n var style = dom.computedStyle(this.element.firstChild);\n this.$padding = {};\n this.$padding.left = parseInt(style.paddingLeft) + 1 || 0;\n this.$padding.right = parseInt(style.paddingRight) || 0;\n return this.$padding;\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) return \"markers\";\n if (this.$showFoldWidgets && point.x > rect.right - padding.right) return \"foldWidgets\";\n };\n }).call(Gutter.prototype);\n exports.Gutter = Gutter;\n});\nace.define(\"ace/layer/marker\", [\"require\", \"exports\", \"module\", \"ace/range\", \"ace/lib/dom\"], function (acequire, exports, module) {\n \"use strict\";\n\n var Range = acequire(\"../range\").Range;\n var dom = acequire(\"../lib/dom\");\n var 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 (function () {\n this.$padding = 0;\n this.setPadding = function (padding) {\n this.$padding = padding;\n };\n this.setSession = function (session) {\n this.session = session;\n };\n this.setMarkers = function (markers) {\n this.markers = markers;\n };\n this.update = function (config) {\n if (!config) return;\n this.config = config;\n var html = [];\n for (var key in this.markers) {\n var marker = this.markers[key];\n if (!marker.range) {\n marker.update(html, this, this.session, config);\n continue;\n }\n var range = marker.range.clipRows(config.firstRow, config.lastRow);\n if (range.isEmpty()) continue;\n range = range.toScreenRange(this.session);\n if (marker.renderer) {\n var top = this.$getTop(range.start.row, config);\n var left = this.$padding + (this.session.$bidiHandler.isBidiRow(range.start.row) ? this.session.$bidiHandler.getPosLeft(range.start.column) : 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\") this.drawTextMarker(html, range, marker.clazz, config);else this.drawMultiLineMarker(html, range, marker.clazz, config);\n } else {\n if (this.session.$bidiHandler.isBidiRow(range.start.row)) {\n this.drawBidiSingleLineMarker(html, range, marker.clazz + \" ace_start\" + \" ace_br15\", config);\n } else {\n this.drawSingleLineMarker(html, range, marker.clazz + \" ace_start\" + \" ace_br15\", config);\n }\n }\n }\n this.element.innerHTML = html.join(\"\");\n };\n this.$getTop = function (row, layerConfig) {\n return (row - layerConfig.firstRowScreen) * layerConfig.lineHeight;\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 clazzModified = null;\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 clazzModified = clazz + (row == start ? \" ace_start\" : \"\") + \" ace_br\" + getBorderClass(row == start || row == start + 1 && range.start.column, prev < curr, curr > next, row == end);\n if (this.session.$bidiHandler.isBidiRow(row)) {\n this.drawBidiSingleLineMarker(stringBuilder, lineRange, clazzModified, layerConfig, row == end ? 0 : 1, extraStyle);\n } else {\n this.drawSingleLineMarker(stringBuilder, lineRange, clazzModified, layerConfig, row == end ? 0 : 1, extraStyle);\n }\n }\n };\n this.drawMultiLineMarker = function (stringBuilder, range, clazz, config, extraStyle) {\n var padding = this.$padding;\n var height, top, left;\n extraStyle = extraStyle || \"\";\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 height = config.lineHeight;\n top = this.$getTop(range.start.row, config);\n left = padding + range.start.column * config.characterWidth;\n stringBuilder.push(\"
\");\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 var width = range.end.column * config.characterWidth;\n height = config.lineHeight;\n top = this.$getTop(range.end.row, config);\n stringBuilder.push(\"
\");\n }\n height = (range.end.row - range.start.row - 1) * config.lineHeight;\n if (height <= 0) return;\n top = this.$getTop(range.start.row + 1, config);\n var radiusClass = (range.start.column ? 1 : 0) | (range.end.column ? 0 : 8);\n stringBuilder.push(\"
\");\n };\n this.drawSingleLineMarker = function (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 var top = this.$getTop(range.start.row, config);\n var left = this.$padding + range.start.column * config.characterWidth;\n stringBuilder.push(\"
\");\n };\n this.drawBidiSingleLineMarker = function (stringBuilder, range, clazz, config, extraLength, extraStyle) {\n var height = config.lineHeight,\n top = this.$getTop(range.start.row, config),\n padding = this.$padding;\n var selections = this.session.$bidiHandler.getSelections(range.start.column, range.end.column);\n selections.forEach(function (selection) {\n stringBuilder.push(\"
\");\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) height += this.$getTop(range.end.row, config) - top;\n stringBuilder.push(\"
\");\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 stringBuilder.push(\"
\");\n };\n }).call(Marker.prototype);\n exports.Marker = Marker;\n});\nace.define(\"ace/layer/text\", [\"require\", \"exports\", \"module\", \"ace/lib/oop\", \"ace/lib/dom\", \"ace/lib/lang\", \"ace/lib/useragent\", \"ace/lib/event_emitter\"], function (acequire, exports, module) {\n \"use strict\";\n\n var oop = acequire(\"../lib/oop\");\n var dom = acequire(\"../lib/dom\");\n var lang = acequire(\"../lib/lang\");\n var useragent = acequire(\"../lib/useragent\");\n var EventEmitter = acequire(\"../lib/event_emitter\").EventEmitter;\n var Text = function (parentEl) {\n this.element = 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 };\n (function () {\n oop.implement(this, EventEmitter);\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.$updateEolChar = function () {\n var EOL_CHAR = this.session.doc.getNewLineCharacter() == \"\\n\" ? 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 this.setPadding = function (padding) {\n this.$padding = padding;\n this.element.style.padding = \"0 \" + padding + \"px\";\n };\n this.getLineHeight = function () {\n return this.$fontMetrics.$characterSize.height || 0;\n };\n this.getCharacterWidth = function () {\n return this.$fontMetrics.$characterSize.width || 0;\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 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) this.$computeTabString();\n };\n this.showInvisibles = false;\n this.setShowInvisibles = function (showInvisibles) {\n if (this.showInvisibles == showInvisibles) return false;\n this.showInvisibles = showInvisibles;\n this.$computeTabString();\n return true;\n };\n this.displayIndentGuides = true;\n this.setDisplayIndentGuides = function (display) {\n if (this.displayIndentGuides == display) return false;\n this.displayIndentGuides = display;\n this.$computeTabString();\n return true;\n };\n this.$tabStrings = [];\n this.onChangeTabSize = 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 tabStr.push(\"\" + lang.stringRepeat(this.TAB_CHAR, i) + \"\");\n } else {\n tabStr.push(lang.stringRepeat(\" \", i));\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 this.$tabStrings[\" \"] = \"\" + spaceContent + \"\";\n this.$tabStrings[\"\\t\"] = \"\" + tabContent + \"\";\n }\n };\n this.updateLines = function (config, firstRow, lastRow) {\n if (this.config.lastRow != config.lastRow || this.config.firstRow != config.firstRow) {\n this.scrollLines(config);\n }\n this.config = config;\n var first = Math.max(firstRow, config.firstRow);\n var last = Math.min(lastRow, config.lastRow);\n var lineElements = this.element.childNodes;\n var lineElementsIdx = 0;\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 var row = first;\n var foldLine = this.session.getNextFoldLine(row);\n var foldStart = foldLine ? foldLine.start.row : Infinity;\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) break;\n var lineElement = lineElements[lineElementsIdx++];\n if (lineElement) {\n var html = [];\n this.$renderLine(html, row, !this.$useLineGroups(), row == foldStart ? foldLine : false);\n lineElement.style.height = config.lineHeight * this.session.getRowLength(row) + \"px\";\n lineElement.innerHTML = html.join(\"\");\n }\n row++;\n }\n };\n this.scrollLines = function (config) {\n var oldConfig = this.config;\n this.config = config;\n if (!oldConfig || oldConfig.lastRow < config.firstRow) return this.update(config);\n if (config.lastRow < oldConfig.firstRow) return this.update(config);\n var el = this.element;\n if (oldConfig.firstRow < config.firstRow) for (var row = this.session.getFoldedRowCount(oldConfig.firstRow, config.firstRow - 1); row > 0; row--) el.removeChild(el.firstChild);\n if (oldConfig.lastRow > config.lastRow) for (var row = this.session.getFoldedRowCount(config.lastRow + 1, oldConfig.lastRow); row > 0; row--) el.removeChild(el.lastChild);\n if (config.firstRow < oldConfig.firstRow) {\n var fragment = this.$renderLinesFragment(config, config.firstRow, oldConfig.firstRow - 1);\n if (el.firstChild) el.insertBefore(fragment, el.firstChild);else el.appendChild(fragment);\n }\n if (config.lastRow > oldConfig.lastRow) {\n var fragment = this.$renderLinesFragment(config, oldConfig.lastRow + 1, config.lastRow);\n el.appendChild(fragment);\n }\n };\n this.$renderLinesFragment = function (config, firstRow, lastRow) {\n var fragment = this.element.ownerDocument.createDocumentFragment();\n var row = firstRow;\n var foldLine = this.session.getNextFoldLine(row);\n var foldStart = foldLine ? foldLine.start.row : Infinity;\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) break;\n var container = dom.createElement(\"div\");\n var html = [];\n this.$renderLine(html, row, false, row == foldStart ? foldLine : false);\n container.innerHTML = html.join(\"\");\n if (this.$useLineGroups()) {\n container.className = 'ace_line_group';\n fragment.appendChild(container);\n container.style.height = config.lineHeight * this.session.getRowLength(row) + \"px\";\n } else {\n while (container.firstChild) fragment.appendChild(container.firstChild);\n }\n row++;\n }\n return fragment;\n };\n this.update = function (config) {\n this.config = config;\n var html = [];\n var firstRow = config.firstRow,\n lastRow = config.lastRow;\n var row = firstRow;\n var foldLine = this.session.getNextFoldLine(row);\n var foldStart = foldLine ? foldLine.start.row : Infinity;\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) break;\n if (this.$useLineGroups()) html.push(\"
\");\n this.$renderLine(html, row, false, row == foldStart ? foldLine : false);\n if (this.$useLineGroups()) html.push(\"
\"); // end the line group\n\n row++;\n }\n this.element.innerHTML = html.join(\"\");\n };\n this.$textToken = {\n \"text\": true,\n \"rparen\": true,\n \"lparen\": true\n };\n this.$renderToken = function (stringBuilder, screenColumn, token, value) {\n var self = this;\n var replaceReg = /\\t|&|<|>|( +)|([\\x00-\\x1f\\x80-\\xa0\\xad\\u1680\\u180E\\u2000-\\u200f\\u2028\\u2029\\u202F\\u205F\\u3000\\uFEFF\\uFFF9-\\uFFFC])|[\\u1100-\\u115F\\u11A3-\\u11A7\\u11FA-\\u11FF\\u2329-\\u232A\\u2E80-\\u2E99\\u2E9B-\\u2EF3\\u2F00-\\u2FD5\\u2FF0-\\u2FFB\\u3000-\\u303E\\u3041-\\u3096\\u3099-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u3190-\\u31BA\\u31C0-\\u31E3\\u31F0-\\u321E\\u3220-\\u3247\\u3250-\\u32FE\\u3300-\\u4DBF\\u4E00-\\uA48C\\uA490-\\uA4C6\\uA960-\\uA97C\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFAFF\\uFE10-\\uFE19\\uFE30-\\uFE52\\uFE54-\\uFE66\\uFE68-\\uFE6B\\uFF01-\\uFF60\\uFFE0-\\uFFE6]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]/g;\n var replaceFunc = function (c, a, b, tabIdx, idx4) {\n if (a) {\n return self.showInvisibles ? \"\" + lang.stringRepeat(self.SPACE_CHAR, c.length) + \"\" : c;\n } else if (c == \"&\") {\n return \"&\";\n } else if (c == \"<\") {\n return \"<\";\n } else if (c == \">\") {\n return \">\";\n } else if (c == \"\\t\") {\n var tabSize = self.session.getScreenTabSize(screenColumn + tabIdx);\n screenColumn += tabSize - 1;\n return self.$tabStrings[tabSize];\n } else if (c == \"\\u3000\") {\n var classToUse = self.showInvisibles ? \"ace_cjk ace_invisible ace_invisible_space\" : \"ace_cjk\";\n var space = self.showInvisibles ? self.SPACE_CHAR : \"\";\n screenColumn += 1;\n return \"\" + space + \"\";\n } else if (b) {\n return \"\" + self.SPACE_CHAR + \"\";\n } else {\n screenColumn += 1;\n return \"\" + c + \"\";\n }\n };\n var output = value.replace(replaceReg, replaceFunc);\n if (!this.$textToken[token.type]) {\n var classes = \"ace_\" + token.type.replace(/\\./g, \" ace_\");\n var style = \"\";\n if (token.type == \"fold\") style = \" style='width:\" + token.value.length * this.config.characterWidth + \"px;' \";\n stringBuilder.push(\"\", output, \"\");\n } else {\n stringBuilder.push(output);\n }\n return screenColumn + value.length;\n };\n this.renderIndentGuide = function (stringBuilder, value, max) {\n var cols = value.search(this.$indentGuideRe);\n if (cols <= 0 || cols >= max) return value;\n if (value[0] == \" \") {\n cols -= cols % this.tabSize;\n stringBuilder.push(lang.stringRepeat(this.$tabStrings[\" \"], cols / this.tabSize));\n return value.substr(cols);\n } else if (value[0] == \"\\t\") {\n stringBuilder.push(lang.stringRepeat(this.$tabStrings[\"\\t\"], cols));\n return value.substr(cols);\n }\n return value;\n };\n this.$renderWrappedLine = function (stringBuilder, tokens, splits, onlyContents) {\n var chars = 0;\n var split = 0;\n var splitChars = splits[0];\n var screenColumn = 0;\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(stringBuilder, value, splitChars);\n if (!value) continue;\n chars -= value.length;\n }\n if (chars + value.length < splitChars) {\n screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value);\n chars += value.length;\n } else {\n while (chars + value.length >= splitChars) {\n screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value.substring(0, splitChars - chars));\n value = value.substring(splitChars - chars);\n chars = splitChars;\n if (!onlyContents) {\n stringBuilder.push(\"\", \"
\");\n }\n stringBuilder.push(lang.stringRepeat(\"\\xa0\", splits.indent));\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(stringBuilder, screenColumn, token, value);\n }\n }\n }\n };\n this.$renderSimpleLine = function (stringBuilder, tokens) {\n var screenColumn = 0;\n var token = tokens[0];\n var value = token.value;\n if (this.displayIndentGuides) value = this.renderIndentGuide(stringBuilder, value);\n if (value) screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value);\n for (var i = 1; i < tokens.length; i++) {\n token = tokens[i];\n value = token.value;\n screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value);\n }\n };\n this.$renderLine = function (stringBuilder, row, onlyContents, foldLine) {\n if (!foldLine && foldLine != false) foldLine = this.session.getFoldLine(row);\n if (foldLine) var tokens = this.$getFoldLineTokens(row, foldLine);else var tokens = this.session.getTokens(row);\n if (!onlyContents) {\n stringBuilder.push(\"
\");\n }\n if (tokens.length) {\n var splits = this.session.getRowSplitData(row);\n if (splits && splits.length) this.$renderWrappedLine(stringBuilder, tokens, splits, onlyContents);else this.$renderSimpleLine(stringBuilder, tokens);\n }\n if (this.showInvisibles) {\n if (foldLine) row = foldLine.end.row;\n stringBuilder.push(\"\", row == this.session.getLength() - 1 ? this.EOF_CHAR : this.EOL_CHAR, \"\");\n }\n if (!onlyContents) stringBuilder.push(\"
\");\n };\n this.$getFoldLineTokens = function (row, foldLine) {\n var session = this.session;\n var renderTokens = [];\n function addTokens(tokens, from, to) {\n var idx = 0,\n col = 0;\n while (col + tokens[idx].value.length < from) {\n col += tokens[idx].value.length;\n idx++;\n if (idx == tokens.length) return;\n }\n if (col != from) {\n var value = tokens[idx].value.substring(from - col);\n if (value.length > to - from) value = value.substring(0, to - from);\n renderTokens.push({\n type: tokens[idx].type,\n value: value\n });\n col = from + value.length;\n idx += 1;\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 renderTokens.push(tokens[idx]);\n col += value.length;\n idx += 1;\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) tokens = session.getTokens(row);\n if (tokens.length) addTokens(tokens, lastColumn, column);\n }\n }, foldLine.end.row, this.session.getLine(foldLine.end.row).length);\n return renderTokens;\n };\n this.$useLineGroups = function () {\n return this.session.getUseWrapMode();\n };\n this.destroy = function () {\n clearInterval(this.$pollSizeChangesTimer);\n if (this.$measureNode) this.$measureNode.parentNode.removeChild(this.$measureNode);\n delete this.$measureNode;\n };\n }).call(Text.prototype);\n exports.Text = Text;\n});\nace.define(\"ace/layer/cursor\", [\"require\", \"exports\", \"module\", \"ace/lib/dom\"], function (acequire, exports, module) {\n \"use strict\";\n\n var dom = acequire(\"../lib/dom\");\n var isIE8;\n var Cursor = function (parentEl) {\n this.element = dom.createElement(\"div\");\n this.element.className = \"ace_layer ace_cursor-layer\";\n parentEl.appendChild(this.element);\n if (isIE8 === undefined) isIE8 = !(\"opacity\" in this.element.style);\n this.isVisible = false;\n this.isBlinking = true;\n this.blinkInterval = 1000;\n this.smoothBlinking = false;\n this.cursors = [];\n this.cursor = this.addCursor();\n dom.addCssClass(this.element, \"ace_hidden-cursors\");\n this.$updateCursors = (isIE8 ? this.$updateVisibility : this.$updateOpacity).bind(this);\n };\n (function () {\n this.$updateVisibility = function (val) {\n var cursors = this.cursors;\n for (var i = cursors.length; i--;) cursors[i].style.visibility = val ? \"\" : \"hidden\";\n };\n this.$updateOpacity = function (val) {\n var cursors = this.cursors;\n for (var i = cursors.length; i--;) cursors[i].style.opacity = val ? \"\" : \"0\";\n };\n this.$padding = 0;\n this.setPadding = function (padding) {\n this.$padding = padding;\n };\n this.setSession = function (session) {\n this.session = session;\n };\n this.setBlinking = function (blinking) {\n if (blinking != this.isBlinking) {\n this.isBlinking = blinking;\n this.restartTimer();\n }\n };\n this.setBlinkInterval = function (blinkInterval) {\n if (blinkInterval != this.blinkInterval) {\n this.blinkInterval = blinkInterval;\n this.restartTimer();\n }\n };\n this.setSmoothBlinking = function (smoothBlinking) {\n if (smoothBlinking != this.smoothBlinking && !isIE8) {\n this.smoothBlinking = smoothBlinking;\n dom.setCssClass(this.element, \"ace_smooth-blinking\", smoothBlinking);\n this.$updateCursors(true);\n this.$updateCursors = this.$updateOpacity.bind(this);\n this.restartTimer();\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 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 this.hideCursor = function () {\n this.isVisible = false;\n dom.addCssClass(this.element, \"ace_hidden-cursors\");\n this.restartTimer();\n };\n this.showCursor = function () {\n this.isVisible = true;\n dom.removeCssClass(this.element, \"ace_hidden-cursors\");\n this.restartTimer();\n };\n this.restartTimer = function () {\n var update = this.$updateCursors;\n clearInterval(this.intervalId);\n clearTimeout(this.timeoutId);\n if (this.smoothBlinking) {\n dom.removeCssClass(this.element, \"ace_smooth-blinking\");\n }\n update(true);\n if (!this.isBlinking || !this.blinkInterval || !this.isVisible) return;\n if (this.smoothBlinking) {\n setTimeout(function () {\n dom.addCssClass(this.element, \"ace_smooth-blinking\");\n }.bind(this));\n }\n var blink = function () {\n this.timeoutId = setTimeout(function () {\n update(false);\n }, 0.6 * this.blinkInterval);\n }.bind(this);\n this.intervalId = setInterval(function () {\n update(true);\n blink();\n }, this.blinkInterval);\n blink();\n };\n this.getPixelPosition = function (position, onScreen) {\n if (!this.config || !this.session) return {\n left: 0,\n top: 0\n };\n if (!position) 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) ? this.session.$bidiHandler.getPosLeft(pos.column) : pos.column * this.config.characterWidth);\n var cursorTop = (pos.row - (onScreen ? this.config.firstRowScreen : 0)) * this.config.lineHeight;\n return {\n left: cursorLeft,\n top: cursorTop\n };\n };\n this.update = function (config) {\n this.config = config;\n var selections = this.session.$selectionMarkers;\n var i = 0,\n cursorIndex = 0;\n if (selections === undefined || selections.length === 0) {\n selections = [{\n 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 || pixelPos.top < 0) && i > 1) {\n continue;\n }\n var style = (this.cursors[cursorIndex++] || this.addCursor()).style;\n if (!this.drawCursor) {\n style.left = pixelPos.left + \"px\";\n style.top = pixelPos.top + \"px\";\n style.width = config.characterWidth + \"px\";\n style.height = config.lineHeight + \"px\";\n } else {\n this.drawCursor(style, pixelPos, config, selections[i], this.session);\n }\n }\n while (this.cursors.length > cursorIndex) this.removeCursor();\n var overwrite = this.session.getOverwrite();\n this.$setOverwrite(overwrite);\n this.$pixelPos = pixelPos;\n this.restartTimer();\n };\n this.drawCursor = null;\n this.$setOverwrite = function (overwrite) {\n if (overwrite != this.overwrite) {\n this.overwrite = overwrite;\n if (overwrite) dom.addCssClass(this.element, \"ace_overwrite-cursors\");else dom.removeCssClass(this.element, \"ace_overwrite-cursors\");\n }\n };\n this.destroy = function () {\n clearInterval(this.intervalId);\n clearTimeout(this.timeoutId);\n };\n }).call(Cursor.prototype);\n exports.Cursor = Cursor;\n});\nace.define(\"ace/scrollbar\", [\"require\", \"exports\", \"module\", \"ace/lib/oop\", \"ace/lib/dom\", \"ace/lib/event\", \"ace/lib/event_emitter\"], function (acequire, exports, module) {\n \"use strict\";\n\n var oop = acequire(\"./lib/oop\");\n var dom = acequire(\"./lib/dom\");\n var event = acequire(\"./lib/event\");\n var EventEmitter = acequire(\"./lib/event_emitter\").EventEmitter;\n var MAX_SCROLL_H = 0x8000;\n var ScrollBar = function (parent) {\n this.element = dom.createElement(\"div\");\n this.element.className = \"ace_scrollbar ace_scrollbar\" + this.classSuffix;\n this.inner = dom.createElement(\"div\");\n this.inner.className = \"ace_scrollbar-inner\";\n this.element.appendChild(this.inner);\n parent.appendChild(this.element);\n this.setVisible(false);\n this.skipEvent = false;\n event.addListener(this.element, \"scroll\", this.onScroll.bind(this));\n event.addListener(this.element, \"mousedown\", event.preventDefault);\n };\n (function () {\n oop.implement(this, EventEmitter);\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);\n var VScrollBar = function (parent, renderer) {\n ScrollBar.call(this, parent);\n this.scrollTop = 0;\n this.scrollHeight = 0;\n renderer.$scrollbarWidth = this.width = dom.scrollbarWidth(parent.ownerDocument);\n this.inner.style.width = this.element.style.width = (this.width || 15) + 5 + \"px\";\n this.$minWidth = 0;\n };\n oop.inherits(VScrollBar, ScrollBar);\n (function () {\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\", {\n data: this.scrollTop\n });\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 = 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 }).call(VScrollBar.prototype);\n var HScrollBar = function (parent, renderer) {\n ScrollBar.call(this, parent);\n this.scrollLeft = 0;\n this.height = renderer.$scrollbarWidth;\n this.inner.style.height = this.element.style.height = (this.height || 15) + 5 + \"px\";\n };\n oop.inherits(HScrollBar, ScrollBar);\n (function () {\n this.classSuffix = '-h';\n this.onScroll = function () {\n if (!this.skipEvent) {\n this.scrollLeft = this.element.scrollLeft;\n this._emit(\"scroll\", {\n data: this.scrollLeft\n });\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 }).call(HScrollBar.prototype);\n exports.ScrollBar = VScrollBar; // backward compatibility\n exports.ScrollBarV = VScrollBar; // backward compatibility\n exports.ScrollBarH = HScrollBar; // backward compatibility\n\n exports.VScrollBar = VScrollBar;\n exports.HScrollBar = HScrollBar;\n});\nace.define(\"ace/renderloop\", [\"require\", \"exports\", \"module\", \"ace/lib/event\"], function (acequire, exports, module) {\n \"use strict\";\n\n var event = acequire(\"./lib/event\");\n var RenderLoop = function (onRender, win) {\n this.onRender = onRender;\n this.pending = false;\n this.changes = 0;\n this.window = win || window;\n };\n (function () {\n this.schedule = function (change) {\n this.changes = this.changes | change;\n if (!this.pending && this.changes) {\n this.pending = true;\n var _self = this;\n event.nextFrame(function () {\n _self.pending = false;\n var changes;\n while (changes = _self.changes) {\n _self.changes = 0;\n _self.onRender(changes);\n }\n }, this.window);\n }\n };\n }).call(RenderLoop.prototype);\n exports.RenderLoop = RenderLoop;\n});\nace.define(\"ace/layer/font_metrics\", [\"require\", \"exports\", \"module\", \"ace/lib/oop\", \"ace/lib/dom\", \"ace/lib/lang\", \"ace/lib/useragent\", \"ace/lib/event_emitter\"], function (acequire, exports, module) {\n var oop = acequire(\"../lib/oop\");\n var dom = acequire(\"../lib/dom\");\n var lang = acequire(\"../lib/lang\");\n var useragent = acequire(\"../lib/useragent\");\n var EventEmitter = acequire(\"../lib/event_emitter\").EventEmitter;\n var CHAR_COUNT = 0;\n var FontMetrics = exports.FontMetrics = function (parentEl) {\n this.el = dom.createElement(\"div\");\n this.$setMeasureNodeStyles(this.el.style, true);\n this.$main = dom.createElement(\"div\");\n this.$setMeasureNodeStyles(this.$main.style);\n this.$measureNode = dom.createElement(\"div\");\n this.$setMeasureNodeStyles(this.$measureNode.style);\n this.el.appendChild(this.$main);\n this.el.appendChild(this.$measureNode);\n parentEl.appendChild(this.el);\n if (!CHAR_COUNT) this.$testFractionalRect();\n this.$measureNode.innerHTML = lang.stringRepeat(\"X\", CHAR_COUNT);\n this.$characterSize = {\n width: 0,\n height: 0\n };\n this.checkForSizeChanges();\n };\n (function () {\n oop.implement(this, EventEmitter);\n this.$characterSize = {\n width: 0,\n height: 0\n };\n this.$testFractionalRect = function () {\n var el = dom.createElement(\"div\");\n this.$setMeasureNodeStyles(el.style);\n el.style.width = \"0.2px\";\n document.documentElement.appendChild(el);\n var w = el.getBoundingClientRect().width;\n if (w > 0 && w < 1) CHAR_COUNT = 50;else CHAR_COUNT = 100;\n el.parentNode.removeChild(el);\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 if (useragent.isIE < 8) {\n style[\"font-family\"] = \"inherit\";\n } else {\n style.font = \"inherit\";\n }\n style.overflow = isRoot ? \"hidden\" : \"visible\";\n };\n this.checkForSizeChanges = function () {\n var 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\", {\n data: size\n });\n }\n };\n this.$pollSizeChanges = function () {\n if (this.$pollSizeChangesTimer) return this.$pollSizeChangesTimer;\n var self = this;\n return this.$pollSizeChangesTimer = setInterval(function () {\n self.checkForSizeChanges();\n }, 500);\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 this.$measureSizes = function () {\n if (CHAR_COUNT === 50) {\n var rect = null;\n try {\n rect = this.$measureNode.getBoundingClientRect();\n } catch (e) {\n rect = {\n width: 0,\n height: 0\n };\n }\n var size = {\n height: rect.height,\n width: rect.width / CHAR_COUNT\n };\n } else {\n var size = {\n height: this.$measureNode.clientHeight,\n width: this.$measureNode.clientWidth / CHAR_COUNT\n };\n }\n if (size.width === 0 || size.height === 0) return null;\n return size;\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 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 this.destroy = function () {\n clearInterval(this.$pollSizeChangesTimer);\n if (this.el && this.el.parentNode) this.el.parentNode.removeChild(this.el);\n };\n }).call(FontMetrics.prototype);\n});\nace.define(\"ace/virtual_renderer\", [\"require\", \"exports\", \"module\", \"ace/lib/oop\", \"ace/lib/dom\", \"ace/config\", \"ace/lib/useragent\", \"ace/layer/gutter\", \"ace/layer/marker\", \"ace/layer/text\", \"ace/layer/cursor\", \"ace/scrollbar\", \"ace/scrollbar\", \"ace/renderloop\", \"ace/layer/font_metrics\", \"ace/lib/event_emitter\"], function (acequire, exports, module) {\n \"use strict\";\n\n var oop = acequire(\"./lib/oop\");\n var dom = acequire(\"./lib/dom\");\n var config = acequire(\"./config\");\n var useragent = acequire(\"./lib/useragent\");\n var GutterLayer = acequire(\"./layer/gutter\").Gutter;\n var MarkerLayer = acequire(\"./layer/marker\").Marker;\n var TextLayer = acequire(\"./layer/text\").Text;\n var CursorLayer = acequire(\"./layer/cursor\").Cursor;\n var HScrollBar = acequire(\"./scrollbar\").HScrollBar;\n var VScrollBar = acequire(\"./scrollbar\").VScrollBar;\n var RenderLoop = acequire(\"./renderloop\").RenderLoop;\n var FontMetrics = acequire(\"./layer/font_metrics\").FontMetrics;\n var EventEmitter = acequire(\"./lib/event_emitter\").EventEmitter;\n var editorCss = \".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;\\\n-moz-box-sizing: border-box;\\\n-webkit-box-sizing: border-box;\\\nbox-sizing: border-box;\\\nmin-width: 100%;\\\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;\\\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 {\\\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 {\\\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;\\\ntext-indent: -1em;\\\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: inherit;\\\ncolor: inherit;\\\nz-index: 1000;\\\nopacity: 1;\\\ntext-indent: 0;\\\n}\\\n.ace_layer {\\\nz-index: 1;\\\nposition: absolute;\\\noverflow: hidden;\\\nword-wrap: normal;\\\nwhite-space: pre;\\\nheight: 100%;\\\nwidth: 100%;\\\n-moz-box-sizing: border-box;\\\n-webkit-box-sizing: border-box;\\\nbox-sizing: border-box;\\\npointer-events: none;\\\n}\\\n.ace_gutter-layer {\\\nposition: relative;\\\nwidth: auto;\\\ntext-align: right;\\\npointer-events: auto;\\\n}\\\n.ace_text-layer {\\\nfont: inherit !important;\\\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;\\\n-moz-box-sizing: border-box;\\\n-webkit-box-sizing: border-box;\\\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_smooth-blinking .ace_cursor {\\\n-webkit-transition: opacity 0.18s;\\\ntransition: opacity 0.18s;\\\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_active-line {\\\nposition: absolute;\\\nz-index: 2;\\\n}\\\n.ace_marker-layer .ace_selected-word {\\\nposition: absolute;\\\nz-index: 4;\\\n-moz-box-sizing: border-box;\\\n-webkit-box-sizing: border-box;\\\nbox-sizing: border-box;\\\n}\\\n.ace_line .ace_fold {\\\n-moz-box-sizing: border-box;\\\n-webkit-box-sizing: border-box;\\\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: -webkit-linear-gradient(top, transparent, rgba(0, 0, 0, 0.1));\\\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;\\\n-moz-box-sizing: border-box;\\\n-webkit-box-sizing: border-box;\\\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 {\\\n-moz-box-sizing: border-box;\\\n-webkit-box-sizing: border-box;\\\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_fold-widget.ace_invalid {\\\nbackground-color: #FFB4B4;\\\nborder-color: #DE5555;\\\n}\\\n.ace_fade-fold-widgets .ace_fold-widget {\\\n-webkit-transition: opacity 0.4s ease 0.05s;\\\ntransition: opacity 0.4s ease 0.05s;\\\nopacity: 0;\\\n}\\\n.ace_fade-fold-widgets:hover .ace_fold-widget {\\\n-webkit-transition: opacity 0.05s ease 0.05s;\\\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_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_text-input-ios {\\\nposition: absolute !important;\\\ntop: -100000px !important;\\\nleft: -100000px !important;\\\n}\\\n\";\n dom.importCssString(editorCss, \"ace_editor.css\");\n var VirtualRenderer = function (container, theme) {\n var _self = this;\n this.container = container || dom.createElement(\"div\");\n this.$keepTextAreaAtCursor = !useragent.isOldIE;\n dom.addCssClass(this.container, \"ace_editor\");\n this.setTheme(theme);\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 this.scroller = dom.createElement(\"div\");\n this.scroller.className = \"ace_scroller\";\n this.container.appendChild(this.scroller);\n this.content = dom.createElement(\"div\");\n this.content.className = \"ace_content\";\n this.scroller.appendChild(this.content);\n this.$gutterLayer = new GutterLayer(this.$gutter);\n this.$gutterLayer.on(\"changeGutterWidth\", this.onGutterResize.bind(this));\n this.$markerBack = new MarkerLayer(this.content);\n var textLayer = this.$textLayer = new TextLayer(this.content);\n this.canvas = textLayer.element;\n this.$markerFront = new MarkerLayer(this.content);\n this.$cursorLayer = new CursorLayer(this.content);\n this.$horizScroll = false;\n this.$vScroll = false;\n this.scrollBar = 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) _self.session.setScrollTop(e.data - _self.scrollMargin.top);\n });\n this.scrollBarH.addEventListener(\"scroll\", function (e) {\n if (!_self.$scrollAnimation) _self.session.setScrollLeft(e.data - _self.scrollMargin.left);\n });\n this.scrollTop = 0;\n this.scrollLeft = 0;\n this.cursorPos = {\n row: 0,\n column: 0\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 this.$size = {\n width: 0,\n height: 0,\n scrollerHeight: 0,\n scrollerWidth: 0,\n $dirty: true\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 this.scrollMargin = {\n left: 0,\n right: 0,\n top: 0,\n bottom: 0,\n v: 0,\n h: 0\n };\n this.$loop = new RenderLoop(this.$renderChanges.bind(this), this.container.ownerDocument.defaultView);\n this.$loop.schedule(this.CHANGE_FULL);\n this.updateCharacterSize();\n this.setPadding(4);\n config.resetOptions(this);\n config._emit(\"renderer\", this);\n };\n (function () {\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 oop.implement(this, EventEmitter);\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 this.layerConfig.characterWidth = this.characterWidth = this.$textLayer.getCharacterWidth();\n this.layerConfig.lineHeight = this.lineHeight = this.$textLayer.getLineHeight();\n this.$updatePrintMargin();\n };\n this.setSession = function (session) {\n if (this.session) this.session.doc.off(\"changeNewLineMode\", this.onChangeNewLineMode);\n this.session = session;\n if (session && this.scrollMargin.top && session.getScrollTop() <= 0) session.setScrollTop(-this.scrollMargin.top);\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) return;\n this.$loop.schedule(this.CHANGE_FULL);\n this.session.$setFontMetrics(this.$fontMetrics);\n this.scrollBarH.scrollLeft = this.scrollBarV.scrollTop = null;\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) lastRow = Infinity;\n if (!this.$changedLines) {\n this.$changedLines = {\n firstRow: firstRow,\n lastRow: lastRow\n };\n } else {\n if (this.$changedLines.firstRow > firstRow) this.$changedLines.firstRow = firstRow;\n if (this.$changedLines.lastRow < lastRow) this.$changedLines.lastRow = lastRow;\n }\n if (this.$changedLines.lastRow < this.layerConfig.firstRow) {\n if (force) this.$changedLines.lastRow = this.layerConfig.lastRow;else return;\n }\n if (this.$changedLines.firstRow > this.layerConfig.lastRow) return;\n this.$loop.schedule(this.CHANGE_LINES);\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 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) this.$renderChanges(this.CHANGE_FULL, true);else this.$loop.schedule(this.CHANGE_FULL);\n };\n this.updateFontSize = function () {\n this.$textLayer.checkForSizeChanges();\n };\n this.$changes = 0;\n this.$updateSizeAsync = function () {\n if (this.$loop.pending) this.$size.$dirty = true;else this.onResize();\n };\n this.onResize = function (force, gutterWidth, width, height) {\n if (this.resizing > 2) return;else if (this.resizing > 0) this.resizing++;else this.resizing = force ? 1 : 0;\n var el = this.container;\n if (!height) height = el.clientHeight || el.scrollHeight;\n if (!width) width = el.clientWidth || el.scrollWidth;\n var changes = this.$updateCachedSize(force, gutterWidth, width, height);\n if (!this.$size.scrollerHeight || !width && !height) return this.resizing = 0;\n if (force) this.$gutterLayer.$padding = null;\n if (force) this.$renderChanges(changes | this.$changes, true);else this.$loop.schedule(changes | this.$changes);\n if (this.resizing) this.resizing = 0;\n this.scrollBarV.scrollLeft = this.scrollBarV.scrollTop = null;\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 size.scrollerHeight = size.height;\n if (this.$horizScroll) size.scrollerHeight -= this.scrollBarH.getHeight();\n this.scrollBarV.element.style.bottom = this.scrollBarH.getHeight() + \"px\";\n changes = changes | this.CHANGE_SCROLL;\n }\n if (width && (force || size.width != width)) {\n changes |= this.CHANGE_SIZE;\n size.width = width;\n if (gutterWidth == null) gutterWidth = this.$showGutter ? this.$gutter.offsetWidth : 0;\n this.gutterWidth = gutterWidth;\n this.scrollBarH.element.style.left = this.scroller.style.left = gutterWidth + \"px\";\n size.scrollerWidth = Math.max(0, width - gutterWidth - this.scrollBarV.getWidth());\n this.scrollBarH.element.style.right = this.scroller.style.right = this.scrollBarV.getWidth() + \"px\";\n this.scroller.style.bottom = this.scrollBarH.getHeight() + \"px\";\n if (this.session && this.session.getUseWrapMode() && this.adjustWrapLimit() || force) changes |= this.CHANGE_FULL;\n }\n size.$dirty = !width || !height;\n if (changes) this._signal(\"resize\", oldSize);\n return changes;\n };\n this.onGutterResize = function () {\n var gutterWidth = this.$showGutter ? this.$gutter.offsetWidth : 0;\n if (gutterWidth != this.gutterWidth) this.$changes |= this.$updateCachedSize(true, gutterWidth, this.$size.width, this.$size.height);\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 this.$loop.schedule(this.CHANGE_MARKER);\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 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 this.getFadeFoldWidgets = function () {\n return this.getOption(\"fadeFoldWidgets\");\n };\n this.setFadeFoldWidgets = function (show) {\n this.setOption(\"fadeFoldWidgets\", show);\n };\n this.setHighlightGutterLine = function (shouldHighlight) {\n this.setOption(\"highlightGutterLine\", shouldHighlight);\n };\n this.getHighlightGutterLine = function () {\n return this.getOption(\"highlightGutterLine\");\n };\n this.$updateGutterLineHighlight = function () {\n var pos = this.$cursorLayer.$pixelPos;\n var height = this.layerConfig.lineHeight;\n if (this.session.getUseWrapMode()) {\n var cursor = this.session.selection.getCursor();\n cursor.column = 0;\n pos = this.$cursorLayer.getPixelPosition(cursor, true);\n height *= this.session.getRowLength(cursor.row);\n }\n this.$gutterLineHighlight.style.top = pos.top - this.layerConfig.offset + \"px\";\n this.$gutterLineHighlight.style.height = height + \"px\";\n };\n this.$updatePrintMargin = function () {\n if (!this.$showPrintMargin && !this.$printMarginEl) return;\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 var style = this.$printMarginEl.style;\n style.left = this.characterWidth * this.$printMarginColumn + this.$padding + \"px\";\n style.visibility = this.$showPrintMargin ? \"visible\" : \"hidden\";\n if (this.session && this.session.$wrap == -1) 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.$keepTextAreaAtCursor) return;\n var config = this.layerConfig;\n var posTop = this.$cursorLayer.$pixelPos.top;\n var posLeft = this.$cursorLayer.$pixelPos.left;\n posTop -= config.offset;\n var style = this.textarea.style;\n var h = this.lineHeight;\n if (posTop < 0 || posTop > config.height - h) {\n style.top = style.left = \"0\";\n return;\n }\n var w = this.characterWidth;\n if (this.$composition) {\n var val = this.textarea.value.replace(/^\\x01+/, \"\");\n w *= this.session.$getStringScreenWidth(val)[0] + 2;\n h += 2;\n }\n posLeft -= this.scrollLeft;\n if (posLeft > this.$size.scrollerWidth - w) posLeft = this.$size.scrollerWidth - w;\n posLeft += this.gutterWidth;\n style.height = h + \"px\";\n style.width = w + \"px\";\n style.left = Math.min(posLeft, this.$size.scrollerWidth - w) + \"px\";\n style.top = Math.min(posTop, this.$size.height - h) + \"px\";\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) return lastRow - 1;\n return lastRow;\n };\n this.getLastVisibleRow = function () {\n return this.layerConfig.lastRow;\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 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) this.session.setScrollTop(-sm.top);\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 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 this.$frozen = false;\n this.freeze = function () {\n this.$frozen = true;\n };\n this.unfreeze = function () {\n this.$frozen = false;\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 this._signal(\"beforeRender\");\n if (this.session && this.session.$bidiHandler) this.session.$bidiHandler.updateCharacterWidths(this.$fontMetrics);\n var config = this.layerConfig;\n if (changes & this.CHANGE_FULL || changes & this.CHANGE_SIZE || changes & this.CHANGE_TEXT || changes & this.CHANGE_LINES || changes & this.CHANGE_SCROLL || changes & this.CHANGE_H_SCROLL) {\n changes |= this.$computeLayerConfig();\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();\n }\n }\n config = this.layerConfig;\n this.$updateScrollBarV();\n if (changes & this.CHANGE_H_SCROLL) this.$updateScrollBarH();\n this.$gutterLayer.element.style.marginTop = -config.offset + \"px\";\n this.content.style.marginTop = -config.offset + \"px\";\n this.content.style.width = config.width + 2 * this.$padding + \"px\";\n this.content.style.height = config.minHeight + \"px\";\n }\n if (changes & this.CHANGE_H_SCROLL) {\n this.content.style.marginLeft = -this.scrollLeft + \"px\";\n this.scroller.className = this.scrollLeft <= 0 ? \"ace_scroller\" : \"ace_scroller ace_scroll-left\";\n }\n if (changes & this.CHANGE_FULL) {\n this.$textLayer.update(config);\n if (this.$showGutter) this.$gutterLayer.update(config);\n this.$markerBack.update(config);\n this.$markerFront.update(config);\n this.$cursorLayer.update(config);\n this.$moveTextAreaToCursor();\n this.$highlightGutterLine && this.$updateGutterLineHighlight();\n this._signal(\"afterRender\");\n return;\n }\n if (changes & this.CHANGE_SCROLL) {\n if (changes & this.CHANGE_TEXT || changes & this.CHANGE_LINES) this.$textLayer.update(config);else this.$textLayer.scrollLines(config);\n if (this.$showGutter) this.$gutterLayer.update(config);\n this.$markerBack.update(config);\n this.$markerFront.update(config);\n this.$cursorLayer.update(config);\n this.$highlightGutterLine && this.$updateGutterLineHighlight();\n this.$moveTextAreaToCursor();\n this._signal(\"afterRender\");\n return;\n }\n if (changes & this.CHANGE_TEXT) {\n this.$textLayer.update(config);\n if (this.$showGutter) this.$gutterLayer.update(config);\n } else if (changes & this.CHANGE_LINES) {\n if (this.$updateLines() || changes & this.CHANGE_GUTTER && this.$showGutter) this.$gutterLayer.update(config);\n } else if (changes & this.CHANGE_TEXT || changes & this.CHANGE_GUTTER) {\n if (this.$showGutter) this.$gutterLayer.update(config);\n }\n if (changes & this.CHANGE_CURSOR) {\n this.$cursorLayer.update(config);\n this.$moveTextAreaToCursor();\n this.$highlightGutterLine && this.$updateGutterLineHighlight();\n }\n if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_FRONT)) {\n this.$markerFront.update(config);\n }\n if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_BACK)) {\n this.$markerBack.update(config);\n }\n this._signal(\"afterRender\");\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, Math.max((this.$minLines || 1) * this.lineHeight, height)) + this.scrollMargin.v + (this.$extraHeight || 0);\n if (this.$horizScroll) desiredHeight += this.scrollBarH.getHeight();\n if (this.$maxPixelHeight && desiredHeight > this.$maxPixelHeight) desiredHeight = this.$maxPixelHeight;\n var vScroll = height > maxHeight;\n if (desiredHeight != this.desiredHeight || this.$size.height != this.desiredHeight || vScroll != this.$vScroll) {\n if (vScroll != this.$vScroll) {\n this.$vScroll = vScroll;\n this.scrollBarV.setVisible(vScroll);\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 this._signal(\"autosize\");\n }\n };\n this.$computeLayerConfig = function () {\n var session = this.session;\n var size = this.$size;\n var hideScrollbars = size.height <= 2 * this.lineHeight;\n var screenLines = this.session.getScreenLength();\n var maxHeight = screenLines * this.lineHeight;\n var longestLine = this.$getLongestLine();\n var horizScroll = !hideScrollbars && (this.$hScrollBarAlwaysVisible || size.scrollerWidth - longestLine - 2 * this.$padding < 0);\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) this.$autosize();\n var offset = this.scrollTop % this.lineHeight;\n var minHeight = size.scrollerHeight + this.lineHeight;\n var scrollPastEnd = !this.$maxLines && this.$scrollPastEnd ? (size.scrollerHeight - this.lineHeight) * this.$scrollPastEnd : 0;\n maxHeight += scrollPastEnd;\n var sm = this.scrollMargin;\n this.session.setScrollTop(Math.max(-sm.top, Math.min(this.scrollTop, maxHeight - size.scrollerHeight + sm.bottom)));\n this.session.setScrollLeft(Math.max(-sm.left, Math.min(this.scrollLeft, longestLine + 2 * this.$padding - size.scrollerWidth + sm.right)));\n var vScroll = !hideScrollbars && (this.$vScrollBarAlwaysVisible || 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 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 firstRowScreen = session.documentToScreenRow(firstRow, 0);\n firstRowHeight = session.getRowLength(firstRow) * lineHeight;\n lastRow = Math.min(session.screenToDocumentRow(lastRow, 0), session.getLength() - 1);\n minHeight = size.scrollerHeight + session.getRowLength(lastRow) * lineHeight + firstRowHeight;\n offset = this.scrollTop - firstRowScreen * lineHeight;\n var changes = 0;\n if (this.layerConfig.width != longestLine) 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) longestLine = this.$getLongestLine();\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 return changes;\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 var layerConfig = this.layerConfig;\n if (firstRow > layerConfig.lastRow + 1) {\n return;\n }\n if (lastRow < layerConfig.firstRow) {\n return;\n }\n if (lastRow === Infinity) {\n if (this.$showGutter) this.$gutterLayer.update(layerConfig);\n this.$textLayer.update(layerConfig);\n return;\n }\n this.$textLayer.updateLines(layerConfig, firstRow, lastRow);\n return true;\n };\n this.$getLongestLine = function () {\n var charCount = this.session.getScreenWidth();\n if (this.showInvisibles && !this.session.$useWrapMode) charCount += 1;\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 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) return;\n var pos = this.$cursorLayer.getPixelPosition(cursor);\n var left = pos.left;\n var top = pos.top;\n var topMargin = $viewMargin && $viewMargin.top || 0;\n var bottomMargin = $viewMargin && $viewMargin.bottom || 0;\n var scrollTop = this.$scrollAnimation ? this.session.getScrollTop() : this.scrollTop;\n if (scrollTop + topMargin > top) {\n if (offset && scrollTop + topMargin > top + this.lineHeight) top -= offset * this.$size.scrollerHeight;\n if (top === 0) 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) top += offset * this.$size.scrollerHeight;\n this.session.setScrollTop(top + this.lineHeight - this.$size.scrollerHeight);\n }\n var scrollLeft = this.scrollLeft;\n if (scrollLeft > left) {\n if (left < this.$padding + 2 * this.layerConfig.characterWidth) 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 this.alignCursor = function (cursor, alignment) {\n if (typeof cursor == \"number\") cursor = {\n row: cursor,\n 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 this.session.setScrollTop(offset);\n return offset;\n };\n this.STEPS = 8;\n this.$calcSteps = function (fromValue, toValue) {\n var i = 0;\n var l = this.STEPS;\n var steps = [];\n var func = function (t, x_min, dx) {\n return dx * (Math.pow(t - 1, 3) + 1) + x_min;\n };\n for (i = 0; i < l; ++i) steps.push(func(i / this.STEPS, fromValue, toValue - fromValue));\n return steps;\n };\n this.scrollToLine = function (line, center, animate, callback) {\n var pos = this.$cursorLayer.getPixelPosition({\n row: line,\n column: 0\n });\n var offset = pos.top;\n if (center) offset -= this.$size.scrollerHeight / 2;\n var initialScroll = this.scrollTop;\n this.session.setScrollTop(offset);\n if (animate !== false) this.animateScrolling(initialScroll, callback);\n };\n this.animateScrolling = function (fromValue, callback) {\n var toValue = this.scrollTop;\n if (!this.$animatedScroll) return;\n var _self = this;\n if (fromValue == toValue) return;\n if (this.$scrollAnimation) {\n var oldSteps = this.$scrollAnimation.steps;\n if (oldSteps.length) {\n fromValue = oldSteps[0];\n if (fromValue == toValue) return;\n }\n }\n var steps = _self.$calcSteps(fromValue, toValue);\n this.$scrollAnimation = {\n from: fromValue,\n to: toValue,\n steps: steps\n };\n clearInterval(this.$timer);\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) 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) return true;\n if (deltaY > 0 && this.session.getScrollTop() + this.$size.scrollerHeight - this.layerConfig.maxHeight < -1 + this.scrollMargin.bottom) return true;\n if (deltaX < 0 && this.session.getScrollLeft() >= 1 - this.scrollMargin.left) return true;\n if (deltaX > 0 && this.session.getScrollLeft() + this.$size.scrollerWidth - this.layerConfig.width < -1 + this.scrollMargin.right) return true;\n };\n this.pixelToScreenCoordinates = function (x, y) {\n var canvasPos = this.scroller.getBoundingClientRect();\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 = Math.round(offset);\n return {\n row: row,\n column: col,\n side: offset - col > 0 ? 1 : -1,\n offsetX: offsetX\n };\n };\n this.screenToTextCoordinates = function (x, y) {\n var canvasPos = this.scroller.getBoundingClientRect();\n var offsetX = x + this.scrollLeft - canvasPos.left - this.$padding;\n var col = Math.round(offsetX / this.characterWidth);\n var row = (y + this.scrollTop - canvasPos.top) / this.lineHeight;\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 var x = this.$padding + (this.session.$bidiHandler.isBidiRow(pos.row, row) ? this.session.$bidiHandler.getPosLeft(pos.column) : Math.round(pos.column * this.characterWidth));\n var y = pos.row * this.lineHeight;\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 (position) {\n if (!this.$composition) this.$composition = {\n keepTextAreaAtCursor: this.$keepTextAreaAtCursor,\n cssText: this.textarea.style.cssText\n };\n this.$keepTextAreaAtCursor = true;\n dom.addCssClass(this.textarea, \"ace_composition\");\n this.textarea.style.cssText = \"\";\n this.$moveTextAreaToCursor();\n };\n this.setCompositionText = function (text) {\n this.$moveTextAreaToCursor();\n };\n this.hideComposition = function () {\n if (!this.$composition) return;\n dom.removeCssClass(this.textarea, \"ace_composition\");\n this.$keepTextAreaAtCursor = this.$composition.keepTextAreaAtCursor;\n this.textarea.style.cssText = this.$composition.cssText;\n this.$composition = null;\n };\n this.setTheme = function (theme, cb) {\n var _self = this;\n this.$themeId = theme;\n _self._dispatchEvent('themeChange', {\n 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 function afterLoad(module) {\n if (_self.$themeId != theme) return cb && cb();\n if (!module || !module.cssClass) throw new Error(\"couldn't load module \" + theme + \" or it didn't call define\");\n dom.importCssString(module.cssText, module.cssClass, _self.container.ownerDocument);\n if (_self.theme) dom.removeCssClass(_self.container, _self.theme.cssClass);\n var padding = \"padding\" in module ? module.padding : \"padding\" in (_self.theme || {}) ? 4 : _self.$padding;\n if (_self.$padding && padding != _self.$padding) _self.setPadding(padding);\n _self.$theme = module.cssClass;\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 _self._dispatchEvent('themeLoaded', {\n theme: module\n });\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 this.setCursorStyle = function (style) {\n if (this.scroller.style.cursor != style) this.scroller.style.cursor = style;\n };\n this.setMouseCursor = function (cursorStyle) {\n this.scroller.style.cursor = cursorStyle;\n };\n this.destroy = function () {\n this.$textLayer.destroy();\n this.$cursorLayer.destroy();\n };\n }).call(VirtualRenderer.prototype);\n config.defineOptions(VirtualRenderer.prototype, \"renderer\", {\n animatedScroll: {\n initialValue: false\n },\n showInvisibles: {\n set: function (value) {\n if (this.$textLayer.setShowInvisibles(value)) this.$loop.schedule(this.CHANGE_TEXT);\n },\n initialValue: false\n },\n showPrintMargin: {\n set: function () {\n this.$updatePrintMargin();\n },\n initialValue: true\n },\n printMarginColumn: {\n set: function () {\n this.$updatePrintMargin();\n },\n initialValue: 80\n },\n printMargin: {\n set: function (val) {\n if (typeof val == \"number\") 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 },\n initialValue: true\n },\n showLineNumbers: {\n set: function (show) {\n this.$gutterLayer.setShowLineNumbers(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)) this.$loop.schedule(this.CHANGE_TEXT);\n },\n initialValue: true\n },\n highlightGutterLine: {\n set: function (shouldHighlight) {\n if (!this.$gutterLineHighlight) {\n this.$gutterLineHighlight = dom.createElement(\"div\");\n this.$gutterLineHighlight.className = \"ace_gutter-active-line\";\n this.$gutter.appendChild(this.$gutterLineHighlight);\n return;\n }\n this.$gutterLineHighlight.style.display = shouldHighlight ? \"\" : \"none\";\n if (this.$cursorLayer.$pixelPos) this.$updateGutterLineHighlight();\n },\n initialValue: false,\n value: true\n },\n hScrollBarAlwaysVisible: {\n set: function (val) {\n if (!this.$hScrollBarAlwaysVisible || !this.$horizScroll) this.$loop.schedule(this.CHANGE_SCROLL);\n },\n initialValue: false\n },\n vScrollBarAlwaysVisible: {\n set: function (val) {\n if (!this.$vScrollBarAlwaysVisible || !this.$vScroll) this.$loop.schedule(this.CHANGE_SCROLL);\n },\n initialValue: false\n },\n fontSize: {\n set: function (size) {\n if (typeof size == \"number\") 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 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) 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) {\n this.setTheme(val);\n },\n get: function () {\n return this.$themeId || this.theme;\n },\n initialValue: \"./theme/textmate\",\n handlesSet: true\n }\n });\n exports.VirtualRenderer = VirtualRenderer;\n});\nace.define(\"ace/worker/worker_client\", [\"require\", \"exports\", \"module\", \"ace/lib/oop\", \"ace/lib/net\", \"ace/lib/event_emitter\", \"ace/config\"], function (acequire, exports, module) {\n \"use strict\";\n\n var oop = acequire(\"../lib/oop\");\n var net = acequire(\"../lib/net\");\n var EventEmitter = acequire(\"../lib/event_emitter\").EventEmitter;\n var config = acequire(\"../config\");\n function $workerBlob(workerUrl, mod) {\n var script = mod.src;\n \"importScripts('\" + net.qualifyURL(workerUrl) + \"');\";\n try {\n return new Blob([script], {\n \"type\": \"application/javascript\"\n });\n } catch (e) {\n // 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 function createWorker(workerUrl, mod) {\n var blob = $workerBlob(workerUrl, mod);\n var URL = window.URL || window.webkitURL;\n var blobURL = URL.createObjectURL(blob);\n return new Worker(blobURL);\n }\n var WorkerClient = function (topLevelNamespaces, mod, classname, workerUrl, importScripts) {\n this.$sendDeltaQueue = this.$sendDeltaQueue.bind(this);\n this.changeListener = this.changeListener.bind(this);\n this.onMessage = this.onMessage.bind(this);\n if (acequire.nameToUrl && !acequire.toUrl) acequire.toUrl = acequire.nameToUrl;\n if (config.get(\"packaged\") || !acequire.toUrl) {\n workerUrl = workerUrl || config.moduleUrl(mod.id, \"worker\");\n } else {\n var normalizePath = this.$normalizePath;\n workerUrl = workerUrl || normalizePath(acequire.toUrl(\"ace/worker/worker.js\", null, \"_\"));\n var tlns = {};\n topLevelNamespaces.forEach(function (ns) {\n tlns[ns] = normalizePath(acequire.toUrl(ns, null, \"_\").replace(/(\\.js)?(\\?.*)?$/, \"\"));\n });\n }\n this.$worker = createWorker(workerUrl, mod);\n if (importScripts) {\n this.send(\"importScripts\", importScripts);\n }\n this.$worker.postMessage({\n init: true,\n tlns: tlns,\n module: mod.id,\n classname: classname\n });\n this.callbackId = 1;\n this.callbacks = {};\n this.$worker.onmessage = this.onMessage;\n };\n (function () {\n oop.implement(this, EventEmitter);\n this.onMessage = function (e) {\n var msg = e.data;\n switch (msg.type) {\n case \"event\":\n this._signal(msg.name, {\n data: msg.data\n });\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 this.reportError = function (err) {\n window.console && console.error && console.error(err);\n };\n this.$normalizePath = function (path) {\n return net.qualifyURL(path);\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) this.$doc.off(\"change\", this.changeListener);\n this.$doc = null;\n };\n this.send = function (cmd, args) {\n this.$worker.postMessage({\n command: cmd,\n 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 this.emit = function (event, data) {\n try {\n this.$worker.postMessage({\n event: event,\n data: {\n data: data.data\n }\n });\n } catch (ex) {\n console.error(ex.stack);\n }\n };\n this.attachToDocument = function (doc) {\n if (this.$doc) this.terminate();\n this.$doc = doc;\n this.call(\"setValue\", [doc.getValue()]);\n doc.on(\"change\", this.changeListener);\n };\n this.changeListener = function (delta) {\n if (!this.deltaQueue) {\n this.deltaQueue = [];\n setTimeout(this.$sendDeltaQueue, 0);\n }\n if (delta.action == \"insert\") this.deltaQueue.push(delta.start, delta.lines);else this.deltaQueue.push(delta.start, delta.end);\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 this.emit(\"change\", {\n data: q\n });\n };\n }).call(WorkerClient.prototype);\n var UIWorkerClient = function (topLevelNamespaces, mod, classname) {\n this.$sendDeltaQueue = this.$sendDeltaQueue.bind(this);\n this.changeListener = this.changeListener.bind(this);\n this.callbackId = 1;\n this.callbacks = {};\n this.messageBuffer = [];\n var main = null;\n var emitSync = false;\n var sender = Object.create(EventEmitter);\n var _self = this;\n this.$worker = {};\n this.$worker.terminate = function () {};\n this.$worker.postMessage = function (e) {\n _self.messageBuffer.push(e);\n if (main) {\n if (emitSync) setTimeout(processNext);else processNext();\n }\n };\n this.setEmitSync = function (val) {\n emitSync = val;\n };\n var processNext = function () {\n var msg = _self.messageBuffer.shift();\n if (msg.command) main[msg.command].apply(main, msg.args);else if (msg.event) sender._signal(msg.event, msg.data);\n };\n sender.postMessage = function (msg) {\n _self.onMessage({\n data: msg\n });\n };\n sender.callback = function (data, callbackId) {\n this.postMessage({\n type: \"call\",\n id: callbackId,\n data: data\n });\n };\n sender.emit = function (name, data) {\n this.postMessage({\n type: \"event\",\n name: name,\n data: data\n });\n };\n config.loadModule([\"worker\", mod], function (Main) {\n main = new Main[classname](sender);\n while (_self.messageBuffer.length) processNext();\n });\n };\n UIWorkerClient.prototype = WorkerClient.prototype;\n exports.UIWorkerClient = UIWorkerClient;\n exports.WorkerClient = WorkerClient;\n exports.createWorker = createWorker;\n});\nace.define(\"ace/placeholder\", [\"require\", \"exports\", \"module\", \"ace/range\", \"ace/lib/event_emitter\", \"ace/lib/oop\"], function (acequire, exports, module) {\n \"use strict\";\n\n var Range = acequire(\"./range\").Range;\n var EventEmitter = acequire(\"./lib/event_emitter\").EventEmitter;\n var oop = acequire(\"./lib/oop\");\n var 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 this.$onCursorChange = function () {\n setTimeout(function () {\n _self.onCursorChange();\n });\n };\n this.$pos = pos;\n var undoStack = session.getUndoManager().$undoStack || session.getUndoManager().$undostack || {\n length: -1\n };\n this.$undoStackDepth = undoStack.length;\n this.setup();\n session.selection.on(\"changeCursor\", this.$onCursorChange);\n };\n (function () {\n oop.implement(this, EventEmitter);\n this.setup = function () {\n var _self = this;\n var doc = this.doc;\n var session = this.session;\n this.selectionBefore = session.selection.toJSON();\n if (session.selection.inMultiSelectMode) session.selection.toSingleRange();\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) return this.updateAnchors(delta);\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 this.updateAnchors(delta);\n if (inMainRange) this.length += lengthDiff;\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 = {\n row: otherPos.row,\n column: otherPos.column + distanceFromStart\n };\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 = {\n row: otherPos.row,\n column: otherPos.column + distanceFromStart\n };\n this.doc.remove(new Range(newPos.row, newPos.column, newPos.row, newPos.column - lengthDiff));\n }\n }\n }\n this.$updating = false;\n this.updateMarkers();\n };\n this.updateAnchors = function (delta) {\n this.pos.onChange(delta);\n for (var i = this.others.length; i--;) this.others[i].onChange(delta);\n this.updateMarkers();\n };\n this.updateMarkers = function () {\n if (this.$updating) 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--;) updateMarker(this.others[i], this.othersClass);\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) 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(true);\n }\n if (this.selectionBefore) this.session.selection.fromJSON(this.selectionBefore);\n };\n }).call(PlaceHolder.prototype);\n exports.PlaceHolder = PlaceHolder;\n});\nace.define(\"ace/mouse/multi_select_handler\", [\"require\", \"exports\", \"module\", \"ace/lib/event\", \"ace/lib/useragent\"], function (acequire, exports, module) {\n var event = acequire(\"../lib/event\");\n var useragent = acequire(\"../lib/useragent\");\n function isSamePoint(p1, p2) {\n return p1.row == p2.row && p1.column == p2.column;\n }\n function 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 if (ctrl && useragent.isMac) button = ev.button;\n if (e.editor.inMultiSelectMode && button == 2) {\n e.editor.textInput.onContextMenu(e.domEvent);\n return;\n }\n if (!ctrl && !alt && !accel) {\n if (button === 0 && e.editor.inMultiSelectMode) e.editor.exitMultiSelectMode();\n return;\n }\n if (button !== 0) return;\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 var mouseX = e.x,\n mouseY = e.y;\n var onMouseSelection = function (e) {\n mouseX = e.clientX;\n mouseY = e.clientY;\n };\n var session = editor.session;\n var screenAnchor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY);\n var screenCursor = screenAnchor;\n var selectionMode;\n if (editor.$mouseHandler.$enableJumpToDef) {\n if (ctrl && alt || accel && alt) selectionMode = shift ? \"block\" : \"add\";else if (alt && editor.$blockSelectEnabled) selectionMode = \"block\";\n } else {\n if (accel && !alt) {\n selectionMode = \"add\";\n if (!isMultiSelect && shift) return;\n } else if (alt && editor.$blockSelectEnabled) {\n selectionMode = \"block\";\n }\n }\n if (selectionMode && useragent.isMac && ev.ctrlKey) {\n editor.$mouseHandler.cancelContextMenu();\n }\n if (selectionMode == \"add\") {\n if (!isMultiSelect && inSelection) return; // dragging\n\n if (!isMultiSelect) {\n var range = selection.toOrientedRange();\n editor.addSelectionMarker(range);\n }\n var oldRange = selection.rangeList.rangeAtPoint(pos);\n editor.$blockScrolling++;\n editor.inVirtualSelectionMode = true;\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 if (oldRange && tmpSel.isEmpty() && isSamePoint(oldRange.cursor, tmpSel.cursor)) selection.substractPoint(tmpSel.cursor);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.$blockScrolling--;\n editor.inVirtualSelectionMode = false;\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 if (isSamePoint(screenCursor, newCursor) && isSamePoint(cursor, selection.lead)) return;\n screenCursor = newCursor;\n editor.$blockScrolling++;\n editor.selection.moveToPosition(cursor);\n editor.renderer.scrollCursorIntoView();\n editor.removeSelectionMarkers(rectSel);\n rectSel = selection.rectangularRangeBlock(screenCursor, screenAnchor);\n if (editor.$mouseHandler.$clickSelection && rectSel.length == 1 && rectSel[0].isEmpty()) rectSel[0] = editor.$mouseHandler.$clickSelection.clone();\n rectSel.forEach(editor.addSelectionMarker, editor);\n editor.updateSelectionMarkers();\n editor.$blockScrolling--;\n };\n editor.$blockScrolling++;\n if (isMultiSelect && !accel) {\n selection.toSingleRange();\n } else if (!isMultiSelect && accel) {\n initialRange = selection.toOrientedRange();\n editor.addSelectionMarker(initialRange);\n }\n if (shift) screenAnchor = session.documentToScreenPosition(selection.lead);else selection.moveToPosition(pos);\n editor.$blockScrolling--;\n screenCursor = {\n row: -1,\n column: -1\n };\n var onMouseSelectionEnd = function (e) {\n clearInterval(timerId);\n editor.removeSelectionMarkers(rectSel);\n if (!rectSel.length) rectSel = [selection.toOrientedRange()];\n editor.$blockScrolling++;\n if (initialRange) {\n editor.removeSelectionMarker(initialRange);\n selection.toSingleRange(initialRange);\n }\n for (var i = 0; i < rectSel.length; i++) selection.addRange(rectSel[i]);\n editor.inVirtualSelectionMode = false;\n editor.$mouseHandler.$clickSelection = null;\n editor.$blockScrolling--;\n };\n var onSelectionInterval = blockSelect;\n event.capture(editor.container, onMouseSelection, onMouseSelectionEnd);\n var timerId = setInterval(function () {\n onSelectionInterval();\n }, 20);\n return e.preventDefault();\n }\n }\n exports.onMouseDown = onMouseDown;\n});\nace.define(\"ace/commands/multi_select_commands\", [\"require\", \"exports\", \"module\", \"ace/keyboard/hash_handler\"], function (acequire, exports, module) {\n exports.defaultCommands = [{\n name: \"addCursorAbove\",\n exec: function (editor) {\n editor.selectMoreLines(-1);\n },\n bindKey: {\n win: \"Ctrl-Alt-Up\",\n mac: \"Ctrl-Alt-Up\"\n },\n scrollIntoView: \"cursor\",\n readOnly: true\n }, {\n name: \"addCursorBelow\",\n exec: function (editor) {\n editor.selectMoreLines(1);\n },\n bindKey: {\n win: \"Ctrl-Alt-Down\",\n mac: \"Ctrl-Alt-Down\"\n },\n scrollIntoView: \"cursor\",\n readOnly: true\n }, {\n name: \"addCursorAboveSkipCurrent\",\n exec: function (editor) {\n editor.selectMoreLines(-1, true);\n },\n bindKey: {\n win: \"Ctrl-Alt-Shift-Up\",\n mac: \"Ctrl-Alt-Shift-Up\"\n },\n scrollIntoView: \"cursor\",\n readOnly: true\n }, {\n name: \"addCursorBelowSkipCurrent\",\n exec: function (editor) {\n editor.selectMoreLines(1, true);\n },\n bindKey: {\n win: \"Ctrl-Alt-Shift-Down\",\n mac: \"Ctrl-Alt-Shift-Down\"\n },\n scrollIntoView: \"cursor\",\n readOnly: true\n }, {\n name: \"selectMoreBefore\",\n exec: function (editor) {\n editor.selectMore(-1);\n },\n bindKey: {\n win: \"Ctrl-Alt-Left\",\n mac: \"Ctrl-Alt-Left\"\n },\n scrollIntoView: \"cursor\",\n readOnly: true\n }, {\n name: \"selectMoreAfter\",\n exec: function (editor) {\n editor.selectMore(1);\n },\n bindKey: {\n win: \"Ctrl-Alt-Right\",\n mac: \"Ctrl-Alt-Right\"\n },\n scrollIntoView: \"cursor\",\n readOnly: true\n }, {\n name: \"selectNextBefore\",\n exec: function (editor) {\n editor.selectMore(-1, true);\n },\n bindKey: {\n win: \"Ctrl-Alt-Shift-Left\",\n mac: \"Ctrl-Alt-Shift-Left\"\n },\n scrollIntoView: \"cursor\",\n readOnly: true\n }, {\n name: \"selectNextAfter\",\n exec: function (editor) {\n editor.selectMore(1, true);\n },\n bindKey: {\n win: \"Ctrl-Alt-Shift-Right\",\n mac: \"Ctrl-Alt-Shift-Right\"\n },\n scrollIntoView: \"cursor\",\n readOnly: true\n }, {\n name: \"splitIntoLines\",\n exec: function (editor) {\n editor.multiSelect.splitIntoLines();\n },\n bindKey: {\n win: \"Ctrl-Alt-L\",\n mac: \"Ctrl-Alt-L\"\n },\n readOnly: true\n }, {\n name: \"alignCursors\",\n exec: function (editor) {\n editor.alignCursors();\n },\n bindKey: {\n win: \"Ctrl-Alt-A\",\n mac: \"Ctrl-Alt-A\"\n },\n scrollIntoView: \"cursor\"\n }, {\n name: \"findAll\",\n exec: function (editor) {\n editor.findAll();\n },\n bindKey: {\n win: \"Ctrl-Alt-K\",\n mac: \"Ctrl-Alt-G\"\n },\n scrollIntoView: \"cursor\",\n readOnly: true\n }];\n exports.multiSelectCommands = [{\n name: \"singleSelection\",\n bindKey: \"esc\",\n exec: function (editor) {\n editor.exitMultiSelectMode();\n },\n scrollIntoView: \"cursor\",\n readOnly: true,\n isAvailable: function (editor) {\n return editor && editor.inMultiSelectMode;\n }\n }];\n var HashHandler = acequire(\"../keyboard/hash_handler\").HashHandler;\n exports.keyboardHandler = new HashHandler(exports.multiSelectCommands);\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 (acequire, exports, module) {\n var RangeList = acequire(\"./range_list\").RangeList;\n var Range = acequire(\"./range\").Range;\n var Selection = acequire(\"./selection\").Selection;\n var onMouseDown = acequire(\"./mouse/multi_select_handler\").onMouseDown;\n var event = acequire(\"./lib/event\");\n var lang = acequire(\"./lib/lang\");\n var commands = acequire(\"./commands/multi_select_commands\");\n exports.commands = commands.defaultCommands.concat(commands.multiSelectCommands);\n var Search = acequire(\"./search\").Search;\n var search = new Search();\n function 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 }\n var EditSession = acequire(\"./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) return;\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 if (!range.cursor) range.cursor = range.end;\n var removed = this.rangeList.add(range);\n this.$onAddRange(range);\n if (removed.length) this.$onRemoveRange(removed);\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 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) this.$onRemoveRange(removed);\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) this.$onRemoveRange(removed);else if (this.ranges[0]) this.fromOrientedRange(this.ranges[0]);\n };\n this.$onAddRange = function (range) {\n this.rangeCount = this.rangeList.ranges.length;\n this.ranges.unshift(range);\n this._signal(\"addRange\", {\n 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 for (var i = removed.length; i--;) {\n var index = this.ranges.indexOf(removed[i]);\n this.ranges.splice(index, 1);\n }\n this._signal(\"removeRange\", {\n 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 lastRange = lastRange || this.ranges[0];\n if (lastRange && !lastRange.isEqual(this.getRange())) this.fromOrientedRange(lastRange);\n };\n this.$initRangeList = function () {\n if (this.rangeList) return;\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 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 this.toSingleRange();\n this.setSelectionRange(range, lastRange.cursor == lastRange.start);\n } else {\n var range = this.getRange();\n var isBackwards = this.isBackwards();\n var startRow = range.start.row;\n var endRow = range.end.row;\n if (startRow == endRow) {\n if (isBackwards) var start = range.end,\n end = range.start;else var start = range.start,\n end = range.end;\n this.addRange(Range.fromPoints(end, end));\n this.addRange(Range.fromPoints(start, start));\n return;\n }\n var rectSel = [];\n var r = this.getLineRange(startRow, true);\n r.start.column = range.start.column;\n rectSel.push(r);\n for (var i = startRow + 1; i < endRow; i++) rectSel.push(this.getLineRange(i, true));\n r = this.getLineRange(endRow, true);\n r.end.column = range.end.column;\n rectSel.push(r);\n rectSel.forEach(this.addRange, this);\n }\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 this.toSingleRange();\n this.setSelectionRange(range, lastRange.cursor == lastRange.start);\n } else {\n var cursor = this.session.documentToScreenPosition(this.selectionLead);\n var anchor = this.session.documentToScreenPosition(this.selectionAnchor);\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 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 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 if (startColumn < 0) startColumn = 0;\n if (startRow < 0) startRow = 0;\n if (startRow == endRow) includeEmptyLines = true;\n for (var row = startRow; row <= endRow; row++) {\n var range = Range.fromPoints(this.session.screenToDocumentPosition(row, startColumn, startOffsetX), this.session.screenToDocumentPosition(row, endColumn, endOffsetX));\n if (range.isEmpty()) {\n if (docEnd && isSamePoint(range.end, docEnd)) break;\n var docEnd = range.end;\n }\n range.cursor = xBackwards ? range.start : range.end;\n rectSel.push(range);\n }\n if (yBackwards) rectSel.reverse();\n if (!includeEmptyLines) {\n var end = rectSel.length - 1;\n while (rectSel[end].isEmpty() && end > 0) end--;\n if (end > 0) {\n var start = 0;\n while (rectSel[start].isEmpty()) start++;\n }\n for (var i = end; i >= start; i--) {\n if (rectSel[i].isEmpty()) rectSel.splice(i, 1);\n }\n }\n return rectSel;\n };\n }).call(Selection.prototype);\n var Editor = acequire(\"./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) orientedRange.cursor = orientedRange.end;\n var style = this.getSelectionStyle();\n orientedRange.marker = this.session.addMarker(orientedRange, \"ace_selection\", style);\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) return;\n this.session.removeMarker(range.marker);\n var index = this.session.$selectionMarkers.indexOf(range);\n if (index != -1) this.session.$selectionMarkers.splice(index, 1);\n this.session.selectionMarkerCount = this.session.$selectionMarkers.length;\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) continue;\n this.session.removeMarker(range.marker);\n var index = markerList.indexOf(range);\n if (index != -1) markerList.splice(index, 1);\n }\n this.session.selectionMarkerCount = markerList.length;\n };\n this.$onAddRange = function (e) {\n this.addSelectionMarker(e.range);\n this.renderer.updateCursor();\n this.renderer.updateBackMarkers();\n };\n this.$onRemoveRange = function (e) {\n this.removeSelectionMarkers(e.ranges);\n this.renderer.updateCursor();\n this.renderer.updateBackMarkers();\n };\n this.$onMultiSelect = function (e) {\n if (this.inMultiSelectMode) return;\n this.inMultiSelectMode = true;\n this.setStyle(\"ace_multiselect\");\n this.keyBinding.addKeyboardHandler(commands.keyboardHandler);\n this.commands.setDefaultHandler(\"exec\", this.$onMultiSelectExec);\n this.renderer.updateCursor();\n this.renderer.updateBackMarkers();\n };\n this.$onSingleSelect = function (e) {\n if (this.session.multiSelect.inVirtualMode) return;\n this.inMultiSelectMode = false;\n this.unsetStyle(\"ace_multiselect\");\n this.keyBinding.removeKeyboardHandler(commands.keyboardHandler);\n this.commands.removeDefaultHandler(\"exec\", this.$onMultiSelectExec);\n this.renderer.updateCursor();\n this.renderer.updateBackMarkers();\n this._emit(\"changeSelection\");\n };\n this.$onMultiSelectExec = function (e) {\n var command = e.command;\n var editor = e.editor;\n if (!editor.multiSelect) 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) 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 if (!ranges.length) return cmd.exec ? cmd.exec(this, args || {}) : cmd(this, args || {});\n var reg = selection._eventRegistry;\n selection._eventRegistry = {};\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) 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) result = cmdResult;\n tmpSel.toOrientedRange(ranges[i]);\n }\n tmpSel.detach();\n this.selection = session.selection = selection;\n this.inVirtualSelectionMode = false;\n selection._eventRegistry = reg;\n selection.mergeOverlappingRanges();\n var anim = this.renderer.$scrollAnimation;\n this.onCursorChange();\n this.onSelectionChange();\n if (anim && anim.from == anim.to) this.renderer.animateScrolling(anim.from);\n return result;\n };\n this.exitMultiSelectMode = function () {\n if (!this.inMultiSelectMode || this.inVirtualSelectionMode) return;\n this.multiSelect.toSingleRange();\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) text = \"\";\n } else if (!this.selection.isEmpty()) {\n text = this.session.getTextRange(this.getSelectionRange());\n }\n return text;\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) return;\n var pos = anchor == this.multiSelect.anchor ? range.cursor == range.start ? range.end : range.start : range.cursor;\n if (pos.row != anchor.row || this.session.$clipPositionToDocument(pos.row, pos.column).column != anchor.column) this.multiSelect.toSingleRange(this.multiSelect.toOrientedRange());\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() ? this.selection.getWordRange() : this.selection.getRange();\n options.needle = this.session.getTextRange(range);\n }\n this.$search.set(options);\n var ranges = this.$search.findAll(this.session);\n if (!ranges.length) return 0;\n this.$blockScrolling += 1;\n var selection = this.multiSelect;\n if (!additive) selection.toSingleRange(ranges[0]);\n for (var i = ranges.length; i--;) selection.addRange(ranges[i], true);\n if (range && selection.rangeList.rangeAtPoint(range.start)) selection.addRange(range, true);\n this.$blockScrolling -= 1;\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 var screenLead = this.session.documentToScreenPosition(range.cursor);\n if (this.selection.$desiredColumn) screenLead.column = this.selection.$desiredColumn;\n var lead = this.session.screenToDocumentPosition(screenLead.row + dir, screenLead.column);\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 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 newRange.desiredColumn = screenLead.column;\n if (!this.selection.inMultiSelectMode) {\n this.selection.addRange(range);\n } else {\n if (skip) var toRemove = range.cursor;\n }\n this.selection.addRange(newRange);\n if (toRemove) 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 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 var words = [];\n for (var i = all.length; i--;) {\n var range = all[i];\n words.unshift(session.getTextRange(range));\n }\n if (dir < 0) words.unshift(words.pop());else words.push(words.shift());\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 };\n this.selectMore = function (dir, skip, stopAtFirst) {\n var session = this.session;\n var sel = session.multiSelect;\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) return;\n }\n var needle = session.getTextRange(range);\n var newRange = find(session, needle, dir);\n if (newRange) {\n newRange.cursor = dir == -1 ? newRange.start : newRange.end;\n this.$blockScrolling += 1;\n this.session.unfold(newRange);\n this.multiSelect.addRange(newRange);\n this.$blockScrolling -= 1;\n this.renderer.scrollCursorIntoView(null, 0.5);\n }\n if (skip) 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) return true;\n row = r.cursor.row;\n });\n if (!ranges.length || sameRowRanges.length == ranges.length - 1) {\n var range = this.selection.getRange();\n var fr = range.start.row,\n 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 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({\n row: fr,\n column: 0\n }, 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 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) spaceOffset = 0;\n if (p.column > maxCol) maxCol = p.column;\n if (spaceOffset < minSpace) 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) session.insert(p, lang.stringRepeat(\" \", l - d));else session.remove(new Range(p.row, p.column, p.row, p.column - l + d));\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 this.$reAlignText = function (lines, forceLeft) {\n var isLeftAligned = true,\n isRightAligned = true;\n var startW, textW, endW;\n return lines.map(function (line) {\n var m = line.match(/(\\s*)(.*?)(\\s*)([=:].*)/);\n if (!m) return [line];\n if (startW == null) {\n startW = m[1].length;\n textW = m[2].length;\n endW = m[3].length;\n return m;\n }\n if (startW + textW + endW != m[1].length + m[2].length + m[3].length) isRightAligned = false;\n if (startW != m[1].length) isLeftAligned = false;\n if (startW > m[1].length) startW = m[1].length;\n if (textW < m[2].length) textW = m[2].length;\n if (endW > m[3].length) endW = m[3].length;\n return m;\n }).map(forceLeft ? alignLeft : isLeftAligned ? isRightAligned ? alignRight : alignLeft : unAlign);\n function spaces(n) {\n return lang.stringRepeat(\" \", n);\n }\n function alignLeft(m) {\n return !m[2] ? m[0] : spaces(startW) + m[2] + spaces(textW - m[2].length + endW) + m[4].replace(/^([=:])\\s+/, \"$1 \");\n }\n function alignRight(m) {\n return !m[2] ? m[0] : spaces(startW + textW - m[2].length) + m[2] + spaces(endW, \" \") + m[4].replace(/^([=:])\\s+/, \"$1 \");\n }\n function unAlign(m) {\n return !m[2] ? m[0] : spaces(startW) + m[2] + spaces(endW) + m[4].replace(/^([=:])\\s+/, \"$1 \");\n }\n };\n }).call(Editor.prototype);\n function isSamePoint(p1, p2) {\n return p1.row == p2.row && p1.column == p2.column;\n }\n exports.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 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 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 if (session && this.inMultiSelectMode != session.selection.inMultiSelectMode) {\n if (session.selection.inMultiSelectMode) this.$onMultiSelect();else this.$onSingleSelect();\n }\n };\n function MultiSelect(editor) {\n if (editor.$multiselectOnSessionChange) 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 editor.$multiselectOnSessionChange(editor);\n editor.on(\"changeSession\", editor.$multiselectOnSessionChange);\n editor.on(\"mousedown\", onMouseDown);\n editor.commands.addCommands(commands.defaultCommands);\n addAltCursorListeners(editor);\n }\n function addAltCursorListeners(editor) {\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 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 exports.MultiSelect = MultiSelect;\n acequire(\"./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});\nace.define(\"ace/mode/folding/fold_mode\", [\"require\", \"exports\", \"module\", \"ace/range\"], function (acequire, exports, module) {\n \"use strict\";\n\n var Range = acequire(\"../../range\").Range;\n var FoldMode = exports.FoldMode = function () {};\n (function () {\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)) return \"start\";\n if (foldStyle == \"markbeginend\" && this.foldingStopMarker && this.foldingStopMarker.test(line)) return \"end\";\n return \"\";\n };\n this.getFoldWidgetRange = function (session, foldStyle, row) {\n return null;\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) return;\n var startColumn = column || line.length;\n var maxRow = session.getLength();\n var startRow = row;\n var endRow = row;\n while (++row < maxRow) {\n var level = session.getLine(row).search(re);\n if (level == -1) continue;\n if (level <= startLevel) break;\n endRow = row;\n }\n if (endRow > startRow) {\n var endColumn = session.getLine(endRow).length;\n return new Range(startRow, startColumn, endRow, endColumn);\n }\n };\n this.openingBracketBlock = function (session, bracket, row, column, typeRe) {\n var start = {\n row: row,\n column: column + 1\n };\n var end = session.$findClosingBracket(bracket, start, typeRe);\n if (!end) return;\n var fw = session.foldWidgets[end.row];\n if (fw == null) fw = session.getFoldWidget(end.row);\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 this.closingBracketBlock = function (session, bracket, row, column, typeRe) {\n var end = {\n row: row,\n column: column\n };\n var start = session.$findOpeningBracket(bracket, end);\n if (!start) return;\n start.column++;\n end.column--;\n return Range.fromPoints(start, end);\n };\n }).call(FoldMode.prototype);\n});\nace.define(\"ace/theme/textmate\", [\"require\", \"exports\", \"module\", \"ace/lib/dom\"], function (acequire, exports, module) {\n \"use strict\";\n\n exports.isDark = false;\n exports.cssClass = \"ace-tm\";\n exports.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\";\n var dom = acequire(\"../lib/dom\");\n dom.importCssString(exports.cssText, exports.cssClass);\n});\nace.define(\"ace/line_widgets\", [\"require\", \"exports\", \"module\", \"ace/lib/oop\", \"ace/lib/dom\", \"ace/range\"], function (acequire, exports, module) {\n \"use strict\";\n\n var oop = acequire(\"./lib/oop\");\n var dom = acequire(\"./lib/dom\");\n var Range = acequire(\"./range\").Range;\n function 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 this.session.on(\"change\", this.updateOnChange);\n this.session.on(\"changeFold\", this.updateOnFold);\n this.session.on(\"changeEditor\", this.$onChangeEditor);\n }\n (function () {\n this.getRowLength = function (row) {\n var h;\n if (this.lineWidgets) h = this.lineWidgets[row] && this.lineWidgets[row].rowCount || 0;else 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 this.$getWidgetScreenLength = function () {\n var screenRows = 0;\n this.lineWidgets.forEach(function (w) {\n if (w && w.rowCount && !w.hidden) screenRows += w.rowCount;\n });\n return screenRows;\n };\n this.$onChangeEditor = function (e) {\n this.attach(e.editor);\n };\n this.attach = function (editor) {\n if (editor && editor.widgetManager && editor.widgetManager != this) editor.widgetManager.detach();\n if (this.editor == editor) return;\n this.detach();\n this.editor = editor;\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) return;\n this.editor = null;\n editor.widgetManager = null;\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 this.updateOnFold = function (e, session) {\n var lineWidgets = session.lineWidgets;\n if (!lineWidgets || !e.action) 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]) lineWidgets[i].hidden = hide;\n }\n if (lineWidgets[end]) {\n if (hide) {\n if (!lineWidgets[start]) lineWidgets[start] = lineWidgets[end];else lineWidgets[end].hidden = hide;\n } else {\n if (lineWidgets[start] == lineWidgets[end]) lineWidgets[start] = undefined;\n lineWidgets[end].hidden = hide;\n }\n }\n };\n this.updateOnChange = function (delta) {\n var lineWidgets = this.session.lineWidgets;\n if (!lineWidgets) return;\n var startRow = delta.start.row;\n var len = delta.end.row - startRow;\n if (len === 0) {} else if (delta.action == 'remove') {\n var removed = lineWidgets.splice(startRow + 1, len);\n removed.forEach(function (w) {\n w && this.removeLineWidget(w);\n }, this);\n this.$updateRows();\n } else {\n var args = new Array(len);\n args.unshift(startRow, 0);\n lineWidgets.splice.apply(lineWidgets, args);\n this.$updateRows();\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) this.session.lineWidgets = null;\n };\n this.addLineWidget = function (w) {\n if (!this.session.lineWidgets) this.session.lineWidgets = new Array(this.session.getLength());\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 this.session.lineWidgets[w.row] = w;\n w.session = this.session;\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 if (w.rowCount == null) {\n w.rowCount = w.pixelHeight / renderer.layerConfig.lineHeight;\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]) lineWidgets[fold.start.row] = w;else w.hidden = true;\n }\n this.session._emit(\"changeFold\", {\n data: {\n start: {\n row: w.row\n }\n }\n });\n this.$updateRows();\n this.renderWidgets(null, renderer);\n this.onWidgetChanged(w);\n return w;\n };\n this.removeLineWidget = function (w) {\n w._inDocument = false;\n w.session = null;\n if (w.el && w.el.parentNode) 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) 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\", {\n data: {\n start: {\n row: w.row\n }\n }\n });\n this.$updateRows();\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 this.onWidgetChanged = function (w) {\n this.session._changedWidgets.push(w);\n this.editor && this.editor.renderer.updateFull();\n };\n this.measureWidgets = function (e, renderer) {\n var changedWidgets = this.session._changedWidgets;\n var config = renderer.layerConfig;\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) continue;\n w._inDocument = true;\n renderer.container.appendChild(w.el);\n }\n w.h = w.el.offsetHeight;\n if (!w.fixedWidth) {\n w.w = w.el.offsetWidth;\n w.screenWidth = Math.ceil(w.w / config.characterWidth);\n }\n var rowCount = w.h / config.lineHeight;\n if (w.coverLine) {\n rowCount -= this.session.getRowLineCount(w.row);\n if (rowCount < 0) rowCount = 0;\n }\n if (w.rowCount != rowCount) {\n w.rowCount = rowCount;\n if (w.row < min) min = w.row;\n }\n }\n if (min != Infinity) {\n this.session._emit(\"changeFold\", {\n data: {\n start: {\n row: min\n }\n }\n });\n this.session.lineWidgetWidth = null;\n }\n this.session._changedWidgets = [];\n };\n this.renderWidgets = function (e, renderer) {\n var config = renderer.layerConfig;\n var lineWidgets = this.session.lineWidgets;\n if (!lineWidgets) return;\n var first = Math.min(this.firstRow, config.firstRow);\n var last = Math.max(this.lastRow, config.lastRow, lineWidgets.length);\n while (first > 0 && !lineWidgets[first]) first--;\n this.firstRow = config.firstRow;\n this.lastRow = config.lastRow;\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({\n row: i,\n column: 0\n }, true).top;\n if (!w.coverLine) top += config.lineHeight * this.session.getRowLineCount(w.row);\n w.el.style.top = top - config.offset + \"px\";\n var left = w.coverGutter ? 0 : renderer.gutterWidth;\n if (!w.fixedWidth) left -= renderer.scrollLeft;\n w.el.style.left = left + \"px\";\n if (w.fullWidth && w.screenWidth) {\n w.el.style.minWidth = config.width + 2 * config.padding + \"px\";\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 }).call(LineWidgets.prototype);\n exports.LineWidgets = LineWidgets;\n});\nace.define(\"ace/ext/error_marker\", [\"require\", \"exports\", \"module\", \"ace/line_widgets\", \"ace/lib/dom\", \"ace/range\"], function (acequire, exports, module) {\n \"use strict\";\n\n var LineWidgets = acequire(\"../line_widgets\").LineWidgets;\n var dom = acequire(\"../lib/dom\");\n var Range = acequire(\"../range\").Range;\n function binarySearch(array, needle, comparator) {\n var first = 0;\n var last = array.length - 1;\n while (first <= last) {\n var mid = first + last >> 1;\n var c = comparator(needle, array[mid]);\n if (c > 0) first = mid + 1;else if (c < 0) last = mid - 1;else return mid;\n }\n return -(first + 1);\n }\n function findAnnotations(session, row, dir) {\n var annotations = session.getAnnotations().sort(Range.comparePoints);\n if (!annotations.length) return;\n var i = binarySearch(annotations, {\n row: row,\n column: -1\n }, Range.comparePoints);\n if (i < 0) i = -i - 1;\n if (i >= annotations.length) i = dir > 0 ? 0 : annotations.length - 1;else if (i === 0 && dir < 0) i = annotations.length - 1;\n var annotation = annotations[i];\n if (!annotation || !dir) return;\n if (annotation.row === row) {\n do {\n annotation = annotations[i += dir];\n } while (annotation && annotation.row === row);\n if (!annotation) return annotations.slice();\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 exports.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 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\" ? annotation.pos.sc : 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 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 var left = editor.renderer.$cursorLayer.getPixelPosition(pos).left;\n arrow.style.left = left + editor.renderer.gutterWidth - 5 + \"px\";\n w.el.className = \"error_widget_wrapper\";\n el.className = \"error_widget \" + gutterAnno.className;\n el.innerHTML = gutterAnno.text.join(\"
\");\n el.appendChild(dom.createElement(\"div\"));\n var kb = function (_, hashId, keyString) {\n if (hashId === 0 && (keyString === \"esc\" || keyString === \"return\")) {\n w.destroy();\n return {\n command: \"null\"\n };\n }\n };\n w.destroy = function () {\n if (editor.$mouseHandler.isMousePressed) 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 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 editor.session.widgetManager.addLineWidget(w);\n w.el.onmousedown = editor.focus.bind(editor);\n editor.renderer.scrollCursorIntoView(null, 0.5, {\n bottom: w.el.offsetHeight\n });\n };\n dom.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});\nace.define(\"ace/ace\", [\"require\", \"exports\", \"module\", \"ace/lib/fixoldbrowsers\", \"ace/lib/dom\", \"ace/lib/event\", \"ace/editor\", \"ace/edit_session\", \"ace/undomanager\", \"ace/virtual_renderer\", \"ace/worker/worker_client\", \"ace/keyboard/hash_handler\", \"ace/placeholder\", \"ace/multi_select\", \"ace/mode/folding/fold_mode\", \"ace/theme/textmate\", \"ace/ext/error_marker\", \"ace/config\"], function (acequire, exports, module) {\n \"use strict\";\n\n acequire(\"./lib/fixoldbrowsers\");\n var dom = acequire(\"./lib/dom\");\n var event = acequire(\"./lib/event\");\n var Editor = acequire(\"./editor\").Editor;\n var EditSession = acequire(\"./edit_session\").EditSession;\n var UndoManager = acequire(\"./undomanager\").UndoManager;\n var Renderer = acequire(\"./virtual_renderer\").VirtualRenderer;\n acequire(\"./worker/worker_client\");\n acequire(\"./keyboard/hash_handler\");\n acequire(\"./placeholder\");\n acequire(\"./multi_select\");\n acequire(\"./mode/folding/fold_mode\");\n acequire(\"./theme/textmate\");\n acequire(\"./ext/error_marker\");\n exports.config = acequire(\"./config\");\n exports.acequire = acequire;\n if (typeof define === \"function\") exports.define = define;\n exports.edit = function (el) {\n if (typeof el == \"string\") {\n var _id = el;\n el = document.getElementById(_id);\n if (!el) throw new Error(\"ace.edit can't find div #\" + _id);\n }\n if (el && el.env && el.env.editor instanceof Editor) return el.env.editor;\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 = dom.getInnerText(el);\n el.innerHTML = \"\";\n }\n var doc = exports.createEditSession(value);\n var editor = new Editor(new Renderer(el));\n editor.setSession(doc);\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 };\n exports.createEditSession = function (text, mode) {\n var doc = new EditSession(text, mode);\n doc.setUndoManager(new UndoManager());\n return doc;\n };\n exports.EditSession = EditSession;\n exports.UndoManager = UndoManager;\n exports.version = \"1.2.9\";\n});\n(function () {\n ace.acequire([\"ace/ace\"], function (a) {\n if (a) {\n a.config.init(true);\n a.define = ace.define;\n }\n if (!window.ace) window.ace = a;\n for (var key in a) if (a.hasOwnProperty(key)) window.ace[key] = a[key];\n });\n})();\nmodule.exports = window.ace.acequire(\"ace/ace\");","import * as ace from 'brace';\nimport 'brace/mode/text';\nimport 'brace/theme/github';\nimport * as i0 from '@angular/core';\nimport { InjectionToken, EventEmitter, Directive, Optional, Inject, Input, Output, Component, ViewEncapsulation, HostBinding, ViewChild, NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nconst ACE_CONFIG = new InjectionToken('ACE_CONFIG');\nconst AceEditorEvents = ['blur', 'focus', 'copy', 'paste', 'change', 'changeSession'];\nconst AceSelectionEvents = ['changeCursor', 'changeSelection'];\nclass AceConfig {\n constructor(config = {}) {\n this.assign(config);\n }\n assign(config = {}, target) {\n target = target || this;\n for (const key in config) {\n if (config[key] && !Array.isArray(config[key]) && typeof config[key] === 'object') {\n target[key] = {};\n this.assign(config[key], target[key]);\n } else {\n target[key] = config[key];\n }\n }\n }\n}\nlet AceDirective = /*#__PURE__*/(() => {\n class AceDirective {\n constructor(zone, elementRef, differs, defaults) {\n this.zone = zone;\n this.elementRef = elementRef;\n this.differs = differs;\n this.defaults = defaults;\n this.instance = null;\n this.instanceEventListeners = [];\n this.selectionEventListeners = [];\n this.configDiff = null;\n this.disabled = false;\n this.blur = new EventEmitter();\n this.focus = new EventEmitter();\n this.copy = new EventEmitter();\n this.paste = new EventEmitter();\n this.change = new EventEmitter();\n this.changeCursor = new EventEmitter();\n this.changeSession = new EventEmitter();\n this.changeSelection = new EventEmitter();\n }\n ngOnInit() {\n const params = new AceConfig(this.defaults);\n params.assign(this.config); // Custom configuration\n if (this.disabled) {\n params.readOnly = true;\n params.highlightActiveLine = false;\n }\n params.mode = 'ace/mode/' + (params.mode || 'text');\n params.theme = 'ace/theme/' + (params.theme || 'github');\n this.zone.runOutsideAngular(() => {\n this.instance = ace.edit(this.elementRef.nativeElement);\n this.instance.$blockScrolling = Infinity;\n this.instance.setOptions(params);\n });\n // Add native Ace event handling\n AceEditorEvents.forEach(eventName => {\n if (this.instance) {\n const callback = (...args) => {\n if (args.length === 1) {\n args = args[0];\n }\n if (this[eventName]) {\n this.zone.run(() => {\n if (this[eventName].observers.length) {\n this[eventName].emit(args);\n }\n });\n }\n };\n this.instance.on(eventName, callback);\n this.instanceEventListeners.push({\n eventName,\n callback\n });\n }\n });\n // Add native Ace selection event handling\n AceSelectionEvents.forEach(eventName => {\n if (this.instance) {\n const callback = (...args) => {\n if (args.length === 1) {\n args = args[0];\n }\n if (this[eventName]) {\n if (this[eventName].observers.length) {\n this[eventName].emit(args);\n }\n }\n };\n this.instance.selection.on(eventName, callback);\n this.selectionEventListeners.push({\n eventName,\n callback\n });\n }\n });\n if (!this.configDiff) {\n this.configDiff = this.differs.find(this.config || {}).create();\n this.configDiff.diff(this.config || {});\n }\n }\n ngDoCheck() {\n if (this.configDiff) {\n const changes = this.configDiff.diff(this.config || {});\n if (changes) {\n this.ngOnDestroy();\n this.ngOnInit();\n }\n }\n }\n ngOnDestroy() {\n if (this.instance) {\n if (this.instance.isFocused()) {\n this.blur.emit();\n }\n this.instanceEventListeners.forEach(el => {\n this.instance.off(el.eventName, el.callback);\n });\n this.instanceEventListeners = [];\n this.selectionEventListeners.forEach(el => {\n this.instance.selection.off(el.eventName, el.callback);\n });\n this.selectionEventListeners = [];\n delete this.instance;\n this.instance = null;\n }\n }\n ngOnChanges(changes) {\n if (changes['disabled']) {\n if (changes['disabled'].currentValue !== changes['disabled'].previousValue) {\n this.zone.runOutsideAngular(() => {\n if (this.instance) {\n const params = new AceConfig(this.defaults);\n params.assign(this.config); // Custom configuration\n this.instance.clearSelection();\n const hlActive = params.highlightActiveLine == null ? true : false;\n this.instance.setHighlightActiveLine(this.disabled ? false : hlActive);\n this.instance.setReadOnly(this.disabled ? true : params.readOnly || false);\n }\n });\n }\n }\n }\n ace() {\n return this.instance;\n }\n clear() {\n if (this.instance) {\n this.instance.setValue('');\n this.instance.clearSelection();\n }\n }\n getValue() {\n if (this.instance) {\n return this.instance.getValue();\n }\n }\n setValue(value, cursorPos) {\n if (this.instance) {\n this.instance.setValue(value || '', cursorPos);\n }\n }\n }\n AceDirective.ɵfac = function AceDirective_Factory(__ngFactoryType__) {\n return new (__ngFactoryType__ || AceDirective)(i0.ɵɵdirectiveInject(i0.NgZone), i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i0.KeyValueDiffers), i0.ɵɵdirectiveInject(ACE_CONFIG, 8));\n };\n AceDirective.ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: AceDirective,\n selectors: [[\"\", \"ace\", \"\"]],\n inputs: {\n disabled: \"disabled\",\n config: [0, \"ace\", \"config\"]\n },\n outputs: {\n blur: \"blur\",\n focus: \"focus\",\n copy: \"copy\",\n paste: \"paste\",\n change: \"change\",\n changeCursor: \"changeCursor\",\n changeSession: \"changeSession\",\n changeSelection: \"changeSelection\"\n },\n exportAs: [\"ngxAce\"],\n standalone: false,\n features: [i0.ɵɵNgOnChangesFeature]\n });\n return AceDirective;\n})();\n(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\nlet AceComponent = /*#__PURE__*/(() => {\n class AceComponent {\n constructor() {\n this.content = '';\n this.disabled = false;\n this.mode = '';\n this.theme = '';\n this.useAceClass = true;\n this.blur = new EventEmitter();\n this.focus = new EventEmitter();\n this.copy = new EventEmitter();\n this.paste = new EventEmitter();\n this.change = new EventEmitter();\n this.valueChange = new EventEmitter();\n this.changeCursor = new EventEmitter();\n this.changeSession = new EventEmitter();\n this.changeSelection = new EventEmitter();\n }\n get value() {\n return this.content;\n }\n set value(value) {\n this.setContent(value);\n }\n ngAfterViewInit() {\n if (this.content != null) {\n this.setContent(this.content, true);\n }\n }\n setContent(value, force) {\n if (force || value !== this.content) {\n if (this.directiveRef) {\n this.directiveRef.setValue(value, 1);\n }\n this.content = value;\n }\n }\n getConfig() {\n this.config = this.config || {};\n this.config.mode = this.mode || this.config.mode;\n this.config.theme = this.theme || this.config.theme;\n return this.config;\n }\n onContentChange(event) {\n if (this.directiveRef) {\n this.change.emit(event);\n this.content = this.directiveRef.getValue() || '';\n this.valueChange.emit(this.value);\n }\n }\n }\n AceComponent.ɵfac = function AceComponent_Factory(__ngFactoryType__) {\n return new (__ngFactoryType__ || AceComponent)();\n };\n AceComponent.ɵcmp = /* @__PURE__ */i0.ɵɵdefineComponent({\n type: AceComponent,\n selectors: [[\"ace\"]],\n viewQuery: function AceComponent_Query(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵviewQuery(AceDirective, 7);\n }\n if (rf & 2) {\n let _t;\n i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.directiveRef = _t.first);\n }\n },\n hostVars: 2,\n hostBindings: function AceComponent_HostBindings(rf, ctx) {\n if (rf & 2) {\n i0.ɵɵclassProp(\"ace\", ctx.useAceClass);\n }\n },\n inputs: {\n value: \"value\",\n disabled: \"disabled\",\n mode: \"mode\",\n theme: \"theme\",\n config: \"config\",\n useAceClass: \"useAceClass\"\n },\n outputs: {\n blur: \"blur\",\n focus: \"focus\",\n copy: \"copy\",\n paste: \"paste\",\n change: \"change\",\n valueChange: \"valueChange\",\n changeCursor: \"changeCursor\",\n changeSession: \"changeSession\",\n changeSelection: \"changeSelection\"\n },\n exportAs: [\"ngxAce\"],\n standalone: false,\n decls: 1,\n vars: 2,\n consts: [[3, \"blur\", \"focus\", \"copy\", \"paste\", \"change\", \"changeCursor\", \"changeSession\", \"changeSelection\", \"ace\", \"disabled\"]],\n template: function AceComponent_Template(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵelementStart(0, \"div\", 0);\n i0.ɵɵlistener(\"blur\", function AceComponent_Template_div_blur_0_listener($event) {\n return ctx.blur.emit($event);\n })(\"focus\", function AceComponent_Template_div_focus_0_listener($event) {\n return ctx.focus.emit($event);\n })(\"copy\", function AceComponent_Template_div_copy_0_listener($event) {\n return ctx.copy.emit($event);\n })(\"paste\", function AceComponent_Template_div_paste_0_listener($event) {\n return ctx.paste.emit($event);\n })(\"change\", function AceComponent_Template_div_change_0_listener($event) {\n return ctx.onContentChange($event);\n })(\"changeCursor\", function AceComponent_Template_div_changeCursor_0_listener($event) {\n return ctx.changeCursor.emit($event);\n })(\"changeSession\", function AceComponent_Template_div_changeSession_0_listener($event) {\n return ctx.changeSession.emit($event);\n })(\"changeSelection\", function AceComponent_Template_div_changeSelection_0_listener($event) {\n return ctx.changeSelection.emit($event);\n });\n i0.ɵɵelementEnd();\n }\n if (rf & 2) {\n i0.ɵɵproperty(\"ace\", ctx.getConfig())(\"disabled\", ctx.disabled);\n }\n },\n dependencies: [AceDirective],\n styles: [\".ace,.ace>.ace_editor{display:block;width:100%;height:100%}.ace[fxflex]{display:flex;flex-direction:inherit;align-items:inherit;min-width:0;min-height:0}.ace[fxflex]>.ace_editor{flex:1 1 auto;min-width:0;min-height:0;-webkit-box-flex:1}\\n\"],\n encapsulation: 2\n });\n return AceComponent;\n})();\n(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\nlet AceModule = /*#__PURE__*/(() => {\n class AceModule {}\n AceModule.ɵfac = function AceModule_Factory(__ngFactoryType__) {\n return new (__ngFactoryType__ || AceModule)();\n };\n AceModule.ɵmod = /* @__PURE__ */i0.ɵɵdefineNgModule({\n type: AceModule\n });\n AceModule.ɵinj = /* @__PURE__ */i0.ɵɵdefineInjector({\n imports: [CommonModule, CommonModule]\n });\n return AceModule;\n})();\n(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/**\n * Generated bundle index. Do not edit.\n */\n\nexport { ACE_CONFIG, AceComponent, AceConfig, AceDirective, AceModule };\n","ace.define(\"ace/theme/github\", [\"require\", \"exports\", \"module\", \"ace/lib/dom\"], function (acequire, exports, module) {\n exports.isDark = false;\n exports.cssClass = \"ace-github\";\n exports.cssText = \"\\\n.ace-github .ace_gutter {\\\nbackground: #e8e8e8;\\\ncolor: #AAA;\\\n}\\\n.ace-github {\\\nbackground: #fff;\\\ncolor: #000;\\\n}\\\n.ace-github .ace_keyword {\\\nfont-weight: bold;\\\n}\\\n.ace-github .ace_string {\\\ncolor: #D14;\\\n}\\\n.ace-github .ace_variable.ace_class {\\\ncolor: teal;\\\n}\\\n.ace-github .ace_constant.ace_numeric {\\\ncolor: #099;\\\n}\\\n.ace-github .ace_constant.ace_buildin {\\\ncolor: #0086B3;\\\n}\\\n.ace-github .ace_support.ace_function {\\\ncolor: #0086B3;\\\n}\\\n.ace-github .ace_comment {\\\ncolor: #998;\\\nfont-style: italic;\\\n}\\\n.ace-github .ace_variable.ace_language {\\\ncolor: #0086B3;\\\n}\\\n.ace-github .ace_paren {\\\nfont-weight: bold;\\\n}\\\n.ace-github .ace_boolean {\\\nfont-weight: bold;\\\n}\\\n.ace-github .ace_string.ace_regexp {\\\ncolor: #009926;\\\nfont-weight: normal;\\\n}\\\n.ace-github .ace_variable.ace_instance {\\\ncolor: teal;\\\n}\\\n.ace-github .ace_constant.ace_language {\\\nfont-weight: bold;\\\n}\\\n.ace-github .ace_cursor {\\\ncolor: black;\\\n}\\\n.ace-github.ace_focus .ace_marker-layer .ace_active-line {\\\nbackground: rgb(255, 255, 204);\\\n}\\\n.ace-github .ace_marker-layer .ace_active-line {\\\nbackground: rgb(245, 245, 245);\\\n}\\\n.ace-github .ace_marker-layer .ace_selection {\\\nbackground: rgb(181, 213, 255);\\\n}\\\n.ace-github.ace_multiselect .ace_selection.ace_start {\\\nbox-shadow: 0 0 3px 0px white;\\\n}\\\n.ace-github.ace_nobold .ace_line > span {\\\nfont-weight: normal !important;\\\n}\\\n.ace-github .ace_marker-layer .ace_step {\\\nbackground: rgb(252, 255, 0);\\\n}\\\n.ace-github .ace_marker-layer .ace_stack {\\\nbackground: rgb(164, 229, 101);\\\n}\\\n.ace-github .ace_marker-layer .ace_bracket {\\\nmargin: -1px 0 0 -1px;\\\nborder: 1px solid rgb(192, 192, 192);\\\n}\\\n.ace-github .ace_gutter-active-line {\\\nbackground-color : rgba(0, 0, 0, 0.07);\\\n}\\\n.ace-github .ace_marker-layer .ace_selected-word {\\\nbackground: rgb(250, 250, 255);\\\nborder: 1px solid rgb(200, 200, 250);\\\n}\\\n.ace-github .ace_invisible {\\\ncolor: #BFBFBF\\\n}\\\n.ace-github .ace_print-margin {\\\nwidth: 1px;\\\nbackground: #e8e8e8;\\\n}\\\n.ace-github .ace_indent-guide {\\\nbackground: url(\\\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\\\") right repeat-y;\\\n}\";\n var dom = acequire(\"../lib/dom\");\n dom.importCssString(exports.cssText, exports.cssClass);\n});","import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';\nimport { EventBrokerService, EventTypeInterface } from '@vendasta/event-broker';\nimport { BehaviorSubject, Observable } from 'rxjs';\nimport { finalize, map, take } from 'rxjs/operators';\n\n@Component({\n selector: 'app-loop-event-selector',\n styleUrls: ['./event-selector.component.scss'],\n templateUrl: './event-selector.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: false,\n})\nexport class EventSelectorComponent implements OnInit {\n private loading$$: BehaviorSubject = new BehaviorSubject(true);\n loading$: Observable = this.loading$$.asObservable();\n private cursor: string;\n hasMore: boolean;\n private events$$: BehaviorSubject = new BehaviorSubject([]);\n events$: Observable = this.events$$.asObservable();\n\n constructor(public eventBrokerService: EventBrokerService) {}\n\n ngOnInit(): void {\n this.loadMoreEvents();\n }\n\n loadMoreEvents(): void {\n this.loading$$.next(true);\n this.eventBrokerService\n .listEventTypes(this.cursor, 30)\n .pipe(\n map((results) => {\n this.hasMore = results.hasMore;\n this.cursor = results.nextCursor;\n this.events$$.next(this.events$$.getValue().concat(results.eventTypes));\n }),\n finalize(() => this.loading$$.next(false)),\n take(1),\n )\n .subscribe();\n }\n}\n","\n \n Select Event\n \n \n \n \n \n \n\n \n \n
\n \n \n
\n
\n
\n","import * as i0 from '@angular/core';\nimport { Injectable, inject } from '@angular/core';\nimport { map } from 'rxjs/operators';\nimport { HttpClient, HttpHeaders } from '@angular/common/http';\n\n// *********************************\n// Code generated by sdkgen\n// DO NOT EDIT!.\n//\n// Enums.\n// *********************************\nvar TemplateType = /*#__PURE__*/function (TemplateType) {\n TemplateType[TemplateType[\"TEMPLATE_TYPE_GOLANG\"] = 0] = \"TEMPLATE_TYPE_GOLANG\";\n TemplateType[TemplateType[\"TEMPLATE_TYPE_DJANGO\"] = 1] = \"TEMPLATE_TYPE_DJANGO\";\n TemplateType[TemplateType[\"TEMPLATE_TYPE_GOLANG_TEXT\"] = 2] = \"TEMPLATE_TYPE_GOLANG_TEXT\";\n return TemplateType;\n}(TemplateType || {});\n// *********************************\n// Code generated by sdkgen\n// DO NOT EDIT!.\n//\n// Enums Index.\n// *********************************\n\nfunction enumStringToValue$4(enumRef, value) {\n if (typeof value === 'number') {\n return value;\n }\n return enumRef[value];\n}\nclass Access {\n static fromProto(proto) {\n let m = new Access();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.scope !== 'undefined') {\n toReturn['scope'] = this.scope;\n }\n if (typeof this.public !== 'undefined') {\n toReturn['public'] = this.public;\n }\n return toReturn;\n }\n}\nfunction enumStringToValue$3(enumRef, value) {\n if (typeof value === 'number') {\n return value;\n }\n return enumRef[value];\n}\nclass InflatedAccountGroupsAccountGroup {\n static fromProto(proto) {\n let m = new InflatedAccountGroupsAccountGroup();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.accountGroupId !== 'undefined') {\n toReturn['accountGroupId'] = this.accountGroupId;\n }\n if (typeof this.name !== 'undefined') {\n toReturn['name'] = this.name;\n }\n if (typeof this.address !== 'undefined') {\n toReturn['address'] = this.address;\n }\n if (typeof this.city !== 'undefined') {\n toReturn['city'] = this.city;\n }\n if (typeof this.state !== 'undefined') {\n toReturn['state'] = this.state;\n }\n if (typeof this.country !== 'undefined') {\n toReturn['country'] = this.country;\n }\n if (typeof this.zip !== 'undefined') {\n toReturn['zip'] = this.zip;\n }\n return toReturn;\n }\n}\nclass AccountGroupsHydrationOption {\n static fromProto(proto) {\n let m = new AccountGroupsHydrationOption();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.accountGroupIds !== 'undefined') {\n toReturn['accountGroupIds'] = this.accountGroupIds;\n }\n if (typeof this.inflatedPropertyName !== 'undefined') {\n toReturn['inflatedPropertyName'] = this.inflatedPropertyName;\n }\n return toReturn;\n }\n}\nclass InflatedAppsApp {\n static fromProto(proto) {\n let m = new InflatedAppsApp();\n m = Object.assign(m, proto);\n if (proto.appKey) {\n m.appKey = AppKey.fromProto(proto.appKey);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.appKey !== 'undefined' && this.appKey !== null) {\n toReturn['appKey'] = 'toApiJson' in this.appKey ? this.appKey.toApiJson() : this.appKey;\n }\n if (typeof this.name !== 'undefined') {\n toReturn['name'] = this.name;\n }\n if (typeof this.editionName !== 'undefined') {\n toReturn['editionName'] = this.editionName;\n }\n return toReturn;\n }\n}\nclass AppKey {\n static fromProto(proto) {\n let m = new AppKey();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.appId !== 'undefined') {\n toReturn['appId'] = this.appId;\n }\n if (typeof this.editionId !== 'undefined') {\n toReturn['editionId'] = this.editionId;\n }\n return toReturn;\n }\n}\nclass InflatedBrandingBrandingApps {\n static fromProto(proto) {\n let m = new InflatedBrandingBrandingApps();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.identifier !== 'undefined') {\n toReturn['identifier'] = this.identifier;\n }\n if (typeof this.name !== 'undefined') {\n toReturn['name'] = this.name;\n }\n return toReturn;\n }\n}\nclass AppsHydrationOption {\n static fromProto(proto) {\n let m = new AppsHydrationOption();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.appKeys !== 'undefined') {\n toReturn['appKeys'] = this.appKeys;\n }\n if (typeof this.partnerId !== 'undefined') {\n toReturn['partnerId'] = this.partnerId;\n }\n if (typeof this.marketId !== 'undefined') {\n toReturn['marketId'] = this.marketId;\n }\n if (typeof this.inflatedPropertyName !== 'undefined') {\n toReturn['inflatedPropertyName'] = this.inflatedPropertyName;\n }\n return toReturn;\n }\n}\nclass InflatedBrandingBrandingAssets {\n static fromProto(proto) {\n let m = new InflatedBrandingBrandingAssets();\n m = Object.assign(m, proto);\n if (proto.logoUrl) {\n m.logoUrl = InflatedBrandingBrandingAssetsUrl.fromProto(proto.logoUrl);\n }\n if (proto.shortcutIconUrl) {\n m.shortcutIconUrl = InflatedBrandingBrandingAssetsUrl.fromProto(proto.shortcutIconUrl);\n }\n if (proto.faviconUrl) {\n m.faviconUrl = InflatedBrandingBrandingAssetsUrl.fromProto(proto.faviconUrl);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.logoUrl !== 'undefined' && this.logoUrl !== null) {\n toReturn['logoUrl'] = 'toApiJson' in this.logoUrl ? this.logoUrl.toApiJson() : this.logoUrl;\n }\n if (typeof this.shortcutIconUrl !== 'undefined' && this.shortcutIconUrl !== null) {\n toReturn['shortcutIconUrl'] = 'toApiJson' in this.shortcutIconUrl ? this.shortcutIconUrl.toApiJson() : this.shortcutIconUrl;\n }\n if (typeof this.faviconUrl !== 'undefined' && this.faviconUrl !== null) {\n toReturn['faviconUrl'] = 'toApiJson' in this.faviconUrl ? this.faviconUrl.toApiJson() : this.faviconUrl;\n }\n return toReturn;\n }\n}\nclass InflatedBrandingBranding {\n static fromProto(proto) {\n let m = new InflatedBrandingBranding();\n m = Object.assign(m, proto);\n if (proto.assets) {\n m.assets = InflatedBrandingBrandingAssets.fromProto(proto.assets);\n }\n if (proto.apps) {\n m.apps = InflatedBrandingBrandingApps.fromProto(proto.apps);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.name !== 'undefined') {\n toReturn['name'] = this.name;\n }\n if (typeof this.primaryColor !== 'undefined') {\n toReturn['primaryColor'] = this.primaryColor;\n }\n if (typeof this.assets !== 'undefined' && this.assets !== null) {\n toReturn['assets'] = 'toApiJson' in this.assets ? this.assets.toApiJson() : this.assets;\n }\n if (typeof this.apps !== 'undefined' && this.apps !== null) {\n toReturn['apps'] = 'toApiJson' in this.apps ? this.apps.toApiJson() : this.apps;\n }\n return toReturn;\n }\n}\nclass BrandingHydrationOption {\n static fromProto(proto) {\n let m = new BrandingHydrationOption();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.partnerId !== 'undefined') {\n toReturn['partnerId'] = this.partnerId;\n }\n if (typeof this.marketId !== 'undefined') {\n toReturn['marketId'] = this.marketId;\n }\n if (typeof this.inflatedPropertyName !== 'undefined') {\n toReturn['inflatedPropertyName'] = this.inflatedPropertyName;\n }\n return toReturn;\n }\n}\nclass HydrationOptions {\n static fromProto(proto) {\n let m = new HydrationOptions();\n m = Object.assign(m, proto);\n if (proto.accountGroups) {\n m.accountGroups = AccountGroupsHydrationOption.fromProto(proto.accountGroups);\n }\n if (proto.apps) {\n m.apps = AppsHydrationOption.fromProto(proto.apps);\n }\n if (proto.packages) {\n m.packages = PackagesHydrationOption.fromProto(proto.packages);\n }\n if (proto.branding) {\n m.branding = BrandingHydrationOption.fromProto(proto.branding);\n }\n if (proto.users) {\n m.users = UsersHydrationOption.fromProto(proto.users);\n }\n if (proto.salesActivities) {\n m.salesActivities = SalesActivitiesHydrationOption.fromProto(proto.salesActivities);\n }\n if (proto.partnerConfig) {\n m.partnerConfig = PartnerConfigHydrationOption.fromProto(proto.partnerConfig);\n }\n if (proto.task) {\n m.task = TasksHydrationOption.fromProto(proto.task);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.accountGroups !== 'undefined' && this.accountGroups !== null) {\n toReturn['accountGroups'] = 'toApiJson' in this.accountGroups ? this.accountGroups.toApiJson() : this.accountGroups;\n }\n if (typeof this.apps !== 'undefined' && this.apps !== null) {\n toReturn['apps'] = 'toApiJson' in this.apps ? this.apps.toApiJson() : this.apps;\n }\n if (typeof this.packages !== 'undefined' && this.packages !== null) {\n toReturn['packages'] = 'toApiJson' in this.packages ? this.packages.toApiJson() : this.packages;\n }\n if (typeof this.branding !== 'undefined' && this.branding !== null) {\n toReturn['branding'] = 'toApiJson' in this.branding ? this.branding.toApiJson() : this.branding;\n }\n if (typeof this.users !== 'undefined' && this.users !== null) {\n toReturn['users'] = 'toApiJson' in this.users ? this.users.toApiJson() : this.users;\n }\n if (typeof this.salesActivities !== 'undefined' && this.salesActivities !== null) {\n toReturn['salesActivities'] = 'toApiJson' in this.salesActivities ? this.salesActivities.toApiJson() : this.salesActivities;\n }\n if (typeof this.partnerConfig !== 'undefined' && this.partnerConfig !== null) {\n toReturn['partnerConfig'] = 'toApiJson' in this.partnerConfig ? this.partnerConfig.toApiJson() : this.partnerConfig;\n }\n if (typeof this.task !== 'undefined' && this.task !== null) {\n toReturn['task'] = 'toApiJson' in this.task ? this.task.toApiJson() : this.task;\n }\n return toReturn;\n }\n}\nclass InflatedAccountGroups {\n static fromProto(proto) {\n let m = new InflatedAccountGroups();\n m = Object.assign(m, proto);\n if (proto.inflatedPropertyName) {\n m.inflatedPropertyName = proto.inflatedPropertyName.map(InflatedAccountGroupsAccountGroup.fromProto);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.inflatedPropertyName !== 'undefined' && this.inflatedPropertyName !== null) {\n toReturn['inflatedPropertyName'] = 'toApiJson' in this.inflatedPropertyName ? this.inflatedPropertyName.toApiJson() : this.inflatedPropertyName;\n }\n return toReturn;\n }\n}\nclass InflatedApps {\n static fromProto(proto) {\n let m = new InflatedApps();\n m = Object.assign(m, proto);\n if (proto.inflatedPropertyName) {\n m.inflatedPropertyName = proto.inflatedPropertyName.map(InflatedAppsApp.fromProto);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.inflatedPropertyName !== 'undefined' && this.inflatedPropertyName !== null) {\n toReturn['inflatedPropertyName'] = 'toApiJson' in this.inflatedPropertyName ? this.inflatedPropertyName.toApiJson() : this.inflatedPropertyName;\n }\n return toReturn;\n }\n}\nclass InflatedBranding {\n static fromProto(proto) {\n let m = new InflatedBranding();\n m = Object.assign(m, proto);\n if (proto.inflatedPropertyName) {\n m.inflatedPropertyName = InflatedBrandingBranding.fromProto(proto.inflatedPropertyName);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.inflatedPropertyName !== 'undefined' && this.inflatedPropertyName !== null) {\n toReturn['inflatedPropertyName'] = 'toApiJson' in this.inflatedPropertyName ? this.inflatedPropertyName.toApiJson() : this.inflatedPropertyName;\n }\n return toReturn;\n }\n}\nclass InflatedPacklages {\n static fromProto(proto) {\n let m = new InflatedPacklages();\n m = Object.assign(m, proto);\n if (proto.inflatedPropertyName) {\n m.inflatedPropertyName = proto.inflatedPropertyName.map(InflatedPacklagesPackage.fromProto);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.inflatedPropertyName !== 'undefined' && this.inflatedPropertyName !== null) {\n toReturn['inflatedPropertyName'] = 'toApiJson' in this.inflatedPropertyName ? this.inflatedPropertyName.toApiJson() : this.inflatedPropertyName;\n }\n return toReturn;\n }\n}\nclass InflatedSalesActivities {\n static fromProto(proto) {\n let m = new InflatedSalesActivities();\n m = Object.assign(m, proto);\n if (proto.inflatedPropertyName) {\n m.inflatedPropertyName = proto.inflatedPropertyName.map(InflatedSalesActivitiesSalesActivity.fromProto);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.inflatedPropertyName !== 'undefined' && this.inflatedPropertyName !== null) {\n toReturn['inflatedPropertyName'] = 'toApiJson' in this.inflatedPropertyName ? this.inflatedPropertyName.toApiJson() : this.inflatedPropertyName;\n }\n return toReturn;\n }\n}\nclass InflatedSalesConfig {\n static fromProto(proto) {\n let m = new InflatedSalesConfig();\n m = Object.assign(m, proto);\n if (proto.inflatedPropertyName) {\n m.inflatedPropertyName = InflatedSalesConfigPartnerConfiguration.fromProto(proto.inflatedPropertyName);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.inflatedPropertyName !== 'undefined' && this.inflatedPropertyName !== null) {\n toReturn['inflatedPropertyName'] = 'toApiJson' in this.inflatedPropertyName ? this.inflatedPropertyName.toApiJson() : this.inflatedPropertyName;\n }\n return toReturn;\n }\n}\nclass InflatedTasks {\n static fromProto(proto) {\n let m = new InflatedTasks();\n m = Object.assign(m, proto);\n if (proto.inflatedPropertyName) {\n m.inflatedPropertyName = proto.inflatedPropertyName.map(InflatedTasksTask.fromProto);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.inflatedPropertyName !== 'undefined' && this.inflatedPropertyName !== null) {\n toReturn['inflatedPropertyName'] = 'toApiJson' in this.inflatedPropertyName ? this.inflatedPropertyName.toApiJson() : this.inflatedPropertyName;\n }\n return toReturn;\n }\n}\nclass InflatedUsers {\n static fromProto(proto) {\n let m = new InflatedUsers();\n m = Object.assign(m, proto);\n if (proto.inflatedPropertyName) {\n m.inflatedPropertyName = proto.inflatedPropertyName.map(InflatedUsersUser.fromProto);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.inflatedPropertyName !== 'undefined' && this.inflatedPropertyName !== null) {\n toReturn['inflatedPropertyName'] = 'toApiJson' in this.inflatedPropertyName ? this.inflatedPropertyName.toApiJson() : this.inflatedPropertyName;\n }\n return toReturn;\n }\n}\nclass InflatedPacklagesPackage {\n static fromProto(proto) {\n let m = new InflatedPacklagesPackage();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.packageId !== 'undefined') {\n toReturn['packageId'] = this.packageId;\n }\n if (typeof this.name !== 'undefined') {\n toReturn['name'] = this.name;\n }\n return toReturn;\n }\n}\nclass PackagesHydrationOption {\n static fromProto(proto) {\n let m = new PackagesHydrationOption();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.packageIds !== 'undefined') {\n toReturn['packageIds'] = this.packageIds;\n }\n if (typeof this.inflatedPropertyName !== 'undefined') {\n toReturn['inflatedPropertyName'] = this.inflatedPropertyName;\n }\n return toReturn;\n }\n}\nclass PartnerConfigHydrationOption {\n static fromProto(proto) {\n let m = new PartnerConfigHydrationOption();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.partnerId !== 'undefined') {\n toReturn['partnerId'] = this.partnerId;\n }\n if (typeof this.marketId !== 'undefined') {\n toReturn['marketId'] = this.marketId;\n }\n if (typeof this.inflatedPropertyName !== 'undefined') {\n toReturn['inflatedPropertyName'] = this.inflatedPropertyName;\n }\n return toReturn;\n }\n}\nclass InflatedSalesConfigPartnerConfiguration {\n static fromProto(proto) {\n let m = new InflatedSalesConfigPartnerConfiguration();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.defaultCurrency !== 'undefined') {\n toReturn['defaultCurrency'] = this.defaultCurrency;\n }\n return toReturn;\n }\n}\nclass SalesActivitiesHydrationOption {\n static fromProto(proto) {\n let m = new SalesActivitiesHydrationOption();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.salesActivityKeys !== 'undefined') {\n toReturn['salesActivityKeys'] = this.salesActivityKeys;\n }\n if (typeof this.inflatedPropertyName !== 'undefined') {\n toReturn['inflatedPropertyName'] = this.inflatedPropertyName;\n }\n return toReturn;\n }\n}\nclass InflatedSalesActivitiesSalesActivity {\n static fromProto(proto) {\n let m = new InflatedSalesActivitiesSalesActivity();\n m = Object.assign(m, proto);\n if (proto.salesActivityKey) {\n m.salesActivityKey = SalesActivityKey.fromProto(proto.salesActivityKey);\n }\n if (proto.created) {\n m.created = new Date(proto.created);\n }\n if (proto.lastEdited) {\n m.lastEdited = new Date(proto.lastEdited);\n }\n if (proto.deleted) {\n m.deleted = new Date(proto.deleted);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.salesActivityKey !== 'undefined' && this.salesActivityKey !== null) {\n toReturn['salesActivityKey'] = 'toApiJson' in this.salesActivityKey ? this.salesActivityKey.toApiJson() : this.salesActivityKey;\n }\n if (typeof this.created !== 'undefined' && this.created !== null) {\n toReturn['created'] = 'toApiJson' in this.created ? this.created.toApiJson() : this.created;\n }\n if (typeof this.lastEdited !== 'undefined' && this.lastEdited !== null) {\n toReturn['lastEdited'] = 'toApiJson' in this.lastEdited ? this.lastEdited.toApiJson() : this.lastEdited;\n }\n if (typeof this.deleted !== 'undefined' && this.deleted !== null) {\n toReturn['deleted'] = 'toApiJson' in this.deleted ? this.deleted.toApiJson() : this.deleted;\n }\n if (typeof this.opportunityId !== 'undefined') {\n toReturn['opportunityId'] = this.opportunityId;\n }\n if (typeof this.salesStatus !== 'undefined') {\n toReturn['salesStatus'] = this.salesStatus;\n }\n if (typeof this.previousSalesStatus !== 'undefined') {\n toReturn['previousSalesStatus'] = this.previousSalesStatus;\n }\n if (typeof this.salespersonAction !== 'undefined') {\n toReturn['salespersonAction'] = this.salespersonAction;\n }\n if (typeof this.customActionName !== 'undefined') {\n toReturn['customActionName'] = this.customActionName;\n }\n if (typeof this.salespersonId !== 'undefined') {\n toReturn['salespersonId'] = this.salespersonId;\n }\n if (typeof this.productName !== 'undefined') {\n toReturn['productName'] = this.productName;\n }\n if (typeof this.productPrice !== 'undefined') {\n toReturn['productPrice'] = this.productPrice;\n }\n if (typeof this.connected !== 'undefined') {\n toReturn['connected'] = this.connected;\n }\n if (typeof this.notes !== 'undefined') {\n toReturn['notes'] = this.notes;\n }\n if (typeof this.closedLostReason !== 'undefined') {\n toReturn['closedLostReason'] = this.closedLostReason;\n }\n if (typeof this.audioKey !== 'undefined') {\n toReturn['audioKey'] = this.audioKey;\n }\n if (typeof this.opportunityName !== 'undefined') {\n toReturn['opportunityName'] = this.opportunityName;\n }\n if (typeof this.audioUrl !== 'undefined') {\n toReturn['audioUrl'] = this.audioUrl;\n }\n if (typeof this.salesPersonFirstName !== 'undefined') {\n toReturn['salesPersonFirstName'] = this.salesPersonFirstName;\n }\n if (typeof this.salesPersonLastName !== 'undefined') {\n toReturn['salesPersonLastName'] = this.salesPersonLastName;\n }\n return toReturn;\n }\n}\nclass SalesActivityKey {\n static fromProto(proto) {\n let m = new SalesActivityKey();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.salesActivityId !== 'undefined') {\n toReturn['salesActivityId'] = this.salesActivityId;\n }\n if (typeof this.businessId !== 'undefined') {\n toReturn['businessId'] = this.businessId;\n }\n return toReturn;\n }\n}\nclass InflatedTasksTask {\n static fromProto(proto) {\n let m = new InflatedTasksTask();\n m = Object.assign(m, proto);\n if (proto.created) {\n m.created = new Date(proto.created);\n }\n if (proto.dueDate) {\n m.dueDate = new Date(proto.dueDate);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.title !== 'undefined') {\n toReturn['title'] = this.title;\n }\n if (typeof this.created !== 'undefined' && this.created !== null) {\n toReturn['created'] = 'toApiJson' in this.created ? this.created.toApiJson() : this.created;\n }\n if (typeof this.dueDate !== 'undefined' && this.dueDate !== null) {\n toReturn['dueDate'] = 'toApiJson' in this.dueDate ? this.dueDate.toApiJson() : this.dueDate;\n }\n if (typeof this.status !== 'undefined') {\n toReturn['status'] = this.status;\n }\n if (typeof this.type !== 'undefined') {\n toReturn['type'] = this.type;\n }\n return toReturn;\n }\n}\nclass TaskKeys {\n static fromProto(proto) {\n let m = new TaskKeys();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.namespace !== 'undefined') {\n toReturn['namespace'] = this.namespace;\n }\n if (typeof this.parentPath !== 'undefined') {\n toReturn['parentPath'] = this.parentPath;\n }\n if (typeof this.taskId !== 'undefined') {\n toReturn['taskId'] = this.taskId;\n }\n return toReturn;\n }\n}\nclass TasksHydrationOption {\n static fromProto(proto) {\n let m = new TasksHydrationOption();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.taskKeys !== 'undefined') {\n toReturn['taskKeys'] = this.taskKeys;\n }\n if (typeof this.inflatedPropertyName !== 'undefined') {\n toReturn['inflatedPropertyName'] = this.inflatedPropertyName;\n }\n return toReturn;\n }\n}\nclass InflatedBrandingBrandingAssetsUrl {\n static fromProto(proto) {\n let m = new InflatedBrandingBrandingAssetsUrl();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.insecure !== 'undefined') {\n toReturn['insecure'] = this.insecure;\n }\n if (typeof this.secure !== 'undefined') {\n toReturn['secure'] = this.secure;\n }\n return toReturn;\n }\n}\nclass InflatedUsersUser {\n static fromProto(proto) {\n let m = new InflatedUsersUser();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.userId !== 'undefined') {\n toReturn['userId'] = this.userId;\n }\n if (typeof this.firstName !== 'undefined') {\n toReturn['firstName'] = this.firstName;\n }\n if (typeof this.lastName !== 'undefined') {\n toReturn['lastName'] = this.lastName;\n }\n return toReturn;\n }\n}\nclass UsersHydrationOption {\n static fromProto(proto) {\n let m = new UsersHydrationOption();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.userIds !== 'undefined') {\n toReturn['userIds'] = this.userIds;\n }\n if (typeof this.inflatedPropertyName !== 'undefined') {\n toReturn['inflatedPropertyName'] = this.inflatedPropertyName;\n }\n return toReturn;\n }\n}\nfunction enumStringToValue$2(enumRef, value) {\n if (typeof value === 'number') {\n return value;\n }\n return enumRef[value];\n}\nclass RawTemplate {\n static fromProto(proto) {\n let m = new RawTemplate();\n m = Object.assign(m, proto);\n if (proto.type) {\n m.type = enumStringToValue$2(TemplateType, proto.type);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.templateContent !== 'undefined') {\n toReturn['templateContent'] = this.templateContent;\n }\n if (typeof this.type !== 'undefined') {\n toReturn['type'] = this.type;\n }\n return toReturn;\n }\n}\nclass Template {\n static fromProto(proto) {\n let m = new Template();\n m = Object.assign(m, proto);\n if (proto.hydrationOptions) {\n m.hydrationOptions = HydrationOptions.fromProto(proto.hydrationOptions);\n }\n if (proto.type) {\n m.type = enumStringToValue$2(TemplateType, proto.type);\n }\n if (proto.created) {\n m.created = new Date(proto.created);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.templateId !== 'undefined') {\n toReturn['templateId'] = this.templateId;\n }\n if (typeof this.name !== 'undefined') {\n toReturn['name'] = this.name;\n }\n if (typeof this.metadata !== 'undefined') {\n toReturn['metadata'] = this.metadata;\n }\n if (typeof this.content !== 'undefined') {\n toReturn['content'] = this.content;\n }\n if (typeof this.locale !== 'undefined') {\n toReturn['locale'] = this.locale;\n }\n if (typeof this.hydrationOptions !== 'undefined' && this.hydrationOptions !== null) {\n toReturn['hydrationOptions'] = 'toApiJson' in this.hydrationOptions ? this.hydrationOptions.toApiJson() : this.hydrationOptions;\n }\n if (typeof this.type !== 'undefined') {\n toReturn['type'] = this.type;\n }\n if (typeof this.created !== 'undefined' && this.created !== null) {\n toReturn['created'] = 'toApiJson' in this.created ? this.created.toApiJson() : this.created;\n }\n return toReturn;\n }\n}\nclass TemplateIdentifier {\n static fromProto(proto) {\n let m = new TemplateIdentifier();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.applicationId !== 'undefined') {\n toReturn['applicationId'] = this.applicationId;\n }\n if (typeof this.templateId !== 'undefined') {\n toReturn['templateId'] = this.templateId;\n }\n return toReturn;\n }\n}\nfunction enumStringToValue$1(enumRef, value) {\n if (typeof value === 'number') {\n return value;\n }\n return enumRef[value];\n}\nclass SubstitutionParameter {\n static fromProto(proto) {\n let m = new SubstitutionParameter();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.replacementTag !== 'undefined') {\n toReturn['replacementTag'] = this.replacementTag;\n }\n if (typeof this.requiredOptions !== 'undefined') {\n toReturn['requiredOptions'] = this.requiredOptions;\n }\n if (typeof this.displayName !== 'undefined') {\n toReturn['displayName'] = this.displayName;\n }\n if (typeof this.isHtml !== 'undefined') {\n toReturn['isHtml'] = this.isHtml;\n }\n if (typeof this.isDeprecated !== 'undefined') {\n toReturn['isDeprecated'] = this.isDeprecated;\n }\n return toReturn;\n }\n}\nclass SubstitutionParameterError {\n static fromProto(proto) {\n let m = new SubstitutionParameterError();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.replacementTag !== 'undefined') {\n toReturn['replacementTag'] = this.replacementTag;\n }\n if (typeof this.reason !== 'undefined') {\n toReturn['reason'] = this.reason;\n }\n return toReturn;\n }\n}\nclass SubstitutionParameterOptions {\n static fromProto(proto) {\n let m = new SubstitutionParameterOptions();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.accountGroupId !== 'undefined') {\n toReturn['accountGroupId'] = this.accountGroupId;\n }\n if (typeof this.partnerId !== 'undefined') {\n toReturn['partnerId'] = this.partnerId;\n }\n if (typeof this.marketId !== 'undefined') {\n toReturn['marketId'] = this.marketId;\n }\n if (typeof this.userId !== 'undefined') {\n toReturn['userId'] = this.userId;\n }\n if (typeof this.orderId !== 'undefined') {\n toReturn['orderId'] = this.orderId;\n }\n if (typeof this.contactId !== 'undefined') {\n toReturn['contactId'] = this.contactId;\n }\n if (typeof this.namespace !== 'undefined') {\n toReturn['namespace'] = this.namespace;\n }\n return toReturn;\n }\n}\nfunction enumStringToValue(enumRef, value) {\n if (typeof value === 'number') {\n return value;\n }\n return enumRef[value];\n}\nclass AddTemplateLocaleRequest {\n static fromProto(proto) {\n let m = new AddTemplateLocaleRequest();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.applicationId !== 'undefined') {\n toReturn['applicationId'] = this.applicationId;\n }\n if (typeof this.templateId !== 'undefined') {\n toReturn['templateId'] = this.templateId;\n }\n if (typeof this.locale !== 'undefined') {\n toReturn['locale'] = this.locale;\n }\n return toReturn;\n }\n}\nclass CreateMultiTemplateRequest {\n static fromProto(proto) {\n let m = new CreateMultiTemplateRequest();\n m = Object.assign(m, proto);\n if (proto.templates) {\n m.templates = proto.templates.map(Template.fromProto);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.applicationId !== 'undefined') {\n toReturn['applicationId'] = this.applicationId;\n }\n if (typeof this.templates !== 'undefined' && this.templates !== null) {\n toReturn['templates'] = 'toApiJson' in this.templates ? this.templates.toApiJson() : this.templates;\n }\n return toReturn;\n }\n}\nclass CreateTemplateRequest {\n static fromProto(proto) {\n let m = new CreateTemplateRequest();\n m = Object.assign(m, proto);\n if (proto.template) {\n m.template = Template.fromProto(proto.template);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.applicationId !== 'undefined') {\n toReturn['applicationId'] = this.applicationId;\n }\n if (typeof this.template !== 'undefined' && this.template !== null) {\n toReturn['template'] = 'toApiJson' in this.template ? this.template.toApiJson() : this.template;\n }\n return toReturn;\n }\n}\nclass DeleteTemplateRequest {\n static fromProto(proto) {\n let m = new DeleteTemplateRequest();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.applicationId !== 'undefined') {\n toReturn['applicationId'] = this.applicationId;\n }\n if (typeof this.templateId !== 'undefined') {\n toReturn['templateId'] = this.templateId;\n }\n return toReturn;\n }\n}\nclass ListSubstitutionParametersRequestFilters {\n static fromProto(proto) {\n let m = new ListSubstitutionParametersRequestFilters();\n m = Object.assign(m, proto);\n if (proto.forRequiredOptions) {\n m.forRequiredOptions = SubstitutionParameterOptions.fromProto(proto.forRequiredOptions);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.includeHtml !== 'undefined') {\n toReturn['includeHtml'] = this.includeHtml;\n }\n if (typeof this.includeDeprecated !== 'undefined') {\n toReturn['includeDeprecated'] = this.includeDeprecated;\n }\n if (typeof this.forRequiredOptions !== 'undefined' && this.forRequiredOptions !== null) {\n toReturn['forRequiredOptions'] = 'toApiJson' in this.forRequiredOptions ? this.forRequiredOptions.toApiJson() : this.forRequiredOptions;\n }\n return toReturn;\n }\n}\nclass GetAllSubstitutionParametersRequest {\n static fromProto(proto) {\n let m = new GetAllSubstitutionParametersRequest();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.locale !== 'undefined') {\n toReturn['locale'] = this.locale;\n }\n return toReturn;\n }\n}\nclass GetAllSubstitutionParametersResponse {\n static fromProto(proto) {\n let m = new GetAllSubstitutionParametersResponse();\n m = Object.assign(m, proto);\n if (proto.substitutionParameters) {\n m.substitutionParameters = proto.substitutionParameters.map(SubstitutionParameter.fromProto);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.substitutionParameters !== 'undefined' && this.substitutionParameters !== null) {\n toReturn['substitutionParameters'] = 'toApiJson' in this.substitutionParameters ? this.substitutionParameters.toApiJson() : this.substitutionParameters;\n }\n return toReturn;\n }\n}\nclass GetMultiTemplateRequest {\n static fromProto(proto) {\n let m = new GetMultiTemplateRequest();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.applicationId !== 'undefined') {\n toReturn['applicationId'] = this.applicationId;\n }\n if (typeof this.templateIds !== 'undefined') {\n toReturn['templateIds'] = this.templateIds;\n }\n return toReturn;\n }\n}\nclass GetMultiTemplateResponse {\n static fromProto(proto) {\n let m = new GetMultiTemplateResponse();\n m = Object.assign(m, proto);\n if (proto.templates) {\n m.templates = proto.templates.map(GetMultiTemplateResponseGetOrError.fromProto);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.templates !== 'undefined' && this.templates !== null) {\n toReturn['templates'] = 'toApiJson' in this.templates ? this.templates.toApiJson() : this.templates;\n }\n return toReturn;\n }\n}\nclass GetMultiTemplateResponseGetOrError {\n static fromProto(proto) {\n let m = new GetMultiTemplateResponseGetOrError();\n m = Object.assign(m, proto);\n if (proto.template) {\n m.template = Template.fromProto(proto.template);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.template !== 'undefined' && this.template !== null) {\n toReturn['template'] = 'toApiJson' in this.template ? this.template.toApiJson() : this.template;\n }\n if (typeof this.errorDescription !== 'undefined') {\n toReturn['errorDescription'] = this.errorDescription;\n }\n return toReturn;\n }\n}\nclass GetTemplateRequest {\n static fromProto(proto) {\n let m = new GetTemplateRequest();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.applicationId !== 'undefined') {\n toReturn['applicationId'] = this.applicationId;\n }\n if (typeof this.templateId !== 'undefined') {\n toReturn['templateId'] = this.templateId;\n }\n if (typeof this.locale !== 'undefined') {\n toReturn['locale'] = this.locale;\n }\n return toReturn;\n }\n}\nclass GetTemplateResponse {\n static fromProto(proto) {\n let m = new GetTemplateResponse();\n m = Object.assign(m, proto);\n if (proto.template) {\n m.template = Template.fromProto(proto.template);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.template !== 'undefined' && this.template !== null) {\n toReturn['template'] = 'toApiJson' in this.template ? this.template.toApiJson() : this.template;\n }\n return toReturn;\n }\n}\nclass ListSubstitutionParametersRequest {\n static fromProto(proto) {\n let m = new ListSubstitutionParametersRequest();\n m = Object.assign(m, proto);\n if (proto.filters) {\n m.filters = ListSubstitutionParametersRequestFilters.fromProto(proto.filters);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.filters !== 'undefined' && this.filters !== null) {\n toReturn['filters'] = 'toApiJson' in this.filters ? this.filters.toApiJson() : this.filters;\n }\n if (typeof this.locale !== 'undefined') {\n toReturn['locale'] = this.locale;\n }\n return toReturn;\n }\n}\nclass ListSubstitutionParametersResponse {\n static fromProto(proto) {\n let m = new ListSubstitutionParametersResponse();\n m = Object.assign(m, proto);\n if (proto.substitutionParameters) {\n m.substitutionParameters = proto.substitutionParameters.map(SubstitutionParameter.fromProto);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.substitutionParameters !== 'undefined' && this.substitutionParameters !== null) {\n toReturn['substitutionParameters'] = 'toApiJson' in this.substitutionParameters ? this.substitutionParameters.toApiJson() : this.substitutionParameters;\n }\n return toReturn;\n }\n}\nclass ListTemplateRequest {\n static fromProto(proto) {\n let m = new ListTemplateRequest();\n m = Object.assign(m, proto);\n if (proto.pageSize) {\n m.pageSize = parseInt(proto.pageSize, 10);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.applicationId !== 'undefined') {\n toReturn['applicationId'] = this.applicationId;\n }\n if (typeof this.prefix !== 'undefined') {\n toReturn['prefix'] = this.prefix;\n }\n if (typeof this.cursor !== 'undefined') {\n toReturn['cursor'] = this.cursor;\n }\n if (typeof this.pageSize !== 'undefined') {\n toReturn['pageSize'] = this.pageSize;\n }\n return toReturn;\n }\n}\nclass ListTemplateResponse {\n static fromProto(proto) {\n let m = new ListTemplateResponse();\n m = Object.assign(m, proto);\n if (proto.templates) {\n m.templates = proto.templates.map(Template.fromProto);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.templates !== 'undefined' && this.templates !== null) {\n toReturn['templates'] = 'toApiJson' in this.templates ? this.templates.toApiJson() : this.templates;\n }\n if (typeof this.cursor !== 'undefined') {\n toReturn['cursor'] = this.cursor;\n }\n if (typeof this.hasMore !== 'undefined') {\n toReturn['hasMore'] = this.hasMore;\n }\n return toReturn;\n }\n}\nclass RenderTemplateMultiRequestParameterizedTemplates {\n static fromProto(proto) {\n let m = new RenderTemplateMultiRequestParameterizedTemplates();\n m = Object.assign(m, proto);\n if (proto.substitutionParameterOptions) {\n m.substitutionParameterOptions = SubstitutionParameterOptions.fromProto(proto.substitutionParameterOptions);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.templateId !== 'undefined') {\n toReturn['templateId'] = this.templateId;\n }\n if (typeof this.parameters !== 'undefined') {\n toReturn['parameters'] = this.parameters;\n }\n if (typeof this.locale !== 'undefined') {\n toReturn['locale'] = this.locale;\n }\n if (typeof this.substitutionParameterOptions !== 'undefined' && this.substitutionParameterOptions !== null) {\n toReturn['substitutionParameterOptions'] = 'toApiJson' in this.substitutionParameterOptions ? this.substitutionParameterOptions.toApiJson() : this.substitutionParameterOptions;\n }\n return toReturn;\n }\n}\nclass RenderMultiRequestRender {\n static fromProto(proto) {\n let m = new RenderMultiRequestRender();\n m = Object.assign(m, proto);\n if (proto.type) {\n m.type = enumStringToValue(TemplateType, proto.type);\n }\n if (proto.hydrationOptions) {\n m.hydrationOptions = HydrationOptions.fromProto(proto.hydrationOptions);\n }\n if (proto.substitutionParameterOptions) {\n m.substitutionParameterOptions = SubstitutionParameterOptions.fromProto(proto.substitutionParameterOptions);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.templateContent !== 'undefined') {\n toReturn['templateContent'] = this.templateContent;\n }\n if (typeof this.parameters !== 'undefined') {\n toReturn['parameters'] = this.parameters;\n }\n if (typeof this.errorOnMissingParam !== 'undefined') {\n toReturn['errorOnMissingParam'] = this.errorOnMissingParam;\n }\n if (typeof this.type !== 'undefined') {\n toReturn['type'] = this.type;\n }\n if (typeof this.hydrationOptions !== 'undefined' && this.hydrationOptions !== null) {\n toReturn['hydrationOptions'] = 'toApiJson' in this.hydrationOptions ? this.hydrationOptions.toApiJson() : this.hydrationOptions;\n }\n if (typeof this.substitutionParameterOptions !== 'undefined' && this.substitutionParameterOptions !== null) {\n toReturn['substitutionParameterOptions'] = 'toApiJson' in this.substitutionParameterOptions ? this.substitutionParameterOptions.toApiJson() : this.substitutionParameterOptions;\n }\n if (typeof this.locale !== 'undefined') {\n toReturn['locale'] = this.locale;\n }\n if (typeof this.renderFakeData !== 'undefined') {\n toReturn['renderFakeData'] = this.renderFakeData;\n }\n if (typeof this.disableAutoEscape !== 'undefined') {\n toReturn['disableAutoEscape'] = this.disableAutoEscape;\n }\n return toReturn;\n }\n}\nclass RenderMultiRequest {\n static fromProto(proto) {\n let m = new RenderMultiRequest();\n m = Object.assign(m, proto);\n if (proto.renderRequests) {\n m.renderRequests = proto.renderRequests.map(RenderMultiRequestRender.fromProto);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.renderRequests !== 'undefined' && this.renderRequests !== null) {\n toReturn['renderRequests'] = 'toApiJson' in this.renderRequests ? this.renderRequests.toApiJson() : this.renderRequests;\n }\n return toReturn;\n }\n}\nclass RenderMultiResponse {\n static fromProto(proto) {\n let m = new RenderMultiResponse();\n m = Object.assign(m, proto);\n if (proto.renders) {\n m.renders = proto.renders.map(RenderMultiResponseRenderOrError.fromProto);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.renders !== 'undefined' && this.renders !== null) {\n toReturn['renders'] = 'toApiJson' in this.renders ? this.renders.toApiJson() : this.renders;\n }\n return toReturn;\n }\n}\nclass RenderMultiResponseRenderOrError {\n static fromProto(proto) {\n let m = new RenderMultiResponseRenderOrError();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.renderedTemplate !== 'undefined') {\n toReturn['renderedTemplate'] = this.renderedTemplate;\n }\n if (typeof this.errorDescription !== 'undefined') {\n toReturn['errorDescription'] = this.errorDescription;\n }\n return toReturn;\n }\n}\nclass RenderRequest {\n static fromProto(proto) {\n let m = new RenderRequest();\n m = Object.assign(m, proto);\n if (proto.type) {\n m.type = enumStringToValue(TemplateType, proto.type);\n }\n if (proto.hydrationOptions) {\n m.hydrationOptions = HydrationOptions.fromProto(proto.hydrationOptions);\n }\n if (proto.substitutionParameterOptions) {\n m.substitutionParameterOptions = SubstitutionParameterOptions.fromProto(proto.substitutionParameterOptions);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.templateContent !== 'undefined') {\n toReturn['templateContent'] = this.templateContent;\n }\n if (typeof this.parameters !== 'undefined') {\n toReturn['parameters'] = this.parameters;\n }\n if (typeof this.errorOnMissingParam !== 'undefined') {\n toReturn['errorOnMissingParam'] = this.errorOnMissingParam;\n }\n if (typeof this.type !== 'undefined') {\n toReturn['type'] = this.type;\n }\n if (typeof this.hydrationOptions !== 'undefined' && this.hydrationOptions !== null) {\n toReturn['hydrationOptions'] = 'toApiJson' in this.hydrationOptions ? this.hydrationOptions.toApiJson() : this.hydrationOptions;\n }\n if (typeof this.substitutionParameterOptions !== 'undefined' && this.substitutionParameterOptions !== null) {\n toReturn['substitutionParameterOptions'] = 'toApiJson' in this.substitutionParameterOptions ? this.substitutionParameterOptions.toApiJson() : this.substitutionParameterOptions;\n }\n if (typeof this.locale !== 'undefined') {\n toReturn['locale'] = this.locale;\n }\n if (typeof this.renderFakeData !== 'undefined') {\n toReturn['renderFakeData'] = this.renderFakeData;\n }\n if (typeof this.disableAutoEscape !== 'undefined') {\n toReturn['disableAutoEscape'] = this.disableAutoEscape;\n }\n return toReturn;\n }\n}\nclass RenderResponse {\n static fromProto(proto) {\n let m = new RenderResponse();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.renderedTemplate !== 'undefined') {\n toReturn['renderedTemplate'] = this.renderedTemplate;\n }\n return toReturn;\n }\n}\nclass RenderTemplateMultiRequest {\n static fromProto(proto) {\n let m = new RenderTemplateMultiRequest();\n m = Object.assign(m, proto);\n if (proto.templatesToRender) {\n m.templatesToRender = proto.templatesToRender.map(RenderTemplateMultiRequestParameterizedTemplates.fromProto);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.applicationId !== 'undefined') {\n toReturn['applicationId'] = this.applicationId;\n }\n if (typeof this.templatesToRender !== 'undefined' && this.templatesToRender !== null) {\n toReturn['templatesToRender'] = 'toApiJson' in this.templatesToRender ? this.templatesToRender.toApiJson() : this.templatesToRender;\n }\n if (typeof this.errorOnMissingParam !== 'undefined') {\n toReturn['errorOnMissingParam'] = this.errorOnMissingParam;\n }\n if (typeof this.disableAutoEscape !== 'undefined') {\n toReturn['disableAutoEscape'] = this.disableAutoEscape;\n }\n return toReturn;\n }\n}\nclass RenderTemplateRequest {\n static fromProto(proto) {\n let m = new RenderTemplateRequest();\n m = Object.assign(m, proto);\n if (proto.substitutionParameterOptions) {\n m.substitutionParameterOptions = SubstitutionParameterOptions.fromProto(proto.substitutionParameterOptions);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.applicationId !== 'undefined') {\n toReturn['applicationId'] = this.applicationId;\n }\n if (typeof this.templateId !== 'undefined') {\n toReturn['templateId'] = this.templateId;\n }\n if (typeof this.parameters !== 'undefined') {\n toReturn['parameters'] = this.parameters;\n }\n if (typeof this.locale !== 'undefined') {\n toReturn['locale'] = this.locale;\n }\n if (typeof this.errorOnMissingParam !== 'undefined') {\n toReturn['errorOnMissingParam'] = this.errorOnMissingParam;\n }\n if (typeof this.substitutionParameterOptions !== 'undefined' && this.substitutionParameterOptions !== null) {\n toReturn['substitutionParameterOptions'] = 'toApiJson' in this.substitutionParameterOptions ? this.substitutionParameterOptions.toApiJson() : this.substitutionParameterOptions;\n }\n if (typeof this.disableAutoEscape !== 'undefined') {\n toReturn['disableAutoEscape'] = this.disableAutoEscape;\n }\n return toReturn;\n }\n}\nclass ReplaceTemplateRequest {\n static fromProto(proto) {\n let m = new ReplaceTemplateRequest();\n m = Object.assign(m, proto);\n if (proto.template) {\n m.template = Template.fromProto(proto.template);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.applicationId !== 'undefined') {\n toReturn['applicationId'] = this.applicationId;\n }\n if (typeof this.template !== 'undefined' && this.template !== null) {\n toReturn['template'] = 'toApiJson' in this.template ? this.template.toApiJson() : this.template;\n }\n return toReturn;\n }\n}\nclass UpdateTemplateRequest {\n static fromProto(proto) {\n let m = new UpdateTemplateRequest();\n m = Object.assign(m, proto);\n if (proto.template) {\n m.template = Template.fromProto(proto.template);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.applicationId !== 'undefined') {\n toReturn['applicationId'] = this.applicationId;\n }\n if (typeof this.template !== 'undefined' && this.template !== null) {\n toReturn['template'] = 'toApiJson' in this.template ? this.template.toApiJson() : this.template;\n }\n return toReturn;\n }\n}\nclass VerifySubstitutionParametersRequest {\n static fromProto(proto) {\n let m = new VerifySubstitutionParametersRequest();\n m = Object.assign(m, proto);\n if (proto.rawTemplate) {\n m.rawTemplate = RawTemplate.fromProto(proto.rawTemplate);\n }\n if (proto.templateIdentifier) {\n m.templateIdentifier = TemplateIdentifier.fromProto(proto.templateIdentifier);\n }\n if (proto.substitutionParameterOptions) {\n m.substitutionParameterOptions = SubstitutionParameterOptions.fromProto(proto.substitutionParameterOptions);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.rawTemplate !== 'undefined' && this.rawTemplate !== null) {\n toReturn['rawTemplate'] = 'toApiJson' in this.rawTemplate ? this.rawTemplate.toApiJson() : this.rawTemplate;\n }\n if (typeof this.templateIdentifier !== 'undefined' && this.templateIdentifier !== null) {\n toReturn['templateIdentifier'] = 'toApiJson' in this.templateIdentifier ? this.templateIdentifier.toApiJson() : this.templateIdentifier;\n }\n if (typeof this.substitutionParameterOptions !== 'undefined' && this.substitutionParameterOptions !== null) {\n toReturn['substitutionParameterOptions'] = 'toApiJson' in this.substitutionParameterOptions ? this.substitutionParameterOptions.toApiJson() : this.substitutionParameterOptions;\n }\n if (typeof this.locale !== 'undefined') {\n toReturn['locale'] = this.locale;\n }\n if (typeof this.parameters !== 'undefined') {\n toReturn['parameters'] = this.parameters;\n }\n return toReturn;\n }\n}\nclass VerifySubstitutionParametersResponse {\n static fromProto(proto) {\n let m = new VerifySubstitutionParametersResponse();\n m = Object.assign(m, proto);\n if (proto.errors) {\n m.errors = proto.errors.map(SubstitutionParameterError.fromProto);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.errors !== 'undefined' && this.errors !== null) {\n toReturn['errors'] = 'toApiJson' in this.errors ? this.errors.toApiJson() : this.errors;\n }\n return toReturn;\n }\n}\n\n// *********************************\n// Code generated by sdkgen\n// DO NOT EDIT!.\n//\n// Objects Index.\n// *********************************\n\nconst environment = (window ? window['environment'] : 'prod') ?? 'prod';\nconst hostMap = {\n 'local': 'templates-api.vendasta-local.com',\n 'test': '',\n 'demo': 'templates-api-demo.apigateway.co',\n 'prod': 'templates-api-prod.apigateway.co',\n 'production': 'templates-api-prod.apigateway.co'\n};\nlet HostService = /*#__PURE__*/(() => {\n class HostService {\n get host() {\n return hostMap[environment.toLowerCase()];\n }\n get hostWithScheme() {\n return 'https://' + this.host;\n }\n }\n HostService.ɵfac = function HostService_Factory(__ngFactoryType__) {\n return new (__ngFactoryType__ || HostService)();\n };\n HostService.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: HostService,\n factory: HostService.ɵfac,\n providedIn: 'root'\n });\n return HostService;\n})();\n(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n// *********************************\n// Code generated by sdkgen\n// DO NOT EDIT!.\n//\n// API Service.\n// *********************************\nlet TemplatesApiService = /*#__PURE__*/(() => {\n class TemplatesApiService {\n constructor() {\n this.hostService = inject(HostService);\n this.http = inject(HttpClient);\n this._host = this.hostService.hostWithScheme;\n }\n apiOptions() {\n return {\n headers: new HttpHeaders({\n 'Content-Type': 'application/json'\n }),\n withCredentials: true\n };\n }\n create(r) {\n const request = r.toApiJson ? r : new CreateTemplateRequest(r);\n return this.http.post(this._host + \"/templates.v1.TemplatesService/Create\", request.toApiJson(), {\n ...this.apiOptions(),\n observe: 'response'\n });\n }\n get(r) {\n const request = r.toApiJson ? r : new GetTemplateRequest(r);\n return this.http.post(this._host + \"/templates.v1.TemplatesService/Get\", request.toApiJson(), this.apiOptions()).pipe(map(resp => GetTemplateResponse.fromProto(resp)));\n }\n getMulti(r) {\n const request = r.toApiJson ? r : new GetMultiTemplateRequest(r);\n return this.http.post(this._host + \"/templates.v1.TemplatesService/GetMulti\", request.toApiJson(), this.apiOptions()).pipe(map(resp => GetMultiTemplateResponse.fromProto(resp)));\n }\n list(r) {\n const request = r.toApiJson ? r : new ListTemplateRequest(r);\n return this.http.post(this._host + \"/templates.v1.TemplatesService/List\", request.toApiJson(), this.apiOptions()).pipe(map(resp => ListTemplateResponse.fromProto(resp)));\n }\n delete(r) {\n const request = r.toApiJson ? r : new DeleteTemplateRequest(r);\n return this.http.post(this._host + \"/templates.v1.TemplatesService/Delete\", request.toApiJson(), {\n ...this.apiOptions(),\n observe: 'response'\n });\n }\n update(r) {\n const request = r.toApiJson ? r : new UpdateTemplateRequest(r);\n return this.http.post(this._host + \"/templates.v1.TemplatesService/Update\", request.toApiJson(), {\n ...this.apiOptions(),\n observe: 'response'\n });\n }\n replace(r) {\n const request = r.toApiJson ? r : new ReplaceTemplateRequest(r);\n return this.http.post(this._host + \"/templates.v1.TemplatesService/Replace\", request.toApiJson(), {\n ...this.apiOptions(),\n observe: 'response'\n });\n }\n addTemplateLocale(r) {\n const request = r.toApiJson ? r : new AddTemplateLocaleRequest(r);\n return this.http.post(this._host + \"/templates.v1.TemplatesService/AddTemplateLocale\", request.toApiJson(), {\n ...this.apiOptions(),\n observe: 'response'\n });\n }\n renderTemplate(r) {\n const request = r.toApiJson ? r : new RenderTemplateRequest(r);\n return this.http.post(this._host + \"/templates.v1.TemplatesService/RenderTemplate\", request.toApiJson(), this.apiOptions()).pipe(map(resp => RenderResponse.fromProto(resp)));\n }\n renderTemplateMulti(r) {\n const request = r.toApiJson ? r : new RenderTemplateMultiRequest(r);\n return this.http.post(this._host + \"/templates.v1.TemplatesService/RenderTemplateMulti\", request.toApiJson(), this.apiOptions()).pipe(map(resp => RenderMultiResponse.fromProto(resp)));\n }\n render(r) {\n const request = r.toApiJson ? r : new RenderRequest(r);\n return this.http.post(this._host + \"/templates.v1.TemplatesService/Render\", request.toApiJson(), this.apiOptions()).pipe(map(resp => RenderResponse.fromProto(resp)));\n }\n renderMulti(r) {\n const request = r.toApiJson ? r : new RenderMultiRequest(r);\n return this.http.post(this._host + \"/templates.v1.TemplatesService/RenderMulti\", request.toApiJson(), this.apiOptions()).pipe(map(resp => RenderMultiResponse.fromProto(resp)));\n }\n getAllSubstitutionParameters(r) {\n const request = r.toApiJson ? r : new GetAllSubstitutionParametersRequest(r);\n return this.http.post(this._host + \"/templates.v1.TemplatesService/GetAllSubstitutionParameters\", request.toApiJson(), this.apiOptions()).pipe(map(resp => GetAllSubstitutionParametersResponse.fromProto(resp)));\n }\n listSubstitutionParameters(r) {\n const request = r.toApiJson ? r : new ListSubstitutionParametersRequest(r);\n return this.http.post(this._host + \"/templates.v1.TemplatesService/ListSubstitutionParameters\", request.toApiJson(), this.apiOptions()).pipe(map(resp => ListSubstitutionParametersResponse.fromProto(resp)));\n }\n verifySubstitutionParameters(r) {\n const request = r.toApiJson ? r : new VerifySubstitutionParametersRequest(r);\n return this.http.post(this._host + \"/templates.v1.TemplatesService/VerifySubstitutionParameters\", request.toApiJson(), this.apiOptions()).pipe(map(resp => VerifySubstitutionParametersResponse.fromProto(resp)));\n }\n createMulti(r) {\n const request = r.toApiJson ? r : new CreateMultiTemplateRequest(r);\n return this.http.post(this._host + \"/templates.v1.TemplatesService/CreateMulti\", request.toApiJson(), {\n ...this.apiOptions(),\n observe: 'response'\n });\n }\n }\n TemplatesApiService.ɵfac = function TemplatesApiService_Factory(__ngFactoryType__) {\n return new (__ngFactoryType__ || TemplatesApiService)();\n };\n TemplatesApiService.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: TemplatesApiService,\n factory: TemplatesApiService.ɵfac,\n providedIn: 'root'\n });\n return TemplatesApiService;\n})();\n(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n// *********************************\n// Code generated by sdkgen\n// DO NOT EDIT!.\n//\n// Index.\n// *********************************\nlet TemplatesService = /*#__PURE__*/(() => {\n class TemplatesService {\n constructor(client) {\n this.client = client;\n }\n get(applicationId, templateId, locale) {\n return this.client.get({\n applicationId,\n templateId,\n locale\n }).pipe(map(resp => resp.template));\n }\n getMulti(applicationId, templateIds) {\n return this.client.getMulti({\n applicationId,\n templateIds\n }).pipe(map(resp => resp.templates));\n }\n create(applicationId, template) {\n return this.client.create({\n applicationId,\n template\n }).pipe(map(() => true));\n }\n update(applicationId, template) {\n return this.client.update({\n applicationId,\n template\n }).pipe(map(() => true));\n }\n /**\n * Render any text content using template hydration\n * @param templateContent The content to render - including substitution tags (Default is GoLang style, but can be overridden)\n * @param parameters Typically contains IDs used for hydration (e.g. partner ID, user ID) using keys of your choosing\n * @param subParamOpts Used for mapping the keys provided in `parameters` to the ones expected by templates microservice\n * @param templateType The templating engine to use.\n * @param locale The locale to use for localizable hydrations (e.g. dates, addresses) - optional\n * @param renderFakeData If true, will return fake data if real data cannot be rendered\n */\n render(templateContent, parameters, templateType = TemplateType.TEMPLATE_TYPE_GOLANG, subParamOpts, locale, errorOnMissingParam, options, renderFakeData) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const request = new RenderRequest({\n templateContent: templateContent,\n errorOnMissingParam: errorOnMissingParam,\n locale: locale,\n parameters: parameters,\n substitutionParameterOptions: subParamOpts,\n hydrationOptions: options,\n type: templateType,\n renderFakeData: renderFakeData\n });\n return this.client.render(request).pipe(map(resp => resp.renderedTemplate || ''));\n }\n renderTemplate(applicationId, templateId, parameters, locale, errorOnMissingParam) {\n return this.client.renderTemplate({\n applicationId: applicationId,\n templateId: templateId,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n parameters: parameters,\n locale: locale,\n errorOnMissingParam: errorOnMissingParam\n }).pipe(map(resp => resp.renderedTemplate || ''));\n }\n listSubstitutionParameters(filters) {\n return this.client.listSubstitutionParameters({\n filters: filters\n }).pipe(map(resp => resp.substitutionParameters));\n }\n }\n TemplatesService.ɵfac = function TemplatesService_Factory(__ngFactoryType__) {\n return new (__ngFactoryType__ || TemplatesService)(i0.ɵɵinject(TemplatesApiService));\n };\n TemplatesService.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: TemplatesService,\n factory: TemplatesService.ɵfac,\n providedIn: 'root'\n });\n return TemplatesService;\n})();\n(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/**\n * Generated bundle index. Do not edit.\n */\n\nexport { CreateTemplateRequest, DeleteTemplateRequest, GetMultiTemplateRequest, GetTemplateRequest, GetTemplateResponse, ListTemplateRequest, RenderMultiResponse, RenderRequest, RenderResponse, RenderTemplateMultiRequest, RenderTemplateRequest, SubstitutionParameter, Template, TemplateType, TemplatesApiService, TemplatesService, UpdateTemplateRequest };\n","import * as i0 from '@angular/core';\nimport { Injectable } from '@angular/core';\nimport { map } from 'rxjs/operators';\nimport * as i1 from '@angular/common/http';\nimport { HttpHeaders } from '@angular/common/http';\nfunction enumStringToValue$7(enumRef, value) {\n if (typeof value === 'number') {\n return value;\n }\n return enumRef[value];\n}\nclass PagedResponseMetadata {\n static fromProto(proto) {\n let m = new PagedResponseMetadata();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.nextCursor !== 'undefined') {\n toReturn['nextCursor'] = this.nextCursor;\n }\n if (typeof this.hasMore !== 'undefined') {\n toReturn['hasMore'] = this.hasMore;\n }\n return toReturn;\n }\n}\nfunction enumStringToValue$6(enumRef, value) {\n if (typeof value === 'number') {\n return value;\n }\n return enumRef[value];\n}\nclass CommonResource {\n static fromProto(proto) {\n let m = new CommonResource();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.id !== 'undefined') {\n toReturn['id'] = this.id;\n }\n if (typeof this.name !== 'undefined') {\n toReturn['name'] = this.name;\n }\n return toReturn;\n }\n}\nfunction enumStringToValue$5(enumRef, value) {\n if (typeof value === 'number') {\n return value;\n }\n return enumRef[value];\n}\nclass ExtractedValue {\n static fromProto(proto) {\n let m = new ExtractedValue();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.id !== 'undefined') {\n toReturn['id'] = this.id;\n }\n if (typeof this.valuePath !== 'undefined') {\n toReturn['valuePath'] = this.valuePath;\n }\n return toReturn;\n }\n}\nclass Filter {\n static fromProto(proto) {\n let m = new Filter();\n m = Object.assign(m, proto);\n if (proto.value) {\n m.value = ExtractedValue.fromProto(proto.value);\n }\n if (proto.options) {\n m.options = proto.options.map(FilterOption.fromProto);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.value !== 'undefined' && this.value !== null) {\n toReturn['value'] = 'toApiJson' in this.value ? this.value.toApiJson() : this.value;\n }\n if (typeof this.label !== 'undefined') {\n toReturn['label'] = this.label;\n }\n if (typeof this.options !== 'undefined' && this.options !== null) {\n toReturn['options'] = 'toApiJson' in this.options ? this.options.toApiJson() : this.options;\n }\n return toReturn;\n }\n}\nclass FilterOption {\n static fromProto(proto) {\n let m = new FilterOption();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.id !== 'undefined') {\n toReturn['id'] = this.id;\n }\n if (typeof this.value !== 'undefined') {\n toReturn['value'] = this.value;\n }\n return toReturn;\n }\n}\nclass Icon {\n static fromProto(proto) {\n let m = new Icon();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.iconPath !== 'undefined') {\n toReturn['iconPath'] = this.iconPath;\n }\n if (typeof this.matIcon !== 'undefined') {\n toReturn['matIcon'] = this.matIcon;\n }\n return toReturn;\n }\n}\nclass IconResource {\n static fromProto(proto) {\n let m = new IconResource();\n m = Object.assign(m, proto);\n if (proto.defaultIcon) {\n m.defaultIcon = Icon.fromProto(proto.defaultIcon);\n }\n if (proto.customTypes) {\n m.customTypes = proto.customTypes.map(IconType.fromProto);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.resourcePath !== 'undefined') {\n toReturn['resourcePath'] = this.resourcePath;\n }\n if (typeof this.defaultIcon !== 'undefined' && this.defaultIcon !== null) {\n toReturn['defaultIcon'] = 'toApiJson' in this.defaultIcon ? this.defaultIcon.toApiJson() : this.defaultIcon;\n }\n if (typeof this.customTypes !== 'undefined' && this.customTypes !== null) {\n toReturn['customTypes'] = 'toApiJson' in this.customTypes ? this.customTypes.toApiJson() : this.customTypes;\n }\n return toReturn;\n }\n}\nclass IconType {\n static fromProto(proto) {\n let m = new IconType();\n m = Object.assign(m, proto);\n if (proto.icon) {\n m.icon = Icon.fromProto(proto.icon);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.type !== 'undefined') {\n toReturn['type'] = this.type;\n }\n if (typeof this.icon !== 'undefined' && this.icon !== null) {\n toReturn['icon'] = 'toApiJson' in this.icon ? this.icon.toApiJson() : this.icon;\n }\n return toReturn;\n }\n}\nclass PostType {\n static fromProto(proto) {\n let m = new PostType();\n m = Object.assign(m, proto);\n if (proto.commonResources) {\n m.commonResources = proto.commonResources.map(ExtractedValue.fromProto);\n }\n if (proto.created) {\n m.created = new Date(proto.created);\n }\n if (proto.updated) {\n m.updated = new Date(proto.updated);\n }\n if (proto.filters) {\n m.filters = proto.filters.map(Filter.fromProto);\n }\n if (proto.iconResource) {\n m.iconResource = IconResource.fromProto(proto.iconResource);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.typeId !== 'undefined') {\n toReturn['typeId'] = this.typeId;\n }\n if (typeof this.name !== 'undefined') {\n toReturn['name'] = this.name;\n }\n if (typeof this.postIdTemplate !== 'undefined') {\n toReturn['postIdTemplate'] = this.postIdTemplate;\n }\n if (typeof this.eventTypeId !== 'undefined') {\n toReturn['eventTypeId'] = this.eventTypeId;\n }\n if (typeof this.commonResources !== 'undefined' && this.commonResources !== null) {\n toReturn['commonResources'] = 'toApiJson' in this.commonResources ? this.commonResources.toApiJson() : this.commonResources;\n }\n if (typeof this.templateId !== 'undefined') {\n toReturn['templateId'] = this.templateId;\n }\n if (typeof this.created !== 'undefined' && this.created !== null) {\n toReturn['created'] = 'toApiJson' in this.created ? this.created.toApiJson() : this.created;\n }\n if (typeof this.updated !== 'undefined' && this.updated !== null) {\n toReturn['updated'] = 'toApiJson' in this.updated ? this.updated.toApiJson() : this.updated;\n }\n if (typeof this.partnerIdPath !== 'undefined') {\n toReturn['partnerIdPath'] = this.partnerIdPath;\n }\n if (typeof this.marketIdPath !== 'undefined') {\n toReturn['marketIdPath'] = this.marketIdPath;\n }\n if (typeof this.userIdPath !== 'undefined') {\n toReturn['userIdPath'] = this.userIdPath;\n }\n if (typeof this.filters !== 'undefined' && this.filters !== null) {\n toReturn['filters'] = 'toApiJson' in this.filters ? this.filters.toApiJson() : this.filters;\n }\n if (typeof this.channel !== 'undefined') {\n toReturn['channel'] = this.channel;\n }\n if (typeof this.iconResource !== 'undefined' && this.iconResource !== null) {\n toReturn['iconResource'] = 'toApiJson' in this.iconResource ? this.iconResource.toApiJson() : this.iconResource;\n }\n return toReturn;\n }\n}\nfunction enumStringToValue$4(enumRef, value) {\n if (typeof value === 'number') {\n return value;\n }\n return enumRef[value];\n}\nclass User {\n static fromProto(proto) {\n let m = new User();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.userId !== 'undefined') {\n toReturn['userId'] = this.userId;\n }\n if (typeof this.email !== 'undefined') {\n toReturn['email'] = this.email;\n }\n if (typeof this.firstName !== 'undefined') {\n toReturn['firstName'] = this.firstName;\n }\n if (typeof this.lastName !== 'undefined') {\n toReturn['lastName'] = this.lastName;\n }\n return toReturn;\n }\n}\nfunction enumStringToValue$3(enumRef, value) {\n if (typeof value === 'number') {\n return value;\n }\n return enumRef[value];\n}\nclass Comment {\n static fromProto(proto) {\n let m = new Comment();\n m = Object.assign(m, proto);\n if (proto.user) {\n m.user = User.fromProto(proto.user);\n }\n if (proto.created) {\n m.created = new Date(proto.created);\n }\n if (proto.updated) {\n m.updated = new Date(proto.updated);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.id !== 'undefined') {\n toReturn['id'] = this.id;\n }\n if (typeof this.user !== 'undefined' && this.user !== null) {\n toReturn['user'] = 'toApiJson' in this.user ? this.user.toApiJson() : this.user;\n }\n if (typeof this.text !== 'undefined') {\n toReturn['text'] = this.text;\n }\n if (typeof this.created !== 'undefined' && this.created !== null) {\n toReturn['created'] = 'toApiJson' in this.created ? this.created.toApiJson() : this.created;\n }\n if (typeof this.updated !== 'undefined' && this.updated !== null) {\n toReturn['updated'] = 'toApiJson' in this.updated ? this.updated.toApiJson() : this.updated;\n }\n return toReturn;\n }\n}\nfunction enumStringToValue$2(enumRef, value) {\n if (typeof value === 'number') {\n return value;\n }\n return enumRef[value];\n}\nclass PostLatestComments {\n static fromProto(proto) {\n let m = new PostLatestComments();\n m = Object.assign(m, proto);\n if (proto.comments) {\n m.comments = proto.comments.map(Comment.fromProto);\n }\n if (proto.pagingMetadata) {\n m.pagingMetadata = PagedResponseMetadata.fromProto(proto.pagingMetadata);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.comments !== 'undefined' && this.comments !== null) {\n toReturn['comments'] = 'toApiJson' in this.comments ? this.comments.toApiJson() : this.comments;\n }\n if (typeof this.pagingMetadata !== 'undefined' && this.pagingMetadata !== null) {\n toReturn['pagingMetadata'] = 'toApiJson' in this.pagingMetadata ? this.pagingMetadata.toApiJson() : this.pagingMetadata;\n }\n return toReturn;\n }\n}\nclass Post {\n static fromProto(proto) {\n let m = new Post();\n m = Object.assign(m, proto);\n if (proto.postIdentifier) {\n m.postIdentifier = PostIdentifier.fromProto(proto.postIdentifier);\n }\n if (proto.user) {\n m.user = User.fromProto(proto.user);\n }\n if (proto.created) {\n m.created = new Date(proto.created);\n }\n if (proto.updated) {\n m.updated = new Date(proto.updated);\n }\n if (proto.likes) {\n m.likes = proto.likes.map(User.fromProto);\n }\n if (proto.latestComments) {\n m.latestComments = PostLatestComments.fromProto(proto.latestComments);\n }\n if (proto.icon) {\n m.icon = Icon.fromProto(proto.icon);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.postIdentifier !== 'undefined' && this.postIdentifier !== null) {\n toReturn['postIdentifier'] = 'toApiJson' in this.postIdentifier ? this.postIdentifier.toApiJson() : this.postIdentifier;\n }\n if (typeof this.partnerId !== 'undefined') {\n toReturn['partnerId'] = this.partnerId;\n }\n if (typeof this.marketId !== 'undefined') {\n toReturn['marketId'] = this.marketId;\n }\n if (typeof this.user !== 'undefined' && this.user !== null) {\n toReturn['user'] = 'toApiJson' in this.user ? this.user.toApiJson() : this.user;\n }\n if (typeof this.resources !== 'undefined') {\n toReturn['resources'] = this.resources;\n }\n if (typeof this.created !== 'undefined' && this.created !== null) {\n toReturn['created'] = 'toApiJson' in this.created ? this.created.toApiJson() : this.created;\n }\n if (typeof this.updated !== 'undefined' && this.updated !== null) {\n toReturn['updated'] = 'toApiJson' in this.updated ? this.updated.toApiJson() : this.updated;\n }\n if (typeof this.html !== 'undefined') {\n toReturn['html'] = this.html;\n }\n if (typeof this.likes !== 'undefined' && this.likes !== null) {\n toReturn['likes'] = 'toApiJson' in this.likes ? this.likes.toApiJson() : this.likes;\n }\n if (typeof this.latestComments !== 'undefined' && this.latestComments !== null) {\n toReturn['latestComments'] = 'toApiJson' in this.latestComments ? this.latestComments.toApiJson() : this.latestComments;\n }\n if (typeof this.isSubscribed !== 'undefined') {\n toReturn['isSubscribed'] = this.isSubscribed;\n }\n if (typeof this.style !== 'undefined') {\n toReturn['style'] = this.style;\n }\n if (typeof this.icon !== 'undefined' && this.icon !== null) {\n toReturn['icon'] = 'toApiJson' in this.icon ? this.icon.toApiJson() : this.icon;\n }\n return toReturn;\n }\n}\nclass PostIdentifier {\n static fromProto(proto) {\n let m = new PostIdentifier();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.postId !== 'undefined') {\n toReturn['postId'] = this.postId;\n }\n if (typeof this.typeId !== 'undefined') {\n toReturn['typeId'] = this.typeId;\n }\n return toReturn;\n }\n}\nfunction enumStringToValue$1(enumRef, value) {\n if (typeof value === 'number') {\n return value;\n }\n return enumRef[value];\n}\nclass Access {\n static fromProto(proto) {\n let m = new Access();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.scope !== 'undefined') {\n toReturn['scope'] = this.scope;\n }\n if (typeof this.public !== 'undefined') {\n toReturn['public'] = this.public;\n }\n return toReturn;\n }\n}\n\n// *********************************\n// Code generated by sdkgen\n// DO NOT EDIT!.\n//\n// Enums.\n// *********************************\nvar RenderOption = /*#__PURE__*/function (RenderOption) {\n RenderOption[RenderOption[\"RENDER_OPTION_FULL\"] = 0] = \"RENDER_OPTION_FULL\";\n RenderOption[RenderOption[\"RENDER_OPTION_COMPACT\"] = 1] = \"RENDER_OPTION_COMPACT\";\n return RenderOption;\n}(RenderOption || {});\n// *********************************\n\nfunction enumStringToValue(enumRef, value) {\n if (typeof value === 'number') {\n return value;\n }\n return enumRef[value];\n}\nclass CommentRequest {\n static fromProto(proto) {\n let m = new CommentRequest();\n m = Object.assign(m, proto);\n if (proto.postIdentifier) {\n m.postIdentifier = PostIdentifier.fromProto(proto.postIdentifier);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.postIdentifier !== 'undefined' && this.postIdentifier !== null) {\n toReturn['postIdentifier'] = 'toApiJson' in this.postIdentifier ? this.postIdentifier.toApiJson() : this.postIdentifier;\n }\n if (typeof this.text !== 'undefined') {\n toReturn['text'] = this.text;\n }\n return toReturn;\n }\n}\nclass CommentResponse {\n static fromProto(proto) {\n let m = new CommentResponse();\n m = Object.assign(m, proto);\n if (proto.comment) {\n m.comment = Comment.fromProto(proto.comment);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.comment !== 'undefined' && this.comment !== null) {\n toReturn['comment'] = 'toApiJson' in this.comment ? this.comment.toApiJson() : this.comment;\n }\n return toReturn;\n }\n}\nclass UpdatePostTypeRequestOperationCommonResources {\n static fromProto(proto) {\n let m = new UpdatePostTypeRequestOperationCommonResources();\n m = Object.assign(m, proto);\n if (proto.commonResources) {\n m.commonResources = proto.commonResources.map(ExtractedValue.fromProto);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.commonResources !== 'undefined' && this.commonResources !== null) {\n toReturn['commonResources'] = 'toApiJson' in this.commonResources ? this.commonResources.toApiJson() : this.commonResources;\n }\n return toReturn;\n }\n}\nclass CreateCommonResourceRequest {\n static fromProto(proto) {\n let m = new CreateCommonResourceRequest();\n m = Object.assign(m, proto);\n if (proto.commonResource) {\n m.commonResource = CommonResource.fromProto(proto.commonResource);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.commonResource !== 'undefined' && this.commonResource !== null) {\n toReturn['commonResource'] = 'toApiJson' in this.commonResource ? this.commonResource.toApiJson() : this.commonResource;\n }\n return toReturn;\n }\n}\nclass CreatePostTypeRequest {\n static fromProto(proto) {\n let m = new CreatePostTypeRequest();\n m = Object.assign(m, proto);\n if (proto.postType) {\n m.postType = PostType.fromProto(proto.postType);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.postType !== 'undefined' && this.postType !== null) {\n toReturn['postType'] = 'toApiJson' in this.postType ? this.postType.toApiJson() : this.postType;\n }\n return toReturn;\n }\n}\nclass CreatePostTypeResponse {\n static fromProto(proto) {\n let m = new CreatePostTypeResponse();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.typeId !== 'undefined') {\n toReturn['typeId'] = this.typeId;\n }\n return toReturn;\n }\n}\nclass ListPostsRequestDateRangeFilter {\n static fromProto(proto) {\n let m = new ListPostsRequestDateRangeFilter();\n m = Object.assign(m, proto);\n if (proto.beginRange) {\n m.beginRange = new Date(proto.beginRange);\n }\n if (proto.endRange) {\n m.endRange = new Date(proto.endRange);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.beginRange !== 'undefined' && this.beginRange !== null) {\n toReturn['beginRange'] = 'toApiJson' in this.beginRange ? this.beginRange.toApiJson() : this.beginRange;\n }\n if (typeof this.endRange !== 'undefined' && this.endRange !== null) {\n toReturn['endRange'] = 'toApiJson' in this.endRange ? this.endRange.toApiJson() : this.endRange;\n }\n return toReturn;\n }\n}\nclass DeletePostTypeRequest {\n static fromProto(proto) {\n let m = new DeletePostTypeRequest();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.typeId !== 'undefined') {\n toReturn['typeId'] = this.typeId;\n }\n return toReturn;\n }\n}\nclass UpdatePostTypeRequestOperationFilters {\n static fromProto(proto) {\n let m = new UpdatePostTypeRequestOperationFilters();\n m = Object.assign(m, proto);\n if (proto.filters) {\n m.filters = proto.filters.map(Filter.fromProto);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.filters !== 'undefined' && this.filters !== null) {\n toReturn['filters'] = 'toApiJson' in this.filters ? this.filters.toApiJson() : this.filters;\n }\n return toReturn;\n }\n}\nclass ListPostTypesRequestFilters {\n static fromProto(proto) {\n let m = new ListPostTypesRequestFilters();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.channel !== 'undefined') {\n toReturn['channel'] = this.channel;\n }\n return toReturn;\n }\n}\nclass GetChannelsRequest {\n static fromProto(proto) {\n let m = new GetChannelsRequest();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n return toReturn;\n }\n}\nclass GetChannelsResponse {\n static fromProto(proto) {\n let m = new GetChannelsResponse();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.channels !== 'undefined') {\n toReturn['channels'] = this.channels;\n }\n return toReturn;\n }\n}\nclass GetPostRequest {\n static fromProto(proto) {\n let m = new GetPostRequest();\n m = Object.assign(m, proto);\n if (proto.postIdentifier) {\n m.postIdentifier = PostIdentifier.fromProto(proto.postIdentifier);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.postIdentifier !== 'undefined' && this.postIdentifier !== null) {\n toReturn['postIdentifier'] = 'toApiJson' in this.postIdentifier ? this.postIdentifier.toApiJson() : this.postIdentifier;\n }\n return toReturn;\n }\n}\nclass GetPostResponse {\n static fromProto(proto) {\n let m = new GetPostResponse();\n m = Object.assign(m, proto);\n if (proto.post) {\n m.post = Post.fromProto(proto.post);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.post !== 'undefined' && this.post !== null) {\n toReturn['post'] = 'toApiJson' in this.post ? this.post.toApiJson() : this.post;\n }\n return toReturn;\n }\n}\nclass GetPostTypeRequest {\n static fromProto(proto) {\n let m = new GetPostTypeRequest();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.typeId !== 'undefined') {\n toReturn['typeId'] = this.typeId;\n }\n return toReturn;\n }\n}\nclass GetPostTypeResponse {\n static fromProto(proto) {\n let m = new GetPostTypeResponse();\n m = Object.assign(m, proto);\n if (proto.postType) {\n m.postType = PostType.fromProto(proto.postType);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.postType !== 'undefined' && this.postType !== null) {\n toReturn['postType'] = 'toApiJson' in this.postType ? this.postType.toApiJson() : this.postType;\n }\n return toReturn;\n }\n}\nclass LikeRequest {\n static fromProto(proto) {\n let m = new LikeRequest();\n m = Object.assign(m, proto);\n if (proto.postIdentifier) {\n m.postIdentifier = PostIdentifier.fromProto(proto.postIdentifier);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.postIdentifier !== 'undefined' && this.postIdentifier !== null) {\n toReturn['postIdentifier'] = 'toApiJson' in this.postIdentifier ? this.postIdentifier.toApiJson() : this.postIdentifier;\n }\n return toReturn;\n }\n}\nclass LikeResponse {\n static fromProto(proto) {\n let m = new LikeResponse();\n m = Object.assign(m, proto);\n if (proto.user) {\n m.user = User.fromProto(proto.user);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.user !== 'undefined' && this.user !== null) {\n toReturn['user'] = 'toApiJson' in this.user ? this.user.toApiJson() : this.user;\n }\n return toReturn;\n }\n}\nclass ListCommentsRequest {\n static fromProto(proto) {\n let m = new ListCommentsRequest();\n m = Object.assign(m, proto);\n if (proto.postIdentifier) {\n m.postIdentifier = PostIdentifier.fromProto(proto.postIdentifier);\n }\n if (proto.pagingOptions) {\n m.pagingOptions = PagedRequestOptions.fromProto(proto.pagingOptions);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.postIdentifier !== 'undefined' && this.postIdentifier !== null) {\n toReturn['postIdentifier'] = 'toApiJson' in this.postIdentifier ? this.postIdentifier.toApiJson() : this.postIdentifier;\n }\n if (typeof this.pagingOptions !== 'undefined' && this.pagingOptions !== null) {\n toReturn['pagingOptions'] = 'toApiJson' in this.pagingOptions ? this.pagingOptions.toApiJson() : this.pagingOptions;\n }\n return toReturn;\n }\n}\nclass ListCommentsResponse {\n static fromProto(proto) {\n let m = new ListCommentsResponse();\n m = Object.assign(m, proto);\n if (proto.comments) {\n m.comments = proto.comments.map(Comment.fromProto);\n }\n if (proto.pagingMetadata) {\n m.pagingMetadata = PagedResponseMetadata.fromProto(proto.pagingMetadata);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.comments !== 'undefined' && this.comments !== null) {\n toReturn['comments'] = 'toApiJson' in this.comments ? this.comments.toApiJson() : this.comments;\n }\n if (typeof this.pagingMetadata !== 'undefined' && this.pagingMetadata !== null) {\n toReturn['pagingMetadata'] = 'toApiJson' in this.pagingMetadata ? this.pagingMetadata.toApiJson() : this.pagingMetadata;\n }\n return toReturn;\n }\n}\nclass ListCommonResourcesRequest {\n static fromProto(proto) {\n let m = new ListCommonResourcesRequest();\n m = Object.assign(m, proto);\n if (proto.pagingOptions) {\n m.pagingOptions = PagedRequestOptions.fromProto(proto.pagingOptions);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.pagingOptions !== 'undefined' && this.pagingOptions !== null) {\n toReturn['pagingOptions'] = 'toApiJson' in this.pagingOptions ? this.pagingOptions.toApiJson() : this.pagingOptions;\n }\n return toReturn;\n }\n}\nclass ListCommonResourcesResponse {\n static fromProto(proto) {\n let m = new ListCommonResourcesResponse();\n m = Object.assign(m, proto);\n if (proto.commonResources) {\n m.commonResources = proto.commonResources.map(CommonResource.fromProto);\n }\n if (proto.pagingMetadata) {\n m.pagingMetadata = PagedResponseMetadata.fromProto(proto.pagingMetadata);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.commonResources !== 'undefined' && this.commonResources !== null) {\n toReturn['commonResources'] = 'toApiJson' in this.commonResources ? this.commonResources.toApiJson() : this.commonResources;\n }\n if (typeof this.pagingMetadata !== 'undefined' && this.pagingMetadata !== null) {\n toReturn['pagingMetadata'] = 'toApiJson' in this.pagingMetadata ? this.pagingMetadata.toApiJson() : this.pagingMetadata;\n }\n return toReturn;\n }\n}\nclass ListPostTypesRequest {\n static fromProto(proto) {\n let m = new ListPostTypesRequest();\n m = Object.assign(m, proto);\n if (proto.filters) {\n m.filters = ListPostTypesRequestFilters.fromProto(proto.filters);\n }\n if (proto.pagingOptions) {\n m.pagingOptions = PagedRequestOptions.fromProto(proto.pagingOptions);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.filters !== 'undefined' && this.filters !== null) {\n toReturn['filters'] = 'toApiJson' in this.filters ? this.filters.toApiJson() : this.filters;\n }\n if (typeof this.pagingOptions !== 'undefined' && this.pagingOptions !== null) {\n toReturn['pagingOptions'] = 'toApiJson' in this.pagingOptions ? this.pagingOptions.toApiJson() : this.pagingOptions;\n }\n return toReturn;\n }\n}\nclass ListPostTypesResponse {\n static fromProto(proto) {\n let m = new ListPostTypesResponse();\n m = Object.assign(m, proto);\n if (proto.postTypes) {\n m.postTypes = proto.postTypes.map(PostType.fromProto);\n }\n if (proto.pagingMetadata) {\n m.pagingMetadata = PagedResponseMetadata.fromProto(proto.pagingMetadata);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.postTypes !== 'undefined' && this.postTypes !== null) {\n toReturn['postTypes'] = 'toApiJson' in this.postTypes ? this.postTypes.toApiJson() : this.postTypes;\n }\n if (typeof this.pagingMetadata !== 'undefined' && this.pagingMetadata !== null) {\n toReturn['pagingMetadata'] = 'toApiJson' in this.pagingMetadata ? this.pagingMetadata.toApiJson() : this.pagingMetadata;\n }\n return toReturn;\n }\n}\nclass ListPostsRequest {\n static fromProto(proto) {\n let m = new ListPostsRequest();\n m = Object.assign(m, proto);\n if (proto.dateRange) {\n m.dateRange = ListPostsRequestDateRangeFilter.fromProto(proto.dateRange);\n }\n if (proto.pagingOptions) {\n m.pagingOptions = PagedRequestOptions.fromProto(proto.pagingOptions);\n }\n if (proto.renderOption) {\n m.renderOption = enumStringToValue(RenderOption, proto.renderOption);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.partnerId !== 'undefined') {\n toReturn['partnerId'] = this.partnerId;\n }\n if (typeof this.marketIds !== 'undefined') {\n toReturn['marketIds'] = this.marketIds;\n }\n if (typeof this.userIds !== 'undefined') {\n toReturn['userIds'] = this.userIds;\n }\n if (typeof this.postTypeIds !== 'undefined') {\n toReturn['postTypeIds'] = this.postTypeIds;\n }\n if (typeof this.resourceFilters !== 'undefined') {\n toReturn['resourceFilters'] = this.resourceFilters;\n }\n if (typeof this.dateRange !== 'undefined' && this.dateRange !== null) {\n toReturn['dateRange'] = 'toApiJson' in this.dateRange ? this.dateRange.toApiJson() : this.dateRange;\n }\n if (typeof this.pagingOptions !== 'undefined' && this.pagingOptions !== null) {\n toReturn['pagingOptions'] = 'toApiJson' in this.pagingOptions ? this.pagingOptions.toApiJson() : this.pagingOptions;\n }\n if (typeof this.renderOption !== 'undefined') {\n toReturn['renderOption'] = this.renderOption;\n }\n return toReturn;\n }\n}\nclass ListPostsResponse {\n static fromProto(proto) {\n let m = new ListPostsResponse();\n m = Object.assign(m, proto);\n if (proto.posts) {\n m.posts = proto.posts.map(Post.fromProto);\n }\n if (proto.pagingMetadata) {\n m.pagingMetadata = PagedResponseMetadata.fromProto(proto.pagingMetadata);\n }\n if (proto.totalResults) {\n m.totalResults = parseInt(proto.totalResults, 10);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.posts !== 'undefined' && this.posts !== null) {\n toReturn['posts'] = 'toApiJson' in this.posts ? this.posts.toApiJson() : this.posts;\n }\n if (typeof this.pagingMetadata !== 'undefined' && this.pagingMetadata !== null) {\n toReturn['pagingMetadata'] = 'toApiJson' in this.pagingMetadata ? this.pagingMetadata.toApiJson() : this.pagingMetadata;\n }\n if (typeof this.totalResults !== 'undefined') {\n toReturn['totalResults'] = this.totalResults;\n }\n return toReturn;\n }\n}\nclass UpdatePostTypeRequestOperation {\n static fromProto(proto) {\n let m = new UpdatePostTypeRequestOperation();\n m = Object.assign(m, proto);\n if (proto.commonResources) {\n m.commonResources = UpdatePostTypeRequestOperationCommonResources.fromProto(proto.commonResources);\n }\n if (proto.filters) {\n m.filters = UpdatePostTypeRequestOperationFilters.fromProto(proto.filters);\n }\n if (proto.iconResource) {\n m.iconResource = IconResource.fromProto(proto.iconResource);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.name !== 'undefined') {\n toReturn['name'] = this.name;\n }\n if (typeof this.commonResources !== 'undefined' && this.commonResources !== null) {\n toReturn['commonResources'] = 'toApiJson' in this.commonResources ? this.commonResources.toApiJson() : this.commonResources;\n }\n if (typeof this.templateId !== 'undefined') {\n toReturn['templateId'] = this.templateId;\n }\n if (typeof this.partnerIdPath !== 'undefined') {\n toReturn['partnerIdPath'] = this.partnerIdPath;\n }\n if (typeof this.marketIdPath !== 'undefined') {\n toReturn['marketIdPath'] = this.marketIdPath;\n }\n if (typeof this.userIdPath !== 'undefined') {\n toReturn['userIdPath'] = this.userIdPath;\n }\n if (typeof this.filters !== 'undefined' && this.filters !== null) {\n toReturn['filters'] = 'toApiJson' in this.filters ? this.filters.toApiJson() : this.filters;\n }\n if (typeof this.channel !== 'undefined') {\n toReturn['channel'] = this.channel;\n }\n if (typeof this.iconResource !== 'undefined' && this.iconResource !== null) {\n toReturn['iconResource'] = 'toApiJson' in this.iconResource ? this.iconResource.toApiJson() : this.iconResource;\n }\n if (typeof this.postIdTemplate !== 'undefined') {\n toReturn['postIdTemplate'] = this.postIdTemplate;\n }\n return toReturn;\n }\n}\nclass PagedRequestOptions {\n static fromProto(proto) {\n let m = new PagedRequestOptions();\n m = Object.assign(m, proto);\n if (proto.pageSize) {\n m.pageSize = parseInt(proto.pageSize, 10);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.cursor !== 'undefined') {\n toReturn['cursor'] = this.cursor;\n }\n if (typeof this.pageSize !== 'undefined') {\n toReturn['pageSize'] = this.pageSize;\n }\n return toReturn;\n }\n}\nclass SubscribeRequest {\n static fromProto(proto) {\n let m = new SubscribeRequest();\n m = Object.assign(m, proto);\n if (proto.postIdentifier) {\n m.postIdentifier = PostIdentifier.fromProto(proto.postIdentifier);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.postIdentifier !== 'undefined' && this.postIdentifier !== null) {\n toReturn['postIdentifier'] = 'toApiJson' in this.postIdentifier ? this.postIdentifier.toApiJson() : this.postIdentifier;\n }\n return toReturn;\n }\n}\nclass UnlikeRequest {\n static fromProto(proto) {\n let m = new UnlikeRequest();\n m = Object.assign(m, proto);\n if (proto.postIdentifier) {\n m.postIdentifier = PostIdentifier.fromProto(proto.postIdentifier);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.postIdentifier !== 'undefined' && this.postIdentifier !== null) {\n toReturn['postIdentifier'] = 'toApiJson' in this.postIdentifier ? this.postIdentifier.toApiJson() : this.postIdentifier;\n }\n return toReturn;\n }\n}\nclass UnsubscribeRequest {\n static fromProto(proto) {\n let m = new UnsubscribeRequest();\n m = Object.assign(m, proto);\n if (proto.postIdentifier) {\n m.postIdentifier = PostIdentifier.fromProto(proto.postIdentifier);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.postIdentifier !== 'undefined' && this.postIdentifier !== null) {\n toReturn['postIdentifier'] = 'toApiJson' in this.postIdentifier ? this.postIdentifier.toApiJson() : this.postIdentifier;\n }\n return toReturn;\n }\n}\nclass UpdatePostTypeRequest {\n static fromProto(proto) {\n let m = new UpdatePostTypeRequest();\n m = Object.assign(m, proto);\n if (proto.operations) {\n m.operations = proto.operations.map(UpdatePostTypeRequestOperation.fromProto);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.typeId !== 'undefined') {\n toReturn['typeId'] = this.typeId;\n }\n if (typeof this.operations !== 'undefined' && this.operations !== null) {\n toReturn['operations'] = 'toApiJson' in this.operations ? this.operations.toApiJson() : this.operations;\n }\n return toReturn;\n }\n}\n\n// *********************************\n\nconst environment = (window ? window['environment'] : 'prod') ?? 'prod';\nconst hostMap = {\n 'local': 'the-loop-api.vendasta-local.com',\n 'test': '',\n 'demo': 'the-loop-demo.apigateway.co',\n 'prod': 'the-loop-prod.apigateway.co',\n 'production': 'the-loop-prod.apigateway.co'\n};\nlet HostService = /*#__PURE__*/(() => {\n class HostService {\n get host() {\n return hostMap[environment.toLowerCase()];\n }\n get hostWithScheme() {\n return 'https://' + this.host;\n }\n }\n HostService.ɵfac = function HostService_Factory(__ngFactoryType__) {\n return new (__ngFactoryType__ || HostService)();\n };\n HostService.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: HostService,\n factory: HostService.ɵfac,\n providedIn: 'root'\n });\n return HostService;\n})();\n(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n// *********************************\nlet TheLoopApiService = /*#__PURE__*/(() => {\n class TheLoopApiService {\n constructor(http, hostService) {\n this.http = http;\n this.hostService = hostService;\n this._host = this.hostService.hostWithScheme;\n }\n apiOptions() {\n return {\n headers: new HttpHeaders({\n 'Content-Type': 'application/json'\n }),\n withCredentials: true\n };\n }\n getPost(r) {\n const request = r.toApiJson ? r : new GetPostRequest(r);\n return this.http.post(this._host + \"/theloop.v1.TheLoop/GetPost\", request.toApiJson(), this.apiOptions()).pipe(map(resp => GetPostResponse.fromProto(resp)));\n }\n listPosts(r) {\n const request = r.toApiJson ? r : new ListPostsRequest(r);\n return this.http.post(this._host + \"/theloop.v1.TheLoop/ListPosts\", request.toApiJson(), this.apiOptions()).pipe(map(resp => ListPostsResponse.fromProto(resp)));\n }\n getPostType(r) {\n const request = r.toApiJson ? r : new GetPostTypeRequest(r);\n return this.http.post(this._host + \"/theloop.v1.TheLoop/GetPostType\", request.toApiJson(), this.apiOptions()).pipe(map(resp => GetPostTypeResponse.fromProto(resp)));\n }\n createPostType(r) {\n const request = r.toApiJson ? r : new CreatePostTypeRequest(r);\n return this.http.post(this._host + \"/theloop.v1.TheLoop/CreatePostType\", request.toApiJson(), this.apiOptions()).pipe(map(resp => CreatePostTypeResponse.fromProto(resp)));\n }\n updatePostType(r) {\n const request = r.toApiJson ? r : new UpdatePostTypeRequest(r);\n return this.http.post(this._host + \"/theloop.v1.TheLoop/UpdatePostType\", request.toApiJson(), {\n ...this.apiOptions(),\n observe: 'response'\n });\n }\n deletePostType(r) {\n const request = r.toApiJson ? r : new DeletePostTypeRequest(r);\n return this.http.post(this._host + \"/theloop.v1.TheLoop/DeletePostType\", request.toApiJson(), {\n ...this.apiOptions(),\n observe: 'response'\n });\n }\n getChannels(r) {\n const request = r.toApiJson ? r : new GetChannelsRequest(r);\n return this.http.post(this._host + \"/theloop.v1.TheLoop/GetChannels\", request.toApiJson(), this.apiOptions()).pipe(map(resp => GetChannelsResponse.fromProto(resp)));\n }\n listPostTypes(r) {\n const request = r.toApiJson ? r : new ListPostTypesRequest(r);\n return this.http.post(this._host + \"/theloop.v1.TheLoop/ListPostTypes\", request.toApiJson(), this.apiOptions()).pipe(map(resp => ListPostTypesResponse.fromProto(resp)));\n }\n createCommonResource(r) {\n const request = r.toApiJson ? r : new CreateCommonResourceRequest(r);\n return this.http.post(this._host + \"/theloop.v1.TheLoop/CreateCommonResource\", request.toApiJson(), {\n ...this.apiOptions(),\n observe: 'response'\n });\n }\n listCommonResources(r) {\n const request = r.toApiJson ? r : new ListCommonResourcesRequest(r);\n return this.http.post(this._host + \"/theloop.v1.TheLoop/ListCommonResources\", request.toApiJson(), this.apiOptions()).pipe(map(resp => ListCommonResourcesResponse.fromProto(resp)));\n }\n comment(r) {\n const request = r.toApiJson ? r : new CommentRequest(r);\n return this.http.post(this._host + \"/theloop.v1.TheLoop/Comment\", request.toApiJson(), this.apiOptions()).pipe(map(resp => CommentResponse.fromProto(resp)));\n }\n listComments(r) {\n const request = r.toApiJson ? r : new ListCommentsRequest(r);\n return this.http.post(this._host + \"/theloop.v1.TheLoop/ListComments\", request.toApiJson(), this.apiOptions()).pipe(map(resp => ListCommentsResponse.fromProto(resp)));\n }\n like(r) {\n const request = r.toApiJson ? r : new LikeRequest(r);\n return this.http.post(this._host + \"/theloop.v1.TheLoop/Like\", request.toApiJson(), this.apiOptions()).pipe(map(resp => LikeResponse.fromProto(resp)));\n }\n unlike(r) {\n const request = r.toApiJson ? r : new UnlikeRequest(r);\n return this.http.post(this._host + \"/theloop.v1.TheLoop/Unlike\", request.toApiJson(), {\n ...this.apiOptions(),\n observe: 'response'\n });\n }\n subscribe(r) {\n const request = r.toApiJson ? r : new SubscribeRequest(r);\n return this.http.post(this._host + \"/theloop.v1.TheLoop/Subscribe\", request.toApiJson(), {\n ...this.apiOptions(),\n observe: 'response'\n });\n }\n unsubscribe(r) {\n const request = r.toApiJson ? r : new UnsubscribeRequest(r);\n return this.http.post(this._host + \"/theloop.v1.TheLoop/Unsubscribe\", request.toApiJson(), {\n ...this.apiOptions(),\n observe: 'response'\n });\n }\n }\n TheLoopApiService.ɵfac = function TheLoopApiService_Factory(__ngFactoryType__) {\n return new (__ngFactoryType__ || TheLoopApiService)(i0.ɵɵinject(i1.HttpClient), i0.ɵɵinject(HostService));\n };\n TheLoopApiService.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: TheLoopApiService,\n factory: TheLoopApiService.ɵfac,\n providedIn: 'root'\n });\n return TheLoopApiService;\n})();\n(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\nfunction fillPostZeroValues(p) {\n p.likes = !!p.likes ? p.likes : [];\n p.latestComments = !!p.latestComments ? p.latestComments : new PostLatestComments({});\n p.latestComments.comments = !!p.latestComments.comments ? p.latestComments.comments : [];\n p.latestComments.pagingMetadata = !!p.latestComments.pagingMetadata ? p.latestComments.pagingMetadata : new PagedResponseMetadata({});\n return p;\n}\nclass PagedResponse {\n constructor(results, nextCursor, hasMore) {\n this.results = results;\n this.nextCursor = nextCursor;\n this.hasMore = hasMore;\n }\n}\nlet TheLoopService = /*#__PURE__*/(() => {\n class TheLoopService {\n constructor(api) {\n this.api = api;\n }\n getPost(typeId, postId) {\n return this.api.getPost({\n postIdentifier: {\n postId: postId,\n typeId: typeId\n }\n }).pipe(map(resp => fillPostZeroValues(resp.post)));\n }\n getPostType(typeId) {\n return this.api.getPostType({\n typeId: typeId\n }).pipe(map(resp => resp.postType));\n }\n createPostType(postType) {\n return this.api.createPostType({\n postType: postType\n }).pipe(map(resp => resp.typeId));\n }\n updatePostType(typeId, operations) {\n return this.api.updatePostType({\n typeId: typeId,\n operations: operations\n }).pipe(map(() => true));\n }\n deletePostType(typeId) {\n return this.api.deletePostType({\n typeId: typeId\n }).pipe(map(() => true));\n }\n createCommonResource(id, name) {\n return this.api.createCommonResource({\n commonResource: {\n id: id,\n name: name\n }\n }).pipe(map(() => true));\n }\n listCommonResources(pagingOptions) {\n return this.api.listCommonResources({\n pagingOptions: pagingOptions\n }).pipe(map(resp => new PagedResponse(resp.commonResources, resp.pagingMetadata.nextCursor, resp.pagingMetadata.hasMore)));\n }\n comment(typeId, postId, text) {\n return this.api.comment({\n postIdentifier: {\n typeId: typeId,\n postId: postId\n },\n text: text\n }).pipe(map(resp => resp.comment));\n }\n like(typeId, postId) {\n return this.api.like({\n postIdentifier: {\n typeId: typeId,\n postId: postId\n }\n }).pipe(map(resp => resp.user));\n }\n unlike(typeId, postId) {\n return this.api.unlike({\n postIdentifier: {\n typeId: typeId,\n postId: postId\n }\n }).pipe(map(() => true));\n }\n listPosts(fitlers) {\n return this.api.listPosts(fitlers).pipe(map(resp => {\n if (!!resp && resp.posts) {\n resp.posts = resp.posts.map(p => fillPostZeroValues(p));\n }\n return resp;\n }));\n }\n listComments(typeId, postId, cursor, pageSize) {\n return this.api.listComments({\n postIdentifier: {\n typeId: typeId,\n postId: postId\n },\n pagingOptions: {\n cursor: cursor,\n pageSize: pageSize\n }\n }).pipe(map(resp => resp));\n }\n subscribe(typeId, postId) {\n return this.api.subscribe({\n postIdentifier: {\n typeId: typeId,\n postId: postId\n }\n }).pipe(map(() => true));\n }\n unsubscribe(typeId, postId) {\n return this.api.unsubscribe({\n postIdentifier: {\n typeId: typeId,\n postId: postId\n }\n }).pipe(map(() => true));\n }\n getChannels() {\n return this.api.getChannels({}).pipe(map(resp => resp.channels));\n }\n listPostTypes(filters, cursor, pageSize) {\n return this.api.listPostTypes({\n filters: filters,\n pagingOptions: {\n cursor: cursor,\n pageSize: pageSize\n }\n }).pipe(map(resp => {\n return new PagedResponse(resp.postTypes, resp.pagingMetadata.nextCursor, resp.pagingMetadata.hasMore);\n }));\n }\n }\n TheLoopService.ɵfac = function TheLoopService_Factory(__ngFactoryType__) {\n return new (__ngFactoryType__ || TheLoopService)(i0.ɵɵinject(TheLoopApiService));\n };\n TheLoopService.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: TheLoopService,\n factory: TheLoopService.ɵfac,\n providedIn: 'root'\n });\n return TheLoopService;\n})();\n(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/**\n * Generated bundle index. Do not edit.\n */\n\nexport { Comment, CommonResource, ExtractedValue, Filter, FilterOption, Post, PostIdentifier, PostType, RenderOption, TheLoopService, UpdatePostTypeRequestOperation, User };\n","import { HttpErrorResponse } from '@angular/common/http';\nimport { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';\nimport { UntypedFormArray, UntypedFormBuilder, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms';\nimport { ActivatedRoute } from '@angular/router';\nimport { SnackbarService } from '@vendasta/galaxy/snackbar-service';\nimport { HydrationOptionsInterface, Template, TemplateInterface, TemplatesService } from '@vendasta/templates';\nimport {\n ExtractedValue,\n PostType,\n PostTypeInterface,\n TheLoopService,\n UpdatePostTypeRequestOperationInterface,\n} from '@vendasta/the-loop';\nimport { BehaviorSubject, Observable, combineLatest, forkJoin, of } from 'rxjs';\nimport { catchError, map, shareReplay, switchMap, take, tap } from 'rxjs/operators';\n\nexport const newChannelOption = '+ New Channel';\nexport const accountGroupIdCommonResourceId = 'account-group-id';\nexport const matIconIconFormat = 'matIcon';\nexport const iconPathIconFormat = 'iconPath';\n\n@Component({\n selector: 'app-loop-post-type-editor',\n styleUrls: ['./post-type-editor.component.scss'],\n templateUrl: './post-type-editor.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: false,\n})\nexport class PostTypeEditorComponent implements OnInit {\n public readonly typeId$: Observable = this.route.params.pipe(map((r) => r.typeId));\n public readonly eventId$: Observable = this.route.queryParams.pipe(map((r) => r.eventId));\n\n templatesLoaded$$: BehaviorSubject = new BehaviorSubject(false);\n templatesLoaded$: Observable = this.templatesLoaded$$.asObservable();\n\n type$: Observable;\n form: UntypedFormGroup;\n\n constructor(\n private route: ActivatedRoute,\n private loopService: TheLoopService,\n private templatesService: TemplatesService,\n private alertService: SnackbarService,\n private fb: UntypedFormBuilder,\n ) {}\n\n ngOnInit(): void {\n this.initForm();\n this.type$ = combineLatest([this.typeId$, this.eventId$]).pipe(\n switchMap(([typeId, eventId]) => {\n if (!typeId) {\n // creating a new post type, includes some common default values\n return of(\n new PostType({\n eventTypeId: eventId,\n partnerIdPath: 'partner_id',\n marketIdPath: 'market_id',\n commonResources: [{ id: accountGroupIdCommonResourceId, valuePath: 'account_group_id' }],\n iconResource: {\n defaultIcon: {\n matIcon: 'all_inclusive',\n },\n customTypes: [],\n },\n }),\n );\n }\n // editing an existing post type\n this.form.get('templates').get('templateId').disable();\n return this.loopService.getPostType(typeId);\n }),\n tap((postType) => this.setInitialFormValuesFromPostType(postType)),\n take(1),\n shareReplay(),\n );\n }\n\n initForm(): void {\n this.form = this.fb.group({\n name: ['', Validators.required],\n eventTypeId: new UntypedFormControl({ value: '', disabled: true }),\n channel: ['', Validators.required],\n newChannel: [''],\n postIdTemplate: ['', Validators.required],\n partnerIdPath: ['', Validators.required],\n marketIdPath: [''],\n accountGroupIdPath: [''],\n userIdPath: [''],\n iconResource: this.fb.group({\n resourcePath: ['', Validators.required],\n defaultIcon: this.fb.group({\n format: [matIconIconFormat],\n value: [''],\n }),\n customTypes: this.fb.array([]),\n }),\n filters: this.fb.array([]),\n templates: this.fb.group({\n templateId: ['', Validators.required],\n hydrators: this.fb.group({\n accountGroups: this.fb.group({\n checked: [''],\n params: this.fb.group({\n accountGroupIds: [{ value: '', disabled: true }, Validators.required],\n inflatedPropertyName: [{ value: '', disabled: true }, Validators.required],\n }),\n }),\n apps: this.fb.group({\n checked: [''],\n params: this.fb.group({\n appKeys: [{ value: '', disabled: true }, Validators.required],\n partnerId: [{ value: '', disabled: true }, Validators.required],\n marketId: [{ value: '', disabled: true }],\n inflatedPropertyName: [{ value: '', disabled: true }, Validators.required],\n }),\n }),\n packages: this.fb.group({\n checked: [''],\n params: this.fb.group({\n packageIds: [{ value: '', disabled: true }, Validators.required],\n inflatedPropertyName: [{ value: '', disabled: true }, Validators.required],\n }),\n }),\n branding: this.fb.group({\n checked: [''],\n params: this.fb.group({\n partnerId: [{ value: '', disabled: true }, Validators.required],\n marketId: [{ value: '', disabled: true }],\n inflatedPropertyName: [{ value: '', disabled: true }, Validators.required],\n }),\n }),\n users: this.fb.group({\n checked: [''],\n params: this.fb.group({\n userIds: [{ value: '', disabled: true }, Validators.required],\n inflatedPropertyName: [{ value: '', disabled: true }, Validators.required],\n }),\n }),\n salesActivities: this.fb.group({\n checked: [''],\n params: this.fb.group({\n salesActivityKeys: [{ value: '', disabled: true }, Validators.required],\n inflatedPropertyName: [{ value: '', disabled: true }, Validators.required],\n }),\n }),\n partnerConfig: this.fb.group({\n checked: [''],\n params: this.fb.group({\n partnerId: [{ value: '', disabled: true }, Validators.required],\n marketId: [{ value: '', disabled: true }],\n inflatedPropertyName: [{ value: '', disabled: true }, Validators.required],\n }),\n }),\n task: this.fb.group({\n checked: [''],\n params: this.fb.group({\n taskKeys: [{ value: '', disabled: true }, Validators.required],\n inflatedPropertyName: [{ value: '', disabled: true }, Validators.required],\n }),\n }),\n }),\n fullHtml: [''],\n styles: [''],\n compactHTML: [''],\n }),\n });\n // Form should not be ready until templates have loaded\n this.form.get('templates').markAsUntouched();\n }\n\n setTemplatesLoaded(): void {\n this.templatesLoaded$$.next(true);\n }\n\n setInitialFormValuesFromPostType(postType: PostTypeInterface): void {\n let defaultIcon = {\n format: iconPathIconFormat,\n value: postType.iconResource.defaultIcon.iconPath,\n };\n if (postType.iconResource.defaultIcon.matIcon) {\n defaultIcon = {\n format: matIconIconFormat,\n value: postType.iconResource.defaultIcon.matIcon,\n };\n }\n\n const accountGroupIdResource = postType.commonResources.find((r) => r.id === accountGroupIdCommonResourceId);\n\n this.form.patchValue({\n name: postType.name,\n eventTypeId: postType.eventTypeId,\n channel: postType.channel,\n postIdTemplate: postType.postIdTemplate,\n partnerIdPath: postType.partnerIdPath,\n marketIdPath: postType.marketIdPath,\n accountGroupIdPath: accountGroupIdResource ? accountGroupIdResource.valuePath : '',\n userIdPath: postType.userIdPath,\n iconResource: {\n resourcePath: postType.iconResource.resourcePath,\n defaultIcon: defaultIcon,\n },\n templates: {\n templateId: postType.templateId,\n },\n });\n\n const customTypes = this.form.get('iconResource').get('customTypes') as UntypedFormArray;\n (postType.iconResource.customTypes || []).forEach((c) => {\n let icon = this.fb.group({\n format: [iconPathIconFormat],\n value: [c.icon.iconPath, Validators.required],\n });\n if (c.icon.matIcon) {\n icon = this.fb.group({\n format: [matIconIconFormat],\n value: [c.icon.matIcon, Validators.required],\n });\n }\n customTypes.push(\n this.fb.group({\n type: [c.type],\n icon: icon,\n }),\n );\n });\n\n const filters = this.form.get('filters') as UntypedFormArray;\n (postType.filters || []).forEach((f) => {\n const filter = this.fb.group({\n label: [f.label, Validators.required],\n value: this.fb.group({\n id: [f.value.id, Validators.required],\n valuePath: [f.value.valuePath, Validators.required],\n }),\n options: new UntypedFormArray(\n f.options.map((o) => {\n return this.fb.group({\n id: [o.id, Validators.required],\n value: [o.value, Validators.required],\n });\n }),\n ),\n });\n filters.push(filter);\n });\n }\n\n save(): void {\n if (!this.form.valid) {\n this.alertService.openErrorSnack('Form is invalid');\n return;\n }\n let channel = this.form.get('channel').value;\n if (channel === newChannelOption) {\n channel = this.form.get('newChannel').value;\n }\n\n const iconResource = this.form.get('iconResource');\n const defaultIcon = {};\n const defaultValue = iconResource.get('defaultIcon').get('value').value;\n if (iconResource.get('defaultIcon').get('format').value === matIconIconFormat) {\n defaultIcon[matIconIconFormat] = defaultValue;\n }\n if (iconResource.get('defaultIcon').get('format').value === iconPathIconFormat) {\n defaultIcon[iconPathIconFormat] = defaultValue;\n }\n\n const customTypes = iconResource.get('customTypes').value.map((c) => {\n const icon = {};\n const value = c.icon.value;\n if (c.icon.format === matIconIconFormat) {\n icon[matIconIconFormat] = value;\n } else if (c.icon.format === iconPathIconFormat) {\n icon[iconPathIconFormat] = value;\n }\n return {\n type: c.type,\n icon: icon,\n };\n });\n\n const filters = this.form.get('filters').value.map((c) => {\n const value = {\n id: c.value.id,\n valuePath: c.value.valuePath,\n };\n const options = c.options.map((o) => {\n return {\n id: o.id,\n value: o.value,\n };\n });\n return {\n label: c.label,\n value: value,\n options: options,\n };\n });\n\n const templateId = this.form.get('templates').get('templateId').value;\n\n const postType = new PostType({\n name: this.form.get('name').value,\n channel: channel,\n postIdTemplate: this.form.get('postIdTemplate').value,\n partnerIdPath: this.form.get('partnerIdPath').value,\n marketIdPath: this.form.get('marketIdPath').value,\n userIdPath: this.form.get('userIdPath').value,\n templateId: templateId,\n iconResource: {\n resourcePath: iconResource.get('resourcePath').value,\n defaultIcon: defaultIcon,\n customTypes: customTypes,\n },\n filters: filters,\n });\n\n this.type$\n .pipe(\n tap((type) => {\n postType.eventTypeId = type.eventTypeId;\n postType.commonResources = type.commonResources.map((r) => {\n if (r.id === accountGroupIdCommonResourceId) {\n r.valuePath = this.form.get('accountGroupIdPath').value;\n }\n return new ExtractedValue(r);\n });\n const templateIds = [templateId, templateId + '-styles', templateId + '-compact'];\n const hydrationOptions = this.getHydrationOptions();\n\n if (!type.typeId) {\n // create a new post type\n\n this.templatesService\n .getMulti('the-loop', templateIds)\n .pipe(\n take(1),\n map((templates) => {\n templates.forEach((t) => {\n if (t.errorDescription !== 'Template not found') {\n // TODO: allow selecting existing templates?\n const errMsg = 'Template with id ' + templateId + 'already exists.';\n this.alertService.openErrorSnack(errMsg);\n throw new Error(errMsg);\n }\n });\n }),\n switchMap(() => {\n const fullTemplate = new Template({\n templateId: templateIds[0],\n name: templateIds[0],\n content: this.form.get('templates').get('fullHtml').value,\n hydrationOptions: hydrationOptions,\n });\n const stylesTemplate = new Template({\n templateId: templateIds[1],\n name: templateIds[1],\n content: this.form.get('templates').get('styles').value,\n });\n const compactTemplate = new Template({\n templateId: templateIds[2],\n name: templateIds[2],\n content: this.form.get('templates').get('compactHTML').value,\n hydrationOptions: hydrationOptions,\n });\n\n const templateCreateCalls$ = [fullTemplate, stylesTemplate, compactTemplate].map((t) =>\n this.templatesService.create('the-loop', t),\n );\n return forkJoin(templateCreateCalls$);\n }),\n catchError((err: HttpErrorResponse) => {\n this.alertService.openErrorSnack('Error creating templates.');\n throw err;\n }),\n switchMap(() => this.loopService.createPostType(postType)),\n catchError((err: HttpErrorResponse) => {\n this.alertService.openErrorSnack('Error creating post type.');\n throw err;\n }),\n tap(() => this.alertService.openSuccessSnack('Post type created.')),\n )\n .subscribe();\n } else {\n // update existing post type\n\n const operations: UpdatePostTypeRequestOperationInterface[] = [\n { name: postType.name },\n { channel: postType.channel },\n { postIdTemplate: postType.postIdTemplate },\n { partnerIdPath: postType.partnerIdPath },\n { marketIdPath: postType.marketIdPath },\n { userIdPath: postType.userIdPath },\n { iconResource: postType.iconResource },\n { commonResources: { commonResources: postType.commonResources } },\n { filters: { filters: postType.filters } },\n ];\n this.templatesService\n .getMulti('the-loop', templateIds)\n .pipe(\n take(1),\n map((templates) => {\n // TODO handle templates[].error\n\n const fullTemplate: TemplateInterface = templates[0].template;\n fullTemplate.content = this.form.get('templates').get('fullHtml').value;\n fullTemplate.hydrationOptions = hydrationOptions;\n\n const styles: TemplateInterface = templates[1].template;\n styles.content = this.form.get('templates').get('styles').value;\n\n const compactTemplate: TemplateInterface = templates[2].template;\n compactTemplate.content = this.form.get('templates').get('compactHTML').value;\n compactTemplate.hydrationOptions = hydrationOptions;\n\n return [fullTemplate, styles, compactTemplate];\n }),\n switchMap((templates) => {\n const results$ = templates.map((t) => this.templatesService.update('the-loop', t));\n return forkJoin(results$);\n }),\n catchError((err: HttpErrorResponse) => {\n this.alertService.openErrorSnack('Error updating templates. Nothing will be updated.');\n throw err;\n }),\n switchMap(() => this.loopService.updatePostType(type.typeId, operations)),\n catchError((err: HttpErrorResponse) => {\n this.alertService.openErrorSnack('Error updating post type. Only templates have been updated.');\n throw err;\n }),\n tap(() => this.alertService.openSuccessSnack('Post type updated.')),\n )\n .subscribe();\n }\n }),\n take(1),\n )\n .subscribe();\n }\n\n getHydrationOptions(): HydrationOptionsInterface {\n const result: HydrationOptionsInterface = {};\n const hydrators = this.form.get('templates').get('hydrators') as UntypedFormGroup;\n\n const accountGroups = hydrators.get('accountGroups');\n if (accountGroups.get('checked').value) {\n result.accountGroups = {\n accountGroupIds: accountGroups.get('params').get('accountGroupIds').value,\n inflatedPropertyName: accountGroups.get('params').get('inflatedPropertyName').value,\n };\n }\n const apps = hydrators.get('apps');\n if (apps.get('checked').value) {\n result.apps = {\n appKeys: apps.get('params').get('appKeys').value,\n partnerId: apps.get('params').get('partnerId').value,\n marketId: apps.get('params').get('marketId').value,\n inflatedPropertyName: apps.get('params').get('inflatedPropertyName').value,\n };\n }\n const packages = hydrators.get('packages');\n if (packages.get('checked').value) {\n result.packages = {\n packageIds: packages.get('params').get('packageIds').value,\n inflatedPropertyName: packages.get('params').get('inflatedPropertyName').value,\n };\n }\n const branding = hydrators.get('branding');\n if (branding.get('checked').value) {\n result.branding = {\n partnerId: branding.get('params').get('partnerId').value,\n marketId: branding.get('params').get('marketId').value,\n inflatedPropertyName: branding.get('params').get('inflatedPropertyName').value,\n };\n }\n const users = hydrators.get('users');\n if (users.get('checked').value) {\n result.users = {\n userIds: users.get('params').get('userIds').value,\n inflatedPropertyName: users.get('params').get('inflatedPropertyName').value,\n };\n }\n const salesActivities = hydrators.get('salesActivities');\n if (salesActivities.get('checked').value) {\n result.salesActivities = {\n salesActivityKeys: salesActivities.get('params').get('salesActivityKeys').value,\n inflatedPropertyName: salesActivities.get('params').get('inflatedPropertyName').value,\n };\n }\n const partnerConfig = hydrators.get('partnerConfig');\n if (partnerConfig.get('checked').value) {\n result.partnerConfig = {\n partnerId: partnerConfig.get('params').get('partnerId').value,\n marketId: partnerConfig.get('params').get('marketId').value,\n inflatedPropertyName: partnerConfig.get('params').get('inflatedPropertyName').value,\n };\n }\n const task = hydrators.get('task');\n if (task.get('checked').value) {\n result.task = {\n taskKeys: task.get('params').get('taskKeys').value,\n inflatedPropertyName: task.get('params').get('inflatedPropertyName').value,\n };\n }\n return result;\n }\n}\n","\n \n {{ (type$ | async)?.name }}\n \n \n \n \n \n \n \n\n \n
\n \n \n \n General\n General post type settings. \n \n \n \n \n \n Filters\n Settings for the filters available to a post type \n \n \n \n \n \n Icons\n \n Settings for the icons that are displayed alongside posts of this type.\n \n \n \n \n \n \n Templates\n \n Settings for the templates used to display posts in the Loop\n \n \n \n \n \n \n
\n
\n
\n\n\n
\n \n
\n
\n","import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';\nimport { UntypedFormArray, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';\n\n@Component({\n selector: 'app-loop-post-type-filter-settings',\n styleUrls: ['./post-type-filter-settings.component.scss'],\n templateUrl: './post-type-filter-settings.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: false,\n})\nexport class PostTypeFilterSettingsComponent implements OnInit {\n @Input() parentForm: UntypedFormGroup;\n filters: UntypedFormArray;\n\n constructor(private fb: UntypedFormBuilder) {}\n\n ngOnInit(): void {\n this.filters = this.parentForm.get('filters') as UntypedFormArray;\n }\n\n addFilter(event): void {\n event.preventDefault();\n this.filters.push(\n this.fb.group({\n label: ['', Validators.required],\n value: this.fb.group({\n id: ['', Validators.required],\n valuePath: ['', Validators.required],\n }),\n options: this.fb.array([]),\n }),\n );\n }\n\n removeFilter(event, index): void {\n event.preventDefault();\n this.filters.removeAt(index);\n }\n\n addOption(event, filterIndex): void {\n event.preventDefault();\n (this.filters.at(filterIndex).get('options') as UntypedFormArray).push(\n this.fb.group({\n id: ['', Validators.required],\n value: ['', Validators.required],\n }),\n );\n }\n\n removeOption(event, filterIndex, index): void {\n event.preventDefault();\n (this.filters.at(filterIndex).get('options') as UntypedFormArray).removeAt(index);\n }\n}\n","
\n
\n \n \n
\n \n \n The label used when selecting the filter\n \n \n \n \n The id that the value extracted from the value path will be saved under on the Loop Post\n \n \n \n \n \n The path to the value on the event for this Loop Post Type that the filter should compare against\n \n \n
\n \n \n
\n \n \n The label for the option\n \n \n \n \n The value for the option that will be compared against the extracted value on the Loop Posts\n \n \n
\n \n
\n
\n \n
\n
\n \n
\n
\n \n
\n
\n","import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';\nimport { UntypedFormGroup } from '@angular/forms';\nimport { TheLoopService } from '@vendasta/the-loop';\nimport { Observable } from 'rxjs';\nimport { map } from 'rxjs/operators';\nimport { newChannelOption } from '../post-type-editor.component';\n\n@Component({\n selector: 'app-loop-post-type-general-settings',\n styleUrls: ['./post-type-general-settings.component.scss'],\n templateUrl: './post-type-general-settings.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: false,\n})\nexport class PostTypeGeneralSettingsComponent implements OnInit {\n @Input() parentForm: UntypedFormGroup;\n channels$: Observable;\n newChannelOption = newChannelOption;\n\n constructor(private loopService: TheLoopService) {}\n\n ngOnInit(): void {\n this.channels$ = this.loopService.getChannels().pipe(\n map((channels) => {\n channels.push(this.newChannelOption);\n return channels;\n }),\n );\n }\n}\n","
\n
\n \n \n A name to describe the Post Type\n \n \n \n The event that will generate posts of this type\n \n \n Channel\n \n \n {{ channel }}\n \n \n \n Similar post types should be contained within the same channel\n \n \n \n \n \n The name of the new channel that will be created for this post type\n \n \n \n \n \n The templated identifier for a post to be created from the event. This\n allows for multiple events to update the same post, if desired. Use the\n {{}} syntax to insert data from the event matching that path into the\n template.\n \n \n \n \n The path to the partner id on the event\n \n \n \n The path to the market id on the event\n \n \n \n \n The path to the account group id on the event\n \n \n \n \n The path to the user id on the event that the post will be attributed to\n \n \n
\n
\n","import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';\nimport { UntypedFormArray, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';\nimport { matIconIconFormat } from '../post-type-editor.component';\n\n@Component({\n selector: 'app-loop-post-type-icon-settings',\n styleUrls: ['./post-type-icon-settings.component.scss'],\n templateUrl: './post-type-icon-settings.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: false,\n})\nexport class PostTypeIconSettingsComponent implements OnInit {\n @Input() parentForm: UntypedFormGroup;\n customTypes: UntypedFormArray;\n\n constructor(private fb: UntypedFormBuilder) {}\n\n ngOnInit(): void {\n this.customTypes = this.parentForm.get('iconResource').get('customTypes') as UntypedFormArray;\n }\n\n addCustomType(event): void {\n event.preventDefault();\n this.customTypes.push(\n this.fb.group({\n type: [''],\n icon: this.fb.group({\n format: [matIconIconFormat],\n value: ['', Validators.required],\n }),\n }),\n );\n }\n\n removeCustomType(event, index): void {\n event.preventDefault();\n this.customTypes.removeAt(index);\n }\n}\n","
\n
\n \n \n The path on the event to extract the value to be used for checking icon type\n \n \n

Default Icon

\n

This icon will be displayed on a post if it does not match any configured types for custom icons below

\n\n \n Mat Icon\n Icon Url\n \n \n \n The mat icon name or the url to an icon\n \n
\n

Custom Types

\n

Custom icons can be displayed for different posts depending on the value in the resource path

\n \n \n
\n \n \n The type that must be in the resource path in order for this icon to be used\n \n \n Mat Icon\n Icon Url\n \n \n \n The mat icon name or the url to an icon\n \n
\n \n
\n
\n \n
\n
\n","import {\n ChangeDetectionStrategy,\n Component,\n EventEmitter,\n Input,\n OnInit,\n Output,\n SecurityContext,\n} from '@angular/core';\nimport { UntypedFormGroup } from '@angular/forms';\nimport { combineLatest, Observable, of, ReplaySubject } from 'rxjs';\nimport { TemplatesService } from '@vendasta/templates';\nimport { catchError, debounceTime, distinctUntilChanged, map, switchMap, take, tap } from 'rxjs/operators';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport moment from 'moment';\nimport Autolinker from 'autolinker';\nimport { HttpErrorResponse } from '@angular/common/http';\nimport { HydrationOptions } from '@vendasta/templates/lib/_internal';\n\n@Component({\n selector: 'app-loop-post-type-templates-settings',\n styleUrls: ['./post-type-templates-settings.component.scss'],\n templateUrl: './post-type-templates-settings.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: false,\n})\nexport class PostTypeTemplatesSettingsComponent implements OnInit {\n @Input() parentForm: UntypedFormGroup;\n @Input() templateId: string;\n @Output() loaded: EventEmitter = new EventEmitter();\n fullHTML$$: ReplaySubject = new ReplaySubject(1);\n fullHTML$: Observable = this.fullHTML$$.asObservable();\n previewFullError$$: ReplaySubject = new ReplaySubject(1);\n previewFullError$: Observable = this.previewFullError$$.asObservable();\n previewFullHTML$: Observable;\n styles$$: ReplaySubject = new ReplaySubject(1);\n styles$: Observable = this.styles$$.asObservable();\n previewStylesError$$: ReplaySubject = new ReplaySubject(1);\n previewStylesError$: Observable = this.previewStylesError$$.asObservable();\n previewStyles$: Observable;\n compactHTML$$: ReplaySubject = new ReplaySubject(1);\n compactHTML$: Observable = this.compactHTML$$.asObservable();\n previewCompactError$$: ReplaySubject = new ReplaySubject(1);\n previewCompactError$: Observable = this.previewCompactError$$.asObservable();\n previewCompactHTML$: Observable;\n sampleData$$: ReplaySubject = new ReplaySubject(1);\n sampleData$: Observable = this.sampleData$$.asObservable();\n\n exampleDate = new Date();\n\n constructor(\n private templatesService: TemplatesService,\n private readonly sanitizer: DomSanitizer,\n ) {}\n\n ngOnInit(): void {\n // TODO: Hydration options\n\n if (this.templateId) {\n const templateIds = [this.templateId, this.templateId + '-styles', this.templateId + '-compact'];\n this.templatesService\n .getMulti('the-loop', templateIds)\n .pipe(\n take(1),\n tap((templates) => {\n // TODO handle templates[].error\n this.fullHTML$$.next(templates[0].template ? templates[0].template.content : '');\n this.styles$$.next(templates[1].template ? templates[1].template.content : '');\n this.compactHTML$$.next(templates[2].template ? templates[2].template.content : '');\n if (templates[0].template.hydrationOptions) {\n this.setInitialHydrationOptions(templates[0].template.hydrationOptions);\n }\n }),\n tap(() => this.loaded.emit(true)),\n )\n .subscribe();\n } else {\n this.fullHTML$$.next('');\n this.styles$$.next('');\n this.compactHTML$$.next('');\n this.loaded.emit(true);\n }\n // TODO: Add sample data to Loop Post Type model so that this persists\n this.sampleData$$.next('{}');\n\n this.previewStyles$ = combineLatest([this.styles$, this.sampleData$]).pipe(\n debounceTime(500),\n distinctUntilChanged(),\n switchMap(([styles, sampleData]) => {\n return this.templatesService.render(styles, convertsampleDataToJson(sampleData)).pipe(\n tap(() => this.previewStylesError$$.next('')),\n catchError((err: HttpErrorResponse) => {\n this.previewStylesError$$.next(err.error.message);\n return of('');\n }),\n );\n }),\n map((renderedTemplate) => {\n return this.sanitizer.bypassSecurityTrustHtml(renderedTemplate);\n }),\n );\n\n this.previewFullHTML$ = combineLatest([this.fullHTML$, this.sampleData$]).pipe(\n debounceTime(500),\n distinctUntilChanged(),\n switchMap(([fullHTML, sampleData]) =>\n this.templatesService.render(fullHTML, convertsampleDataToJson(sampleData)).pipe(\n tap(() => this.previewFullError$$.next('')),\n catchError((err: HttpErrorResponse) => {\n this.previewFullError$$.next(err.error.message);\n return of('');\n }),\n ),\n ),\n map((renderedTemplate) => {\n return this.sanitizer.sanitize(SecurityContext.HTML, Autolinker.link(renderedTemplate));\n }),\n );\n\n this.previewCompactHTML$ = combineLatest([this.compactHTML$, this.sampleData$]).pipe(\n debounceTime(500),\n distinctUntilChanged(),\n switchMap(([compactHTML, sampleData]) =>\n this.templatesService.render(compactHTML, convertsampleDataToJson(sampleData)).pipe(\n tap(() => this.previewCompactError$$.next('')),\n catchError((err: HttpErrorResponse) => {\n this.previewCompactError$$.next(err.error.message);\n return of('');\n }),\n ),\n ),\n map((renderedTemplate) => {\n return this.sanitizer.sanitize(SecurityContext.HTML, Autolinker.link(renderedTemplate));\n }),\n );\n }\n\n updateFullHTML(content: string): void {\n this.fullHTML$$.next(content);\n this.parentForm.get('templates').patchValue({\n fullHtml: content,\n });\n }\n\n updateStyles(content: string): void {\n this.styles$$.next(content);\n this.parentForm.get('templates').patchValue({\n styles: content,\n });\n }\n\n updateCompactHTML(content: string): void {\n this.compactHTML$$.next(content);\n this.parentForm.get('templates').patchValue({\n compactHTML: content,\n });\n }\n\n updateSampleData(content: string): void {\n this.sampleData$$.next(content);\n }\n\n fromNow(date: Date): string {\n return moment(date).fromNow();\n }\n\n setInitialHydrationOptions(hydrationOptions: HydrationOptions): void {\n const hydrators = this.parentForm.get('templates').get('hydrators');\n if (hydrationOptions.accountGroups) {\n const accountGroups = hydrators.get('accountGroups') as UntypedFormGroup;\n accountGroups.get('checked').setValue(true);\n this.hydratorChecked('accountGroups', true);\n accountGroups.get('params').get('accountGroupIds').setValue(hydrationOptions.accountGroups.accountGroupIds);\n accountGroups\n .get('params')\n .get('inflatedPropertyName')\n .setValue(hydrationOptions.accountGroups.inflatedPropertyName);\n }\n if (hydrationOptions.apps) {\n const apps = hydrators.get('apps') as UntypedFormGroup;\n apps.get('checked').setValue(true);\n this.hydratorChecked('apps', true);\n apps.get('params').get('appKeys').setValue(hydrationOptions.apps.appKeys);\n apps.get('params').get('partnerId').setValue(hydrationOptions.apps.partnerId);\n apps.get('params').get('marketId').setValue(hydrationOptions.apps.marketId);\n apps.get('params').get('inflatedPropertyName').setValue(hydrationOptions.apps.inflatedPropertyName);\n }\n if (hydrationOptions.packages) {\n const packages = hydrators.get('packages') as UntypedFormGroup;\n packages.get('checked').setValue(true);\n this.hydratorChecked('packages', true);\n packages.get('params').get('packageIds').setValue(hydrationOptions.packages.packageIds);\n packages.get('params').get('inflatedPropertyName').setValue(hydrationOptions.packages.inflatedPropertyName);\n }\n if (hydrationOptions.branding) {\n const branding = hydrators.get('branding') as UntypedFormGroup;\n branding.get('checked').setValue(true);\n this.hydratorChecked('branding', true);\n branding.get('params').get('partnerId').setValue(hydrationOptions.branding.partnerId);\n branding.get('params').get('marketId').setValue(hydrationOptions.branding.marketId);\n branding.get('params').get('inflatedPropertyName').setValue(hydrationOptions.branding.inflatedPropertyName);\n }\n if (hydrationOptions.users) {\n const users = hydrators.get('users') as UntypedFormGroup;\n users.get('checked').setValue(true);\n this.hydratorChecked('users', true);\n users.get('params').get('userIds').setValue(hydrationOptions.users.userIds);\n users.get('params').get('inflatedPropertyName').setValue(hydrationOptions.users.inflatedPropertyName);\n }\n if (hydrationOptions.salesActivities) {\n const salesActivities = hydrators.get('salesActivities') as UntypedFormGroup;\n salesActivities.get('checked').setValue(true);\n this.hydratorChecked('salesActivities', true);\n salesActivities\n .get('params')\n .get('salesActivityKeys')\n .setValue(hydrationOptions.salesActivities.salesActivityKeys);\n salesActivities\n .get('params')\n .get('inflatedPropertyName')\n .setValue(hydrationOptions.salesActivities.inflatedPropertyName);\n }\n if (hydrationOptions.partnerConfig) {\n const partnerConfig = hydrators.get('partnerConfig') as UntypedFormGroup;\n partnerConfig.get('checked').setValue(true);\n this.hydratorChecked('partnerConfig', true);\n partnerConfig.get('params').get('partnerId').setValue(hydrationOptions.partnerConfig.partnerId);\n partnerConfig.get('params').get('marketId').setValue(hydrationOptions.partnerConfig.marketId);\n partnerConfig\n .get('params')\n .get('inflatedPropertyName')\n .setValue(hydrationOptions.partnerConfig.inflatedPropertyName);\n }\n if (hydrationOptions.task) {\n const task = hydrators.get('task') as UntypedFormGroup;\n task.get('checked').setValue(true);\n this.hydratorChecked('task', true);\n task.get('params').get('taskKeys').setValue(hydrationOptions.task.taskKeys);\n task.get('params').get('inflatedPropertyName').setValue(hydrationOptions.task.inflatedPropertyName);\n }\n }\n\n hydratorChecked(hydratorName: string, checked: boolean): void {\n const params = this.parentForm\n .get('templates')\n .get('hydrators')\n .get(hydratorName)\n .get('params') as UntypedFormGroup;\n Object.keys(params.controls).forEach((field) => {\n const c = params.controls[field];\n if (checked) {\n c.enable();\n } else {\n c.disable();\n }\n });\n }\n}\n\nfunction convertsampleDataToJson(sampleData: string): any {\n let sampleJson = {};\n try {\n sampleJson = JSON.parse(sampleData || '{}');\n } catch {\n // do nothing\n }\n return sampleJson;\n}\n","
\n
\n \n \n The base id for the templates for this post type\n \n
\n

Hydration Options

\n \n These options will allow identifiers on the event data to be inflated into entities that will be accessible in\n the template\n \n
\n \n Account Groups\n \n \n \n \n The path to the account group id or list of account group ids on the event\n \n \n \n \n The name that the inflated list of account groups will be available under in the template\n \n \n
\n
\n
\n Apps\n \n \n \n \n The path to the app key or list of app keys on the event (a key must have an `app_id`, and optionally an\n `edition_id`)\n \n \n \n \n The path to the partner id on the event\n \n \n \n The path to the market id on the event\n \n \n \n The name that the inflated list of apps will be available under in the template\n \n
\n
\n
\n \n Packages\n \n \n \n \n The path to the package id or list of package ids on the event\n \n \n \n The name that the inflated list of packages will be available under in the template\n \n
\n
\n
\n \n Branding\n \n \n \n \n The path to the partner id on the event\n \n \n \n The path to the market id on the event\n \n \n \n The name that the inflated branding will be available under in the template\n \n
\n \n
\n Users\n \n \n \n The path to the user id or list of user ids on the event\n \n \n \n The name that the inflated list of users will be available under in the template\n \n
\n \n
\n \n Sales Activities\n \n \n \n \n \n The path to the sales activity key or sales activity keys on the event (a key must have a\n `sales_activity_id` and `business_id`)\n \n \n \n \n \n The name that the inflated list of sales activities will be available under in the template\n \n \n
\n \n
\n \n Partner Config\n \n \n \n \n The path to the partner id on the event\n \n \n \n The path to the market id on the event\n \n \n \n The name that the inflated partner config will be available under in the template\n \n
\n \n
\n Tasks\n \n \n \n \n The path to the task key or list of task keys on the event (a key must have a `namespace`, `parent_path`\n and `task_id`)\n \n \n \n \n The name that the inflated list of tasks will be available under in the template\n \n
\n \n \n \n\n

\n These HTML templates will be sanitized by the\n Angular DomSanitizer\n .\n

\n

\n The styles template will be trusted and bypass security, so please do not include any variables that could have user\n input in them.\n

\n\n \n
\n
\n \n \n
\n \n
\n
\n \n
\n \n
\n
\n
\n
\n \n
\n
\n \n error_outline\n {{ error }}\n \n
\n
\n \n error_outline\n {{ error }}\n \n
\n \n \n
\n
\n all_inclusive\n
\n
\n
\n
\n
\n {{ exampleDate | date: 'MMM dd, y - h:mm a' }} ({{ fromNow(exampleDate) }})\n
\n
\n
\n
\n \n
\n
\n
\n \n
\n
\n
\n \n
\n
\n \n
\n
\n \n error_outline\n {{ error }}\n \n
\n \n
\n
\n all_inclusive\n
\n
\n
\n
\n {{ exampleDate | date: 'MMM dd, y - h:mm a' }} ({{ fromNow(exampleDate) }})\n
\n
\n
\n \n
\n
\n
\n \n
\n
\n
\n \n
\n
\n
\n
\n
\n","// Important: this file is generated from the 'build' script and should not be\n// edited directly\nexport var version = '4.0.0';\n","/**\n * Simpler helper method to check for undefined simply for the benefit of\n * gaining better compression when minified by not needing to have multiple\n * comparisons to the `undefined` keyword in the codebase.\n */\nexport function isUndefined(value) {\n return value === undefined;\n}\n/**\n * Simpler helper method to check for a boolean type simply for the benefit of\n * gaining better compression when minified by not needing to have multiple\n * `typeof` comparisons in the codebase.\n */\nexport function isBoolean(value) {\n return typeof value === 'boolean';\n}\n/**\n * Assigns (shallow copies) the properties of `src` onto `dest`, if the\n * corresponding property on `dest` === `undefined`.\n *\n * @param {Object} dest The destination object.\n * @param {Object} src The source object.\n * @return {Object} The destination object (`dest`)\n */\nexport function defaults(dest, src) {\n for (var prop in src) {\n if (src.hasOwnProperty(prop) && isUndefined(dest[prop])) {\n dest[prop] = src[prop];\n }\n }\n return dest;\n}\n/**\n * Truncates the `str` at `len - ellipsisChars.length`, and adds the `ellipsisChars` to the\n * end of the string (by default, two periods: '..'). If the `str` length does not exceed\n * `len`, the string will be returned unchanged.\n *\n * @param {String} str The string to truncate and add an ellipsis to.\n * @param {Number} truncateLen The length to truncate the string at.\n * @param {String} [ellipsisChars=...] The ellipsis character(s) to add to the end of `str`\n * when truncated. Defaults to '...'\n */\nexport function ellipsis(str, truncateLen, ellipsisChars) {\n var ellipsisLength;\n if (str.length > truncateLen) {\n if (ellipsisChars == null) {\n ellipsisChars = '…';\n ellipsisLength = 3;\n } else {\n ellipsisLength = ellipsisChars.length;\n }\n str = str.substring(0, truncateLen - ellipsisLength) + ellipsisChars;\n }\n return str;\n}\n/**\n * Removes array elements by value. Mutates the input array.\n *\n * Using this instead of the ES5 Array.prototype.filter() function to prevent\n * creating many new arrays in memory for removing an element.\n *\n * @param arr The array to remove elements from. This array is mutated.\n * @param fn The element to remove.\n */\nexport function remove(arr, item) {\n for (var i = arr.length - 1; i >= 0; i--) {\n if (arr[i] === item) {\n arr.splice(i, 1);\n }\n }\n}\n/**\n * Removes array elements based on a filtering function. Mutates the input\n * array.\n *\n * Using this instead of the ES5 Array.prototype.filter() function to prevent\n * creating many new arrays in memory for filtering.\n *\n * @param arr The array to remove elements from. This array is mutated.\n * @param fn The predicate function which should return `true` to remove an\n * element.\n */\nexport function removeWithPredicate(arr, fn) {\n for (var i = arr.length - 1; i >= 0; i--) {\n if (fn(arr[i]) === true) {\n arr.splice(i, 1);\n }\n }\n}\n/**\n * Function that should never be called but is used to check that every\n * enum value is handled using TypeScript's 'never' type.\n */\nexport function assertNever(theValue) {\n throw new Error(\"Unhandled case for value: '\".concat(theValue, \"'\"));\n}\n","/*\n * This file builds and stores a library of the common regular expressions used\n * by the Autolinker utility.\n *\n * Other regular expressions may exist ad-hoc, but these are generally the\n * regular expressions that are shared between source files.\n */\n/**\n * Regular expression to match upper and lowercase ASCII letters\n */\nexport var letterRe = /[A-Za-z]/;\n/**\n * Regular expression to match ASCII digits\n */\nexport var digitRe = /[\\d]/;\n/**\n * Regular expression to match everything *except* ASCII digits\n */\nexport var nonDigitRe = /[\\D]/;\n/**\n * Regular expression to match whitespace\n */\nexport var whitespaceRe = /\\s/;\n/**\n * Regular expression to match quote characters\n */\nexport var quoteRe = /['\"]/;\n/**\n * Regular expression to match the range of ASCII control characters (0-31), and\n * the backspace char (127)\n */\nexport var controlCharsRe = /[\\x00-\\x1F\\x7F]/;\n/**\n * The string form of a regular expression that would match all of the\n * alphabetic (\"letter\") chars in the unicode character set when placed in a\n * RegExp character class (`[]`). This includes all international alphabetic\n * characters.\n *\n * These would be the characters matched by unicode regex engines `\\p{L}`\n * escape (\"all letters\").\n *\n * Taken from the XRegExp library: http://xregexp.com/ (thanks @https://github.com/slevithan)\n * Specifically: http://xregexp.com/v/3.2.0/xregexp-all.js, the 'Letter'\n * regex's bmp\n *\n * VERY IMPORTANT: This set of characters is defined inside of a Regular\n * Expression literal rather than a string literal to prevent UglifyJS from\n * compressing the unicode escape sequences into their actual unicode\n * characters. If Uglify compresses these into the unicode characters\n * themselves, this results in the error \"Range out of order in character\n * class\" when these characters are used inside of a Regular Expression\n * character class (`[]`). See usages of this const. Alternatively, we can set\n * the UglifyJS option `ascii_only` to true for the build, but that doesn't\n * help others who are pulling in Autolinker into their own build and running\n * UglifyJS themselves.\n */\n// prettier-ignore\nexport var alphaCharsStr = /A-Za-z\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u08A0-\\u08B4\\u08B6-\\u08BD\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0AF9\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58-\\u0C5A\\u0C60\\u0C61\\u0C80\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D54-\\u0D56\\u0D5F-\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F5\\u13F8-\\u13FD\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16F1-\\u16F8\\u1700-\\u170C\\u170E-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1877\\u1880-\\u1884\\u1887-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4B\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1C80-\\u1C88\\u1CE9-\\u1CEC\\u1CEE-\\u1CF1\\u1CF5\\u1CF6\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183\\u2184\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005\\u3006\\u3031-\\u3035\\u303B\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31BA\\u31F0-\\u31FF\\u3400-\\u4DB5\\u4E00-\\u9FD5\\uA000-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6E5\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA7AE\\uA7B0-\\uA7B7\\uA7F7-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA8FD\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB65\\uAB70-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC/.source; // see note in above variable description\n/**\n * The string form of a regular expression that would match all emoji characters\n * Based on the emoji regex defined in this article: https://thekevinscott.com/emojis-in-javascript/\n */\nexport var emojiStr = /\\u2700-\\u27bf\\udde6-\\uddff\\ud800-\\udbff\\udc00-\\udfff\\ufe0e\\ufe0f\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0\\ud83c\\udffb-\\udfff\\u200d\\u3299\\u3297\\u303d\\u3030\\u24c2\\ud83c\\udd70-\\udd71\\udd7e-\\udd7f\\udd8e\\udd91-\\udd9a\\udde6-\\uddff\\ude01-\\ude02\\ude1a\\ude2f\\ude32-\\ude3a\\ude50-\\ude51\\u203c\\u2049\\u25aa-\\u25ab\\u25b6\\u25c0\\u25fb-\\u25fe\\u00a9\\u00ae\\u2122\\u2139\\udc04\\u2600-\\u26FF\\u2b05\\u2b06\\u2b07\\u2b1b\\u2b1c\\u2b50\\u2b55\\u231a\\u231b\\u2328\\u23cf\\u23e9-\\u23f3\\u23f8-\\u23fa\\udccf\\u2935\\u2934\\u2190-\\u21ff/.source;\n/**\n * The string form of a regular expression that would match all of the\n * combining mark characters in the unicode character set when placed in a\n * RegExp character class (`[]`).\n *\n * These would be the characters matched by unicode regex engines `\\p{M}`\n * escape (\"all marks\").\n *\n * Taken from the XRegExp library: http://xregexp.com/ (thanks @https://github.com/slevithan)\n * Specifically: http://xregexp.com/v/3.2.0/xregexp-all.js, the 'Mark'\n * regex's bmp\n *\n * VERY IMPORTANT: This set of characters is defined inside of a Regular\n * Expression literal rather than a string literal to prevent UglifyJS from\n * compressing the unicode escape sequences into their actual unicode\n * characters. If Uglify compresses these into the unicode characters\n * themselves, this results in the error \"Range out of order in character\n * class\" when these characters are used inside of a Regular Expression\n * character class (`[]`). See usages of this const. Alternatively, we can set\n * the UglifyJS option `ascii_only` to true for the build, but that doesn't\n * help others who are pulling in Autolinker into their own build and running\n * UglifyJS themselves.\n */\n// prettier-ignore\nexport var marksStr = /\\u0300-\\u036F\\u0483-\\u0489\\u0591-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u05C5\\u05C7\\u0610-\\u061A\\u064B-\\u065F\\u0670\\u06D6-\\u06DC\\u06DF-\\u06E4\\u06E7\\u06E8\\u06EA-\\u06ED\\u0711\\u0730-\\u074A\\u07A6-\\u07B0\\u07EB-\\u07F3\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u082D\\u0859-\\u085B\\u08D4-\\u08E1\\u08E3-\\u0903\\u093A-\\u093C\\u093E-\\u094F\\u0951-\\u0957\\u0962\\u0963\\u0981-\\u0983\\u09BC\\u09BE-\\u09C4\\u09C7\\u09C8\\u09CB-\\u09CD\\u09D7\\u09E2\\u09E3\\u0A01-\\u0A03\\u0A3C\\u0A3E-\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A51\\u0A70\\u0A71\\u0A75\\u0A81-\\u0A83\\u0ABC\\u0ABE-\\u0AC5\\u0AC7-\\u0AC9\\u0ACB-\\u0ACD\\u0AE2\\u0AE3\\u0B01-\\u0B03\\u0B3C\\u0B3E-\\u0B44\\u0B47\\u0B48\\u0B4B-\\u0B4D\\u0B56\\u0B57\\u0B62\\u0B63\\u0B82\\u0BBE-\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCD\\u0BD7\\u0C00-\\u0C03\\u0C3E-\\u0C44\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56\\u0C62\\u0C63\\u0C81-\\u0C83\\u0CBC\\u0CBE-\\u0CC4\\u0CC6-\\u0CC8\\u0CCA-\\u0CCD\\u0CD5\\u0CD6\\u0CE2\\u0CE3\\u0D01-\\u0D03\\u0D3E-\\u0D44\\u0D46-\\u0D48\\u0D4A-\\u0D4D\\u0D57\\u0D62\\u0D63\\u0D82\\u0D83\\u0DCA\\u0DCF-\\u0DD4\\u0DD6\\u0DD8-\\u0DDF\\u0DF2\\u0DF3\\u0E31\\u0E34-\\u0E3A\\u0E47-\\u0E4E\\u0EB1\\u0EB4-\\u0EB9\\u0EBB\\u0EBC\\u0EC8-\\u0ECD\\u0F18\\u0F19\\u0F35\\u0F37\\u0F39\\u0F3E\\u0F3F\\u0F71-\\u0F84\\u0F86\\u0F87\\u0F8D-\\u0F97\\u0F99-\\u0FBC\\u0FC6\\u102B-\\u103E\\u1056-\\u1059\\u105E-\\u1060\\u1062-\\u1064\\u1067-\\u106D\\u1071-\\u1074\\u1082-\\u108D\\u108F\\u109A-\\u109D\\u135D-\\u135F\\u1712-\\u1714\\u1732-\\u1734\\u1752\\u1753\\u1772\\u1773\\u17B4-\\u17D3\\u17DD\\u180B-\\u180D\\u1885\\u1886\\u18A9\\u1920-\\u192B\\u1930-\\u193B\\u1A17-\\u1A1B\\u1A55-\\u1A5E\\u1A60-\\u1A7C\\u1A7F\\u1AB0-\\u1ABE\\u1B00-\\u1B04\\u1B34-\\u1B44\\u1B6B-\\u1B73\\u1B80-\\u1B82\\u1BA1-\\u1BAD\\u1BE6-\\u1BF3\\u1C24-\\u1C37\\u1CD0-\\u1CD2\\u1CD4-\\u1CE8\\u1CED\\u1CF2-\\u1CF4\\u1CF8\\u1CF9\\u1DC0-\\u1DF5\\u1DFB-\\u1DFF\\u20D0-\\u20F0\\u2CEF-\\u2CF1\\u2D7F\\u2DE0-\\u2DFF\\u302A-\\u302F\\u3099\\u309A\\uA66F-\\uA672\\uA674-\\uA67D\\uA69E\\uA69F\\uA6F0\\uA6F1\\uA802\\uA806\\uA80B\\uA823-\\uA827\\uA880\\uA881\\uA8B4-\\uA8C5\\uA8E0-\\uA8F1\\uA926-\\uA92D\\uA947-\\uA953\\uA980-\\uA983\\uA9B3-\\uA9C0\\uA9E5\\uAA29-\\uAA36\\uAA43\\uAA4C\\uAA4D\\uAA7B-\\uAA7D\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uAAEB-\\uAAEF\\uAAF5\\uAAF6\\uABE3-\\uABEA\\uABEC\\uABED\\uFB1E\\uFE00-\\uFE0F\\uFE20-\\uFE2F/.source; // see note in above variable description\n/**\n * The string form of a regular expression that would match all of the\n * alphabetic (\"letter\") chars, emoji, and combining marks in the unicode character set\n * when placed in a RegExp character class (`[]`). This includes all\n * international alphabetic characters.\n *\n * These would be the characters matched by unicode regex engines `\\p{L}\\p{M}`\n * escapes and emoji characters.\n */\nexport var alphaCharsAndMarksStr = alphaCharsStr + emojiStr + marksStr;\n/**\n * The string form of a regular expression that would match all of the\n * decimal number chars in the unicode character set when placed in a RegExp\n * character class (`[]`).\n *\n * These would be the characters matched by unicode regex engines `\\p{Nd}`\n * escape (\"all decimal numbers\")\n *\n * Taken from the XRegExp library: http://xregexp.com/ (thanks @https://github.com/slevithan)\n * Specifically: http://xregexp.com/v/3.2.0/xregexp-all.js, the 'Decimal_Number'\n * regex's bmp\n *\n * VERY IMPORTANT: This set of characters is defined inside of a Regular\n * Expression literal rather than a string literal to prevent UglifyJS from\n * compressing the unicode escape sequences into their actual unicode\n * characters. If Uglify compresses these into the unicode characters\n * themselves, this results in the error \"Range out of order in character\n * class\" when these characters are used inside of a Regular Expression\n * character class (`[]`). See usages of this const. Alternatively, we can set\n * the UglifyJS option `ascii_only` to true for the build, but that doesn't\n * help others who are pulling in Autolinker into their own build and running\n * UglifyJS themselves.\n */\n// prettier-ignore\nexport var decimalNumbersStr = /0-9\\u0660-\\u0669\\u06F0-\\u06F9\\u07C0-\\u07C9\\u0966-\\u096F\\u09E6-\\u09EF\\u0A66-\\u0A6F\\u0AE6-\\u0AEF\\u0B66-\\u0B6F\\u0BE6-\\u0BEF\\u0C66-\\u0C6F\\u0CE6-\\u0CEF\\u0D66-\\u0D6F\\u0DE6-\\u0DEF\\u0E50-\\u0E59\\u0ED0-\\u0ED9\\u0F20-\\u0F29\\u1040-\\u1049\\u1090-\\u1099\\u17E0-\\u17E9\\u1810-\\u1819\\u1946-\\u194F\\u19D0-\\u19D9\\u1A80-\\u1A89\\u1A90-\\u1A99\\u1B50-\\u1B59\\u1BB0-\\u1BB9\\u1C40-\\u1C49\\u1C50-\\u1C59\\uA620-\\uA629\\uA8D0-\\uA8D9\\uA900-\\uA909\\uA9D0-\\uA9D9\\uA9F0-\\uA9F9\\uAA50-\\uAA59\\uABF0-\\uABF9\\uFF10-\\uFF19/.source; // see note in above variable description\n/**\n * The regular expression that will match all of the letters and decimal number\n * chars in the unicode character set when placed in a RegExp character class\n * (`[]`).\n *\n * These would be the characters matched by unicode regex engines\n * `[\\p{L}\\p{Nd}]` escape (\"all letters and decimal numbers\")\n */\nexport var alphaNumericCharsRe = new RegExp(\"[\".concat(alphaCharsStr + decimalNumbersStr, \"]\"));\n/**\n * The string form of a regular expression that would match all of the\n * letters, combining marks, and decimal number chars in the unicode character\n * set when placed in a RegExp character class (`[]`).\n *\n * These would be the characters matched by unicode regex engines\n * `[\\p{L}\\p{M}\\p{Nd}]` escape (\"all letters, combining marks, and decimal\n * numbers\")\n */\nexport var alphaNumericAndMarksCharsStr = alphaCharsAndMarksStr + decimalNumbersStr;\n/**\n * The regular expression that will match a single letter of the\n * {@link #alphaNumericAndMarksCharsStr}.\n */\nexport var alphaNumericAndMarksRe = new RegExp(\"[\".concat(alphaNumericAndMarksCharsStr, \"]\"));\n","import { whitespaceRe } from './regex-lib';\n/**\n * @class Autolinker.HtmlTag\n * @extends Object\n *\n * Represents an HTML tag, which can be used to easily build/modify HTML tags programmatically.\n *\n * Autolinker uses this abstraction to create HTML tags, and then write them out as strings. You may also use\n * this class in your code, especially within a {@link Autolinker#replaceFn replaceFn}.\n *\n * ## Examples\n *\n * Example instantiation:\n *\n * var tag = new Autolinker.HtmlTag( {\n * tagName : 'a',\n * attrs : { 'href': 'http://google.com', 'class': 'external-link' },\n * innerHtml : 'Google'\n * } );\n *\n * tag.toAnchorString(); // Google\n *\n * // Individual accessor methods\n * tag.getTagName(); // 'a'\n * tag.getAttr( 'href' ); // 'http://google.com'\n * tag.hasClass( 'external-link' ); // true\n *\n *\n * Using mutator methods (which may be used in combination with instantiation config properties):\n *\n * var tag = new Autolinker.HtmlTag();\n * tag.setTagName( 'a' );\n * tag.setAttr( 'href', 'http://google.com' );\n * tag.addClass( 'external-link' );\n * tag.setInnerHtml( 'Google' );\n *\n * tag.getTagName(); // 'a'\n * tag.getAttr( 'href' ); // 'http://google.com'\n * tag.hasClass( 'external-link' ); // true\n *\n * tag.toAnchorString(); // Google\n *\n *\n * ## Example use within a {@link Autolinker#replaceFn replaceFn}\n *\n * var html = Autolinker.link( \"Test google.com\", {\n * replaceFn : function( match ) {\n * var tag = match.buildTag(); // returns an {@link Autolinker.HtmlTag} instance, configured with the Match's href and anchor text\n * tag.setAttr( 'rel', 'nofollow' );\n *\n * return tag;\n * }\n * } );\n *\n * // generated html:\n * // Test google.com\n *\n *\n * ## Example use with a new tag for the replacement\n *\n * var html = Autolinker.link( \"Test google.com\", {\n * replaceFn : function( match ) {\n * var tag = new Autolinker.HtmlTag( {\n * tagName : 'button',\n * attrs : { 'title': 'Load URL: ' + match.getAnchorHref() },\n * innerHtml : 'Load URL: ' + match.getAnchorText()\n * } );\n *\n * return tag;\n * }\n * } );\n *\n * // generated html:\n * // Test \n */\nvar HtmlTag = /** @class */function () {\n /**\n * @method constructor\n * @param {Object} [cfg] The configuration properties for this class, in an Object (map)\n */\n function HtmlTag(cfg) {\n if (cfg === void 0) {\n cfg = {};\n }\n /**\n * @cfg {String} tagName\n *\n * The tag name. Ex: 'a', 'button', etc.\n *\n * Not required at instantiation time, but should be set using {@link #setTagName} before {@link #toAnchorString}\n * is executed.\n */\n this.tagName = ''; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @cfg {Object.} attrs\n *\n * An key/value Object (map) of attributes to create the tag with. The keys are the attribute names, and the\n * values are the attribute values.\n */\n this.attrs = {}; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @cfg {String} innerHTML\n *\n * The inner HTML for the tag.\n */\n this.innerHTML = ''; // default value just to get the above doc comment in the ES5 output and documentation generator\n this.tagName = cfg.tagName || '';\n this.attrs = cfg.attrs || {};\n this.innerHTML = cfg.innerHtml || cfg.innerHTML || ''; // accept either the camelCased form or the fully capitalized acronym as in the DOM\n }\n /**\n * Sets the tag name that will be used to generate the tag with.\n *\n * @param {String} tagName\n * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained.\n */\n HtmlTag.prototype.setTagName = function (tagName) {\n this.tagName = tagName;\n return this;\n };\n /**\n * Retrieves the tag name.\n *\n * @return {String}\n */\n HtmlTag.prototype.getTagName = function () {\n return this.tagName || '';\n };\n /**\n * Sets an attribute on the HtmlTag.\n *\n * @param {String} attrName The attribute name to set.\n * @param {String} attrValue The attribute value to set.\n * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained.\n */\n HtmlTag.prototype.setAttr = function (attrName, attrValue) {\n var tagAttrs = this.getAttrs();\n tagAttrs[attrName] = attrValue;\n return this;\n };\n /**\n * Retrieves an attribute from the HtmlTag. If the attribute does not exist, returns `undefined`.\n *\n * @param {String} attrName The attribute name to retrieve.\n * @return {String} The attribute's value, or `undefined` if it does not exist on the HtmlTag.\n */\n HtmlTag.prototype.getAttr = function (attrName) {\n return this.getAttrs()[attrName];\n };\n /**\n * Sets one or more attributes on the HtmlTag.\n *\n * @param {Object.} attrs A key/value Object (map) of the attributes to set.\n * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained.\n */\n HtmlTag.prototype.setAttrs = function (attrs) {\n Object.assign(this.getAttrs(), attrs);\n return this;\n };\n /**\n * Retrieves the attributes Object (map) for the HtmlTag.\n *\n * @return {Object.} A key/value object of the attributes for the HtmlTag.\n */\n HtmlTag.prototype.getAttrs = function () {\n return this.attrs || (this.attrs = {});\n };\n /**\n * Sets the provided `cssClass`, overwriting any current CSS classes on the HtmlTag.\n *\n * @param {String} cssClass One or more space-separated CSS classes to set (overwrite).\n * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained.\n */\n HtmlTag.prototype.setClass = function (cssClass) {\n return this.setAttr('class', cssClass);\n };\n /**\n * Convenience method to add one or more CSS classes to the HtmlTag. Will not add duplicate CSS classes.\n *\n * @param {String} cssClass One or more space-separated CSS classes to add.\n * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained.\n */\n HtmlTag.prototype.addClass = function (cssClass) {\n var classAttr = this.getClass(),\n classes = !classAttr ? [] : classAttr.split(whitespaceRe),\n newClasses = cssClass.split(whitespaceRe),\n newClass;\n while (newClass = newClasses.shift()) {\n if (classes.indexOf(newClass) === -1) {\n classes.push(newClass);\n }\n }\n this.getAttrs()['class'] = classes.join(' ');\n return this;\n };\n /**\n * Convenience method to remove one or more CSS classes from the HtmlTag.\n *\n * @param {String} cssClass One or more space-separated CSS classes to remove.\n * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained.\n */\n HtmlTag.prototype.removeClass = function (cssClass) {\n var classAttr = this.getClass(),\n classes = !classAttr ? [] : classAttr.split(whitespaceRe),\n removeClasses = cssClass.split(whitespaceRe),\n removeClass;\n while (classes.length && (removeClass = removeClasses.shift())) {\n var idx = classes.indexOf(removeClass);\n if (idx !== -1) {\n classes.splice(idx, 1);\n }\n }\n this.getAttrs()['class'] = classes.join(' ');\n return this;\n };\n /**\n * Convenience method to retrieve the CSS class(es) for the HtmlTag, which will each be separated by spaces when\n * there are multiple.\n *\n * @return {String}\n */\n HtmlTag.prototype.getClass = function () {\n return this.getAttrs()['class'] || '';\n };\n /**\n * Convenience method to check if the tag has a CSS class or not.\n *\n * @param {String} cssClass The CSS class to check for.\n * @return {Boolean} `true` if the HtmlTag has the CSS class, `false` otherwise.\n */\n HtmlTag.prototype.hasClass = function (cssClass) {\n return (' ' + this.getClass() + ' ').indexOf(' ' + cssClass + ' ') !== -1;\n };\n /**\n * Sets the inner HTML for the tag.\n *\n * @param {String} html The inner HTML to set.\n * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained.\n */\n HtmlTag.prototype.setInnerHTML = function (html) {\n this.innerHTML = html;\n return this;\n };\n /**\n * Backwards compatibility method name.\n *\n * @param {String} html The inner HTML to set.\n * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained.\n */\n HtmlTag.prototype.setInnerHtml = function (html) {\n return this.setInnerHTML(html);\n };\n /**\n * Retrieves the inner HTML for the tag.\n *\n * @return {String}\n */\n HtmlTag.prototype.getInnerHTML = function () {\n return this.innerHTML || '';\n };\n /**\n * Backward compatibility method name.\n *\n * @return {String}\n */\n HtmlTag.prototype.getInnerHtml = function () {\n return this.getInnerHTML();\n };\n /**\n * Generates the HTML string for the tag.\n *\n * @return {String}\n */\n HtmlTag.prototype.toAnchorString = function () {\n var tagName = this.getTagName(),\n attrsStr = this.buildAttrsStr();\n attrsStr = attrsStr ? ' ' + attrsStr : ''; // prepend a space if there are actually attributes\n return ['<', tagName, attrsStr, '>', this.getInnerHtml(), ''].join('');\n };\n /**\n * Support method for {@link #toAnchorString}, returns the string space-separated key=\"value\" pairs, used to populate\n * the stringified HtmlTag.\n *\n * @protected\n * @return {String} Example return: `attr1=\"value1\" attr2=\"value2\"`\n */\n HtmlTag.prototype.buildAttrsStr = function () {\n if (!this.attrs) return ''; // no `attrs` Object (map) has been set, return empty string\n var attrs = this.getAttrs(),\n attrsArr = [];\n for (var prop in attrs) {\n if (attrs.hasOwnProperty(prop)) {\n attrsArr.push(prop + '=\"' + attrs[prop] + '\"');\n }\n }\n return attrsArr.join(' ');\n };\n return HtmlTag;\n}();\nexport { HtmlTag };\n","/**\n * Date: 2015-10-05\n * Author: Kasper Søfren (https://github.com/kafoso)\n *\n * A truncation feature, where the ellipsis will be placed at a section within\n * the URL making it still somewhat human readable.\n *\n * @param {String} url\t\t\t\t\t\t A URL.\n * @param {Number} truncateLen\t\t The maximum length of the truncated output URL string.\n * @param {String} ellipsisChars\t The characters to place within the url, e.g. \"...\".\n * @return {String} The truncated URL.\n */\nexport function truncateSmart(url, truncateLen, ellipsisChars) {\n var ellipsisLengthBeforeParsing;\n var ellipsisLength;\n if (ellipsisChars == null) {\n ellipsisChars = '…';\n ellipsisLength = 3;\n ellipsisLengthBeforeParsing = 8;\n } else {\n ellipsisLength = ellipsisChars.length;\n ellipsisLengthBeforeParsing = ellipsisChars.length;\n }\n var parse_url = function (url) {\n // Functionality inspired by PHP function of same name\n var urlObj = {};\n var urlSub = url;\n var match = urlSub.match(/^([a-z]+):\\/\\//i);\n if (match) {\n urlObj.scheme = match[1];\n urlSub = urlSub.substr(match[0].length);\n }\n match = urlSub.match(/^(.*?)(?=(\\?|#|\\/|$))/i);\n if (match) {\n urlObj.host = match[1];\n urlSub = urlSub.substr(match[0].length);\n }\n match = urlSub.match(/^\\/(.*?)(?=(\\?|#|$))/i);\n if (match) {\n urlObj.path = match[1];\n urlSub = urlSub.substr(match[0].length);\n }\n match = urlSub.match(/^\\?(.*?)(?=(#|$))/i);\n if (match) {\n urlObj.query = match[1];\n urlSub = urlSub.substr(match[0].length);\n }\n match = urlSub.match(/^#(.*?)$/i);\n if (match) {\n urlObj.fragment = match[1];\n //urlSub = urlSub.substr(match[0].length); -- not used. Uncomment if adding another block.\n }\n return urlObj;\n };\n var buildUrl = function (urlObj) {\n var url = '';\n if (urlObj.scheme && urlObj.host) {\n url += urlObj.scheme + '://';\n }\n if (urlObj.host) {\n url += urlObj.host;\n }\n if (urlObj.path) {\n url += '/' + urlObj.path;\n }\n if (urlObj.query) {\n url += '?' + urlObj.query;\n }\n if (urlObj.fragment) {\n url += '#' + urlObj.fragment;\n }\n return url;\n };\n var buildSegment = function (segment, remainingAvailableLength) {\n var remainingAvailableLengthHalf = remainingAvailableLength / 2,\n startOffset = Math.ceil(remainingAvailableLengthHalf),\n endOffset = -1 * Math.floor(remainingAvailableLengthHalf),\n end = '';\n if (endOffset < 0) {\n end = segment.substr(endOffset);\n }\n return segment.substr(0, startOffset) + ellipsisChars + end;\n };\n if (url.length <= truncateLen) {\n return url;\n }\n var availableLength = truncateLen - ellipsisLength;\n var urlObj = parse_url(url);\n // Clean up the URL\n if (urlObj.query) {\n var matchQuery = urlObj.query.match(/^(.*?)(?=(\\?|\\#))(.*?)$/i);\n if (matchQuery) {\n // Malformed URL; two or more \"?\". Removed any content behind the 2nd.\n urlObj.query = urlObj.query.substr(0, matchQuery[1].length);\n url = buildUrl(urlObj);\n }\n }\n if (url.length <= truncateLen) {\n return url;\n }\n if (urlObj.host) {\n urlObj.host = urlObj.host.replace(/^www\\./, '');\n url = buildUrl(urlObj);\n }\n if (url.length <= truncateLen) {\n return url;\n }\n // Process and build the URL\n var str = '';\n if (urlObj.host) {\n str += urlObj.host;\n }\n if (str.length >= availableLength) {\n if (urlObj.host.length == truncateLen) {\n return (urlObj.host.substr(0, truncateLen - ellipsisLength) + ellipsisChars).substr(0, availableLength + ellipsisLengthBeforeParsing);\n }\n return buildSegment(str, availableLength).substr(0, availableLength + ellipsisLengthBeforeParsing);\n }\n var pathAndQuery = '';\n if (urlObj.path) {\n pathAndQuery += '/' + urlObj.path;\n }\n if (urlObj.query) {\n pathAndQuery += '?' + urlObj.query;\n }\n if (pathAndQuery) {\n if ((str + pathAndQuery).length >= availableLength) {\n if ((str + pathAndQuery).length == truncateLen) {\n return (str + pathAndQuery).substr(0, truncateLen);\n }\n var remainingAvailableLength = availableLength - str.length;\n return (str + buildSegment(pathAndQuery, remainingAvailableLength)).substr(0, availableLength + ellipsisLengthBeforeParsing);\n } else {\n str += pathAndQuery;\n }\n }\n if (urlObj.fragment) {\n var fragment = '#' + urlObj.fragment;\n if ((str + fragment).length >= availableLength) {\n if ((str + fragment).length == truncateLen) {\n return (str + fragment).substr(0, truncateLen);\n }\n var remainingAvailableLength2 = availableLength - str.length;\n return (str + buildSegment(fragment, remainingAvailableLength2)).substr(0, availableLength + ellipsisLengthBeforeParsing);\n } else {\n str += fragment;\n }\n }\n if (urlObj.scheme && urlObj.host) {\n var scheme = urlObj.scheme + '://';\n if ((str + scheme).length < availableLength) {\n return (scheme + str).substr(0, truncateLen);\n }\n }\n if (str.length <= truncateLen) {\n return str;\n }\n var end = '';\n if (availableLength > 0) {\n end = str.substr(-1 * Math.floor(availableLength / 2));\n }\n return (str.substr(0, Math.ceil(availableLength / 2)) + ellipsisChars + end).substr(0, availableLength + ellipsisLengthBeforeParsing);\n}\n","/**\n * Date: 2015-10-05\n * Author: Kasper Søfren (https://github.com/kafoso)\n *\n * A truncation feature, where the ellipsis will be placed in the dead-center of the URL.\n *\n * @param {String} url A URL.\n * @param {Number} truncateLen The maximum length of the truncated output URL string.\n * @param {String} ellipsisChars The characters to place within the url, e.g. \"..\".\n * @return {String} The truncated URL.\n */\nexport function truncateMiddle(url, truncateLen, ellipsisChars) {\n if (url.length <= truncateLen) {\n return url;\n }\n var ellipsisLengthBeforeParsing;\n var ellipsisLength;\n if (ellipsisChars == null) {\n ellipsisChars = '…';\n ellipsisLengthBeforeParsing = 8;\n ellipsisLength = 3;\n } else {\n ellipsisLengthBeforeParsing = ellipsisChars.length;\n ellipsisLength = ellipsisChars.length;\n }\n var availableLength = truncateLen - ellipsisLength;\n var end = '';\n if (availableLength > 0) {\n end = url.substr(-1 * Math.floor(availableLength / 2));\n }\n return (url.substr(0, Math.ceil(availableLength / 2)) + ellipsisChars + end).substr(0, availableLength + ellipsisLengthBeforeParsing);\n}\n","import { ellipsis } from '../utils';\n/**\n * A truncation feature where the ellipsis will be placed at the end of the URL.\n *\n * @param {String} anchorText\n * @param {Number} truncateLen The maximum length of the truncated output URL string.\n * @param {String} ellipsisChars The characters to place within the url, e.g. \"..\".\n * @return {String} The truncated URL.\n */\nexport function truncateEnd(anchorText, truncateLen, ellipsisChars) {\n return ellipsis(anchorText, truncateLen, ellipsisChars);\n}\n","import { HtmlTag } from './html-tag';\nimport { truncateSmart } from './truncate/truncate-smart';\nimport { truncateMiddle } from './truncate/truncate-middle';\nimport { truncateEnd } from './truncate/truncate-end';\n/**\n * @protected\n * @class Autolinker.AnchorTagBuilder\n * @extends Object\n *\n * Builds anchor (<a>) tags for the Autolinker utility when a match is\n * found.\n *\n * Normally this class is instantiated, configured, and used internally by an\n * {@link Autolinker} instance, but may actually be used indirectly in a\n * {@link Autolinker#replaceFn replaceFn} to create {@link Autolinker.HtmlTag HtmlTag}\n * instances which may be modified before returning from the\n * {@link Autolinker#replaceFn replaceFn}. For example:\n *\n * var html = Autolinker.link( \"Test google.com\", {\n * replaceFn : function( match ) {\n * var tag = match.buildTag(); // returns an {@link Autolinker.HtmlTag} instance\n * tag.setAttr( 'rel', 'nofollow' );\n *\n * return tag;\n * }\n * } );\n *\n * // generated html:\n * // Test google.com\n */\nvar AnchorTagBuilder = /** @class */function () {\n /**\n * @method constructor\n * @param {Object} [cfg] The configuration options for the AnchorTagBuilder instance, specified in an Object (map).\n */\n function AnchorTagBuilder(cfg) {\n if (cfg === void 0) {\n cfg = {};\n }\n /**\n * @cfg {Boolean} newWindow\n * @inheritdoc Autolinker#newWindow\n */\n this.newWindow = false; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @cfg {Object} truncate\n * @inheritdoc Autolinker#truncate\n */\n this.truncate = {}; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @cfg {String} className\n * @inheritdoc Autolinker#className\n */\n this.className = ''; // default value just to get the above doc comment in the ES5 output and documentation generator\n this.newWindow = cfg.newWindow || false;\n this.truncate = cfg.truncate || {};\n this.className = cfg.className || '';\n }\n /**\n * Generates the actual anchor (<a>) tag to use in place of the\n * matched text, via its `match` object.\n *\n * @param match The Match instance to generate an anchor tag from.\n * @return The HtmlTag instance for the anchor tag.\n */\n AnchorTagBuilder.prototype.build = function (match) {\n return new HtmlTag({\n tagName: 'a',\n attrs: this.createAttrs(match),\n innerHtml: this.processAnchorText(match.getAnchorText())\n });\n };\n /**\n * Creates the Object (map) of the HTML attributes for the anchor (<a>)\n * tag being generated.\n *\n * @protected\n * @param match The Match instance to generate an anchor tag from.\n * @return A key/value Object (map) of the anchor tag's attributes.\n */\n AnchorTagBuilder.prototype.createAttrs = function (match) {\n var attrs = {\n href: match.getAnchorHref() // we'll always have the `href` attribute\n };\n var cssClass = this.createCssClass(match);\n if (cssClass) {\n attrs['class'] = cssClass;\n }\n if (this.newWindow) {\n attrs['target'] = '_blank';\n attrs['rel'] = 'noopener noreferrer'; // Issue #149. See https://mathiasbynens.github.io/rel-noopener/\n }\n if (this.truncate) {\n if (this.truncate.length && this.truncate.length < match.getAnchorText().length) {\n attrs['title'] = match.getAnchorHref();\n }\n }\n return attrs;\n };\n /**\n * Creates the CSS class that will be used for a given anchor tag, based on\n * the `matchType` and the {@link #className} config.\n *\n * Example returns:\n *\n * - \"\" // no {@link #className}\n * - \"myLink myLink-url\" // url match\n * - \"myLink myLink-email\" // email match\n * - \"myLink myLink-phone\" // phone match\n * - \"myLink myLink-hashtag\" // hashtag match\n * - \"myLink myLink-mention myLink-twitter\" // mention match with Twitter service\n *\n * @protected\n * @param match The Match instance to generate an\n * anchor tag from.\n * @return The CSS class string for the link. Example return:\n * \"myLink myLink-url\". If no {@link #className} was configured, returns\n * an empty string.\n */\n AnchorTagBuilder.prototype.createCssClass = function (match) {\n var className = this.className;\n if (!className) {\n return '';\n } else {\n var returnClasses = [className],\n cssClassSuffixes = match.getCssClassSuffixes();\n for (var i = 0, len = cssClassSuffixes.length; i < len; i++) {\n returnClasses.push(className + '-' + cssClassSuffixes[i]);\n }\n return returnClasses.join(' ');\n }\n };\n /**\n * Processes the `anchorText` by truncating the text according to the\n * {@link #truncate} config.\n *\n * @private\n * @param anchorText The anchor tag's text (i.e. what will be\n * displayed).\n * @return The processed `anchorText`.\n */\n AnchorTagBuilder.prototype.processAnchorText = function (anchorText) {\n anchorText = this.doTruncate(anchorText);\n return anchorText;\n };\n /**\n * Performs the truncation of the `anchorText` based on the {@link #truncate}\n * option. If the `anchorText` is longer than the length specified by the\n * {@link #truncate} option, the truncation is performed based on the\n * `location` property. See {@link #truncate} for details.\n *\n * @private\n * @param anchorText The anchor tag's text (i.e. what will be\n * displayed).\n * @return The truncated anchor text.\n */\n AnchorTagBuilder.prototype.doTruncate = function (anchorText) {\n var truncate = this.truncate;\n if (!truncate || !truncate.length) return anchorText;\n var truncateLength = truncate.length,\n truncateLocation = truncate.location;\n if (truncateLocation === 'smart') {\n return truncateSmart(anchorText, truncateLength);\n } else if (truncateLocation === 'middle') {\n return truncateMiddle(anchorText, truncateLength);\n } else {\n return truncateEnd(anchorText, truncateLength);\n }\n };\n return AnchorTagBuilder;\n}();\nexport { AnchorTagBuilder };\n","/**\n * @abstract\n * @class Autolinker.match.AbstractMatch\n *\n * Represents a match found in an input string which should be Autolinked. A Match object is what is provided in a\n * {@link Autolinker#replaceFn replaceFn}, and may be used to query for details about the match.\n *\n * For example:\n *\n * var input = \"...\"; // string with URLs, Email Addresses, and Mentions (Twitter, Instagram, Soundcloud)\n *\n * var linkedText = Autolinker.link( input, {\n * replaceFn : function( match ) {\n * console.log( \"href = \", match.getAnchorHref() );\n * console.log( \"text = \", match.getAnchorText() );\n *\n * switch( match.getType() ) {\n * case 'url' :\n * console.log( \"url: \", match.getUrl() );\n *\n * case 'email' :\n * console.log( \"email: \", match.getEmail() );\n *\n * case 'mention' :\n * console.log( \"mention: \", match.getMention() );\n * }\n * }\n * } );\n *\n * See the {@link Autolinker} class for more details on using the {@link Autolinker#replaceFn replaceFn}.\n */\nvar AbstractMatch = /** @class */function () {\n /**\n * @member Autolinker.match.Match\n * @method constructor\n * @param {Object} cfg The configuration properties for the Match\n * instance, specified in an Object (map).\n */\n function AbstractMatch(cfg) {\n /**\n * @cfg {Autolinker.AnchorTagBuilder} tagBuilder (required)\n *\n * Reference to the AnchorTagBuilder instance to use to generate an anchor\n * tag for the Match.\n */\n // @ts-ignore\n this._ = null; // property used just to get the above doc comment into the ES5 output and documentation generator\n /**\n * @cfg {String} matchedText (required)\n *\n * The original text that was matched by the {@link Autolinker.matcher.Matcher}.\n */\n this.matchedText = ''; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @cfg {Number} offset (required)\n *\n * The offset of where the match was made in the input string.\n */\n this.offset = 0; // default value just to get the above doc comment in the ES5 output and documentation generator\n this.tagBuilder = cfg.tagBuilder;\n this.matchedText = cfg.matchedText;\n this.offset = cfg.offset;\n }\n /**\n * Returns the original text that was matched.\n *\n * @return {String}\n */\n AbstractMatch.prototype.getMatchedText = function () {\n return this.matchedText;\n };\n /**\n * Sets the {@link #offset} of where the match was made in the input string.\n *\n * A {@link Autolinker.matcher.Matcher} will be fed only HTML text nodes,\n * and will therefore set an original offset that is relative to the HTML\n * text node itself. However, we want this offset to be relative to the full\n * HTML input string, and thus if using {@link Autolinker#parse} (rather\n * than calling a {@link Autolinker.matcher.Matcher} directly), then this\n * offset is corrected after the Matcher itself has done its job.\n *\n * @private\n * @param {Number} offset\n */\n AbstractMatch.prototype.setOffset = function (offset) {\n this.offset = offset;\n };\n /**\n * Returns the offset of where the match was made in the input string. This\n * is the 0-based index of the match.\n *\n * @return {Number}\n */\n AbstractMatch.prototype.getOffset = function () {\n return this.offset;\n };\n /**\n * Returns the CSS class suffix(es) for this match.\n *\n * A CSS class suffix is appended to the {@link Autolinker#className} in\n * the {@link Autolinker.AnchorTagBuilder} when a match is translated into\n * an anchor tag.\n *\n * For example, if {@link Autolinker#className} was configured as 'myLink',\n * and this method returns `[ 'url' ]`, the final class name of the element\n * will become: 'myLink myLink-url'.\n *\n * The match may provide multiple CSS class suffixes to be appended to the\n * {@link Autolinker#className} in order to facilitate better styling\n * options for different match criteria. See {@link Autolinker.match.Mention}\n * for an example.\n *\n * By default, this method returns a single array with the match's\n * {@link #getType type} name, but may be overridden by subclasses.\n *\n * @return {String[]}\n */\n AbstractMatch.prototype.getCssClassSuffixes = function () {\n return [this.type];\n };\n /**\n * Builds and returns an {@link Autolinker.HtmlTag} instance based on the\n * Match.\n *\n * This can be used to easily generate anchor tags from matches, and either\n * return their HTML string, or modify them before doing so.\n *\n * Example Usage:\n *\n * var tag = match.buildTag();\n * tag.addClass( 'cordova-link' );\n * tag.setAttr( 'target', '_system' );\n *\n * tag.toAnchorString(); // Google\n *\n * Example Usage in {@link Autolinker#replaceFn}:\n *\n * var html = Autolinker.link( \"Test google.com\", {\n * replaceFn : function( match ) {\n * var tag = match.buildTag(); // returns an {@link Autolinker.HtmlTag} instance\n * tag.setAttr( 'rel', 'nofollow' );\n *\n * return tag;\n * }\n * } );\n *\n * // generated html:\n * // Test google.com\n */\n AbstractMatch.prototype.buildTag = function () {\n return this.tagBuilder.build(this);\n };\n return AbstractMatch;\n}();\nexport { AbstractMatch };\n","// NOTE: THIS IS A GENERATED FILE\n// To update with the latest TLD list, run `npm run update-tld-regex`\nexport var tldRegexStr = '(?:xn--vermgensberatung-pwb|xn--vermgensberater-ctb|xn--clchc0ea0b2g2a9gcd|xn--w4r85el8fhu5dnra|northwesternmutual|travelersinsurance|vermögensberatung|xn--5su34j936bgsg|xn--bck1b9a5dre4c|xn--mgbah1a3hjkrd|xn--mgbai9azgqp6j|xn--mgberp4a5d4ar|xn--xkc2dl3a5ee0h|vermögensberater|xn--fzys8d69uvgm|xn--mgba7c0bbn0a|xn--mgbcpq6gpa1a|xn--xkc2al3hye2a|americanexpress|kerryproperties|sandvikcoromant|xn--i1b6b1a6a2e|xn--kcrx77d1x4a|xn--lgbbat1ad8j|xn--mgba3a4f16a|xn--mgbaakc7dvf|xn--mgbc0a9azcg|xn--nqv7fs00ema|americanfamily|bananarepublic|cancerresearch|cookingchannel|kerrylogistics|weatherchannel|xn--54b7fta0cc|xn--6qq986b3xl|xn--80aqecdr1a|xn--b4w605ferd|xn--fiq228c5hs|xn--h2breg3eve|xn--jlq480n2rg|xn--jlq61u9w7b|xn--mgba3a3ejt|xn--mgbaam7a8h|xn--mgbayh7gpa|xn--mgbbh1a71e|xn--mgbca7dzdo|xn--mgbi4ecexp|xn--mgbx4cd0ab|xn--rvc1e0am3e|international|lifeinsurance|travelchannel|wolterskluwer|xn--cckwcxetd|xn--eckvdtc9d|xn--fpcrj9c3d|xn--fzc2c9e2c|xn--h2brj9c8c|xn--tiq49xqyj|xn--yfro4i67o|xn--ygbi2ammx|construction|lplfinancial|scholarships|versicherung|xn--3e0b707e|xn--45br5cyl|xn--4dbrk0ce|xn--80adxhks|xn--80asehdb|xn--8y0a063a|xn--gckr3f0f|xn--mgb9awbf|xn--mgbab2bd|xn--mgbgu82a|xn--mgbpl2fh|xn--mgbt3dhd|xn--mk1bu44c|xn--ngbc5azd|xn--ngbe9e0a|xn--ogbpf8fl|xn--qcka1pmc|accountants|barclaycard|blackfriday|blockbuster|bridgestone|calvinklein|contractors|creditunion|engineering|enterprises|foodnetwork|investments|kerryhotels|lamborghini|motorcycles|olayangroup|photography|playstation|productions|progressive|redumbrella|williamhill|xn--11b4c3d|xn--1ck2e1b|xn--1qqw23a|xn--2scrj9c|xn--3bst00m|xn--3ds443g|xn--3hcrj9c|xn--42c2d9a|xn--45brj9c|xn--55qw42g|xn--6frz82g|xn--80ao21a|xn--9krt00a|xn--cck2b3b|xn--czr694b|xn--d1acj3b|xn--efvy88h|xn--fct429k|xn--fjq720a|xn--flw351e|xn--g2xx48c|xn--gecrj9c|xn--gk3at1e|xn--h2brj9c|xn--hxt814e|xn--imr513n|xn--j6w193g|xn--jvr189m|xn--kprw13d|xn--kpry57d|xn--mgbbh1a|xn--mgbtx2b|xn--mix891f|xn--nyqy26a|xn--otu796d|xn--pgbs0dh|xn--q9jyb4c|xn--rhqv96g|xn--rovu88b|xn--s9brj9c|xn--ses554g|xn--t60b56a|xn--vuq861b|xn--w4rs40l|xn--xhq521b|xn--zfr164b|சிங்கப்பூர்|accountant|apartments|associates|basketball|bnpparibas|boehringer|capitalone|consulting|creditcard|cuisinella|eurovision|extraspace|foundation|healthcare|immobilien|industries|management|mitsubishi|nextdirect|properties|protection|prudential|realestate|republican|restaurant|schaeffler|tatamotors|technology|university|vlaanderen|volkswagen|xn--30rr7y|xn--3pxu8k|xn--45q11c|xn--4gbrim|xn--55qx5d|xn--5tzm5g|xn--80aswg|xn--90a3ac|xn--9dbq2a|xn--9et52u|xn--c2br7g|xn--cg4bki|xn--czrs0t|xn--czru2d|xn--fiq64b|xn--fiqs8s|xn--fiqz9s|xn--io0a7i|xn--kput3i|xn--mxtq1m|xn--o3cw4h|xn--pssy2u|xn--q7ce6a|xn--unup4y|xn--wgbh1c|xn--wgbl6a|xn--y9a3aq|accenture|alfaromeo|allfinanz|amsterdam|analytics|aquarelle|barcelona|bloomberg|christmas|community|directory|education|equipment|fairwinds|financial|firestone|fresenius|frontdoor|furniture|goldpoint|hisamitsu|homedepot|homegoods|homesense|institute|insurance|kuokgroup|lancaster|landrover|lifestyle|marketing|marshalls|melbourne|microsoft|panasonic|passagens|pramerica|richardli|shangrila|solutions|statebank|statefarm|stockholm|travelers|vacations|xn--90ais|xn--c1avg|xn--d1alf|xn--e1a4c|xn--fhbei|xn--j1aef|xn--j1amh|xn--l1acc|xn--ngbrx|xn--nqv7f|xn--p1acf|xn--qxa6a|xn--tckwe|xn--vhquv|yodobashi|موريتانيا|abudhabi|airforce|allstate|attorney|barclays|barefoot|bargains|baseball|boutique|bradesco|broadway|brussels|builders|business|capetown|catering|catholic|cipriani|cityeats|cleaning|clinique|clothing|commbank|computer|delivery|deloitte|democrat|diamonds|discount|discover|download|engineer|ericsson|etisalat|exchange|feedback|fidelity|firmdale|football|frontier|goodyear|grainger|graphics|guardian|hdfcbank|helsinki|holdings|hospital|infiniti|ipiranga|istanbul|jpmorgan|lighting|lundbeck|marriott|maserati|mckinsey|memorial|merckmsd|mortgage|observer|partners|pharmacy|pictures|plumbing|property|redstone|reliance|saarland|samsclub|security|services|shopping|showtime|softbank|software|stcgroup|supplies|training|vanguard|ventures|verisign|woodside|xn--90ae|xn--node|xn--p1ai|xn--qxam|yokohama|السعودية|abogado|academy|agakhan|alibaba|android|athleta|auction|audible|auspost|avianca|banamex|bauhaus|bentley|bestbuy|booking|brother|bugatti|capital|caravan|careers|channel|charity|chintai|citadel|clubmed|college|cologne|comcast|company|compare|contact|cooking|corsica|country|coupons|courses|cricket|cruises|dentist|digital|domains|exposed|express|farmers|fashion|ferrari|ferrero|finance|fishing|fitness|flights|florist|flowers|forsale|frogans|fujitsu|gallery|genting|godaddy|grocery|guitars|hamburg|hangout|hitachi|holiday|hosting|hoteles|hotmail|hyundai|ismaili|jewelry|juniper|kitchen|komatsu|lacaixa|lanxess|lasalle|latrobe|leclerc|limited|lincoln|markets|monster|netbank|netflix|network|neustar|okinawa|oldnavy|organic|origins|philips|pioneer|politie|realtor|recipes|rentals|reviews|rexroth|samsung|sandvik|schmidt|schwarz|science|shiksha|singles|staples|storage|support|surgery|systems|temasek|theater|theatre|tickets|tiffany|toshiba|trading|walmart|wanggou|watches|weather|website|wedding|whoswho|windows|winners|xfinity|yamaxun|youtube|zuerich|католик|اتصالات|البحرين|الجزائر|العليان|پاکستان|كاثوليك|இந்தியா|abarth|abbott|abbvie|africa|agency|airbus|airtel|alipay|alsace|alstom|amazon|anquan|aramco|author|bayern|beauty|berlin|bharti|bostik|boston|broker|camera|career|casino|center|chanel|chrome|church|circle|claims|clinic|coffee|comsec|condos|coupon|credit|cruise|dating|datsun|dealer|degree|dental|design|direct|doctor|dunlop|dupont|durban|emerck|energy|estate|events|expert|family|flickr|futbol|gallup|garden|george|giving|global|google|gratis|health|hermes|hiphop|hockey|hotels|hughes|imamat|insure|intuit|jaguar|joburg|juegos|kaufen|kinder|kindle|kosher|lancia|latino|lawyer|lefrak|living|locker|london|luxury|madrid|maison|makeup|market|mattel|mobile|monash|mormon|moscow|museum|mutual|nagoya|natura|nissan|nissay|norton|nowruz|office|olayan|online|oracle|orange|otsuka|pfizer|photos|physio|pictet|quebec|racing|realty|reisen|repair|report|review|rocher|rogers|ryukyu|safety|sakura|sanofi|school|schule|search|secure|select|shouji|soccer|social|stream|studio|supply|suzuki|swatch|sydney|taipei|taobao|target|tattoo|tennis|tienda|tjmaxx|tkmaxx|toyota|travel|unicom|viajes|viking|villas|virgin|vision|voting|voyage|vuelos|walter|webcam|xihuan|yachts|yandex|zappos|москва|онлайн|ابوظبي|ارامكو|الاردن|المغرب|امارات|فلسطين|مليسيا|भारतम्|இலங்கை|ファッション|actor|adult|aetna|amfam|amica|apple|archi|audio|autos|azure|baidu|beats|bible|bingo|black|boats|bosch|build|canon|cards|chase|cheap|cisco|citic|click|cloud|coach|codes|crown|cymru|dabur|dance|deals|delta|drive|dubai|earth|edeka|email|epson|faith|fedex|final|forex|forum|gallo|games|gifts|gives|glass|globo|gmail|green|gripe|group|gucci|guide|homes|honda|horse|house|hyatt|ikano|irish|jetzt|koeln|kyoto|lamer|lease|legal|lexus|lilly|linde|lipsy|loans|locus|lotte|lotto|macys|mango|media|miami|money|movie|music|nexus|nikon|ninja|nokia|nowtv|omega|osaka|paris|parts|party|phone|photo|pizza|place|poker|praxi|press|prime|promo|quest|radio|rehab|reise|ricoh|rocks|rodeo|rugby|salon|sener|seven|sharp|shell|shoes|skype|sling|smart|smile|solar|space|sport|stada|store|study|style|sucks|swiss|tatar|tires|tirol|tmall|today|tokyo|tools|toray|total|tours|trade|trust|tunes|tushu|ubank|vegas|video|vodka|volvo|wales|watch|weber|weibo|works|world|xerox|yahoo|ישראל|ایران|بازار|بھارت|سودان|سورية|همراه|भारोत|संगठन|বাংলা|భారత్|ഭാരതം|嘉里大酒店|aarp|able|adac|aero|akdn|ally|amex|arab|army|arpa|arte|asda|asia|audi|auto|baby|band|bank|bbva|beer|best|bike|bing|blog|blue|bofa|bond|book|buzz|cafe|call|camp|care|cars|casa|case|cash|cbre|cern|chat|citi|city|club|cool|coop|cyou|data|date|dclk|deal|dell|desi|diet|dish|docs|dvag|erni|fage|fail|fans|farm|fast|fiat|fido|film|fire|fish|flir|food|ford|free|fund|game|gbiz|gent|ggee|gift|gmbh|gold|golf|goog|guge|guru|hair|haus|hdfc|help|here|hgtv|host|hsbc|icbc|ieee|imdb|immo|info|itau|java|jeep|jobs|jprs|kddi|kids|kiwi|kpmg|kred|land|lego|lgbt|lidl|life|like|limo|link|live|loan|loft|love|ltda|luxe|maif|meet|meme|menu|mini|mint|mobi|moda|moto|name|navy|news|next|nico|nike|ollo|open|page|pars|pccw|pics|ping|pink|play|plus|pohl|porn|post|prod|prof|qpon|read|reit|rent|rest|rich|room|rsvp|ruhr|safe|sale|sarl|save|saxo|scot|seat|seek|sexy|shaw|shia|shop|show|silk|sina|site|skin|sncf|sohu|song|sony|spot|star|surf|talk|taxi|team|tech|teva|tiaa|tips|town|toys|tube|vana|visa|viva|vivo|vote|voto|wang|weir|wien|wiki|wine|work|xbox|yoga|zara|zero|zone|дети|сайт|بارت|بيتك|ڀارت|تونس|شبكة|عراق|عمان|موقع|भारत|ভারত|ভাৰত|ਭਾਰਤ|ભારત|ଭାରତ|ಭಾರತ|ලංකා|アマゾン|グーグル|クラウド|ポイント|组织机构|電訊盈科|香格里拉|aaa|abb|abc|aco|ads|aeg|afl|aig|anz|aol|app|art|aws|axa|bar|bbc|bbt|bcg|bcn|bet|bid|bio|biz|bms|bmw|bom|boo|bot|box|buy|bzh|cab|cal|cam|car|cat|cba|cbn|cbs|ceo|cfa|cfd|com|cpa|crs|dad|day|dds|dev|dhl|diy|dnp|dog|dot|dtv|dvr|eat|eco|edu|esq|eus|fan|fit|fly|foo|fox|frl|ftr|fun|fyi|gal|gap|gay|gdn|gea|gle|gmo|gmx|goo|gop|got|gov|hbo|hiv|hkt|hot|how|ibm|ice|icu|ifm|inc|ing|ink|int|ist|itv|jcb|jio|jll|jmp|jnj|jot|joy|kfh|kia|kim|kpn|krd|lat|law|lds|llc|llp|lol|lpl|ltd|man|map|mba|med|men|mil|mit|mlb|mls|mma|moe|moi|mom|mov|msd|mtn|mtr|nab|nba|nec|net|new|nfl|ngo|nhk|now|nra|nrw|ntt|nyc|obi|one|ong|onl|ooo|org|ott|ovh|pay|pet|phd|pid|pin|pnc|pro|pru|pub|pwc|red|ren|ril|rio|rip|run|rwe|sap|sas|sbi|sbs|sca|scb|ses|sew|sex|sfr|ski|sky|soy|spa|srl|stc|tab|tax|tci|tdk|tel|thd|tjx|top|trv|tui|tvs|ubs|uno|uol|ups|vet|vig|vin|vip|wed|win|wme|wow|wtc|wtf|xin|xxx|xyz|you|yun|zip|бел|ком|қаз|мкд|мон|орг|рус|срб|укр|հայ|קום|عرب|قطر|كوم|مصر|कॉम|नेट|คอม|ไทย|ລາວ|ストア|セール|みんな|中文网|亚马逊|天主教|我爱你|新加坡|淡马锡|诺基亚|飞利浦|ac|ad|ae|af|ag|ai|al|am|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cw|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw|ελ|ευ|бг|ею|рф|გე|닷넷|닷컴|삼성|한국|コム|世界|中信|中国|中國|企业|佛山|信息|健康|八卦|公司|公益|台湾|台灣|商城|商店|商标|嘉里|在线|大拿|娱乐|家電|广东|微博|慈善|手机|招聘|政务|政府|新闻|时尚|書籍|机构|游戏|澳門|点看|移动|网址|网店|网站|网络|联通|谷歌|购物|通販|集团|食品|餐厅|香港)';\nexport var tldRegex = new RegExp('^' + tldRegexStr + '$');\n","import { alphaNumericAndMarksRe, letterRe, digitRe } from '../regex-lib';\nimport { tldRegex } from './tld-regex';\n/**\n * A regular expression that is simply the character class of the characters\n * that may be used in a domain name, minus the '-' or '.'\n */\nexport var domainNameCharRegex = alphaNumericAndMarksRe;\n/**\n * The set of characters that will start a URL suffix (i.e. the path, query, and\n * hash part of the URL)\n */\nexport var urlSuffixStartCharsRe = /[\\/?#]/;\n/**\n * The set of characters that are allowed in the URL suffix (i.e. the path,\n * query, and hash part of the URL) which may also form the ending character of\n * the URL.\n *\n * The {@link #urlSuffixNotAllowedAsLastCharRe} are additional allowed URL\n * suffix characters, but (generally) should not be the last character of a URL.\n */\nexport var urlSuffixAllowedSpecialCharsRe = /[-+&@#/%=~_()|'$*\\[\\]{}\\u2713]/;\n/**\n * URL suffix characters (i.e. path, query, and has part of the URL) that are\n * not allowed as the *last character* in the URL suffix as they would normally\n * form the end of a sentence.\n *\n * The {@link #urlSuffixAllowedSpecialCharsRe} contains additional allowed URL\n * suffix characters which are allowed as the last character.\n */\nexport var urlSuffixNotAllowedAsLastCharRe = /[?!:,.;^]/;\n/**\n * Regular expression to match an http:// or https:// scheme.\n */\nexport var httpSchemeRe = /https?:\\/\\//i;\n/**\n * Regular expression to match an http:// or https:// scheme as the prefix of\n * a string.\n */\nexport var httpSchemePrefixRe = new RegExp('^' + httpSchemeRe.source, 'i');\nexport var urlSuffixedCharsNotAllowedAtEndRe = new RegExp(urlSuffixNotAllowedAsLastCharRe.source + '$');\n/**\n * A regular expression used to determine the schemes we should not autolink\n */\nexport var invalidSchemeRe = /^(javascript|vbscript):/i;\n// A regular expression used to determine if the URL is a scheme match (such as\n// 'http://google.com', and as opposed to a \"TLD match\"). This regular\n// expression is used to parse out the host along with if the URL has an\n// authority component (i.e. '//')\n//\n// Capturing groups:\n// 1. '//' if the URL has an authority component, empty string otherwise\n// 2. The host (if one exists). Ex: 'google.com'\n//\n// See https://www.rfc-editor.org/rfc/rfc3986#appendix-A for terminology\nexport var schemeUrlRe = /^[A-Za-z][-.+A-Za-z0-9]*:(\\/\\/)?([^:/]*)/;\n// A regular expression used to determine if the URL is a TLD match (such as\n// 'google.com', and as opposed to a \"scheme match\"). This regular\n// expression is used to help parse out the TLD (top-level domain) of the host.\n//\n// See https://www.rfc-editor.org/rfc/rfc3986#appendix-A for terminology\nexport var tldUrlHostRe = /^(?:\\/\\/)?([^/#?:]+)/; // optionally prefixed with protocol-relative '//' chars\n/**\n * Determines if the given character may start a scheme (ex: 'http').\n */\nexport function isSchemeStartChar(char) {\n return letterRe.test(char);\n}\n/**\n * Determines if the given character is a valid character in a scheme (such as\n * 'http' or 'ssh+git'), but only after the start char (which is handled by\n * {@link isSchemeStartChar}.\n */\nexport function isSchemeChar(char) {\n return letterRe.test(char) || digitRe.test(char) || char === '+' || char === '-' || char === '.';\n}\n/**\n * Determines if the character can begin a domain label, which must be an\n * alphanumeric character and not an underscore or dash.\n *\n * A domain label is a segment of a hostname such as subdomain.google.com.\n */\nexport function isDomainLabelStartChar(char) {\n return alphaNumericAndMarksRe.test(char);\n}\n/**\n * Determines if the character is part of a domain label (but not a domain label\n * start character).\n *\n * A domain label is a segment of a hostname such as subdomain.google.com.\n */\nexport function isDomainLabelChar(char) {\n return char === '_' || isDomainLabelStartChar(char);\n}\n/**\n * Determines if the character is a path character (\"pchar\") as defined by\n * https://tools.ietf.org/html/rfc3986#appendix-A\n *\n * pchar = unreserved / pct-encoded / sub-delims / \":\" / \"@\"\n *\n * unreserved = ALPHA / DIGIT / \"-\" / \".\" / \"_\" / \"~\"\n * pct-encoded = \"%\" HEXDIG HEXDIG\n * sub-delims = \"!\" / \"$\" / \"&\" / \"'\" / \"(\" / \")\"\n * / \"*\" / \"+\" / \",\" / \";\" / \"=\"\n *\n * Note that this implementation doesn't follow the spec exactly, but rather\n * follows URL path characters found out in the wild (spec might be out of date?)\n */\nexport function isPathChar(char) {\n return alphaNumericAndMarksRe.test(char) || urlSuffixAllowedSpecialCharsRe.test(char) || urlSuffixNotAllowedAsLastCharRe.test(char);\n}\n/**\n * Determines if the character given may begin the \"URL Suffix\" section of a\n * URI (i.e. the path, query, or hash section). These are the '/', '?' and '#'\n * characters.\n *\n * See https://tools.ietf.org/html/rfc3986#appendix-A\n */\nexport function isUrlSuffixStartChar(char) {\n return urlSuffixStartCharsRe.test(char);\n}\n/**\n * Determines if the TLD read in the host is a known TLD (Top-Level Domain).\n *\n * Example: 'com' would be a known TLD (for a host of 'google.com'), but\n * 'local' would not (for a domain name of 'my-computer.local').\n */\nexport function isKnownTld(tld) {\n return tldRegex.test(tld.toLowerCase()); // make sure the tld is lowercase for the regex\n}\n/**\n * Determines if the given `url` is a valid scheme-prefixed URL.\n */\nexport function isValidSchemeUrl(url) {\n // If the scheme is 'javascript:' or 'vbscript:', these link\n // types can be dangerous. Don't link them.\n if (invalidSchemeRe.test(url)) {\n return false;\n }\n var schemeMatch = url.match(schemeUrlRe);\n if (!schemeMatch) {\n return false;\n }\n var isAuthorityMatch = !!schemeMatch[1];\n var host = schemeMatch[2];\n if (isAuthorityMatch) {\n // Any match that has an authority ('//' chars) after the scheme is\n // valid, such as 'http://anything'\n return true;\n }\n // If there's no authority ('//' chars), check that we have a hostname\n // that looks valid.\n //\n // The host must contain at least one '.' char and have a domain label\n // with at least one letter to be considered valid.\n //\n // Accept:\n // - git:domain.com (scheme followed by a host\n // Do not accept:\n // - git:something ('something' doesn't look like a host)\n // - version:1.0 ('1.0' doesn't look like a host)\n if (host.indexOf('.') === -1 || !letterRe.test(host)) {\n return false;\n }\n return true;\n}\n/**\n * Determines if the given `url` is a match with a valid TLD.\n */\nexport function isValidTldMatch(url) {\n // TLD URL such as 'google.com', we need to confirm that we have a valid\n // top-level domain\n var tldUrlHostMatch = url.match(tldUrlHostRe);\n if (!tldUrlHostMatch) {\n // At this point, if the URL didn't match our TLD re, it must be invalid\n // (highly unlikely to happen, but just in case)\n return false;\n }\n var host = tldUrlHostMatch[0];\n var hostLabels = host.split('.');\n if (hostLabels.length < 2) {\n // 0 or 1 host label, there's no TLD. Ex: 'localhost'\n return false;\n }\n var tld = hostLabels[hostLabels.length - 1];\n if (!isKnownTld(tld)) {\n return false;\n }\n // TODO: Implement these conditions for TLD matcher:\n // (\n // this.longestDomainLabelLength <= 63 &&\n // this.domainNameLength <= 255\n // );\n return true;\n}\n// Regular expression to confirm a valid IPv4 address (ex: '192.168.0.1')\nvar ipV4Re = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;\n// Regular expression used to split the IPv4 address itself from any port/path/query/hash\nvar ipV4PartRe = /[:/?#]/;\n/**\n * Determines if the given URL is a valid IPv4-prefixed URL.\n */\nexport function isValidIpV4Address(url) {\n // Grab just the IP address\n var ipV4Part = url.split(ipV4PartRe, 1)[0]; // only 1 result needed\n return ipV4Re.test(ipV4Part);\n}\n","import { __extends } from \"tslib\";\nimport { AbstractMatch } from './abstract-match';\nimport { httpSchemePrefixRe } from '../parser/uri-utils';\n/**\n * A regular expression used to remove the 'www.' from URLs.\n */\nvar wwwPrefixRegex = /^(https?:\\/\\/)?(www\\.)?/i;\n/**\n * The regular expression used to remove the protocol-relative '//' from a URL\n * string, for purposes of formatting the anchor text. A protocol-relative URL\n * is, for example, \"//yahoo.com\"\n */\nvar protocolRelativeRegex = /^\\/\\//;\n/**\n * @class Autolinker.match.Url\n * @extends Autolinker.match.AbstractMatch\n *\n * Represents a Url match found in an input string which should be Autolinked.\n *\n * See this class's superclass ({@link Autolinker.match.Match}) for more details.\n */\nvar UrlMatch = /** @class */function (_super) {\n __extends(UrlMatch, _super);\n /**\n * @method constructor\n * @param {Object} cfg The configuration properties for the Match\n * instance, specified in an Object (map).\n */\n function UrlMatch(cfg) {\n var _this = _super.call(this, cfg) || this;\n /**\n * @public\n * @property {'url'} type\n *\n * A string name for the type of match that this class represents. Can be\n * used in a TypeScript discriminating union to type-narrow from the\n * `Match` type.\n */\n _this.type = 'url';\n /**\n * @cfg {String} url (required)\n *\n * The url that was matched.\n */\n _this.url = ''; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @cfg {\"scheme\"/\"www\"/\"tld\"} urlMatchType (required)\n *\n * The type of URL match that this class represents. This helps to determine\n * if the match was made in the original text with a prefixed scheme (ex:\n * 'http://www.google.com'), a prefixed 'www' (ex: 'www.google.com'), or\n * was matched by a known top-level domain (ex: 'google.com').\n */\n _this.urlMatchType = 'scheme'; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @cfg {Boolean} protocolRelativeMatch (required)\n *\n * `true` if the URL is a protocol-relative match. A protocol-relative match\n * is a URL that starts with '//', and will be either http:// or https://\n * based on the protocol that the site is loaded under.\n */\n _this.protocolRelativeMatch = false; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @cfg {Object} stripPrefix (required)\n *\n * The Object form of {@link Autolinker#cfg-stripPrefix}.\n */\n _this.stripPrefix = {\n scheme: true,\n www: true\n }; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @cfg {Boolean} stripTrailingSlash (required)\n * @inheritdoc Autolinker#cfg-stripTrailingSlash\n */\n _this.stripTrailingSlash = true; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @cfg {Boolean} decodePercentEncoding (required)\n * @inheritdoc Autolinker#cfg-decodePercentEncoding\n */\n _this.decodePercentEncoding = true; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @private\n * @property {Boolean} protocolPrepended\n *\n * Will be set to `true` if the 'http://' protocol has been prepended to the {@link #url} (because the\n * {@link #url} did not have a protocol)\n */\n _this.protocolPrepended = false;\n _this.urlMatchType = cfg.urlMatchType;\n _this.url = cfg.url;\n _this.protocolRelativeMatch = cfg.protocolRelativeMatch;\n _this.stripPrefix = cfg.stripPrefix;\n _this.stripTrailingSlash = cfg.stripTrailingSlash;\n _this.decodePercentEncoding = cfg.decodePercentEncoding;\n return _this;\n }\n /**\n * Returns a string name for the type of match that this class represents.\n * For the case of UrlMatch, returns 'url'.\n *\n * @return {String}\n */\n UrlMatch.prototype.getType = function () {\n return 'url';\n };\n /**\n * Returns a string name for the type of URL match that this class\n * represents.\n *\n * This helps to determine if the match was made in the original text with a\n * prefixed scheme (ex: 'http://www.google.com'), a prefixed 'www' (ex:\n * 'www.google.com'), or was matched by a known top-level domain (ex:\n * 'google.com').\n *\n * @return {\"scheme\"/\"www\"/\"tld\"}\n */\n UrlMatch.prototype.getUrlMatchType = function () {\n return this.urlMatchType;\n };\n /**\n * Returns the url that was matched, assuming the protocol to be 'http://' if the original\n * match was missing a protocol.\n *\n * @return {String}\n */\n UrlMatch.prototype.getUrl = function () {\n var url = this.url;\n // if the url string doesn't begin with a scheme, assume 'http://'\n if (!this.protocolRelativeMatch && this.urlMatchType !== 'scheme' && !this.protocolPrepended) {\n url = this.url = 'http://' + url;\n this.protocolPrepended = true;\n }\n return url;\n };\n /**\n * Returns the anchor href that should be generated for the match.\n *\n * @return {String}\n */\n UrlMatch.prototype.getAnchorHref = function () {\n var url = this.getUrl();\n return url.replace(/&/g, '&'); // any &'s in the URL should be converted back to '&' if they were displayed as & in the source html\n };\n /**\n * Returns the anchor text that should be generated for the match.\n *\n * @return {String}\n */\n UrlMatch.prototype.getAnchorText = function () {\n var anchorText = this.getMatchedText();\n if (this.protocolRelativeMatch) {\n // Strip off any protocol-relative '//' from the anchor text\n anchorText = stripProtocolRelativePrefix(anchorText);\n }\n if (this.stripPrefix.scheme) {\n anchorText = stripSchemePrefix(anchorText);\n }\n if (this.stripPrefix.www) {\n anchorText = stripWwwPrefix(anchorText);\n }\n if (this.stripTrailingSlash) {\n anchorText = removeTrailingSlash(anchorText); // remove trailing slash, if there is one\n }\n if (this.decodePercentEncoding) {\n anchorText = removePercentEncoding(anchorText);\n }\n return anchorText;\n };\n return UrlMatch;\n}(AbstractMatch);\nexport { UrlMatch };\n// Utility Functionality\n/**\n * Strips the scheme prefix (such as \"http://\" or \"https://\") from the given\n * `url`.\n *\n * @private\n * @param {String} url The text of the anchor that is being generated, for\n * which to strip off the url scheme.\n * @return {String} The `url`, with the scheme stripped.\n */\nfunction stripSchemePrefix(url) {\n return url.replace(httpSchemePrefixRe, '');\n}\n/**\n * Strips the 'www' prefix from the given `url`.\n *\n * @private\n * @param {String} url The text of the anchor that is being generated, for\n * which to strip off the 'www' if it exists.\n * @return {String} The `url`, with the 'www' stripped.\n */\nfunction stripWwwPrefix(url) {\n return url.replace(wwwPrefixRegex, '$1'); // leave any scheme ($1), it one exists\n}\n/**\n * Strips any protocol-relative '//' from the anchor text.\n *\n * @private\n * @param {String} text The text of the anchor that is being generated, for which to strip off the\n * protocol-relative prefix (such as stripping off \"//\")\n * @return {String} The `anchorText`, with the protocol-relative prefix stripped.\n */\nfunction stripProtocolRelativePrefix(text) {\n return text.replace(protocolRelativeRegex, '');\n}\n/**\n * Removes any trailing slash from the given `anchorText`, in preparation for the text to be displayed.\n *\n * @private\n * @param {String} anchorText The text of the anchor that is being generated, for which to remove any trailing\n * slash ('/') that may exist.\n * @return {String} The `anchorText`, with the trailing slash removed.\n */\nfunction removeTrailingSlash(anchorText) {\n if (anchorText.charAt(anchorText.length - 1) === '/') {\n anchorText = anchorText.slice(0, -1);\n }\n return anchorText;\n}\n/**\n * Decodes percent-encoded characters from the given `anchorText`, in\n * preparation for the text to be displayed.\n *\n * @private\n * @param {String} anchorText The text of the anchor that is being\n * generated, for which to decode any percent-encoded characters.\n * @return {String} The `anchorText`, with the percent-encoded characters\n * decoded.\n */\nfunction removePercentEncoding(anchorText) {\n // First, convert a few of the known % encodings to the corresponding\n // HTML entities that could accidentally be interpretted as special\n // HTML characters\n var preProcessedEntityAnchorText = anchorText.replace(/%22/gi, '"') // \" char\n .replace(/%26/gi, '&') // & char\n .replace(/%27/gi, ''') // ' char\n .replace(/%3C/gi, '<') // < char\n .replace(/%3E/gi, '>'); // > char\n try {\n // Now attempt to decode the rest of the anchor text\n return decodeURIComponent(preProcessedEntityAnchorText);\n } catch (e) {\n // Invalid % escape sequence in the anchor text\n return preProcessedEntityAnchorText;\n }\n}\n","import { alphaNumericAndMarksCharsStr, alphaNumericAndMarksRe } from '../regex-lib';\nimport { isKnownTld } from './uri-utils';\n/**\n * A regular expression to match a 'mailto:' prefix on an email address.\n */\nexport var mailtoSchemePrefixRe = /^mailto:/i;\n/**\n * Regular expression for all of the valid characters of the local part of an\n * email address.\n */\nvar emailLocalPartCharRegex = new RegExp(\"[\".concat(alphaNumericAndMarksCharsStr, \"!#$%&'*+/=?^_`{|}~-]\"));\n/**\n * Determines if the given character may start the \"local part\" of an email\n * address. The local part is the part to the left of the '@' sign.\n *\n * Technically according to the email spec, any of the characters in the\n * {@link emailLocalPartCharRegex} can start an email address (including any of\n * the special characters), but this is so rare in the wild and the\n * implementation is much simpler by only starting an email address with a word\n * character. This is especially important when matching the '{' character which\n * generally starts a brace that isn't part of the email address.\n */\nexport function isEmailLocalPartStartChar(char) {\n return alphaNumericAndMarksRe.test(char);\n}\n/**\n * Determines if the given character can be part of the \"local part\" of an email\n * address. The local part is the part to the left of the '@' sign.\n */\nexport function isEmailLocalPartChar(char) {\n return emailLocalPartCharRegex.test(char);\n}\n/**\n * Determines if the given email address is valid. We consider it valid if it\n * has a valid TLD in its host.\n *\n * @param emailAddress email address\n * @return true is email have valid TLD, false otherwise\n */\nexport function isValidEmail(emailAddress) {\n var emailAddressTld = emailAddress.split('.').pop() || '';\n return isKnownTld(emailAddressTld);\n}\n","import { __extends } from \"tslib\";\nimport { AbstractMatch } from './abstract-match';\n/**\n * @class Autolinker.match.Email\n * @extends Autolinker.match.AbstractMatch\n *\n * Represents a Email match found in an input string which should be Autolinked.\n *\n * See this class's superclass ({@link Autolinker.match.Match}) for more details.\n */\nvar EmailMatch = /** @class */function (_super) {\n __extends(EmailMatch, _super);\n /**\n * @method constructor\n * @param {Object} cfg The configuration properties for the Match\n * instance, specified in an Object (map).\n */\n function EmailMatch(cfg) {\n var _this = _super.call(this, cfg) || this;\n /**\n * @public\n * @property {'email'} type\n *\n * A string name for the type of match that this class represents. Can be\n * used in a TypeScript discriminating union to type-narrow from the\n * `Match` type.\n */\n _this.type = 'email';\n /**\n * @cfg {String} email (required)\n *\n * The email address that was matched.\n */\n _this.email = ''; // default value just to get the above doc comment in the ES5 output and documentation generator\n _this.email = cfg.email;\n return _this;\n }\n /**\n * Returns a string name for the type of match that this class represents.\n * For the case of EmailMatch, returns 'email'.\n *\n * @return {String}\n */\n EmailMatch.prototype.getType = function () {\n return 'email';\n };\n /**\n * Returns the email address that was matched.\n *\n * @return {String}\n */\n EmailMatch.prototype.getEmail = function () {\n return this.email;\n };\n /**\n * Returns the anchor href that should be generated for the match.\n *\n * @return {String}\n */\n EmailMatch.prototype.getAnchorHref = function () {\n return 'mailto:' + this.email;\n };\n /**\n * Returns the anchor text that should be generated for the match.\n *\n * @return {String}\n */\n EmailMatch.prototype.getAnchorText = function () {\n return this.email;\n };\n return EmailMatch;\n}(AbstractMatch);\nexport { EmailMatch };\n","import { alphaNumericAndMarksRe } from '../regex-lib';\n/**\n * Determines if the given `char` is a an allowed character in a hashtag. These\n * are underscores or any alphanumeric char.\n */\nexport function isHashtagTextChar(char) {\n return char === '_' || alphaNumericAndMarksRe.test(char);\n}\n/**\n * Determines if a hashtag match is valid.\n */\nexport function isValidHashtag(hashtag) {\n // Max length of 140 for a hashtag ('#' char + 139 word chars)\n return hashtag.length <= 140;\n}\nexport var hashtagServices = ['twitter', 'facebook', 'instagram', 'tiktok'];\n","import { __extends } from \"tslib\";\nimport { assertNever } from '../utils';\nimport { AbstractMatch } from './abstract-match';\n/**\n * @class Autolinker.match.Hashtag\n * @extends Autolinker.match.AbstractMatch\n *\n * Represents a Hashtag match found in an input string which should be\n * Autolinked.\n *\n * See this class's superclass ({@link Autolinker.match.Match}) for more\n * details.\n */\nvar HashtagMatch = /** @class */function (_super) {\n __extends(HashtagMatch, _super);\n /**\n * @method constructor\n * @param {Object} cfg The configuration properties for the Match\n * instance, specified in an Object (map).\n */\n function HashtagMatch(cfg) {\n var _this = _super.call(this, cfg) || this;\n /**\n * @public\n * @property {'hashtag'} type\n *\n * A string name for the type of match that this class represents. Can be\n * used in a TypeScript discriminating union to type-narrow from the\n * `Match` type.\n */\n _this.type = 'hashtag';\n /**\n * @cfg {String} serviceName\n *\n * The service to point hashtag matches to. See {@link Autolinker#hashtag}\n * for available values.\n */\n _this.serviceName = 'twitter'; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @cfg {String} hashtag (required)\n *\n * The HashtagMatch that was matched, without the '#'.\n */\n _this.hashtag = ''; // default value just to get the above doc comment in the ES5 output and documentation generator\n _this.serviceName = cfg.serviceName;\n _this.hashtag = cfg.hashtag;\n return _this;\n }\n /**\n * Returns a string name for the type of match that this class represents.\n * For the case of HashtagMatch, returns 'hashtag'.\n *\n * @return {String}\n */\n HashtagMatch.prototype.getType = function () {\n return 'hashtag';\n };\n /**\n * Returns the configured {@link #serviceName} to point the HashtagMatch to.\n * Ex: 'facebook', 'twitter'.\n *\n * @return {String}\n */\n HashtagMatch.prototype.getServiceName = function () {\n return this.serviceName;\n };\n /**\n * Returns the matched hashtag, without the '#' character.\n *\n * @return {String}\n */\n HashtagMatch.prototype.getHashtag = function () {\n return this.hashtag;\n };\n /**\n * Returns the anchor href that should be generated for the match.\n *\n * @return {String}\n */\n HashtagMatch.prototype.getAnchorHref = function () {\n var serviceName = this.serviceName,\n hashtag = this.hashtag;\n switch (serviceName) {\n case 'twitter':\n return 'https://twitter.com/hashtag/' + hashtag;\n case 'facebook':\n return 'https://www.facebook.com/hashtag/' + hashtag;\n case 'instagram':\n return 'https://instagram.com/explore/tags/' + hashtag;\n case 'tiktok':\n return 'https://www.tiktok.com/tag/' + hashtag;\n default:\n // Shouldn't happen because Autolinker's constructor should block any invalid values, but just in case\n assertNever(serviceName);\n throw new Error(\"Invalid hashtag service: \".concat(serviceName));\n }\n };\n /**\n * Returns the anchor text that should be generated for the match.\n *\n * @return {String}\n */\n HashtagMatch.prototype.getAnchorText = function () {\n return '#' + this.hashtag;\n };\n /**\n * Returns the CSS class suffixes that should be used on a tag built with\n * the match. See {@link Autolinker.match.Match#getCssClassSuffixes} for\n * details.\n *\n * @return {String[]}\n */\n HashtagMatch.prototype.getCssClassSuffixes = function () {\n var cssClassSuffixes = _super.prototype.getCssClassSuffixes.call(this),\n serviceName = this.getServiceName();\n if (serviceName) {\n cssClassSuffixes.push(serviceName);\n }\n return cssClassSuffixes;\n };\n return HashtagMatch;\n}(AbstractMatch);\nexport { HashtagMatch };\n","var mentionRegexes = {\n twitter: /^@\\w{1,15}$/,\n instagram: /^@[_\\w]{1,30}$/,\n soundcloud: /^@[-a-z0-9_]{3,25}$/,\n // TikTok usernames are 1-24 characters containing letters, numbers, underscores\n // and periods, but cannot end in a period: https://support.tiktok.com/en/getting-started/setting-up-your-profile/changing-your-username\n tiktok: /^@[.\\w]{1,23}[\\w]$/\n};\n// Regex that allows for all possible mention characters for any service. We'll\n// confirm the match based on the user-configured service name after a match is\n// found.\nvar mentionTextCharRe = /[-\\w.]/;\n/**\n * Determines if the given character can be part of a mention's text characters.\n */\nexport function isMentionTextChar(char) {\n return mentionTextCharRe.test(char);\n}\n/**\n * Determines if the given `mention` text is valid.\n */\nexport function isValidMention(mention, serviceName) {\n var re = mentionRegexes[serviceName];\n return re.test(mention);\n}\nexport var mentionServices = ['twitter', 'instagram', 'soundcloud', 'tiktok'];\n","import { __extends } from \"tslib\";\nimport { AbstractMatch } from './abstract-match';\n/**\n * @class Autolinker.match.Mention\n * @extends Autolinker.match.AbstractMatch\n *\n * Represents a Mention match found in an input string which should be Autolinked.\n *\n * See this class's superclass ({@link Autolinker.match.Match}) for more details.\n */\nvar MentionMatch = /** @class */function (_super) {\n __extends(MentionMatch, _super);\n /**\n * @method constructor\n * @param {Object} cfg The configuration properties for the Match\n * instance, specified in an Object (map).\n */\n function MentionMatch(cfg) {\n var _this = _super.call(this, cfg) || this;\n /**\n * @public\n * @property {'mention'} type\n *\n * A string name for the type of match that this class represents. Can be\n * used in a TypeScript discriminating union to type-narrow from the\n * `Match` type.\n */\n _this.type = 'mention';\n /**\n * @cfg {String} serviceName\n *\n * The service to point mention matches to. See {@link Autolinker#mention}\n * for available values.\n */\n _this.serviceName = 'twitter'; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @cfg {String} mention (required)\n *\n * The Mention that was matched, without the '@' character.\n */\n _this.mention = ''; // default value just to get the above doc comment in the ES5 output and documentation generator\n _this.mention = cfg.mention;\n _this.serviceName = cfg.serviceName;\n return _this;\n }\n /**\n * Returns a string name for the type of match that this class represents.\n * For the case of MentionMatch, returns 'mention'.\n *\n * @return {String}\n */\n MentionMatch.prototype.getType = function () {\n return 'mention';\n };\n /**\n * Returns the mention, without the '@' character.\n *\n * @return {String}\n */\n MentionMatch.prototype.getMention = function () {\n return this.mention;\n };\n /**\n * Returns the configured {@link #serviceName} to point the mention to.\n * Ex: 'instagram', 'twitter', 'soundcloud'.\n *\n * @return {String}\n */\n MentionMatch.prototype.getServiceName = function () {\n return this.serviceName;\n };\n /**\n * Returns the anchor href that should be generated for the match.\n *\n * @return {String}\n */\n MentionMatch.prototype.getAnchorHref = function () {\n switch (this.serviceName) {\n case 'twitter':\n return 'https://twitter.com/' + this.mention;\n case 'instagram':\n return 'https://instagram.com/' + this.mention;\n case 'soundcloud':\n return 'https://soundcloud.com/' + this.mention;\n case 'tiktok':\n return 'https://www.tiktok.com/@' + this.mention;\n default:\n // Shouldn't happen because Autolinker's constructor should block any invalid values, but just in case.\n throw new Error('Unknown service name to point mention to: ' + this.serviceName);\n }\n };\n /**\n * Returns the anchor text that should be generated for the match.\n *\n * @return {String}\n */\n MentionMatch.prototype.getAnchorText = function () {\n return '@' + this.mention;\n };\n /**\n * Returns the CSS class suffixes that should be used on a tag built with\n * the match. See {@link Autolinker.match.Match#getCssClassSuffixes} for\n * details.\n *\n * @return {String[]}\n */\n MentionMatch.prototype.getCssClassSuffixes = function () {\n var cssClassSuffixes = _super.prototype.getCssClassSuffixes.call(this),\n serviceName = this.getServiceName();\n if (serviceName) {\n cssClassSuffixes.push(serviceName);\n }\n return cssClassSuffixes;\n };\n return MentionMatch;\n}(AbstractMatch);\nexport { MentionMatch };\n","// Regex that holds the characters used to separate segments of a phone number\nvar separatorCharRe = /[-. ]/;\n// Regex that specifies any delimiter char that allows us to treat the number as\n// a phone number rather than just any other number that could appear in text.\nvar hasDelimCharsRe = /[-. ()]/;\n// \"Pause\" and \"Wait\" control chars\nvar controlCharRe = /[,;]/;\n// Over the years, many people have added to this regex, but it should have been\n// split up by country. Maybe one day we can break this down.\nvar mostPhoneNumbers = /(?:(?:(?:(\\+)?\\d{1,3}[-. ]?)?\\(?\\d{3}\\)?[-. ]?\\d{3}[-. ]?\\d{4})|(?:(\\+)(?:9[976]\\d|8[987530]\\d|6[987]\\d|5[90]\\d|42\\d|3[875]\\d|2[98654321]\\d|9[8543210]|8[6421]|6[6543210]|5[87654321]|4[987654310]|3[9643210]|2[70]|7|1)[-. ]?(?:\\d[-. ]?){6,12}\\d+))([,;]+[0-9]+#?)*/;\n// Regex for Japanese phone numbers\nvar japanesePhoneRe = /(0([1-9]-?[1-9]\\d{3}|[1-9]{2}-?\\d{3}|[1-9]{2}\\d{1}-?\\d{2}|[1-9]{2}\\d{2}-?\\d{1})-?\\d{4}|0[789]0-?\\d{4}-?\\d{4}|050-?\\d{4}-?\\d{4})/;\n// Combined regex\nvar validPhoneNumberRe = new RegExp(\"^\".concat(mostPhoneNumbers.source, \"|\").concat(japanesePhoneRe.source, \"$\"));\n/**\n * Determines if the character is a phone number separator character (i.e.\n * '-', '.', or ' ' (space))\n */\nexport function isPhoneNumberSeparatorChar(char) {\n return separatorCharRe.test(char);\n}\n/**\n * Determines if the character is a control character in a phone number. Control\n * characters are as follows:\n *\n * - ',': A 1 second pause. Useful for dialing extensions once the main phone number has been reached\n * - ';': A \"wait\" that waits for the user to take action (tap something, for instance on a smart phone)\n */\nexport function isPhoneNumberControlChar(char) {\n return controlCharRe.test(char);\n}\n/**\n * Determines if the given phone number text found in a string is a valid phone\n * number.\n *\n * Our state machine parser is simplified to grab anything that looks like a\n * phone number, and this function confirms the match.\n */\nexport function isValidPhoneNumber(phoneNumberText) {\n // We'll only consider the match as a phone number if there is some kind of\n // delimiter character (a prefixed '+' sign, or separator chars).\n //\n // Accepts:\n // (123) 456-7890\n // +38755233976\n // Does not accept:\n // 1234567890 (no delimiter chars - may just be a random number that's not a phone number)\n var hasDelimiters = phoneNumberText.charAt(0) === '+' || hasDelimCharsRe.test(phoneNumberText);\n return hasDelimiters && validPhoneNumberRe.test(phoneNumberText);\n}\n","import { __extends } from \"tslib\";\nimport { AbstractMatch } from './abstract-match';\n/**\n * @class Autolinker.match.Phone\n * @extends Autolinker.match.AbstractMatch\n *\n * Represents a Phone number match found in an input string which should be\n * Autolinked.\n *\n * See this class's superclass ({@link Autolinker.match.Match}) for more\n * details.\n */\nvar PhoneMatch = /** @class */function (_super) {\n __extends(PhoneMatch, _super);\n /**\n * @method constructor\n * @param {Object} cfg The configuration properties for the Match\n * instance, specified in an Object (map).\n */\n function PhoneMatch(cfg) {\n var _this = _super.call(this, cfg) || this;\n /**\n * @public\n * @property {'phone'} type\n *\n * A string name for the type of match that this class represents. Can be\n * used in a TypeScript discriminating union to type-narrow from the\n * `Match` type.\n */\n _this.type = 'phone';\n /**\n * @protected\n * @property {String} number (required)\n *\n * The phone number that was matched, without any delimiter characters.\n *\n * Note: This is a string to allow for prefixed 0's.\n */\n _this.number = ''; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @protected\n * @property {Boolean} plusSign (required)\n *\n * `true` if the matched phone number started with a '+' sign. We'll include\n * it in the `tel:` URL if so, as this is needed for international numbers.\n *\n * Ex: '+1 (123) 456 7879'\n */\n _this.plusSign = false; // default value just to get the above doc comment in the ES5 output and documentation generator\n _this.number = cfg.number;\n _this.plusSign = cfg.plusSign;\n return _this;\n }\n /**\n * Returns a string name for the type of match that this class represents.\n * For the case of PhoneMatch, returns 'phone'.\n *\n * @return {String}\n */\n PhoneMatch.prototype.getType = function () {\n return 'phone';\n };\n /**\n * Returns the phone number that was matched as a string, without any\n * delimiter characters.\n *\n * Note: This is a string to allow for prefixed 0's.\n *\n * @return {String}\n */\n PhoneMatch.prototype.getPhoneNumber = function () {\n return this.number;\n };\n /**\n * Alias of {@link #getPhoneNumber}, returns the phone number that was\n * matched as a string, without any delimiter characters.\n *\n * Note: This is a string to allow for prefixed 0's.\n *\n * @return {String}\n */\n PhoneMatch.prototype.getNumber = function () {\n return this.getPhoneNumber();\n };\n /**\n * Returns the anchor href that should be generated for the match.\n *\n * @return {String}\n */\n PhoneMatch.prototype.getAnchorHref = function () {\n return 'tel:' + (this.plusSign ? '+' : '') + this.number;\n };\n /**\n * Returns the anchor text that should be generated for the match.\n *\n * @return {String}\n */\n PhoneMatch.prototype.getAnchorText = function () {\n return this.matchedText;\n };\n return PhoneMatch;\n}(AbstractMatch);\nexport { PhoneMatch };\n","import { alphaNumericAndMarksRe, digitRe } from '../regex-lib';\nimport { UrlMatch } from '../match/url-match';\nimport { remove, assertNever } from '../utils';\nimport { httpSchemeRe, isDomainLabelChar, isDomainLabelStartChar, isPathChar, isSchemeChar, isSchemeStartChar, isUrlSuffixStartChar, isValidIpV4Address, isValidSchemeUrl, isValidTldMatch, urlSuffixedCharsNotAllowedAtEndRe } from './uri-utils';\nimport { isEmailLocalPartChar, isEmailLocalPartStartChar, isValidEmail, mailtoSchemePrefixRe } from './email-utils';\nimport { EmailMatch } from '../match/email-match';\nimport { isHashtagTextChar, isValidHashtag } from './hashtag-utils';\nimport { HashtagMatch } from '../match/hashtag-match';\nimport { isMentionTextChar, isValidMention } from './mention-utils';\nimport { MentionMatch } from '../match/mention-match';\nimport { isPhoneNumberSeparatorChar, isPhoneNumberControlChar, isValidPhoneNumber } from './phone-number-utils';\nimport { PhoneMatch } from '../match/phone-match';\n// For debugging: search for and uncomment other \"For debugging\" lines\n// import CliTable from 'cli-table';\n/**\n * Parses URL, email, twitter, mention, and hashtag matches from the given\n * `text`.\n */\nexport function parseMatches(text, args) {\n var tagBuilder = args.tagBuilder;\n var stripPrefix = args.stripPrefix;\n var stripTrailingSlash = args.stripTrailingSlash;\n var decodePercentEncoding = args.decodePercentEncoding;\n var hashtagServiceName = args.hashtagServiceName;\n var mentionServiceName = args.mentionServiceName;\n var matches = [];\n var textLen = text.length;\n // An array of all active state machines. Empty array means we're in the\n // \"no url\" state\n var stateMachines = [];\n // For debugging: search for and uncomment other \"For debugging\" lines\n // const table = new CliTable({\n // head: ['charIdx', 'char', 'states', 'charIdx', 'startIdx', 'reached accept state'],\n // });\n var charIdx = 0;\n for (; charIdx < textLen; charIdx++) {\n var char = text.charAt(charIdx);\n if (stateMachines.length === 0) {\n stateNoMatch(char);\n } else {\n // Must loop through the state machines backwards for when one\n // is removed\n for (var stateIdx = stateMachines.length - 1; stateIdx >= 0; stateIdx--) {\n var stateMachine = stateMachines[stateIdx];\n switch (stateMachine.state) {\n // Protocol-relative URL states\n case 11 /* ProtocolRelativeSlash1 */:\n stateProtocolRelativeSlash1(stateMachine, char);\n break;\n case 12 /* ProtocolRelativeSlash2 */:\n stateProtocolRelativeSlash2(stateMachine, char);\n break;\n case 0 /* SchemeChar */:\n stateSchemeChar(stateMachine, char);\n break;\n case 1 /* SchemeHyphen */:\n stateSchemeHyphen(stateMachine, char);\n break;\n case 2 /* SchemeColon */:\n stateSchemeColon(stateMachine, char);\n break;\n case 3 /* SchemeSlash1 */:\n stateSchemeSlash1(stateMachine, char);\n break;\n case 4 /* SchemeSlash2 */:\n stateSchemeSlash2(stateMachine, char);\n break;\n case 5 /* DomainLabelChar */:\n stateDomainLabelChar(stateMachine, char);\n break;\n case 6 /* DomainHyphen */:\n stateDomainHyphen(stateMachine, char);\n break;\n case 7 /* DomainDot */:\n stateDomainDot(stateMachine, char);\n break;\n case 13 /* IpV4Digit */:\n stateIpV4Digit(stateMachine, char);\n break;\n case 14 /* IpV4Dot */:\n stateIPv4Dot(stateMachine, char);\n break;\n case 8 /* PortColon */:\n statePortColon(stateMachine, char);\n break;\n case 9 /* PortNumber */:\n statePortNumber(stateMachine, char);\n break;\n case 10 /* Path */:\n statePath(stateMachine, char);\n break;\n // Email States\n case 15 /* EmailMailto_M */:\n stateEmailMailto_M(stateMachine, char);\n break;\n case 16 /* EmailMailto_A */:\n stateEmailMailto_A(stateMachine, char);\n break;\n case 17 /* EmailMailto_I */:\n stateEmailMailto_I(stateMachine, char);\n break;\n case 18 /* EmailMailto_L */:\n stateEmailMailto_L(stateMachine, char);\n break;\n case 19 /* EmailMailto_T */:\n stateEmailMailto_T(stateMachine, char);\n break;\n case 20 /* EmailMailto_O */:\n stateEmailMailto_O(stateMachine, char);\n break;\n case 21 /* EmailMailto_Colon */:\n stateEmailMailtoColon(stateMachine, char);\n break;\n case 22 /* EmailLocalPart */:\n stateEmailLocalPart(stateMachine, char);\n break;\n case 23 /* EmailLocalPartDot */:\n stateEmailLocalPartDot(stateMachine, char);\n break;\n case 24 /* EmailAtSign */:\n stateEmailAtSign(stateMachine, char);\n break;\n case 25 /* EmailDomainChar */:\n stateEmailDomainChar(stateMachine, char);\n break;\n case 26 /* EmailDomainHyphen */:\n stateEmailDomainHyphen(stateMachine, char);\n break;\n case 27 /* EmailDomainDot */:\n stateEmailDomainDot(stateMachine, char);\n break;\n // Hashtag states\n case 28 /* HashtagHashChar */:\n stateHashtagHashChar(stateMachine, char);\n break;\n case 29 /* HashtagTextChar */:\n stateHashtagTextChar(stateMachine, char);\n break;\n // Mention states\n case 30 /* MentionAtChar */:\n stateMentionAtChar(stateMachine, char);\n break;\n case 31 /* MentionTextChar */:\n stateMentionTextChar(stateMachine, char);\n break;\n // Phone number states\n case 32 /* PhoneNumberOpenParen */:\n statePhoneNumberOpenParen(stateMachine, char);\n break;\n case 33 /* PhoneNumberAreaCodeDigit1 */:\n statePhoneNumberAreaCodeDigit1(stateMachine, char);\n break;\n case 34 /* PhoneNumberAreaCodeDigit2 */:\n statePhoneNumberAreaCodeDigit2(stateMachine, char);\n break;\n case 35 /* PhoneNumberAreaCodeDigit3 */:\n statePhoneNumberAreaCodeDigit3(stateMachine, char);\n break;\n case 36 /* PhoneNumberCloseParen */:\n statePhoneNumberCloseParen(stateMachine, char);\n break;\n case 37 /* PhoneNumberPlus */:\n statePhoneNumberPlus(stateMachine, char);\n break;\n case 38 /* PhoneNumberDigit */:\n statePhoneNumberDigit(stateMachine, char);\n break;\n case 39 /* PhoneNumberSeparator */:\n statePhoneNumberSeparator(stateMachine, char);\n break;\n case 40 /* PhoneNumberControlChar */:\n statePhoneNumberControlChar(stateMachine, char);\n break;\n case 41 /* PhoneNumberPoundChar */:\n statePhoneNumberPoundChar(stateMachine, char);\n break;\n default:\n assertNever(stateMachine.state);\n }\n }\n }\n // For debugging: search for and uncomment other \"For debugging\" lines\n // table.push([\n // charIdx,\n // char,\n // stateMachines.map(machine => State[machine.state]).join('\\n') || '(none)',\n // charIdx,\n // stateMachines.map(m => m.startIdx).join('\\n'),\n // stateMachines.map(m => m.acceptStateReached).join('\\n'),\n // ]);\n }\n // Capture any valid match at the end of the string\n // Note: this loop must happen in reverse because\n // captureMatchIfValidAndRemove() removes state machines from the array\n // and we'll end up skipping every other one if we remove while looping\n // forward\n for (var i = stateMachines.length - 1; i >= 0; i--) {\n stateMachines.forEach(function (stateMachine) {\n return captureMatchIfValidAndRemove(stateMachine);\n });\n }\n // For debugging: search for and uncomment other \"For debugging\" lines\n // console.log(`\\nRead string:\\n ${text}`);\n // console.log(table.toString());\n return matches;\n // Handles the state when we're not in a URL/email/etc. (i.e. when no state machines exist)\n function stateNoMatch(char) {\n if (char === '#') {\n // Hash char, start a Hashtag match\n stateMachines.push(createHashtagStateMachine(charIdx, 28 /* HashtagHashChar */));\n } else if (char === '@') {\n // '@' char, start a Mention match\n stateMachines.push(createMentionStateMachine(charIdx, 30 /* MentionAtChar */));\n } else if (char === '/') {\n // A slash could begin a protocol-relative URL\n stateMachines.push(createTldUrlStateMachine(charIdx, 11 /* ProtocolRelativeSlash1 */));\n } else if (char === '+') {\n // A '+' char can start a Phone number\n stateMachines.push(createPhoneNumberStateMachine(charIdx, 37 /* PhoneNumberPlus */));\n } else if (char === '(') {\n stateMachines.push(createPhoneNumberStateMachine(charIdx, 32 /* PhoneNumberOpenParen */));\n } else {\n if (digitRe.test(char)) {\n // A digit could start a phone number\n stateMachines.push(createPhoneNumberStateMachine(charIdx, 38 /* PhoneNumberDigit */));\n // A digit could start an IP address\n stateMachines.push(createIpV4UrlStateMachine(charIdx, 13 /* IpV4Digit */));\n }\n if (isEmailLocalPartStartChar(char)) {\n // Any email local part. An 'm' character in particular could\n // start a 'mailto:' match\n var startState = char.toLowerCase() === 'm' ? 15 /* EmailMailto_M */ : 22 /* EmailLocalPart */;\n stateMachines.push(createEmailStateMachine(charIdx, startState));\n }\n if (isSchemeStartChar(char)) {\n // An uppercase or lowercase letter may start a scheme match\n stateMachines.push(createSchemeUrlStateMachine(charIdx, 0 /* SchemeChar */));\n }\n if (alphaNumericAndMarksRe.test(char)) {\n // A unicode alpha character or digit could start a domain name\n // label for a TLD match\n stateMachines.push(createTldUrlStateMachine(charIdx, 5 /* DomainLabelChar */));\n }\n }\n // Anything else, remain in the \"non-url\" state by not creating any\n // state machines\n }\n // Implements ABNF: ALPHA *( ALPHA / DIGIT / \"+\" / \"-\" / \".\" )\n function stateSchemeChar(stateMachine, char) {\n if (char === ':') {\n stateMachine.state = 2 /* SchemeColon */;\n } else if (char === '-') {\n stateMachine.state = 1 /* SchemeHyphen */;\n } else if (isSchemeChar(char)) {\n // Stay in SchemeChar state\n } else {\n // Any other character, not a scheme\n remove(stateMachines, stateMachine);\n }\n }\n function stateSchemeHyphen(stateMachine, char) {\n if (char === '-') {\n // Stay in SchemeHyphen state\n // TODO: Should a colon following a dash be counted as the end of the scheme?\n // } else if (char === ':') {\n // stateMachine.state = State.SchemeColon;\n } else if (char === '/') {\n // Not a valid scheme match, but may be the start of a\n // protocol-relative match (such as //google.com)\n remove(stateMachines, stateMachine);\n stateMachines.push(createTldUrlStateMachine(charIdx, 11 /* ProtocolRelativeSlash1 */));\n } else if (isSchemeChar(char)) {\n stateMachine.state = 0 /* SchemeChar */;\n } else {\n // Any other character, not a scheme\n remove(stateMachines, stateMachine);\n }\n }\n function stateSchemeColon(stateMachine, char) {\n if (char === '/') {\n stateMachine.state = 3 /* SchemeSlash1 */;\n } else if (char === '.') {\n // We've read something like 'hello:.' - don't capture\n remove(stateMachines, stateMachine);\n } else if (isDomainLabelStartChar(char)) {\n stateMachine.state = 5 /* DomainLabelChar */;\n // It's possible that we read an \"introduction\" piece of text,\n // and the character after the current colon actually starts an\n // actual scheme. An example of this is:\n // \"The link:http://google.com\"\n // Hence, start a new machine to capture this match if so\n if (isSchemeStartChar(char)) {\n stateMachines.push(createSchemeUrlStateMachine(charIdx, 0 /* SchemeChar */));\n }\n } else {\n remove(stateMachines, stateMachine);\n }\n }\n function stateSchemeSlash1(stateMachine, char) {\n if (char === '/') {\n stateMachine.state = 4 /* SchemeSlash2 */;\n } else if (isPathChar(char)) {\n stateMachine.state = 10 /* Path */;\n stateMachine.acceptStateReached = true;\n } else {\n captureMatchIfValidAndRemove(stateMachine);\n }\n }\n function stateSchemeSlash2(stateMachine, char) {\n if (char === '/') {\n // 3rd slash, must be an absolute path (path-absolute in the\n // ABNF), such as in a file:///c:/windows/etc. See\n // https://tools.ietf.org/html/rfc3986#appendix-A\n stateMachine.state = 10 /* Path */;\n } else if (isDomainLabelStartChar(char)) {\n // start of \"authority\" section - see https://tools.ietf.org/html/rfc3986#appendix-A\n stateMachine.state = 5 /* DomainLabelChar */;\n stateMachine.acceptStateReached = true;\n } else {\n // not valid\n remove(stateMachines, stateMachine);\n }\n }\n // Handles reading a '/' from the NonUrl state\n function stateProtocolRelativeSlash1(stateMachine, char) {\n if (char === '/') {\n stateMachine.state = 12 /* ProtocolRelativeSlash2 */;\n } else {\n // Anything else, cannot be the start of a protocol-relative\n // URL.\n remove(stateMachines, stateMachine);\n }\n }\n // Handles reading a second '/', which could start a protocol-relative URL\n function stateProtocolRelativeSlash2(stateMachine, char) {\n if (isDomainLabelStartChar(char)) {\n stateMachine.state = 5 /* DomainLabelChar */;\n } else {\n // Anything else, not a URL\n remove(stateMachines, stateMachine);\n }\n }\n // Handles when we have read a domain label character\n function stateDomainLabelChar(stateMachine, char) {\n if (char === '.') {\n stateMachine.state = 7 /* DomainDot */;\n } else if (char === '-') {\n stateMachine.state = 6 /* DomainHyphen */;\n } else if (char === ':') {\n // Beginning of a port number, end the domain name\n stateMachine.state = 8 /* PortColon */;\n } else if (isUrlSuffixStartChar(char)) {\n // '/', '?', or '#'\n stateMachine.state = 10 /* Path */;\n } else if (isDomainLabelChar(char)) {\n // Stay in the DomainLabelChar state\n } else {\n // Anything else, end the domain name\n captureMatchIfValidAndRemove(stateMachine);\n }\n }\n function stateDomainHyphen(stateMachine, char) {\n if (char === '-') {\n // Remain in the DomainHyphen state\n } else if (char === '.') {\n // Not valid to have a '-.' in a domain label\n captureMatchIfValidAndRemove(stateMachine);\n } else if (isDomainLabelStartChar(char)) {\n stateMachine.state = 5 /* DomainLabelChar */;\n } else {\n captureMatchIfValidAndRemove(stateMachine);\n }\n }\n function stateDomainDot(stateMachine, char) {\n if (char === '.') {\n // domain names cannot have multiple '.'s next to each other.\n // It's possible we've already read a valid domain name though,\n // and that the '..' sequence just forms an ellipsis at the end\n // of a sentence\n captureMatchIfValidAndRemove(stateMachine);\n } else if (isDomainLabelStartChar(char)) {\n stateMachine.state = 5 /* DomainLabelChar */;\n stateMachine.acceptStateReached = true; // after hitting a dot, and then another domain label, we've reached an accept state\n } else {\n // Anything else, end the domain name\n captureMatchIfValidAndRemove(stateMachine);\n }\n }\n function stateIpV4Digit(stateMachine, char) {\n if (char === '.') {\n stateMachine.state = 14 /* IpV4Dot */;\n } else if (char === ':') {\n // Beginning of a port number\n stateMachine.state = 8 /* PortColon */;\n } else if (digitRe.test(char)) {\n // stay in the IPv4 digit state\n } else if (isUrlSuffixStartChar(char)) {\n stateMachine.state = 10 /* Path */;\n } else if (alphaNumericAndMarksRe.test(char)) {\n // If we hit an alpha character, must not be an IPv4\n // Example of this: 1.2.3.4abc\n remove(stateMachines, stateMachine);\n } else {\n captureMatchIfValidAndRemove(stateMachine);\n }\n }\n function stateIPv4Dot(stateMachine, char) {\n if (digitRe.test(char)) {\n stateMachine.octetsEncountered++;\n // Once we have encountered 4 octets, it's *potentially* a valid\n // IPv4 address. Our IPv4 regex will confirm the match later\n // though to make sure each octet is in the 0-255 range, and\n // there's exactly 4 octets (not 5 or more)\n if (stateMachine.octetsEncountered === 4) {\n stateMachine.acceptStateReached = true;\n }\n stateMachine.state = 13 /* IpV4Digit */;\n } else {\n captureMatchIfValidAndRemove(stateMachine);\n }\n }\n function statePortColon(stateMachine, char) {\n if (digitRe.test(char)) {\n stateMachine.state = 9 /* PortNumber */;\n } else {\n captureMatchIfValidAndRemove(stateMachine);\n }\n }\n function statePortNumber(stateMachine, char) {\n if (digitRe.test(char)) {\n // Stay in port number state\n } else if (isUrlSuffixStartChar(char)) {\n // '/', '?', or '#'\n stateMachine.state = 10 /* Path */;\n } else {\n captureMatchIfValidAndRemove(stateMachine);\n }\n }\n function statePath(stateMachine, char) {\n if (isPathChar(char)) {\n // Stay in the path state\n } else {\n captureMatchIfValidAndRemove(stateMachine);\n }\n }\n // Handles if we're reading a 'mailto:' prefix on the string\n function stateEmailMailto_M(stateMachine, char) {\n if (char.toLowerCase() === 'a') {\n stateMachine.state = 16 /* EmailMailto_A */;\n } else {\n stateEmailLocalPart(stateMachine, char);\n }\n }\n function stateEmailMailto_A(stateMachine, char) {\n if (char.toLowerCase() === 'i') {\n stateMachine.state = 17 /* EmailMailto_I */;\n } else {\n stateEmailLocalPart(stateMachine, char);\n }\n }\n function stateEmailMailto_I(stateMachine, char) {\n if (char.toLowerCase() === 'l') {\n stateMachine.state = 18 /* EmailMailto_L */;\n } else {\n stateEmailLocalPart(stateMachine, char);\n }\n }\n function stateEmailMailto_L(stateMachine, char) {\n if (char.toLowerCase() === 't') {\n stateMachine.state = 19 /* EmailMailto_T */;\n } else {\n stateEmailLocalPart(stateMachine, char);\n }\n }\n function stateEmailMailto_T(stateMachine, char) {\n if (char.toLowerCase() === 'o') {\n stateMachine.state = 20 /* EmailMailto_O */;\n } else {\n stateEmailLocalPart(stateMachine, char);\n }\n }\n function stateEmailMailto_O(stateMachine, char) {\n if (char.toLowerCase() === ':') {\n stateMachine.state = 21 /* EmailMailto_Colon */;\n } else {\n stateEmailLocalPart(stateMachine, char);\n }\n }\n function stateEmailMailtoColon(stateMachine, char) {\n if (isEmailLocalPartChar(char)) {\n stateMachine.state = 22 /* EmailLocalPart */;\n } else {\n remove(stateMachines, stateMachine);\n }\n }\n // Handles the state when we're currently in the \"local part\" of an\n // email address (as opposed to the \"domain part\")\n function stateEmailLocalPart(stateMachine, char) {\n if (char === '.') {\n stateMachine.state = 23 /* EmailLocalPartDot */;\n } else if (char === '@') {\n stateMachine.state = 24 /* EmailAtSign */;\n } else if (isEmailLocalPartChar(char)) {\n // stay in the \"local part\" of the email address\n // Note: because stateEmailLocalPart() is called from the\n // 'mailto' states (when the 'mailto' prefix itself has been\n // broken), make sure to set the state to EmailLocalPart\n stateMachine.state = 22 /* EmailLocalPart */;\n } else {\n // not an email address character\n remove(stateMachines, stateMachine);\n }\n }\n // Handles the state where we've read\n function stateEmailLocalPartDot(stateMachine, char) {\n if (char === '.') {\n // We read a second '.' in a row, not a valid email address\n // local part\n remove(stateMachines, stateMachine);\n } else if (char === '@') {\n // We read the '@' character immediately after a dot ('.'), not\n // an email address\n remove(stateMachines, stateMachine);\n } else if (isEmailLocalPartChar(char)) {\n stateMachine.state = 22 /* EmailLocalPart */;\n } else {\n // Anything else, not an email address\n remove(stateMachines, stateMachine);\n }\n }\n function stateEmailAtSign(stateMachine, char) {\n if (isDomainLabelStartChar(char)) {\n stateMachine.state = 25 /* EmailDomainChar */;\n } else {\n // Anything else, not an email address\n remove(stateMachines, stateMachine);\n }\n }\n function stateEmailDomainChar(stateMachine, char) {\n if (char === '.') {\n stateMachine.state = 27 /* EmailDomainDot */;\n } else if (char === '-') {\n stateMachine.state = 26 /* EmailDomainHyphen */;\n } else if (isDomainLabelChar(char)) {\n // Stay in the DomainChar state\n } else {\n // Anything else, we potentially matched if the criteria has\n // been met\n captureMatchIfValidAndRemove(stateMachine);\n }\n }\n function stateEmailDomainHyphen(stateMachine, char) {\n if (char === '-' || char === '.') {\n // Not valid to have two hyphens (\"--\") or hypen+dot (\"-.\")\n captureMatchIfValidAndRemove(stateMachine);\n } else if (isDomainLabelChar(char)) {\n stateMachine.state = 25 /* EmailDomainChar */;\n } else {\n // Anything else\n captureMatchIfValidAndRemove(stateMachine);\n }\n }\n function stateEmailDomainDot(stateMachine, char) {\n if (char === '.' || char === '-') {\n // not valid to have two dots (\"..\") or dot+hypen (\".-\")\n captureMatchIfValidAndRemove(stateMachine);\n } else if (isDomainLabelStartChar(char)) {\n stateMachine.state = 25 /* EmailDomainChar */;\n // After having read a '.' and then a valid domain character,\n // we now know that the domain part of the email is valid, and\n // we have found at least a partial EmailMatch (however, the\n // email address may have additional characters from this point)\n stateMachine.acceptStateReached = true;\n } else {\n // Anything else\n captureMatchIfValidAndRemove(stateMachine);\n }\n }\n // Handles the state when we've just encountered a '#' character\n function stateHashtagHashChar(stateMachine, char) {\n if (isHashtagTextChar(char)) {\n // '#' char with valid hash text char following\n stateMachine.state = 29 /* HashtagTextChar */;\n stateMachine.acceptStateReached = true;\n } else {\n remove(stateMachines, stateMachine);\n }\n }\n // Handles the state when we're currently in the hash tag's text chars\n function stateHashtagTextChar(stateMachine, char) {\n if (isHashtagTextChar(char)) {\n // Continue reading characters in the HashtagText state\n } else {\n captureMatchIfValidAndRemove(stateMachine);\n }\n }\n // Handles the state when we've just encountered a '@' character\n function stateMentionAtChar(stateMachine, char) {\n if (isMentionTextChar(char)) {\n // '@' char with valid mention text char following\n stateMachine.state = 31 /* MentionTextChar */;\n stateMachine.acceptStateReached = true;\n } else {\n remove(stateMachines, stateMachine);\n }\n }\n // Handles the state when we're currently in the mention's text chars\n function stateMentionTextChar(stateMachine, char) {\n if (isMentionTextChar(char)) {\n // Continue reading characters in the HashtagText state\n } else if (alphaNumericAndMarksRe.test(char)) {\n // Char is invalid for a mention text char, not a valid match.\n // Note that ascii alphanumeric chars are okay (which are tested\n // in the previous 'if' statement, but others are not)\n remove(stateMachines, stateMachine);\n } else {\n captureMatchIfValidAndRemove(stateMachine);\n }\n }\n function statePhoneNumberPlus(stateMachine, char) {\n if (digitRe.test(char)) {\n stateMachine.state = 38 /* PhoneNumberDigit */;\n } else {\n remove(stateMachines, stateMachine);\n // This character may start a new match. Add states for it\n stateNoMatch(char);\n }\n }\n function statePhoneNumberOpenParen(stateMachine, char) {\n if (digitRe.test(char)) {\n stateMachine.state = 33 /* PhoneNumberAreaCodeDigit1 */;\n } else {\n remove(stateMachines, stateMachine);\n }\n // It's also possible that the paren was just an open brace for\n // a piece of text. Start other machines\n stateNoMatch(char);\n }\n function statePhoneNumberAreaCodeDigit1(stateMachine, char) {\n if (digitRe.test(char)) {\n stateMachine.state = 34 /* PhoneNumberAreaCodeDigit2 */;\n } else {\n remove(stateMachines, stateMachine);\n }\n }\n function statePhoneNumberAreaCodeDigit2(stateMachine, char) {\n if (digitRe.test(char)) {\n stateMachine.state = 35 /* PhoneNumberAreaCodeDigit3 */;\n } else {\n remove(stateMachines, stateMachine);\n }\n }\n function statePhoneNumberAreaCodeDigit3(stateMachine, char) {\n if (char === ')') {\n stateMachine.state = 36 /* PhoneNumberCloseParen */;\n } else {\n remove(stateMachines, stateMachine);\n }\n }\n function statePhoneNumberCloseParen(stateMachine, char) {\n if (digitRe.test(char)) {\n stateMachine.state = 38 /* PhoneNumberDigit */;\n } else if (isPhoneNumberSeparatorChar(char)) {\n stateMachine.state = 39 /* PhoneNumberSeparator */;\n } else {\n remove(stateMachines, stateMachine);\n }\n }\n function statePhoneNumberDigit(stateMachine, char) {\n // For now, if we've reached any digits, we'll say that the machine\n // has reached its accept state. The phone regex will confirm the\n // match later.\n // Alternatively, we could count the number of digits to avoid\n // invoking the phone number regex\n stateMachine.acceptStateReached = true;\n if (isPhoneNumberControlChar(char)) {\n stateMachine.state = 40 /* PhoneNumberControlChar */;\n } else if (char === '#') {\n stateMachine.state = 41 /* PhoneNumberPoundChar */;\n } else if (digitRe.test(char)) {\n // Stay in the phone number digit state\n } else if (char === '(') {\n stateMachine.state = 32 /* PhoneNumberOpenParen */;\n } else if (isPhoneNumberSeparatorChar(char)) {\n stateMachine.state = 39 /* PhoneNumberSeparator */;\n } else {\n captureMatchIfValidAndRemove(stateMachine);\n // The transition from a digit character to a letter can be the\n // start of a new scheme URL match\n if (isSchemeStartChar(char)) {\n stateMachines.push(createSchemeUrlStateMachine(charIdx, 0 /* SchemeChar */));\n }\n }\n }\n function statePhoneNumberSeparator(stateMachine, char) {\n if (digitRe.test(char)) {\n stateMachine.state = 38 /* PhoneNumberDigit */;\n } else if (char === '(') {\n stateMachine.state = 32 /* PhoneNumberOpenParen */;\n } else {\n captureMatchIfValidAndRemove(stateMachine);\n // This character may start a new match. Add states for it\n stateNoMatch(char);\n }\n }\n // The \";\" characters is \"wait\" in a phone number\n // The \",\" characters is \"pause\" in a phone number\n function statePhoneNumberControlChar(stateMachine, char) {\n if (isPhoneNumberControlChar(char)) {\n // Stay in the \"control char\" state\n } else if (char === '#') {\n stateMachine.state = 41 /* PhoneNumberPoundChar */;\n } else if (digitRe.test(char)) {\n stateMachine.state = 38 /* PhoneNumberDigit */;\n } else {\n captureMatchIfValidAndRemove(stateMachine);\n }\n }\n // The \"#\" characters is \"pound\" in a phone number\n function statePhoneNumberPoundChar(stateMachine, char) {\n if (isPhoneNumberControlChar(char)) {\n stateMachine.state = 40 /* PhoneNumberControlChar */;\n } else if (digitRe.test(char)) {\n // According to some of the older tests, if there's a digit\n // after a '#' sign, the match is invalid. TODO: Revisit if this is true\n remove(stateMachines, stateMachine);\n } else {\n captureMatchIfValidAndRemove(stateMachine);\n }\n }\n /*\n * Captures a match if it is valid (i.e. has a full domain name for a\n * TLD match). If a match is not valid, it is possible that we want to\n * keep reading characters in order to make a full match.\n */\n function captureMatchIfValidAndRemove(stateMachine) {\n // Remove the state machine first. There are a number of code paths\n // which return out of this function early, so make sure we have\n // this done\n remove(stateMachines, stateMachine);\n // Make sure the state machine being checked has actually reached an\n // \"accept\" state. If it hasn't reach one, it can't be a match\n if (!stateMachine.acceptStateReached) {\n return;\n }\n var startIdx = stateMachine.startIdx;\n var matchedText = text.slice(stateMachine.startIdx, charIdx);\n // Handle any unbalanced braces (parens, square brackets, or curly\n // brackets) inside the URL. This handles situations like:\n // The link (google.com)\n // and\n // Check out this link here (en.wikipedia.org/wiki/IANA_(disambiguation))\n //\n // And also remove any punctuation chars at the end such as:\n // '?', ',', ':', '.', etc.\n matchedText = excludeUnbalancedTrailingBracesAndPunctuation(matchedText);\n if (stateMachine.type === 'url') {\n // We don't want to accidentally match a URL that is preceded by an\n // '@' character, which would be an email address\n var charBeforeUrlMatch = text.charAt(stateMachine.startIdx - 1);\n if (charBeforeUrlMatch === '@') {\n return;\n }\n // For the purpose of this parser, we've generalized 'www'\n // matches as part of 'tld' matches. However, for backward\n // compatibility, we distinguish beween TLD matches and matches\n // that begin with 'www.' so that users may turn off 'www'\n // matches. As such, we need to correct for that now if the\n // URL begins with 'www.'\n var urlMatchType = stateMachine.matchType;\n if (urlMatchType === 'scheme') {\n // Autolinker accepts many characters in a url's scheme (like `fake://test.com`).\n // However, in cases where a URL is missing whitespace before an obvious link,\n // (for example: `nowhitespacehttp://www.test.com`), we only want the match to start\n // at the http:// part. We will check if the match contains a common scheme and then\n // shift the match to start from there.\n var httpSchemeMatch = httpSchemeRe.exec(matchedText);\n if (httpSchemeMatch) {\n // If we found an overmatched URL, we want to find the index\n // of where the match should start and shift the match to\n // start from the beginning of the common scheme\n startIdx = startIdx + httpSchemeMatch.index;\n matchedText = matchedText.slice(httpSchemeMatch.index);\n }\n if (!isValidSchemeUrl(matchedText)) {\n return; // not a valid match\n }\n } else if (urlMatchType === 'tld') {\n if (!isValidTldMatch(matchedText)) {\n return; // not a valid match\n }\n } else if (urlMatchType === 'ipV4') {\n if (!isValidIpV4Address(matchedText)) {\n return; // not a valid match\n }\n } else {\n assertNever(urlMatchType);\n }\n matches.push(new UrlMatch({\n tagBuilder: tagBuilder,\n matchedText: matchedText,\n offset: startIdx,\n urlMatchType: urlMatchType,\n url: matchedText,\n protocolRelativeMatch: matchedText.slice(0, 2) === '//',\n // TODO: Do these settings need to be passed to the match,\n // or should we handle them here in UrlMatcher?\n stripPrefix: stripPrefix,\n stripTrailingSlash: stripTrailingSlash,\n decodePercentEncoding: decodePercentEncoding\n }));\n } else if (stateMachine.type === 'email') {\n // if the email address has a valid TLD, add it to the list of matches\n if (isValidEmail(matchedText)) {\n matches.push(new EmailMatch({\n tagBuilder: tagBuilder,\n matchedText: matchedText,\n offset: startIdx,\n email: matchedText.replace(mailtoSchemePrefixRe, '')\n }));\n }\n } else if (stateMachine.type === 'hashtag') {\n if (isValidHashtag(matchedText)) {\n matches.push(new HashtagMatch({\n tagBuilder: tagBuilder,\n matchedText: matchedText,\n offset: startIdx,\n serviceName: hashtagServiceName,\n hashtag: matchedText.slice(1)\n }));\n }\n } else if (stateMachine.type === 'mention') {\n if (isValidMention(matchedText, mentionServiceName)) {\n matches.push(new MentionMatch({\n tagBuilder: tagBuilder,\n matchedText: matchedText,\n offset: startIdx,\n serviceName: mentionServiceName,\n mention: matchedText.slice(1) // strip off the '@' character at the beginning\n }));\n }\n } else if (stateMachine.type === 'phone') {\n // remove any trailing spaces that were considered as \"separator\"\n // chars by the state machine\n matchedText = matchedText.replace(/ +$/g, '');\n if (isValidPhoneNumber(matchedText)) {\n var cleanNumber = matchedText.replace(/[^0-9,;#]/g, ''); // strip out non-digit characters exclude comma semicolon and #\n matches.push(new PhoneMatch({\n tagBuilder: tagBuilder,\n matchedText: matchedText,\n offset: startIdx,\n number: cleanNumber,\n plusSign: matchedText.charAt(0) === '+'\n }));\n }\n } else {\n assertNever(stateMachine);\n }\n }\n}\nvar openBraceRe = /[\\(\\{\\[]/;\nvar closeBraceRe = /[\\)\\}\\]]/;\nvar oppositeBrace = {\n ')': '(',\n '}': '{',\n ']': '['\n};\n/**\n * Determines if a match found has unmatched closing parenthesis,\n * square brackets or curly brackets. If so, these unbalanced symbol(s) will be\n * removed from the URL match itself.\n *\n * A match may have an extra closing parenthesis/square brackets/curly brackets\n * at the end of the match because these are valid URL path characters. For\n * example, \"wikipedia.com/something_(disambiguation)\" should be auto-linked.\n *\n * However, an extra parenthesis *will* be included when the URL itself is\n * wrapped in parenthesis, such as in the case of:\n *\n * \"(wikipedia.com/something_(disambiguation))\"\n *\n * In this case, the last closing parenthesis should *not* be part of the\n * URL itself, and this method will exclude it from the returned URL.\n *\n * For square brackets in URLs such as in PHP arrays, the same behavior as\n * parenthesis discussed above should happen:\n *\n * \"[http://www.example.com/foo.php?bar[]=1&bar[]=2&bar[]=3]\"\n *\n * The very last closing square bracket should not be part of the URL itself,\n * and therefore this method will remove it.\n *\n * @param matchedText The full matched URL/email/hashtag/etc. from the state\n * machine parser.\n * @return The updated matched text with extraneous suffix characters removed.\n */\nexport function excludeUnbalancedTrailingBracesAndPunctuation(matchedText) {\n var braceCounts = {\n '(': 0,\n '{': 0,\n '[': 0\n };\n for (var i = 0; i < matchedText.length; i++) {\n var char_1 = matchedText.charAt(i);\n if (openBraceRe.test(char_1)) {\n braceCounts[char_1]++;\n } else if (closeBraceRe.test(char_1)) {\n braceCounts[oppositeBrace[char_1]]--;\n }\n }\n var endIdx = matchedText.length - 1;\n var char;\n while (endIdx >= 0) {\n char = matchedText.charAt(endIdx);\n if (closeBraceRe.test(char)) {\n var oppositeBraceChar = oppositeBrace[char];\n if (braceCounts[oppositeBraceChar] < 0) {\n braceCounts[oppositeBraceChar]++;\n endIdx--;\n } else {\n break;\n }\n } else if (urlSuffixedCharsNotAllowedAtEndRe.test(char)) {\n // Walk back a punctuation char like '?', ',', ':', '.', etc.\n endIdx--;\n } else {\n break;\n }\n }\n return matchedText.slice(0, endIdx + 1);\n}\nfunction createSchemeUrlStateMachine(startIdx, state) {\n return {\n type: 'url',\n startIdx: startIdx,\n state: state,\n acceptStateReached: false,\n matchType: 'scheme'\n };\n}\nfunction createTldUrlStateMachine(startIdx, state) {\n return {\n type: 'url',\n startIdx: startIdx,\n state: state,\n acceptStateReached: false,\n matchType: 'tld'\n };\n}\nfunction createIpV4UrlStateMachine(startIdx, state) {\n return {\n type: 'url',\n startIdx: startIdx,\n state: state,\n acceptStateReached: false,\n matchType: 'ipV4',\n octetsEncountered: 1 // starts at 1 because we create this machine when encountering the first octet\n };\n}\nfunction createEmailStateMachine(startIdx, state) {\n return {\n type: 'email',\n startIdx: startIdx,\n state: state,\n acceptStateReached: false\n };\n}\nfunction createHashtagStateMachine(startIdx, state) {\n return {\n type: 'hashtag',\n startIdx: startIdx,\n state: state,\n acceptStateReached: false\n };\n}\nfunction createMentionStateMachine(startIdx, state) {\n return {\n type: 'mention',\n startIdx: startIdx,\n state: state,\n acceptStateReached: false\n };\n}\nfunction createPhoneNumberStateMachine(startIdx, state) {\n return {\n type: 'phone',\n startIdx: startIdx,\n state: state,\n acceptStateReached: false\n };\n}\n","import { __assign } from \"tslib\";\nimport { letterRe, digitRe, whitespaceRe, quoteRe, controlCharsRe } from '../regex-lib';\nimport { assertNever } from '../utils';\n// For debugging: search for other \"For debugging\" lines\n// import CliTable from 'cli-table';\n/**\n * Parses an HTML string, calling the callbacks to notify of tags and text.\n *\n * ## History\n *\n * This file previously used a regular expression to find html tags in the input\n * text. Unfortunately, we ran into a bunch of catastrophic backtracking issues\n * with certain input text, causing Autolinker to either hang or just take a\n * really long time to parse the string.\n *\n * The current code is intended to be a O(n) algorithm that walks through\n * the string in one pass, and tries to be as cheap as possible. We don't need\n * to implement the full HTML spec, but rather simply determine where the string\n * looks like an HTML tag, and where it looks like text (so that we can autolink\n * that).\n *\n * This state machine parser is intended just to be a simple but performant\n * parser of HTML for the subset of requirements we have. We simply need to:\n *\n * 1. Determine where HTML tags are\n * 2. Determine the tag name (Autolinker specifically only cares about ,\n *