@lingxiteam/lcdp-ueditor-react 1.0.2 → 1.0.3-alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/LcdpUeditor.d.ts +4 -0
- package/es/LcdpUeditor.js +45 -8
- package/es/tools/UeditorResourceLoader.d.ts +1 -1
- package/es/tools/UeditorResourceLoader.js +18 -7
- package/es/tools/filterHtmlNode.js +7 -2
- package/lib/LcdpUeditor.d.ts +4 -0
- package/lib/LcdpUeditor.js +35 -10
- package/lib/tools/UeditorResourceLoader.d.ts +1 -1
- package/lib/tools/UeditorResourceLoader.js +15 -7
- package/lib/tools/filterHtmlNode.js +8 -4
- package/package.json +1 -1
- package/ueditor-resource/dialogs/anchor/anchor.html +1 -1
- package/ueditor-resource/dialogs/attachment/attachment.css +2 -715
- package/ueditor-resource/dialogs/attachment/attachment.html +6 -6
- package/ueditor-resource/dialogs/attachment/attachment.js +2 -803
- package/ueditor-resource/dialogs/audio/audio.css +2 -878
- package/ueditor-resource/dialogs/audio/audio.js +2 -815
- package/ueditor-resource/dialogs/background/background.css +2 -192
- package/ueditor-resource/dialogs/background/background.html +3 -3
- package/ueditor-resource/dialogs/background/background.js +2 -370
- package/ueditor-resource/dialogs/contentimport/contentimport.html +3 -3
- package/ueditor-resource/dialogs/contentimport/contentimport.js +2 -91
- package/ueditor-resource/dialogs/emotion/emotion.css +2 -128
- package/ueditor-resource/dialogs/emotion/emotion.html +3 -3
- package/ueditor-resource/dialogs/emotion/emotion.js +2 -186
- package/ueditor-resource/dialogs/formula/formula.html +4 -4
- package/ueditor-resource/dialogs/formula/formula.js +2 -147
- package/ueditor-resource/dialogs/help/help.css +2 -36
- package/ueditor-resource/dialogs/help/help.html +3 -3
- package/ueditor-resource/dialogs/help/help.js +2 -57
- package/ueditor-resource/dialogs/image/image.css +2 -767
- package/ueditor-resource/dialogs/image/image.js +2 -1060
- package/ueditor-resource/dialogs/insertframe/insertframe.html +2 -2
- package/ueditor-resource/dialogs/internal.js +2 -81
- package/ueditor-resource/dialogs/preview/preview.html +2 -2
- package/ueditor-resource/dialogs/scrawl/scrawl.css +2 -323
- package/ueditor-resource/dialogs/scrawl/scrawl.html +3 -3
- package/ueditor-resource/dialogs/scrawl/scrawl.js +2 -682
- package/ueditor-resource/dialogs/searchreplace/searchreplace.html +2 -2
- package/ueditor-resource/dialogs/searchreplace/searchreplace.js +2 -174
- package/ueditor-resource/dialogs/spechars/spechars.html +2 -2
- package/ueditor-resource/dialogs/spechars/spechars.js +2 -86
- package/ueditor-resource/dialogs/table/edittable.css +2 -84
- package/ueditor-resource/dialogs/table/edittable.html +3 -3
- package/ueditor-resource/dialogs/table/edittable.js +2 -241
- package/ueditor-resource/dialogs/table/edittd.html +1 -1
- package/ueditor-resource/dialogs/table/edittip.html +1 -1
- package/ueditor-resource/dialogs/template/config.js +2 -42
- package/ueditor-resource/dialogs/template/template.css +2 -98
- package/ueditor-resource/dialogs/template/template.html +4 -4
- package/ueditor-resource/dialogs/template/template.js +2 -53
- package/ueditor-resource/dialogs/video/video.css +2 -908
- package/ueditor-resource/dialogs/video/video.js +2 -867
- package/ueditor-resource/dialogs/wordimage/wordimage.html +5 -5
- package/ueditor-resource/dialogs/wordimage/wordimage.js +2 -93
- package/ueditor-resource/lang/en/en.js +2 -686
- package/ueditor-resource/lang/zh-cn/zh-cn.js +2 -748
- package/ueditor-resource/lang/zh-tw/zh-tw.js +2 -748
- package/ueditor-resource/plugins/browser-image-compression.js +9 -0
- package/ueditor-resource/themes/default/css/ueditor.css +2 -2148
- package/ueditor-resource/themes/default/dialog.css +2 -16
- package/ueditor-resource/themes/default/dialogbase.css +2 -131
- package/ueditor-resource/themes/iframe.css +2 -62
- package/ueditor-resource/third-party/SyntaxHighlighter/shCore.js +4 -3655
- package/ueditor-resource/third-party/SyntaxHighlighter/shCoreDefault.css +3 -1
- package/ueditor-resource/third-party/clipboard/clipboard.js +2 -753
- package/ueditor-resource/third-party/codemirror/codemirror.css +2 -105
- package/ueditor-resource/third-party/codemirror/codemirror.js +4 -3581
- package/ueditor-resource/third-party/jquery-3.5.1.js +4 -2
- package/ueditor-resource/third-party/jquery-3.5.1_1.js +4 -4314
- package/ueditor-resource/third-party/webuploader/webuploader.css +2 -87
- package/ueditor-resource/third-party/webuploader/webuploader.js +5 -4
- package/ueditor-resource/ueditor.all.js +23 -32644
- package/ueditor-resource/ueditor.config.js +2 -655
- package/ueditor-resource/ueditor.parse.js +2 -639
- package/es/LcdpUeditor.d.ts.map +0 -1
- package/es/const.d.ts.map +0 -1
- package/es/index.d.ts.map +0 -1
- package/es/tools/UeditorResourceLoader.d.ts.map +0 -1
- package/es/tools/filterHtmlNode.d.ts.map +0 -1
- package/es/tools/loadScript.d.ts.map +0 -1
- package/es/type.d.ts.map +0 -1
| @@ -1,3581 +1,4 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
            //
         | 
| 3 | 
            -
            // All functions that need access to the editor's state live inside
         | 
| 4 | 
            -
            // the CodeMirror function. Below that, at the bottom of the file,
         | 
| 5 | 
            -
            // some utilities are defined.
         | 
| 6 | 
            -
             | 
| 7 | 
            -
            // CodeMirror is the only global var we claim
         | 
| 8 | 
            -
            var CodeMirror = (function() {
         | 
| 9 | 
            -
                // This is the function that produces an editor instance. It's
         | 
| 10 | 
            -
                // closure is used to store the editor state.
         | 
| 11 | 
            -
                function CodeMirror(place, givenOptions) {
         | 
| 12 | 
            -
                    // Determine effective options based on given values and defaults.
         | 
| 13 | 
            -
                    var options = {}, defaults = CodeMirror.defaults;
         | 
| 14 | 
            -
                    for (var opt in defaults)
         | 
| 15 | 
            -
                        if (defaults.hasOwnProperty(opt))
         | 
| 16 | 
            -
                            options[opt] = (givenOptions && givenOptions.hasOwnProperty(opt) ? givenOptions : defaults)[opt];
         | 
| 17 | 
            -
             | 
| 18 | 
            -
                    var targetDocument = options["document"];
         | 
| 19 | 
            -
                    // The element in which the editor lives.
         | 
| 20 | 
            -
                    var wrapper = targetDocument.createElement("div");
         | 
| 21 | 
            -
                    wrapper.className = "CodeMirror" + (options.lineWrapping ? " CodeMirror-wrap" : "");
         | 
| 22 | 
            -
                    // This mess creates the base DOM structure for the editor.
         | 
| 23 | 
            -
                    wrapper.innerHTML =
         | 
| 24 | 
            -
                        '<div style="overflow: hidden; position: relative; width: 3px; height: 0px;">' + // Wraps and hides input textarea
         | 
| 25 | 
            -
                            '<textarea style="position: absolute; padding: 0; width: 1px;" wrap="off" ' +
         | 
| 26 | 
            -
                            'autocorrect="off" autocapitalize="off"></textarea></div>' +
         | 
| 27 | 
            -
                            '<div class="CodeMirror-scroll" tabindex="-1">' +
         | 
| 28 | 
            -
                            '<div style="position: relative">' + // Set to the height of the text, causes scrolling
         | 
| 29 | 
            -
                            '<div style="position: relative">' + // Moved around its parent to cover visible view
         | 
| 30 | 
            -
                            '<div class="CodeMirror-gutter"><div class="CodeMirror-gutter-text"></div></div>' +
         | 
| 31 | 
            -
                            // Provides positioning relative to (visible) text origin
         | 
| 32 | 
            -
                            '<div class="CodeMirror-lines"><div style="position: relative">' +
         | 
| 33 | 
            -
                            '<div style="position: absolute; width: 100%; height: 0; overflow: hidden; visibility: hidden"></div>' +
         | 
| 34 | 
            -
                            '<pre class="CodeMirror-cursor"> </pre>' + // Absolutely positioned blinky cursor
         | 
| 35 | 
            -
                            '<div></div>' + // This DIV contains the actual code
         | 
| 36 | 
            -
                            '</div></div></div></div></div>';
         | 
| 37 | 
            -
                    if (place.appendChild) place.appendChild(wrapper); else place(wrapper);
         | 
| 38 | 
            -
                    // I've never seen more elegant code in my life.
         | 
| 39 | 
            -
                    var inputDiv = wrapper.firstChild, input = inputDiv.firstChild,
         | 
| 40 | 
            -
                        scroller = wrapper.lastChild, code = scroller.firstChild,
         | 
| 41 | 
            -
                        mover = code.firstChild, gutter = mover.firstChild, gutterText = gutter.firstChild,
         | 
| 42 | 
            -
                        lineSpace = gutter.nextSibling.firstChild, measure = lineSpace.firstChild,
         | 
| 43 | 
            -
                        cursor = measure.nextSibling, lineDiv = cursor.nextSibling;
         | 
| 44 | 
            -
                    themeChanged();
         | 
| 45 | 
            -
                    // Needed to hide big blue blinking cursor on Mobile Safari
         | 
| 46 | 
            -
                    if (/AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent)) input.style.width = "0px";
         | 
| 47 | 
            -
                    if (!webkit) lineSpace.draggable = true;
         | 
| 48 | 
            -
                    if (options.tabindex != null) input.tabIndex = options.tabindex;
         | 
| 49 | 
            -
                    if (!options.gutter && !options.lineNumbers) gutter.style.display = "none";
         | 
| 50 | 
            -
             | 
| 51 | 
            -
                    // Check for problem with IE innerHTML not working when we have a
         | 
| 52 | 
            -
                    // P (or similar) parent node.
         | 
| 53 | 
            -
                    try { stringWidth("x"); }
         | 
| 54 | 
            -
                    catch (e) {
         | 
| 55 | 
            -
                        if (e.message.match(/runtime/i))
         | 
| 56 | 
            -
                            e = new Error("A CodeMirror inside a P-style element does not work in Internet Explorer. (innerHTML bug)");
         | 
| 57 | 
            -
                        throw e;
         | 
| 58 | 
            -
                    }
         | 
| 59 | 
            -
             | 
| 60 | 
            -
                    // Delayed object wrap timeouts, making sure only one is active. blinker holds an interval.
         | 
| 61 | 
            -
                    var poll = new Delayed(), highlight = new Delayed(), blinker;
         | 
| 62 | 
            -
             | 
| 63 | 
            -
                    // mode holds a mode API object. doc is the tree of Line objects,
         | 
| 64 | 
            -
                    // work an array of lines that should be parsed, and history the
         | 
| 65 | 
            -
                    // undo history (instance of History constructor).
         | 
| 66 | 
            -
                    var mode, doc = new BranchChunk([new LeafChunk([new Line("")])]), work, focused;
         | 
| 67 | 
            -
                    loadMode();
         | 
| 68 | 
            -
                    // The selection. These are always maintained to point at valid
         | 
| 69 | 
            -
                    // positions. Inverted is used to remember that the user is
         | 
| 70 | 
            -
                    // selecting bottom-to-top.
         | 
| 71 | 
            -
                    var sel = {from: {line: 0, ch: 0}, to: {line: 0, ch: 0}, inverted: false};
         | 
| 72 | 
            -
                    // Selection-related flags. shiftSelecting obviously tracks
         | 
| 73 | 
            -
                    // whether the user is holding shift.
         | 
| 74 | 
            -
                    var shiftSelecting, lastClick, lastDoubleClick, draggingText, overwrite = false;
         | 
| 75 | 
            -
                    // Variables used by startOperation/endOperation to track what
         | 
| 76 | 
            -
                    // happened during the operation.
         | 
| 77 | 
            -
                    var updateInput, userSelChange, changes, textChanged, selectionChanged, leaveInputAlone,
         | 
| 78 | 
            -
                        gutterDirty, callbacks;
         | 
| 79 | 
            -
                    // Current visible range (may be bigger than the view window).
         | 
| 80 | 
            -
                    var displayOffset = 0, showingFrom = 0, showingTo = 0, lastSizeC = 0;
         | 
| 81 | 
            -
                    // bracketHighlighted is used to remember that a backet has been
         | 
| 82 | 
            -
                    // marked.
         | 
| 83 | 
            -
                    var bracketHighlighted;
         | 
| 84 | 
            -
                    // Tracks the maximum line length so that the horizontal scrollbar
         | 
| 85 | 
            -
                    // can be kept static when scrolling.
         | 
| 86 | 
            -
                    var maxLine = "", maxWidth, tabText = computeTabText();
         | 
| 87 | 
            -
             | 
| 88 | 
            -
                    // Initialize the content.
         | 
| 89 | 
            -
                    operation(function(){setValue(options.value || ""); updateInput = false;})();
         | 
| 90 | 
            -
                    var history = new History();
         | 
| 91 | 
            -
             | 
| 92 | 
            -
                    // Register our event handlers.
         | 
| 93 | 
            -
                    connect(scroller, "mousedown", operation(onMouseDown));
         | 
| 94 | 
            -
                    connect(scroller, "dblclick", operation(onDoubleClick));
         | 
| 95 | 
            -
                    connect(lineSpace, "dragstart", onDragStart);
         | 
| 96 | 
            -
                    connect(lineSpace, "selectstart", e_preventDefault);
         | 
| 97 | 
            -
                    // Gecko browsers fire contextmenu *after* opening the menu, at
         | 
| 98 | 
            -
                    // which point we can't mess with it anymore. Context menu is
         | 
| 99 | 
            -
                    // handled in onMouseDown for Gecko.
         | 
| 100 | 
            -
                    if (!gecko) connect(scroller, "contextmenu", onContextMenu);
         | 
| 101 | 
            -
                    connect(scroller, "scroll", function() {
         | 
| 102 | 
            -
                        updateDisplay([]);
         | 
| 103 | 
            -
                        if (options.fixedGutter) gutter.style.left = scroller.scrollLeft + "px";
         | 
| 104 | 
            -
                        if (options.onScroll) options.onScroll(instance);
         | 
| 105 | 
            -
                    });
         | 
| 106 | 
            -
                    connect(window, "resize", function() {updateDisplay(true);});
         | 
| 107 | 
            -
                    connect(input, "keyup", operation(onKeyUp));
         | 
| 108 | 
            -
                    connect(input, "input", fastPoll);
         | 
| 109 | 
            -
                    connect(input, "keydown", operation(onKeyDown));
         | 
| 110 | 
            -
                    connect(input, "keypress", operation(onKeyPress));
         | 
| 111 | 
            -
                    connect(input, "focus", onFocus);
         | 
| 112 | 
            -
                    connect(input, "blur", onBlur);
         | 
| 113 | 
            -
             | 
| 114 | 
            -
                    connect(scroller, "dragenter", e_stop);
         | 
| 115 | 
            -
                    connect(scroller, "dragover", e_stop);
         | 
| 116 | 
            -
                    connect(scroller, "drop", operation(onDrop));
         | 
| 117 | 
            -
                    connect(scroller, "paste", function(){focusInput(); fastPoll();});
         | 
| 118 | 
            -
                    connect(input, "paste", fastPoll);
         | 
| 119 | 
            -
                    connect(input, "cut", operation(function(){replaceSelection("");}));
         | 
| 120 | 
            -
             | 
| 121 | 
            -
                    // IE throws unspecified error in certain cases, when
         | 
| 122 | 
            -
                    // trying to access activeElement before onload
         | 
| 123 | 
            -
                    var hasFocus; try { hasFocus = (targetDocument.activeElement == input); } catch(e) { }
         | 
| 124 | 
            -
                    if (hasFocus) setTimeout(onFocus, 20);
         | 
| 125 | 
            -
                    else onBlur();
         | 
| 126 | 
            -
             | 
| 127 | 
            -
                    function isLine(l) {return l >= 0 && l < doc.size;}
         | 
| 128 | 
            -
                    // The instance object that we'll return. Mostly calls out to
         | 
| 129 | 
            -
                    // local functions in the CodeMirror function. Some do some extra
         | 
| 130 | 
            -
                    // range checking and/or clipping. operation is used to wrap the
         | 
| 131 | 
            -
                    // call so that changes it makes are tracked, and the display is
         | 
| 132 | 
            -
                    // updated afterwards.
         | 
| 133 | 
            -
                    var instance = wrapper.CodeMirror = {
         | 
| 134 | 
            -
                        getValue: getValue,
         | 
| 135 | 
            -
                        setValue: operation(setValue),
         | 
| 136 | 
            -
                        getSelection: getSelection,
         | 
| 137 | 
            -
                        replaceSelection: operation(replaceSelection),
         | 
| 138 | 
            -
                        focus: function(){focusInput(); onFocus(); fastPoll();},
         | 
| 139 | 
            -
                        setOption: function(option, value) {
         | 
| 140 | 
            -
                            var oldVal = options[option];
         | 
| 141 | 
            -
                            options[option] = value;
         | 
| 142 | 
            -
                            if (option == "mode" || option == "indentUnit") loadMode();
         | 
| 143 | 
            -
                            else if (option == "readOnly" && value) {onBlur(); input.blur();}
         | 
| 144 | 
            -
                            else if (option == "theme") themeChanged();
         | 
| 145 | 
            -
                            else if (option == "lineWrapping" && oldVal != value) operation(wrappingChanged)();
         | 
| 146 | 
            -
                            else if (option == "tabSize") operation(tabsChanged)();
         | 
| 147 | 
            -
                            if (option == "lineNumbers" || option == "gutter" || option == "firstLineNumber" || option == "theme")
         | 
| 148 | 
            -
                                operation(gutterChanged)();
         | 
| 149 | 
            -
                        },
         | 
| 150 | 
            -
                        getOption: function(option) {return options[option];},
         | 
| 151 | 
            -
                        undo: operation(undo),
         | 
| 152 | 
            -
                        redo: operation(redo),
         | 
| 153 | 
            -
                        indentLine: operation(function(n, dir) {
         | 
| 154 | 
            -
                            if (isLine(n)) indentLine(n, dir == null ? "smart" : dir ? "add" : "subtract");
         | 
| 155 | 
            -
                        }),
         | 
| 156 | 
            -
                        indentSelection: operation(indentSelected),
         | 
| 157 | 
            -
                        historySize: function() {return {undo: history.done.length, redo: history.undone.length};},
         | 
| 158 | 
            -
                        clearHistory: function() {history = new History();},
         | 
| 159 | 
            -
                        matchBrackets: operation(function(){matchBrackets(true);}),
         | 
| 160 | 
            -
                        getTokenAt: operation(function(pos) {
         | 
| 161 | 
            -
                            pos = clipPos(pos);
         | 
| 162 | 
            -
                            return getLine(pos.line).getTokenAt(mode, getStateBefore(pos.line), pos.ch);
         | 
| 163 | 
            -
                        }),
         | 
| 164 | 
            -
                        getStateAfter: function(line) {
         | 
| 165 | 
            -
                            line = clipLine(line == null ? doc.size - 1: line);
         | 
| 166 | 
            -
                            return getStateBefore(line + 1);
         | 
| 167 | 
            -
                        },
         | 
| 168 | 
            -
                        cursorCoords: function(start){
         | 
| 169 | 
            -
                            if (start == null) start = sel.inverted;
         | 
| 170 | 
            -
                            return pageCoords(start ? sel.from : sel.to);
         | 
| 171 | 
            -
                        },
         | 
| 172 | 
            -
                        charCoords: function(pos){return pageCoords(clipPos(pos));},
         | 
| 173 | 
            -
                        coordsChar: function(coords) {
         | 
| 174 | 
            -
                            var off = eltOffset(lineSpace);
         | 
| 175 | 
            -
                            return coordsChar(coords.x - off.left, coords.y - off.top);
         | 
| 176 | 
            -
                        },
         | 
| 177 | 
            -
                        markText: operation(markText),
         | 
| 178 | 
            -
                        setBookmark: setBookmark,
         | 
| 179 | 
            -
                        setMarker: operation(addGutterMarker),
         | 
| 180 | 
            -
                        clearMarker: operation(removeGutterMarker),
         | 
| 181 | 
            -
                        setLineClass: operation(setLineClass),
         | 
| 182 | 
            -
                        hideLine: operation(function(h) {return setLineHidden(h, true);}),
         | 
| 183 | 
            -
                        showLine: operation(function(h) {return setLineHidden(h, false);}),
         | 
| 184 | 
            -
                        onDeleteLine: function(line, f) {
         | 
| 185 | 
            -
                            if (typeof line == "number") {
         | 
| 186 | 
            -
                                if (!isLine(line)) return null;
         | 
| 187 | 
            -
                                line = getLine(line);
         | 
| 188 | 
            -
                            }
         | 
| 189 | 
            -
                            (line.handlers || (line.handlers = [])).push(f);
         | 
| 190 | 
            -
                            return line;
         | 
| 191 | 
            -
                        },
         | 
| 192 | 
            -
                        lineInfo: lineInfo,
         | 
| 193 | 
            -
                        addWidget: function(pos, node, scroll, vert, horiz) {
         | 
| 194 | 
            -
                            pos = localCoords(clipPos(pos));
         | 
| 195 | 
            -
                            var top = pos.yBot, left = pos.x;
         | 
| 196 | 
            -
                            node.style.position = "absolute";
         | 
| 197 | 
            -
                            code.appendChild(node);
         | 
| 198 | 
            -
                            if (vert == "over") top = pos.y;
         | 
| 199 | 
            -
                            else if (vert == "near") {
         | 
| 200 | 
            -
                                var vspace = Math.max(scroller.offsetHeight, doc.height * textHeight()),
         | 
| 201 | 
            -
                                    hspace = Math.max(code.clientWidth, lineSpace.clientWidth) - paddingLeft();
         | 
| 202 | 
            -
                                if (pos.yBot + node.offsetHeight > vspace && pos.y > node.offsetHeight)
         | 
| 203 | 
            -
                                    top = pos.y - node.offsetHeight;
         | 
| 204 | 
            -
                                if (left + node.offsetWidth > hspace)
         | 
| 205 | 
            -
                                    left = hspace - node.offsetWidth;
         | 
| 206 | 
            -
                            }
         | 
| 207 | 
            -
                            node.style.top = (top + paddingTop()) + "px";
         | 
| 208 | 
            -
                            node.style.left = node.style.right = "";
         | 
| 209 | 
            -
                            if (horiz == "right") {
         | 
| 210 | 
            -
                                left = code.clientWidth - node.offsetWidth;
         | 
| 211 | 
            -
                                node.style.right = "0px";
         | 
| 212 | 
            -
                            } else {
         | 
| 213 | 
            -
                                if (horiz == "left") left = 0;
         | 
| 214 | 
            -
                                else if (horiz == "middle") left = (code.clientWidth - node.offsetWidth) / 2;
         | 
| 215 | 
            -
                                node.style.left = (left + paddingLeft()) + "px";
         | 
| 216 | 
            -
                            }
         | 
| 217 | 
            -
                            if (scroll)
         | 
| 218 | 
            -
                                scrollIntoView(left, top, left + node.offsetWidth, top + node.offsetHeight);
         | 
| 219 | 
            -
                        },
         | 
| 220 | 
            -
             | 
| 221 | 
            -
                        lineCount: function() {return doc.size;},
         | 
| 222 | 
            -
                        clipPos: clipPos,
         | 
| 223 | 
            -
                        getCursor: function(start) {
         | 
| 224 | 
            -
                            if (start == null) start = sel.inverted;
         | 
| 225 | 
            -
                            return copyPos(start ? sel.from : sel.to);
         | 
| 226 | 
            -
                        },
         | 
| 227 | 
            -
                        somethingSelected: function() {return !posEq(sel.from, sel.to);},
         | 
| 228 | 
            -
                        setCursor: operation(function(line, ch, user) {
         | 
| 229 | 
            -
                            if (ch == null && typeof line.line == "number") setCursor(line.line, line.ch, user);
         | 
| 230 | 
            -
                            else setCursor(line, ch, user);
         | 
| 231 | 
            -
                        }),
         | 
| 232 | 
            -
                        setSelection: operation(function(from, to, user) {
         | 
| 233 | 
            -
                            (user ? setSelectionUser : setSelection)(clipPos(from), clipPos(to || from));
         | 
| 234 | 
            -
                        }),
         | 
| 235 | 
            -
                        getLine: function(line) {if (isLine(line)) return getLine(line).text;},
         | 
| 236 | 
            -
                        getLineHandle: function(line) {if (isLine(line)) return getLine(line);},
         | 
| 237 | 
            -
                        setLine: operation(function(line, text) {
         | 
| 238 | 
            -
                            if (isLine(line)) replaceRange(text, {line: line, ch: 0}, {line: line, ch: getLine(line).text.length});
         | 
| 239 | 
            -
                        }),
         | 
| 240 | 
            -
                        removeLine: operation(function(line) {
         | 
| 241 | 
            -
                            if (isLine(line)) replaceRange("", {line: line, ch: 0}, clipPos({line: line+1, ch: 0}));
         | 
| 242 | 
            -
                        }),
         | 
| 243 | 
            -
                        replaceRange: operation(replaceRange),
         | 
| 244 | 
            -
                        getRange: function(from, to) {return getRange(clipPos(from), clipPos(to));},
         | 
| 245 | 
            -
             | 
| 246 | 
            -
                        execCommand: function(cmd) {return commands[cmd](instance);},
         | 
| 247 | 
            -
                        // Stuff used by commands, probably not much use to outside code.
         | 
| 248 | 
            -
                        moveH: operation(moveH),
         | 
| 249 | 
            -
                        deleteH: operation(deleteH),
         | 
| 250 | 
            -
                        moveV: operation(moveV),
         | 
| 251 | 
            -
                        toggleOverwrite: function() {overwrite = !overwrite;},
         | 
| 252 | 
            -
             | 
| 253 | 
            -
                        posFromIndex: function(off) {
         | 
| 254 | 
            -
                            var lineNo = 0, ch;
         | 
| 255 | 
            -
                            doc.iter(0, doc.size, function(line) {
         | 
| 256 | 
            -
                                var sz = line.text.length + 1;
         | 
| 257 | 
            -
                                if (sz > off) { ch = off; return true; }
         | 
| 258 | 
            -
                                off -= sz;
         | 
| 259 | 
            -
                                ++lineNo;
         | 
| 260 | 
            -
                            });
         | 
| 261 | 
            -
                            return clipPos({line: lineNo, ch: ch});
         | 
| 262 | 
            -
                        },
         | 
| 263 | 
            -
                        indexFromPos: function (coords) {
         | 
| 264 | 
            -
                            if (coords.line < 0 || coords.ch < 0) return 0;
         | 
| 265 | 
            -
                            var index = coords.ch;
         | 
| 266 | 
            -
                            doc.iter(0, coords.line, function (line) {
         | 
| 267 | 
            -
                                index += line.text.length + 1;
         | 
| 268 | 
            -
                            });
         | 
| 269 | 
            -
                            return index;
         | 
| 270 | 
            -
                        },
         | 
| 271 | 
            -
             | 
| 272 | 
            -
                        operation: function(f){return operation(f)();},
         | 
| 273 | 
            -
                        refresh: function(){updateDisplay(true);},
         | 
| 274 | 
            -
                        getInputField: function(){return input;},
         | 
| 275 | 
            -
                        getWrapperElement: function(){return wrapper;},
         | 
| 276 | 
            -
                        getScrollerElement: function(){return scroller;},
         | 
| 277 | 
            -
                        getGutterElement: function(){return gutter;}
         | 
| 278 | 
            -
                    };
         | 
| 279 | 
            -
             | 
| 280 | 
            -
                    function getLine(n) { return getLineAt(doc, n); }
         | 
| 281 | 
            -
                    function updateLineHeight(line, height) {
         | 
| 282 | 
            -
                        gutterDirty = true;
         | 
| 283 | 
            -
                        var diff = height - line.height;
         | 
| 284 | 
            -
                        for (var n = line; n; n = n.parent) n.height += diff;
         | 
| 285 | 
            -
                    }
         | 
| 286 | 
            -
             | 
| 287 | 
            -
                    function setValue(code) {
         | 
| 288 | 
            -
                        var top = {line: 0, ch: 0};
         | 
| 289 | 
            -
                        updateLines(top, {line: doc.size - 1, ch: getLine(doc.size-1).text.length},
         | 
| 290 | 
            -
                            splitLines(code), top, top);
         | 
| 291 | 
            -
                        updateInput = true;
         | 
| 292 | 
            -
                    }
         | 
| 293 | 
            -
                    function getValue(code) {
         | 
| 294 | 
            -
                        var text = [];
         | 
| 295 | 
            -
                        doc.iter(0, doc.size, function(line) { text.push(line.text); });
         | 
| 296 | 
            -
                        return text.join("\n");
         | 
| 297 | 
            -
                    }
         | 
| 298 | 
            -
             | 
| 299 | 
            -
                    function onMouseDown(e) {
         | 
| 300 | 
            -
                        setShift(e.shiftKey);
         | 
| 301 | 
            -
                        // Check whether this is a click in a widget
         | 
| 302 | 
            -
                        for (var n = e_target(e); n != wrapper; n = n.parentNode)
         | 
| 303 | 
            -
                            if (n.parentNode == code && n != mover) return;
         | 
| 304 | 
            -
             | 
| 305 | 
            -
                        // See if this is a click in the gutter
         | 
| 306 | 
            -
                        for (var n = e_target(e); n != wrapper; n = n.parentNode)
         | 
| 307 | 
            -
                            if (n.parentNode == gutterText) {
         | 
| 308 | 
            -
                                if (options.onGutterClick)
         | 
| 309 | 
            -
                                    options.onGutterClick(instance, indexOf(gutterText.childNodes, n) + showingFrom, e);
         | 
| 310 | 
            -
                                return e_preventDefault(e);
         | 
| 311 | 
            -
                            }
         | 
| 312 | 
            -
             | 
| 313 | 
            -
                        var start = posFromMouse(e);
         | 
| 314 | 
            -
             | 
| 315 | 
            -
                        switch (e_button(e)) {
         | 
| 316 | 
            -
                            case 3:
         | 
| 317 | 
            -
                                if (gecko && !mac) onContextMenu(e);
         | 
| 318 | 
            -
                                return;
         | 
| 319 | 
            -
                            case 2:
         | 
| 320 | 
            -
                                if (start) setCursor(start.line, start.ch, true);
         | 
| 321 | 
            -
                                return;
         | 
| 322 | 
            -
                        }
         | 
| 323 | 
            -
                        // For button 1, if it was clicked inside the editor
         | 
| 324 | 
            -
                        // (posFromMouse returning non-null), we have to adjust the
         | 
| 325 | 
            -
                        // selection.
         | 
| 326 | 
            -
                        if (!start) {if (e_target(e) == scroller) e_preventDefault(e); return;}
         | 
| 327 | 
            -
             | 
| 328 | 
            -
                        if (!focused) onFocus();
         | 
| 329 | 
            -
             | 
| 330 | 
            -
                        var now = +new Date;
         | 
| 331 | 
            -
                        if (lastDoubleClick && lastDoubleClick.time > now - 400 && posEq(lastDoubleClick.pos, start)) {
         | 
| 332 | 
            -
                            e_preventDefault(e);
         | 
| 333 | 
            -
                            setTimeout(focusInput, 20);
         | 
| 334 | 
            -
                            return selectLine(start.line);
         | 
| 335 | 
            -
                        } else if (lastClick && lastClick.time > now - 400 && posEq(lastClick.pos, start)) {
         | 
| 336 | 
            -
                            lastDoubleClick = {time: now, pos: start};
         | 
| 337 | 
            -
                            e_preventDefault(e);
         | 
| 338 | 
            -
                            return selectWordAt(start);
         | 
| 339 | 
            -
                        } else { lastClick = {time: now, pos: start}; }
         | 
| 340 | 
            -
             | 
| 341 | 
            -
                        var last = start, going;
         | 
| 342 | 
            -
                        if (dragAndDrop && !posEq(sel.from, sel.to) &&
         | 
| 343 | 
            -
                            !posLess(start, sel.from) && !posLess(sel.to, start)) {
         | 
| 344 | 
            -
                            // Let the drag handler handle this.
         | 
| 345 | 
            -
                            if (webkit) lineSpace.draggable = true;
         | 
| 346 | 
            -
                            var up = connect(targetDocument, "mouseup", operation(function(e2) {
         | 
| 347 | 
            -
                                if (webkit) lineSpace.draggable = false;
         | 
| 348 | 
            -
                                draggingText = false;
         | 
| 349 | 
            -
                                up();
         | 
| 350 | 
            -
                                if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
         | 
| 351 | 
            -
                                    e_preventDefault(e2);
         | 
| 352 | 
            -
                                    setCursor(start.line, start.ch, true);
         | 
| 353 | 
            -
                                    focusInput();
         | 
| 354 | 
            -
                                }
         | 
| 355 | 
            -
                            }), true);
         | 
| 356 | 
            -
                            draggingText = true;
         | 
| 357 | 
            -
                            return;
         | 
| 358 | 
            -
                        }
         | 
| 359 | 
            -
                        e_preventDefault(e);
         | 
| 360 | 
            -
                        setCursor(start.line, start.ch, true);
         | 
| 361 | 
            -
             | 
| 362 | 
            -
                        function extend(e) {
         | 
| 363 | 
            -
                            var cur = posFromMouse(e, true);
         | 
| 364 | 
            -
                            if (cur && !posEq(cur, last)) {
         | 
| 365 | 
            -
                                if (!focused) onFocus();
         | 
| 366 | 
            -
                                last = cur;
         | 
| 367 | 
            -
                                setSelectionUser(start, cur);
         | 
| 368 | 
            -
                                updateInput = false;
         | 
| 369 | 
            -
                                var visible = visibleLines();
         | 
| 370 | 
            -
                                if (cur.line >= visible.to || cur.line < visible.from)
         | 
| 371 | 
            -
                                    going = setTimeout(operation(function(){extend(e);}), 150);
         | 
| 372 | 
            -
                            }
         | 
| 373 | 
            -
                        }
         | 
| 374 | 
            -
             | 
| 375 | 
            -
                        var move = connect(targetDocument, "mousemove", operation(function(e) {
         | 
| 376 | 
            -
                            clearTimeout(going);
         | 
| 377 | 
            -
                            e_preventDefault(e);
         | 
| 378 | 
            -
                            extend(e);
         | 
| 379 | 
            -
                        }), true);
         | 
| 380 | 
            -
                        var up = connect(targetDocument, "mouseup", operation(function(e) {
         | 
| 381 | 
            -
                            clearTimeout(going);
         | 
| 382 | 
            -
                            var cur = posFromMouse(e);
         | 
| 383 | 
            -
                            if (cur) setSelectionUser(start, cur);
         | 
| 384 | 
            -
                            e_preventDefault(e);
         | 
| 385 | 
            -
                            focusInput();
         | 
| 386 | 
            -
                            updateInput = true;
         | 
| 387 | 
            -
                            move(); up();
         | 
| 388 | 
            -
                        }), true);
         | 
| 389 | 
            -
                    }
         | 
| 390 | 
            -
                    function onDoubleClick(e) {
         | 
| 391 | 
            -
                        for (var n = e_target(e); n != wrapper; n = n.parentNode)
         | 
| 392 | 
            -
                            if (n.parentNode == gutterText) return e_preventDefault(e);
         | 
| 393 | 
            -
                        var start = posFromMouse(e);
         | 
| 394 | 
            -
                        if (!start) return;
         | 
| 395 | 
            -
                        lastDoubleClick = {time: +new Date, pos: start};
         | 
| 396 | 
            -
                        e_preventDefault(e);
         | 
| 397 | 
            -
                        selectWordAt(start);
         | 
| 398 | 
            -
                    }
         | 
| 399 | 
            -
                    function onDrop(e) {
         | 
| 400 | 
            -
                        e.preventDefault();
         | 
| 401 | 
            -
                        var pos = posFromMouse(e, true), files = e.dataTransfer.files;
         | 
| 402 | 
            -
                        if (!pos || options.readOnly) return;
         | 
| 403 | 
            -
                        if (files && files.length && window.FileReader && window.File) {
         | 
| 404 | 
            -
                            function loadFile(file, i) {
         | 
| 405 | 
            -
                                var reader = new FileReader;
         | 
| 406 | 
            -
                                reader.onload = function() {
         | 
| 407 | 
            -
                                    text[i] = reader.result;
         | 
| 408 | 
            -
                                    if (++read == n) {
         | 
| 409 | 
            -
                                        pos = clipPos(pos);
         | 
| 410 | 
            -
                                        operation(function() {
         | 
| 411 | 
            -
                                            var end = replaceRange(text.join(""), pos, pos);
         | 
| 412 | 
            -
                                            setSelectionUser(pos, end);
         | 
| 413 | 
            -
                                        })();
         | 
| 414 | 
            -
                                    }
         | 
| 415 | 
            -
                                };
         | 
| 416 | 
            -
                                reader.readAsText(file);
         | 
| 417 | 
            -
                            }
         | 
| 418 | 
            -
                            var n = files.length, text = Array(n), read = 0;
         | 
| 419 | 
            -
                            for (var i = 0; i < n; ++i) loadFile(files[i], i);
         | 
| 420 | 
            -
                        }
         | 
| 421 | 
            -
                        else {
         | 
| 422 | 
            -
                            try {
         | 
| 423 | 
            -
                                var text = e.dataTransfer.getData("Text");
         | 
| 424 | 
            -
                                if (text) {
         | 
| 425 | 
            -
                                    var end = replaceRange(text, pos, pos);
         | 
| 426 | 
            -
                                    var curFrom = sel.from, curTo = sel.to;
         | 
| 427 | 
            -
                                    setSelectionUser(pos, end);
         | 
| 428 | 
            -
                                    if (draggingText) replaceRange("", curFrom, curTo);
         | 
| 429 | 
            -
                                    focusInput();
         | 
| 430 | 
            -
                                }
         | 
| 431 | 
            -
                            }
         | 
| 432 | 
            -
                            catch(e){}
         | 
| 433 | 
            -
                        }
         | 
| 434 | 
            -
                    }
         | 
| 435 | 
            -
                    function onDragStart(e) {
         | 
| 436 | 
            -
                        var txt = getSelection();
         | 
| 437 | 
            -
                        // This will reset escapeElement
         | 
| 438 | 
            -
                        htmlEscape(txt);
         | 
| 439 | 
            -
                        e.dataTransfer.setDragImage(escapeElement, 0, 0);
         | 
| 440 | 
            -
                        e.dataTransfer.setData("Text", txt);
         | 
| 441 | 
            -
                    }
         | 
| 442 | 
            -
                    function handleKeyBinding(e) {
         | 
| 443 | 
            -
                        var name = keyNames[e.keyCode], next = keyMap[options.keyMap].auto, bound, dropShift;
         | 
| 444 | 
            -
                        if (name == null || e.altGraphKey) {
         | 
| 445 | 
            -
                            if (next) options.keyMap = next;
         | 
| 446 | 
            -
                            return null;
         | 
| 447 | 
            -
                        }
         | 
| 448 | 
            -
                        if (e.altKey) name = "Alt-" + name;
         | 
| 449 | 
            -
                        if (e.ctrlKey) name = "Ctrl-" + name;
         | 
| 450 | 
            -
                        if (e.metaKey) name = "Cmd-" + name;
         | 
| 451 | 
            -
                        if (e.shiftKey && (bound = lookupKey("Shift-" + name, options.extraKeys, options.keyMap))) {
         | 
| 452 | 
            -
                            dropShift = true;
         | 
| 453 | 
            -
                        } else {
         | 
| 454 | 
            -
                            bound = lookupKey(name, options.extraKeys, options.keyMap);
         | 
| 455 | 
            -
                        }
         | 
| 456 | 
            -
                        if (typeof bound == "string") {
         | 
| 457 | 
            -
                            if (commands.propertyIsEnumerable(bound)) bound = commands[bound];
         | 
| 458 | 
            -
                            else bound = null;
         | 
| 459 | 
            -
                        }
         | 
| 460 | 
            -
                        if (next && (bound || !isModifierKey(e))) options.keyMap = next;
         | 
| 461 | 
            -
                        if (!bound) return false;
         | 
| 462 | 
            -
                        if (dropShift) {
         | 
| 463 | 
            -
                            var prevShift = shiftSelecting;
         | 
| 464 | 
            -
                            shiftSelecting = null;
         | 
| 465 | 
            -
                            bound(instance);
         | 
| 466 | 
            -
                            shiftSelecting = prevShift;
         | 
| 467 | 
            -
                        } else bound(instance);
         | 
| 468 | 
            -
                        e_preventDefault(e);
         | 
| 469 | 
            -
                        return true;
         | 
| 470 | 
            -
                    }
         | 
| 471 | 
            -
                    var lastStoppedKey = null;
         | 
| 472 | 
            -
                    function onKeyDown(e) {
         | 
| 473 | 
            -
                        if (!focused) onFocus();
         | 
| 474 | 
            -
                        var code = e.keyCode;
         | 
| 475 | 
            -
                        // IE does strange things with escape.
         | 
| 476 | 
            -
                        if (ie && code == 27) { e.returnValue = false; }
         | 
| 477 | 
            -
                        setShift(code == 16 || e.shiftKey);
         | 
| 478 | 
            -
                        // First give onKeyEvent option a chance to handle this.
         | 
| 479 | 
            -
                        if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return;
         | 
| 480 | 
            -
                        var handled = handleKeyBinding(e);
         | 
| 481 | 
            -
                        if (window.opera) {
         | 
| 482 | 
            -
                            lastStoppedKey = handled ? e.keyCode : null;
         | 
| 483 | 
            -
                            // Opera has no cut event... we try to at least catch the key combo
         | 
| 484 | 
            -
                            if (!handled && (mac ? e.metaKey : e.ctrlKey) && e.keyCode == 88)
         | 
| 485 | 
            -
                                replaceSelection("");
         | 
| 486 | 
            -
                        }
         | 
| 487 | 
            -
                    }
         | 
| 488 | 
            -
                    function onKeyPress(e) {
         | 
| 489 | 
            -
                        if (window.opera && e.keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;}
         | 
| 490 | 
            -
                        if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return;
         | 
| 491 | 
            -
                        if (window.opera && !e.which && handleKeyBinding(e)) return;
         | 
| 492 | 
            -
                        if (options.electricChars && mode.electricChars) {
         | 
| 493 | 
            -
                            var ch = String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode);
         | 
| 494 | 
            -
                            if (mode.electricChars.indexOf(ch) > -1)
         | 
| 495 | 
            -
                                setTimeout(operation(function() {indentLine(sel.to.line, "smart");}), 75);
         | 
| 496 | 
            -
                        }
         | 
| 497 | 
            -
                        fastPoll();
         | 
| 498 | 
            -
                    }
         | 
| 499 | 
            -
                    function onKeyUp(e) {
         | 
| 500 | 
            -
                        if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return;
         | 
| 501 | 
            -
                        if (e.keyCode == 16) shiftSelecting = null;
         | 
| 502 | 
            -
                    }
         | 
| 503 | 
            -
             | 
| 504 | 
            -
                    function onFocus() {
         | 
| 505 | 
            -
                        if (options.readOnly) return;
         | 
| 506 | 
            -
                        if (!focused) {
         | 
| 507 | 
            -
                            if (options.onFocus) options.onFocus(instance);
         | 
| 508 | 
            -
                            focused = true;
         | 
| 509 | 
            -
                            if (wrapper.className.search(/\bCodeMirror-focused\b/) == -1)
         | 
| 510 | 
            -
                                wrapper.className += " CodeMirror-focused";
         | 
| 511 | 
            -
                            if (!leaveInputAlone) resetInput(true);
         | 
| 512 | 
            -
                        }
         | 
| 513 | 
            -
                        slowPoll();
         | 
| 514 | 
            -
                        restartBlink();
         | 
| 515 | 
            -
                    }
         | 
| 516 | 
            -
                    function onBlur() {
         | 
| 517 | 
            -
                        if (focused) {
         | 
| 518 | 
            -
                            if (options.onBlur) options.onBlur(instance);
         | 
| 519 | 
            -
                            focused = false;
         | 
| 520 | 
            -
                            wrapper.className = wrapper.className.replace(" CodeMirror-focused", "");
         | 
| 521 | 
            -
                        }
         | 
| 522 | 
            -
                        clearInterval(blinker);
         | 
| 523 | 
            -
                        setTimeout(function() {if (!focused) shiftSelecting = null;}, 150);
         | 
| 524 | 
            -
                    }
         | 
| 525 | 
            -
             | 
| 526 | 
            -
                    // Replace the range from from to to by the strings in newText.
         | 
| 527 | 
            -
                    // Afterwards, set the selection to selFrom, selTo.
         | 
| 528 | 
            -
                    function updateLines(from, to, newText, selFrom, selTo) {
         | 
| 529 | 
            -
                        if (history) {
         | 
| 530 | 
            -
                            var old = [];
         | 
| 531 | 
            -
                            doc.iter(from.line, to.line + 1, function(line) { old.push(line.text); });
         | 
| 532 | 
            -
                            history.addChange(from.line, newText.length, old);
         | 
| 533 | 
            -
                            while (history.done.length > options.undoDepth) history.done.shift();
         | 
| 534 | 
            -
                        }
         | 
| 535 | 
            -
                        updateLinesNoUndo(from, to, newText, selFrom, selTo);
         | 
| 536 | 
            -
                    }
         | 
| 537 | 
            -
                    function unredoHelper(from, to) {
         | 
| 538 | 
            -
                        var change = from.pop();
         | 
| 539 | 
            -
                        if (change) {
         | 
| 540 | 
            -
                            var replaced = [], end = change.start + change.added;
         | 
| 541 | 
            -
                            doc.iter(change.start, end, function(line) { replaced.push(line.text); });
         | 
| 542 | 
            -
                            to.push({start: change.start, added: change.old.length, old: replaced});
         | 
| 543 | 
            -
                            var pos = clipPos({line: change.start + change.old.length - 1,
         | 
| 544 | 
            -
                                ch: editEnd(replaced[replaced.length-1], change.old[change.old.length-1])});
         | 
| 545 | 
            -
                            updateLinesNoUndo({line: change.start, ch: 0}, {line: end - 1, ch: getLine(end-1).text.length}, change.old, pos, pos);
         | 
| 546 | 
            -
                            updateInput = true;
         | 
| 547 | 
            -
                        }
         | 
| 548 | 
            -
                    }
         | 
| 549 | 
            -
                    function undo() {unredoHelper(history.done, history.undone);}
         | 
| 550 | 
            -
                    function redo() {unredoHelper(history.undone, history.done);}
         | 
| 551 | 
            -
             | 
| 552 | 
            -
                    function updateLinesNoUndo(from, to, newText, selFrom, selTo) {
         | 
| 553 | 
            -
                        var recomputeMaxLength = false, maxLineLength = maxLine.length;
         | 
| 554 | 
            -
                        if (!options.lineWrapping)
         | 
| 555 | 
            -
                            doc.iter(from.line, to.line, function(line) {
         | 
| 556 | 
            -
                                if (line.text.length == maxLineLength) {recomputeMaxLength = true; return true;}
         | 
| 557 | 
            -
                            });
         | 
| 558 | 
            -
                        if (from.line != to.line || newText.length > 1) gutterDirty = true;
         | 
| 559 | 
            -
             | 
| 560 | 
            -
                        var nlines = to.line - from.line, firstLine = getLine(from.line), lastLine = getLine(to.line);
         | 
| 561 | 
            -
                        // First adjust the line structure, taking some care to leave highlighting intact.
         | 
| 562 | 
            -
                        if (from.ch == 0 && to.ch == 0 && newText[newText.length - 1] == "") {
         | 
| 563 | 
            -
                            // This is a whole-line replace. Treated specially to make
         | 
| 564 | 
            -
                            // sure line objects move the way they are supposed to.
         | 
| 565 | 
            -
                            var added = [], prevLine = null;
         | 
| 566 | 
            -
                            if (from.line) {
         | 
| 567 | 
            -
                                prevLine = getLine(from.line - 1);
         | 
| 568 | 
            -
                                prevLine.fixMarkEnds(lastLine);
         | 
| 569 | 
            -
                            } else lastLine.fixMarkStarts();
         | 
| 570 | 
            -
                            for (var i = 0, e = newText.length - 1; i < e; ++i)
         | 
| 571 | 
            -
                                added.push(Line.inheritMarks(newText[i], prevLine));
         | 
| 572 | 
            -
                            if (nlines) doc.remove(from.line, nlines, callbacks);
         | 
| 573 | 
            -
                            if (added.length) doc.insert(from.line, added);
         | 
| 574 | 
            -
                        } else if (firstLine == lastLine) {
         | 
| 575 | 
            -
                            if (newText.length == 1)
         | 
| 576 | 
            -
                                firstLine.replace(from.ch, to.ch, newText[0]);
         | 
| 577 | 
            -
                            else {
         | 
| 578 | 
            -
                                lastLine = firstLine.split(to.ch, newText[newText.length-1]);
         | 
| 579 | 
            -
                                firstLine.replace(from.ch, null, newText[0]);
         | 
| 580 | 
            -
                                firstLine.fixMarkEnds(lastLine);
         | 
| 581 | 
            -
                                var added = [];
         | 
| 582 | 
            -
                                for (var i = 1, e = newText.length - 1; i < e; ++i)
         | 
| 583 | 
            -
                                    added.push(Line.inheritMarks(newText[i], firstLine));
         | 
| 584 | 
            -
                                added.push(lastLine);
         | 
| 585 | 
            -
                                doc.insert(from.line + 1, added);
         | 
| 586 | 
            -
                            }
         | 
| 587 | 
            -
                        } else if (newText.length == 1) {
         | 
| 588 | 
            -
                            firstLine.replace(from.ch, null, newText[0]);
         | 
| 589 | 
            -
                            lastLine.replace(null, to.ch, "");
         | 
| 590 | 
            -
                            firstLine.append(lastLine);
         | 
| 591 | 
            -
                            doc.remove(from.line + 1, nlines, callbacks);
         | 
| 592 | 
            -
                        } else {
         | 
| 593 | 
            -
                            var added = [];
         | 
| 594 | 
            -
                            firstLine.replace(from.ch, null, newText[0]);
         | 
| 595 | 
            -
                            lastLine.replace(null, to.ch, newText[newText.length-1]);
         | 
| 596 | 
            -
                            firstLine.fixMarkEnds(lastLine);
         | 
| 597 | 
            -
                            for (var i = 1, e = newText.length - 1; i < e; ++i)
         | 
| 598 | 
            -
                                added.push(Line.inheritMarks(newText[i], firstLine));
         | 
| 599 | 
            -
                            if (nlines > 1) doc.remove(from.line + 1, nlines - 1, callbacks);
         | 
| 600 | 
            -
                            doc.insert(from.line + 1, added);
         | 
| 601 | 
            -
                        }
         | 
| 602 | 
            -
                        if (options.lineWrapping) {
         | 
| 603 | 
            -
                            var perLine = scroller.clientWidth / charWidth() - 3;
         | 
| 604 | 
            -
                            doc.iter(from.line, from.line + newText.length, function(line) {
         | 
| 605 | 
            -
                                if (line.hidden) return;
         | 
| 606 | 
            -
                                var guess = Math.ceil(line.text.length / perLine) || 1;
         | 
| 607 | 
            -
                                if (guess != line.height) updateLineHeight(line, guess);
         | 
| 608 | 
            -
                            });
         | 
| 609 | 
            -
                        } else {
         | 
| 610 | 
            -
                            doc.iter(from.line, i + newText.length, function(line) {
         | 
| 611 | 
            -
                                var l = line.text;
         | 
| 612 | 
            -
                                if (l.length > maxLineLength) {
         | 
| 613 | 
            -
                                    maxLine = l; maxLineLength = l.length; maxWidth = null;
         | 
| 614 | 
            -
                                    recomputeMaxLength = false;
         | 
| 615 | 
            -
                                }
         | 
| 616 | 
            -
                            });
         | 
| 617 | 
            -
                            if (recomputeMaxLength) {
         | 
| 618 | 
            -
                                maxLineLength = 0; maxLine = ""; maxWidth = null;
         | 
| 619 | 
            -
                                doc.iter(0, doc.size, function(line) {
         | 
| 620 | 
            -
                                    var l = line.text;
         | 
| 621 | 
            -
                                    if (l.length > maxLineLength) {
         | 
| 622 | 
            -
                                        maxLineLength = l.length; maxLine = l;
         | 
| 623 | 
            -
                                    }
         | 
| 624 | 
            -
                                });
         | 
| 625 | 
            -
                            }
         | 
| 626 | 
            -
                        }
         | 
| 627 | 
            -
             | 
| 628 | 
            -
                        // Add these lines to the work array, so that they will be
         | 
| 629 | 
            -
                        // highlighted. Adjust work lines if lines were added/removed.
         | 
| 630 | 
            -
                        var newWork = [], lendiff = newText.length - nlines - 1;
         | 
| 631 | 
            -
                        for (var i = 0, l = work.length; i < l; ++i) {
         | 
| 632 | 
            -
                            var task = work[i];
         | 
| 633 | 
            -
                            if (task < from.line) newWork.push(task);
         | 
| 634 | 
            -
                            else if (task > to.line) newWork.push(task + lendiff);
         | 
| 635 | 
            -
                        }
         | 
| 636 | 
            -
                        var hlEnd = from.line + Math.min(newText.length, 500);
         | 
| 637 | 
            -
                        highlightLines(from.line, hlEnd);
         | 
| 638 | 
            -
                        newWork.push(hlEnd);
         | 
| 639 | 
            -
                        work = newWork;
         | 
| 640 | 
            -
                        startWorker(100);
         | 
| 641 | 
            -
                        // Remember that these lines changed, for updating the display
         | 
| 642 | 
            -
                        changes.push({from: from.line, to: to.line + 1, diff: lendiff});
         | 
| 643 | 
            -
                        var changeObj = {from: from, to: to, text: newText};
         | 
| 644 | 
            -
                        if (textChanged) {
         | 
| 645 | 
            -
                            for (var cur = textChanged; cur.next; cur = cur.next) {}
         | 
| 646 | 
            -
                            cur.next = changeObj;
         | 
| 647 | 
            -
                        } else textChanged = changeObj;
         | 
| 648 | 
            -
             | 
| 649 | 
            -
                        // Update the selection
         | 
| 650 | 
            -
                        function updateLine(n) {return n <= Math.min(to.line, to.line + lendiff) ? n : n + lendiff;}
         | 
| 651 | 
            -
                        setSelection(selFrom, selTo, updateLine(sel.from.line), updateLine(sel.to.line));
         | 
| 652 | 
            -
             | 
| 653 | 
            -
                        // Make sure the scroll-size div has the correct height.
         | 
| 654 | 
            -
                        code.style.height = (doc.height * textHeight() + 2 * paddingTop()) + "px";
         | 
| 655 | 
            -
                    }
         | 
| 656 | 
            -
             | 
| 657 | 
            -
                    function replaceRange(code, from, to) {
         | 
| 658 | 
            -
                        from = clipPos(from);
         | 
| 659 | 
            -
                        if (!to) to = from; else to = clipPos(to);
         | 
| 660 | 
            -
                        code = splitLines(code);
         | 
| 661 | 
            -
                        function adjustPos(pos) {
         | 
| 662 | 
            -
                            if (posLess(pos, from)) return pos;
         | 
| 663 | 
            -
                            if (!posLess(to, pos)) return end;
         | 
| 664 | 
            -
                            var line = pos.line + code.length - (to.line - from.line) - 1;
         | 
| 665 | 
            -
                            var ch = pos.ch;
         | 
| 666 | 
            -
                            if (pos.line == to.line)
         | 
| 667 | 
            -
                                ch += code[code.length-1].length - (to.ch - (to.line == from.line ? from.ch : 0));
         | 
| 668 | 
            -
                            return {line: line, ch: ch};
         | 
| 669 | 
            -
                        }
         | 
| 670 | 
            -
                        var end;
         | 
| 671 | 
            -
                        replaceRange1(code, from, to, function(end1) {
         | 
| 672 | 
            -
                            end = end1;
         | 
| 673 | 
            -
                            return {from: adjustPos(sel.from), to: adjustPos(sel.to)};
         | 
| 674 | 
            -
                        });
         | 
| 675 | 
            -
                        return end;
         | 
| 676 | 
            -
                    }
         | 
| 677 | 
            -
                    function replaceSelection(code, collapse) {
         | 
| 678 | 
            -
                        replaceRange1(splitLines(code), sel.from, sel.to, function(end) {
         | 
| 679 | 
            -
                            if (collapse == "end") return {from: end, to: end};
         | 
| 680 | 
            -
                            else if (collapse == "start") return {from: sel.from, to: sel.from};
         | 
| 681 | 
            -
                            else return {from: sel.from, to: end};
         | 
| 682 | 
            -
                        });
         | 
| 683 | 
            -
                    }
         | 
| 684 | 
            -
                    function replaceRange1(code, from, to, computeSel) {
         | 
| 685 | 
            -
                        var endch = code.length == 1 ? code[0].length + from.ch : code[code.length-1].length;
         | 
| 686 | 
            -
                        var newSel = computeSel({line: from.line + code.length - 1, ch: endch});
         | 
| 687 | 
            -
                        updateLines(from, to, code, newSel.from, newSel.to);
         | 
| 688 | 
            -
                    }
         | 
| 689 | 
            -
             | 
| 690 | 
            -
                    function getRange(from, to) {
         | 
| 691 | 
            -
                        var l1 = from.line, l2 = to.line;
         | 
| 692 | 
            -
                        if (l1 == l2) return getLine(l1).text.slice(from.ch, to.ch);
         | 
| 693 | 
            -
                        var code = [getLine(l1).text.slice(from.ch)];
         | 
| 694 | 
            -
                        doc.iter(l1 + 1, l2, function(line) { code.push(line.text); });
         | 
| 695 | 
            -
                        code.push(getLine(l2).text.slice(0, to.ch));
         | 
| 696 | 
            -
                        return code.join("\n");
         | 
| 697 | 
            -
                    }
         | 
| 698 | 
            -
                    function getSelection() {
         | 
| 699 | 
            -
                        return getRange(sel.from, sel.to);
         | 
| 700 | 
            -
                    }
         | 
| 701 | 
            -
             | 
| 702 | 
            -
                    var pollingFast = false; // Ensures slowPoll doesn't cancel fastPoll
         | 
| 703 | 
            -
                    function slowPoll() {
         | 
| 704 | 
            -
                        if (pollingFast) return;
         | 
| 705 | 
            -
                        poll.set(options.pollInterval, function() {
         | 
| 706 | 
            -
                            startOperation();
         | 
| 707 | 
            -
                            readInput();
         | 
| 708 | 
            -
                            if (focused) slowPoll();
         | 
| 709 | 
            -
                            endOperation();
         | 
| 710 | 
            -
                        });
         | 
| 711 | 
            -
                    }
         | 
| 712 | 
            -
                    function fastPoll() {
         | 
| 713 | 
            -
                        var missed = false;
         | 
| 714 | 
            -
                        pollingFast = true;
         | 
| 715 | 
            -
                        function p() {
         | 
| 716 | 
            -
                            startOperation();
         | 
| 717 | 
            -
                            var changed = readInput();
         | 
| 718 | 
            -
                            if (!changed && !missed) {missed = true; poll.set(60, p);}
         | 
| 719 | 
            -
                            else {pollingFast = false; slowPoll();}
         | 
| 720 | 
            -
                            endOperation();
         | 
| 721 | 
            -
                        }
         | 
| 722 | 
            -
                        poll.set(20, p);
         | 
| 723 | 
            -
                    }
         | 
| 724 | 
            -
             | 
| 725 | 
            -
                    // Previnput is a hack to work with IME. If we reset the textarea
         | 
| 726 | 
            -
                    // on every change, that breaks IME. So we look for changes
         | 
| 727 | 
            -
                    // compared to the previous content instead. (Modern browsers have
         | 
| 728 | 
            -
                    // events that indicate IME taking place, but these are not widely
         | 
| 729 | 
            -
                    // supported or compatible enough yet to rely on.)
         | 
| 730 | 
            -
                    var prevInput = "";
         | 
| 731 | 
            -
                    function readInput() {
         | 
| 732 | 
            -
                        if (leaveInputAlone || !focused || hasSelection(input)) return false;
         | 
| 733 | 
            -
                        var text = input.value;
         | 
| 734 | 
            -
                        if (text == prevInput) return false;
         | 
| 735 | 
            -
                        shiftSelecting = null;
         | 
| 736 | 
            -
                        var same = 0, l = Math.min(prevInput.length, text.length);
         | 
| 737 | 
            -
                        while (same < l && prevInput[same] == text[same]) ++same;
         | 
| 738 | 
            -
                        if (same < prevInput.length)
         | 
| 739 | 
            -
                            sel.from = {line: sel.from.line, ch: sel.from.ch - (prevInput.length - same)};
         | 
| 740 | 
            -
                        else if (overwrite && posEq(sel.from, sel.to))
         | 
| 741 | 
            -
                            sel.to = {line: sel.to.line, ch: Math.min(getLine(sel.to.line).text.length, sel.to.ch + (text.length - same))};
         | 
| 742 | 
            -
                        replaceSelection(text.slice(same), "end");
         | 
| 743 | 
            -
                        prevInput = text;
         | 
| 744 | 
            -
                        return true;
         | 
| 745 | 
            -
                    }
         | 
| 746 | 
            -
                    function resetInput(user) {
         | 
| 747 | 
            -
                        if (!posEq(sel.from, sel.to)) {
         | 
| 748 | 
            -
                            prevInput = "";
         | 
| 749 | 
            -
                            input.value = getSelection();
         | 
| 750 | 
            -
                            input.select();
         | 
| 751 | 
            -
                        } else if (user) prevInput = input.value = "";
         | 
| 752 | 
            -
                    }
         | 
| 753 | 
            -
             | 
| 754 | 
            -
                    function focusInput() {
         | 
| 755 | 
            -
                        if (!options.readOnly) input.focus();
         | 
| 756 | 
            -
                    }
         | 
| 757 | 
            -
             | 
| 758 | 
            -
                    function scrollEditorIntoView() {
         | 
| 759 | 
            -
                        if (!cursor.getBoundingClientRect) return;
         | 
| 760 | 
            -
                        var rect = cursor.getBoundingClientRect();
         | 
| 761 | 
            -
                        // IE returns bogus coordinates when the instance sits inside of an iframe and the cursor is hidden
         | 
| 762 | 
            -
                        if (ie && rect.top == rect.bottom) return;
         | 
| 763 | 
            -
                        var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);
         | 
| 764 | 
            -
                        if (rect.top < 0 || rect.bottom > winH) cursor.scrollIntoView();
         | 
| 765 | 
            -
                    }
         | 
| 766 | 
            -
                    function scrollCursorIntoView() {
         | 
| 767 | 
            -
                        var cursor = localCoords(sel.inverted ? sel.from : sel.to);
         | 
| 768 | 
            -
                        var x = options.lineWrapping ? Math.min(cursor.x, lineSpace.offsetWidth) : cursor.x;
         | 
| 769 | 
            -
                        return scrollIntoView(x, cursor.y, x, cursor.yBot);
         | 
| 770 | 
            -
                    }
         | 
| 771 | 
            -
                    function scrollIntoView(x1, y1, x2, y2) {
         | 
| 772 | 
            -
                        var pl = paddingLeft(), pt = paddingTop(), lh = textHeight();
         | 
| 773 | 
            -
                        y1 += pt; y2 += pt; x1 += pl; x2 += pl;
         | 
| 774 | 
            -
                        var screen = scroller.clientHeight, screentop = scroller.scrollTop, scrolled = false, result = true;
         | 
| 775 | 
            -
                        if (y1 < screentop) {scroller.scrollTop = Math.max(0, y1 - 2*lh); scrolled = true;}
         | 
| 776 | 
            -
                        else if (y2 > screentop + screen) {scroller.scrollTop = y2 + lh - screen; scrolled = true;}
         | 
| 777 | 
            -
             | 
| 778 | 
            -
                        var screenw = scroller.clientWidth, screenleft = scroller.scrollLeft;
         | 
| 779 | 
            -
                        var gutterw = options.fixedGutter ? gutter.clientWidth : 0;
         | 
| 780 | 
            -
                        if (x1 < screenleft + gutterw) {
         | 
| 781 | 
            -
                            if (x1 < 50) x1 = 0;
         | 
| 782 | 
            -
                            scroller.scrollLeft = Math.max(0, x1 - 10 - gutterw);
         | 
| 783 | 
            -
                            scrolled = true;
         | 
| 784 | 
            -
                        }
         | 
| 785 | 
            -
                        else if (x2 > screenw + screenleft - 3) {
         | 
| 786 | 
            -
                            scroller.scrollLeft = x2 + 10 - screenw;
         | 
| 787 | 
            -
                            scrolled = true;
         | 
| 788 | 
            -
                            if (x2 > code.clientWidth) result = false;
         | 
| 789 | 
            -
                        }
         | 
| 790 | 
            -
                        if (scrolled && options.onScroll) options.onScroll(instance);
         | 
| 791 | 
            -
                        return result;
         | 
| 792 | 
            -
                    }
         | 
| 793 | 
            -
             | 
| 794 | 
            -
                    function visibleLines() {
         | 
| 795 | 
            -
                        var lh = textHeight(), top = scroller.scrollTop - paddingTop();
         | 
| 796 | 
            -
                        var from_height = Math.max(0, Math.floor(top / lh));
         | 
| 797 | 
            -
                        var to_height = Math.ceil((top + scroller.clientHeight) / lh);
         | 
| 798 | 
            -
                        return {from: lineAtHeight(doc, from_height),
         | 
| 799 | 
            -
                            to: lineAtHeight(doc, to_height)};
         | 
| 800 | 
            -
                    }
         | 
| 801 | 
            -
                    // Uses a set of changes plus the current scroll position to
         | 
| 802 | 
            -
                    // determine which DOM updates have to be made, and makes the
         | 
| 803 | 
            -
                    // updates.
         | 
| 804 | 
            -
                    function updateDisplay(changes, suppressCallback) {
         | 
| 805 | 
            -
                        if (!scroller.clientWidth) {
         | 
| 806 | 
            -
                            showingFrom = showingTo = displayOffset = 0;
         | 
| 807 | 
            -
                            return;
         | 
| 808 | 
            -
                        }
         | 
| 809 | 
            -
                        // Compute the new visible window
         | 
| 810 | 
            -
                        var visible = visibleLines();
         | 
| 811 | 
            -
                        // Bail out if the visible area is already rendered and nothing changed.
         | 
| 812 | 
            -
                        if (changes !== true && changes.length == 0 && visible.from >= showingFrom && visible.to <= showingTo) return;
         | 
| 813 | 
            -
                        var from = Math.max(visible.from - 100, 0), to = Math.min(doc.size, visible.to + 100);
         | 
| 814 | 
            -
                        if (showingFrom < from && from - showingFrom < 20) from = showingFrom;
         | 
| 815 | 
            -
                        if (showingTo > to && showingTo - to < 20) to = Math.min(doc.size, showingTo);
         | 
| 816 | 
            -
             | 
| 817 | 
            -
                        // Create a range of theoretically intact lines, and punch holes
         | 
| 818 | 
            -
                        // in that using the change info.
         | 
| 819 | 
            -
                        var intact = changes === true ? [] :
         | 
| 820 | 
            -
                            computeIntact([{from: showingFrom, to: showingTo, domStart: 0}], changes);
         | 
| 821 | 
            -
                        // Clip off the parts that won't be visible
         | 
| 822 | 
            -
                        var intactLines = 0;
         | 
| 823 | 
            -
                        for (var i = 0; i < intact.length; ++i) {
         | 
| 824 | 
            -
                            var range = intact[i];
         | 
| 825 | 
            -
                            if (range.from < from) {range.domStart += (from - range.from); range.from = from;}
         | 
| 826 | 
            -
                            if (range.to > to) range.to = to;
         | 
| 827 | 
            -
                            if (range.from >= range.to) intact.splice(i--, 1);
         | 
| 828 | 
            -
                            else intactLines += range.to - range.from;
         | 
| 829 | 
            -
                        }
         | 
| 830 | 
            -
                        if (intactLines == to - from) return;
         | 
| 831 | 
            -
                        intact.sort(function(a, b) {return a.domStart - b.domStart;});
         | 
| 832 | 
            -
             | 
| 833 | 
            -
                        var th = textHeight(), gutterDisplay = gutter.style.display;
         | 
| 834 | 
            -
                        lineDiv.style.display = gutter.style.display = "none";
         | 
| 835 | 
            -
                        patchDisplay(from, to, intact);
         | 
| 836 | 
            -
                        lineDiv.style.display = "";
         | 
| 837 | 
            -
             | 
| 838 | 
            -
                        // Position the mover div to align with the lines it's supposed
         | 
| 839 | 
            -
                        // to be showing (which will cover the visible display)
         | 
| 840 | 
            -
                        var different = from != showingFrom || to != showingTo || lastSizeC != scroller.clientHeight + th;
         | 
| 841 | 
            -
                        // This is just a bogus formula that detects when the editor is
         | 
| 842 | 
            -
                        // resized or the font size changes.
         | 
| 843 | 
            -
                        if (different) lastSizeC = scroller.clientHeight + th;
         | 
| 844 | 
            -
                        showingFrom = from; showingTo = to;
         | 
| 845 | 
            -
                        displayOffset = heightAtLine(doc, from);
         | 
| 846 | 
            -
                        mover.style.top = (displayOffset * th) + "px";
         | 
| 847 | 
            -
                        code.style.height = (doc.height * th + 2 * paddingTop()) + "px";
         | 
| 848 | 
            -
             | 
| 849 | 
            -
                        // Since this is all rather error prone, it is honoured with the
         | 
| 850 | 
            -
                        // only assertion in the whole file.
         | 
| 851 | 
            -
                        if (lineDiv.childNodes.length != showingTo - showingFrom)
         | 
| 852 | 
            -
                            throw new Error("BAD PATCH! " + JSON.stringify(intact) + " size=" + (showingTo - showingFrom) +
         | 
| 853 | 
            -
                                " nodes=" + lineDiv.childNodes.length);
         | 
| 854 | 
            -
             | 
| 855 | 
            -
                        if (options.lineWrapping) {
         | 
| 856 | 
            -
                            maxWidth = scroller.clientWidth;
         | 
| 857 | 
            -
                            var curNode = lineDiv.firstChild;
         | 
| 858 | 
            -
                            doc.iter(showingFrom, showingTo, function(line) {
         | 
| 859 | 
            -
                                if (!line.hidden) {
         | 
| 860 | 
            -
                                    var height = Math.round(curNode.offsetHeight / th) || 1;
         | 
| 861 | 
            -
                                    if (line.height != height) {updateLineHeight(line, height); gutterDirty = true;}
         | 
| 862 | 
            -
                                }
         | 
| 863 | 
            -
                                curNode = curNode.nextSibling;
         | 
| 864 | 
            -
                            });
         | 
| 865 | 
            -
                        } else {
         | 
| 866 | 
            -
                            if (maxWidth == null) maxWidth = stringWidth(maxLine);
         | 
| 867 | 
            -
                            if (maxWidth > scroller.clientWidth) {
         | 
| 868 | 
            -
                                lineSpace.style.width = maxWidth + "px";
         | 
| 869 | 
            -
                                // Needed to prevent odd wrapping/hiding of widgets placed in here.
         | 
| 870 | 
            -
                                code.style.width = "";
         | 
| 871 | 
            -
                                code.style.width = scroller.scrollWidth + "px";
         | 
| 872 | 
            -
                            } else {
         | 
| 873 | 
            -
                                lineSpace.style.width = code.style.width = "";
         | 
| 874 | 
            -
                            }
         | 
| 875 | 
            -
                        }
         | 
| 876 | 
            -
                        gutter.style.display = gutterDisplay;
         | 
| 877 | 
            -
                        if (different || gutterDirty) updateGutter();
         | 
| 878 | 
            -
                        updateCursor();
         | 
| 879 | 
            -
                        if (!suppressCallback && options.onUpdate) options.onUpdate(instance);
         | 
| 880 | 
            -
                        return true;
         | 
| 881 | 
            -
                    }
         | 
| 882 | 
            -
             | 
| 883 | 
            -
                    function computeIntact(intact, changes) {
         | 
| 884 | 
            -
                        for (var i = 0, l = changes.length || 0; i < l; ++i) {
         | 
| 885 | 
            -
                            var change = changes[i], intact2 = [], diff = change.diff || 0;
         | 
| 886 | 
            -
                            for (var j = 0, l2 = intact.length; j < l2; ++j) {
         | 
| 887 | 
            -
                                var range = intact[j];
         | 
| 888 | 
            -
                                if (change.to <= range.from && change.diff)
         | 
| 889 | 
            -
                                    intact2.push({from: range.from + diff, to: range.to + diff,
         | 
| 890 | 
            -
                                        domStart: range.domStart});
         | 
| 891 | 
            -
                                else if (change.to <= range.from || change.from >= range.to)
         | 
| 892 | 
            -
                                    intact2.push(range);
         | 
| 893 | 
            -
                                else {
         | 
| 894 | 
            -
                                    if (change.from > range.from)
         | 
| 895 | 
            -
                                        intact2.push({from: range.from, to: change.from, domStart: range.domStart});
         | 
| 896 | 
            -
                                    if (change.to < range.to)
         | 
| 897 | 
            -
                                        intact2.push({from: change.to + diff, to: range.to + diff,
         | 
| 898 | 
            -
                                            domStart: range.domStart + (change.to - range.from)});
         | 
| 899 | 
            -
                                }
         | 
| 900 | 
            -
                            }
         | 
| 901 | 
            -
                            intact = intact2;
         | 
| 902 | 
            -
                        }
         | 
| 903 | 
            -
                        return intact;
         | 
| 904 | 
            -
                    }
         | 
| 905 | 
            -
             | 
| 906 | 
            -
                    function patchDisplay(from, to, intact) {
         | 
| 907 | 
            -
                        // The first pass removes the DOM nodes that aren't intact.
         | 
| 908 | 
            -
                        if (!intact.length) lineDiv.innerHTML = "";
         | 
| 909 | 
            -
                        else {
         | 
| 910 | 
            -
                            function killNode(node) {
         | 
| 911 | 
            -
                                var tmp = node.nextSibling;
         | 
| 912 | 
            -
                                node.parentNode.removeChild(node);
         | 
| 913 | 
            -
                                return tmp;
         | 
| 914 | 
            -
                            }
         | 
| 915 | 
            -
                            var domPos = 0, curNode = lineDiv.firstChild, n;
         | 
| 916 | 
            -
                            for (var i = 0; i < intact.length; ++i) {
         | 
| 917 | 
            -
                                var cur = intact[i];
         | 
| 918 | 
            -
                                while (cur.domStart > domPos) {curNode = killNode(curNode); domPos++;}
         | 
| 919 | 
            -
                                for (var j = 0, e = cur.to - cur.from; j < e; ++j) {curNode = curNode.nextSibling; domPos++;}
         | 
| 920 | 
            -
                            }
         | 
| 921 | 
            -
                            while (curNode) curNode = killNode(curNode);
         | 
| 922 | 
            -
                        }
         | 
| 923 | 
            -
                        // This pass fills in the lines that actually changed.
         | 
| 924 | 
            -
                        var nextIntact = intact.shift(), curNode = lineDiv.firstChild, j = from;
         | 
| 925 | 
            -
                        var sfrom = sel.from.line, sto = sel.to.line, inSel = sfrom < from && sto >= from;
         | 
| 926 | 
            -
                        var scratch = targetDocument.createElement("div"), newElt;
         | 
| 927 | 
            -
                        doc.iter(from, to, function(line) {
         | 
| 928 | 
            -
                            var ch1 = null, ch2 = null;
         | 
| 929 | 
            -
                            if (inSel) {
         | 
| 930 | 
            -
                                ch1 = 0;
         | 
| 931 | 
            -
                                if (sto == j) {inSel = false; ch2 = sel.to.ch;}
         | 
| 932 | 
            -
                            } else if (sfrom == j) {
         | 
| 933 | 
            -
                                if (sto == j) {ch1 = sel.from.ch; ch2 = sel.to.ch;}
         | 
| 934 | 
            -
                                else {inSel = true; ch1 = sel.from.ch;}
         | 
| 935 | 
            -
                            }
         | 
| 936 | 
            -
                            if (nextIntact && nextIntact.to == j) nextIntact = intact.shift();
         | 
| 937 | 
            -
                            if (!nextIntact || nextIntact.from > j) {
         | 
| 938 | 
            -
                                if (line.hidden) scratch.innerHTML = "<pre></pre>";
         | 
| 939 | 
            -
                                else scratch.innerHTML = line.getHTML(ch1, ch2, true, tabText);
         | 
| 940 | 
            -
                                lineDiv.insertBefore(scratch.firstChild, curNode);
         | 
| 941 | 
            -
                            } else {
         | 
| 942 | 
            -
                                curNode = curNode.nextSibling;
         | 
| 943 | 
            -
                            }
         | 
| 944 | 
            -
                            ++j;
         | 
| 945 | 
            -
                        });
         | 
| 946 | 
            -
                    }
         | 
| 947 | 
            -
             | 
| 948 | 
            -
                    function updateGutter() {
         | 
| 949 | 
            -
                        if (!options.gutter && !options.lineNumbers) return;
         | 
| 950 | 
            -
                        var hText = mover.offsetHeight, hEditor = scroller.clientHeight;
         | 
| 951 | 
            -
                        gutter.style.height = (hText - hEditor < 2 ? hEditor : hText) + "px";
         | 
| 952 | 
            -
                        var html = [], i = showingFrom;
         | 
| 953 | 
            -
                        doc.iter(showingFrom, Math.max(showingTo, showingFrom + 1), function(line) {
         | 
| 954 | 
            -
                            if (line.hidden) {
         | 
| 955 | 
            -
                                html.push("<pre></pre>");
         | 
| 956 | 
            -
                            } else {
         | 
| 957 | 
            -
                                var marker = line.gutterMarker;
         | 
| 958 | 
            -
                                var text = options.lineNumbers ? i + options.firstLineNumber : null;
         | 
| 959 | 
            -
                                if (marker && marker.text)
         | 
| 960 | 
            -
                                    text = marker.text.replace("%N%", text != null ? text : "");
         | 
| 961 | 
            -
                                else if (text == null)
         | 
| 962 | 
            -
                                    text = "\u00a0";
         | 
| 963 | 
            -
                                html.push((marker && marker.style ? '<pre class="' + marker.style + '">' : "<pre>"), text);
         | 
| 964 | 
            -
                                for (var j = 1; j < line.height; ++j) html.push("<br/> ");
         | 
| 965 | 
            -
                                html.push("</pre>");
         | 
| 966 | 
            -
                            }
         | 
| 967 | 
            -
                            ++i;
         | 
| 968 | 
            -
                        });
         | 
| 969 | 
            -
                        gutter.style.display = "none";
         | 
| 970 | 
            -
                        gutterText.innerHTML = html.join("");
         | 
| 971 | 
            -
                        var minwidth = String(doc.size).length, firstNode = gutterText.firstChild, val = eltText(firstNode), pad = "";
         | 
| 972 | 
            -
                        while (val.length + pad.length < minwidth) pad += "\u00a0";
         | 
| 973 | 
            -
                        if (pad) firstNode.insertBefore(targetDocument.createTextNode(pad), firstNode.firstChild);
         | 
| 974 | 
            -
                        gutter.style.display = "";
         | 
| 975 | 
            -
                        lineSpace.style.marginLeft = gutter.offsetWidth + "px";
         | 
| 976 | 
            -
                        gutterDirty = false;
         | 
| 977 | 
            -
                    }
         | 
| 978 | 
            -
                    function updateCursor() {
         | 
| 979 | 
            -
                        var head = sel.inverted ? sel.from : sel.to, lh = textHeight();
         | 
| 980 | 
            -
                        var pos = localCoords(head, true);
         | 
| 981 | 
            -
                        var wrapOff = eltOffset(wrapper), lineOff = eltOffset(lineDiv);
         | 
| 982 | 
            -
                        inputDiv.style.top = (pos.y + lineOff.top - wrapOff.top) + "px";
         | 
| 983 | 
            -
                        inputDiv.style.left = (pos.x + lineOff.left - wrapOff.left) + "px";
         | 
| 984 | 
            -
                        if (posEq(sel.from, sel.to)) {
         | 
| 985 | 
            -
                            cursor.style.top = pos.y + "px";
         | 
| 986 | 
            -
                            cursor.style.left = (options.lineWrapping ? Math.min(pos.x, lineSpace.offsetWidth) : pos.x) + "px";
         | 
| 987 | 
            -
                            cursor.style.display = "";
         | 
| 988 | 
            -
                        }
         | 
| 989 | 
            -
                        else cursor.style.display = "none";
         | 
| 990 | 
            -
                    }
         | 
| 991 | 
            -
             | 
| 992 | 
            -
                    function setShift(val) {
         | 
| 993 | 
            -
                        if (val) shiftSelecting = shiftSelecting || (sel.inverted ? sel.to : sel.from);
         | 
| 994 | 
            -
                        else shiftSelecting = null;
         | 
| 995 | 
            -
                    }
         | 
| 996 | 
            -
                    function setSelectionUser(from, to) {
         | 
| 997 | 
            -
                        var sh = shiftSelecting && clipPos(shiftSelecting);
         | 
| 998 | 
            -
                        if (sh) {
         | 
| 999 | 
            -
                            if (posLess(sh, from)) from = sh;
         | 
| 1000 | 
            -
                            else if (posLess(to, sh)) to = sh;
         | 
| 1001 | 
            -
                        }
         | 
| 1002 | 
            -
                        setSelection(from, to);
         | 
| 1003 | 
            -
                        userSelChange = true;
         | 
| 1004 | 
            -
                    }
         | 
| 1005 | 
            -
                    // Update the selection. Last two args are only used by
         | 
| 1006 | 
            -
                    // updateLines, since they have to be expressed in the line
         | 
| 1007 | 
            -
                    // numbers before the update.
         | 
| 1008 | 
            -
                    function setSelection(from, to, oldFrom, oldTo) {
         | 
| 1009 | 
            -
                        goalColumn = null;
         | 
| 1010 | 
            -
                        if (oldFrom == null) {oldFrom = sel.from.line; oldTo = sel.to.line;}
         | 
| 1011 | 
            -
                        if (posEq(sel.from, from) && posEq(sel.to, to)) return;
         | 
| 1012 | 
            -
                        if (posLess(to, from)) {var tmp = to; to = from; from = tmp;}
         | 
| 1013 | 
            -
             | 
| 1014 | 
            -
                        // Skip over hidden lines.
         | 
| 1015 | 
            -
                        if (from.line != oldFrom) from = skipHidden(from, oldFrom, sel.from.ch);
         | 
| 1016 | 
            -
                        if (to.line != oldTo) to = skipHidden(to, oldTo, sel.to.ch);
         | 
| 1017 | 
            -
             | 
| 1018 | 
            -
                        if (posEq(from, to)) sel.inverted = false;
         | 
| 1019 | 
            -
                        else if (posEq(from, sel.to)) sel.inverted = false;
         | 
| 1020 | 
            -
                        else if (posEq(to, sel.from)) sel.inverted = true;
         | 
| 1021 | 
            -
             | 
| 1022 | 
            -
                        // Some ugly logic used to only mark the lines that actually did
         | 
| 1023 | 
            -
                        // see a change in selection as changed, rather than the whole
         | 
| 1024 | 
            -
                        // selected range.
         | 
| 1025 | 
            -
                        if (posEq(from, to)) {
         | 
| 1026 | 
            -
                            if (!posEq(sel.from, sel.to))
         | 
| 1027 | 
            -
                                changes.push({from: oldFrom, to: oldTo + 1});
         | 
| 1028 | 
            -
                        }
         | 
| 1029 | 
            -
                        else if (posEq(sel.from, sel.to)) {
         | 
| 1030 | 
            -
                            changes.push({from: from.line, to: to.line + 1});
         | 
| 1031 | 
            -
                        }
         | 
| 1032 | 
            -
                        else {
         | 
| 1033 | 
            -
                            if (!posEq(from, sel.from)) {
         | 
| 1034 | 
            -
                                if (from.line < oldFrom)
         | 
| 1035 | 
            -
                                    changes.push({from: from.line, to: Math.min(to.line, oldFrom) + 1});
         | 
| 1036 | 
            -
                                else
         | 
| 1037 | 
            -
                                    changes.push({from: oldFrom, to: Math.min(oldTo, from.line) + 1});
         | 
| 1038 | 
            -
                            }
         | 
| 1039 | 
            -
                            if (!posEq(to, sel.to)) {
         | 
| 1040 | 
            -
                                if (to.line < oldTo)
         | 
| 1041 | 
            -
                                    changes.push({from: Math.max(oldFrom, from.line), to: oldTo + 1});
         | 
| 1042 | 
            -
                                else
         | 
| 1043 | 
            -
                                    changes.push({from: Math.max(from.line, oldTo), to: to.line + 1});
         | 
| 1044 | 
            -
                            }
         | 
| 1045 | 
            -
                        }
         | 
| 1046 | 
            -
                        sel.from = from; sel.to = to;
         | 
| 1047 | 
            -
                        selectionChanged = true;
         | 
| 1048 | 
            -
                    }
         | 
| 1049 | 
            -
                    function skipHidden(pos, oldLine, oldCh) {
         | 
| 1050 | 
            -
                        function getNonHidden(dir) {
         | 
| 1051 | 
            -
                            var lNo = pos.line + dir, end = dir == 1 ? doc.size : -1;
         | 
| 1052 | 
            -
                            while (lNo != end) {
         | 
| 1053 | 
            -
                                var line = getLine(lNo);
         | 
| 1054 | 
            -
                                if (!line.hidden) {
         | 
| 1055 | 
            -
                                    var ch = pos.ch;
         | 
| 1056 | 
            -
                                    if (ch > oldCh || ch > line.text.length) ch = line.text.length;
         | 
| 1057 | 
            -
                                    return {line: lNo, ch: ch};
         | 
| 1058 | 
            -
                                }
         | 
| 1059 | 
            -
                                lNo += dir;
         | 
| 1060 | 
            -
                            }
         | 
| 1061 | 
            -
                        }
         | 
| 1062 | 
            -
                        var line = getLine(pos.line);
         | 
| 1063 | 
            -
                        if (!line.hidden) return pos;
         | 
| 1064 | 
            -
                        if (pos.line >= oldLine) return getNonHidden(1) || getNonHidden(-1);
         | 
| 1065 | 
            -
                        else return getNonHidden(-1) || getNonHidden(1);
         | 
| 1066 | 
            -
                    }
         | 
| 1067 | 
            -
                    function setCursor(line, ch, user) {
         | 
| 1068 | 
            -
                        var pos = clipPos({line: line, ch: ch || 0});
         | 
| 1069 | 
            -
                        (user ? setSelectionUser : setSelection)(pos, pos);
         | 
| 1070 | 
            -
                    }
         | 
| 1071 | 
            -
             | 
| 1072 | 
            -
                    function clipLine(n) {return Math.max(0, Math.min(n, doc.size-1));}
         | 
| 1073 | 
            -
                    function clipPos(pos) {
         | 
| 1074 | 
            -
                        if (pos.line < 0) return {line: 0, ch: 0};
         | 
| 1075 | 
            -
                        if (pos.line >= doc.size) return {line: doc.size-1, ch: getLine(doc.size-1).text.length};
         | 
| 1076 | 
            -
                        var ch = pos.ch, linelen = getLine(pos.line).text.length;
         | 
| 1077 | 
            -
                        if (ch == null || ch > linelen) return {line: pos.line, ch: linelen};
         | 
| 1078 | 
            -
                        else if (ch < 0) return {line: pos.line, ch: 0};
         | 
| 1079 | 
            -
                        else return pos;
         | 
| 1080 | 
            -
                    }
         | 
| 1081 | 
            -
             | 
| 1082 | 
            -
                    function findPosH(dir, unit) {
         | 
| 1083 | 
            -
                        var end = sel.inverted ? sel.from : sel.to, line = end.line, ch = end.ch;
         | 
| 1084 | 
            -
                        var lineObj = getLine(line);
         | 
| 1085 | 
            -
                        function findNextLine() {
         | 
| 1086 | 
            -
                            for (var l = line + dir, e = dir < 0 ? -1 : doc.size; l != e; l += dir) {
         | 
| 1087 | 
            -
                                var lo = getLine(l);
         | 
| 1088 | 
            -
                                if (!lo.hidden) { line = l; lineObj = lo; return true; }
         | 
| 1089 | 
            -
                            }
         | 
| 1090 | 
            -
                        }
         | 
| 1091 | 
            -
                        function moveOnce(boundToLine) {
         | 
| 1092 | 
            -
                            if (ch == (dir < 0 ? 0 : lineObj.text.length)) {
         | 
| 1093 | 
            -
                                if (!boundToLine && findNextLine()) ch = dir < 0 ? lineObj.text.length : 0;
         | 
| 1094 | 
            -
                                else return false;
         | 
| 1095 | 
            -
                            } else ch += dir;
         | 
| 1096 | 
            -
                            return true;
         | 
| 1097 | 
            -
                        }
         | 
| 1098 | 
            -
                        if (unit == "char") moveOnce();
         | 
| 1099 | 
            -
                        else if (unit == "column") moveOnce(true);
         | 
| 1100 | 
            -
                        else if (unit == "word") {
         | 
| 1101 | 
            -
                            var sawWord = false;
         | 
| 1102 | 
            -
                            for (;;) {
         | 
| 1103 | 
            -
                                if (dir < 0) if (!moveOnce()) break;
         | 
| 1104 | 
            -
                                if (isWordChar(lineObj.text.charAt(ch))) sawWord = true;
         | 
| 1105 | 
            -
                                else if (sawWord) {if (dir < 0) {dir = 1; moveOnce();} break;}
         | 
| 1106 | 
            -
                                if (dir > 0) if (!moveOnce()) break;
         | 
| 1107 | 
            -
                            }
         | 
| 1108 | 
            -
                        }
         | 
| 1109 | 
            -
                        return {line: line, ch: ch};
         | 
| 1110 | 
            -
                    }
         | 
| 1111 | 
            -
                    function moveH(dir, unit) {
         | 
| 1112 | 
            -
                        var pos = dir < 0 ? sel.from : sel.to;
         | 
| 1113 | 
            -
                        if (shiftSelecting || posEq(sel.from, sel.to)) pos = findPosH(dir, unit);
         | 
| 1114 | 
            -
                        setCursor(pos.line, pos.ch, true);
         | 
| 1115 | 
            -
                    }
         | 
| 1116 | 
            -
                    function deleteH(dir, unit) {
         | 
| 1117 | 
            -
                        if (!posEq(sel.from, sel.to)) replaceRange("", sel.from, sel.to);
         | 
| 1118 | 
            -
                        else if (dir < 0) replaceRange("", findPosH(dir, unit), sel.to);
         | 
| 1119 | 
            -
                        else replaceRange("", sel.from, findPosH(dir, unit));
         | 
| 1120 | 
            -
                        userSelChange = true;
         | 
| 1121 | 
            -
                    }
         | 
| 1122 | 
            -
                    var goalColumn = null;
         | 
| 1123 | 
            -
                    function moveV(dir, unit) {
         | 
| 1124 | 
            -
                        var dist = 0, pos = localCoords(sel.inverted ? sel.from : sel.to, true);
         | 
| 1125 | 
            -
                        if (goalColumn != null) pos.x = goalColumn;
         | 
| 1126 | 
            -
                        if (unit == "page") dist = scroller.clientHeight;
         | 
| 1127 | 
            -
                        else if (unit == "line") dist = textHeight();
         | 
| 1128 | 
            -
                        var target = coordsChar(pos.x, pos.y + dist * dir + 2);
         | 
| 1129 | 
            -
                        setCursor(target.line, target.ch, true);
         | 
| 1130 | 
            -
                        goalColumn = pos.x;
         | 
| 1131 | 
            -
                    }
         | 
| 1132 | 
            -
             | 
| 1133 | 
            -
                    function selectWordAt(pos) {
         | 
| 1134 | 
            -
                        var line = getLine(pos.line).text;
         | 
| 1135 | 
            -
                        var start = pos.ch, end = pos.ch;
         | 
| 1136 | 
            -
                        while (start > 0 && isWordChar(line.charAt(start - 1))) --start;
         | 
| 1137 | 
            -
                        while (end < line.length && isWordChar(line.charAt(end))) ++end;
         | 
| 1138 | 
            -
                        setSelectionUser({line: pos.line, ch: start}, {line: pos.line, ch: end});
         | 
| 1139 | 
            -
                    }
         | 
| 1140 | 
            -
                    function selectLine(line) {
         | 
| 1141 | 
            -
                        setSelectionUser({line: line, ch: 0}, {line: line, ch: getLine(line).text.length});
         | 
| 1142 | 
            -
                    }
         | 
| 1143 | 
            -
                    function indentSelected(mode) {
         | 
| 1144 | 
            -
                        if (posEq(sel.from, sel.to)) return indentLine(sel.from.line, mode);
         | 
| 1145 | 
            -
                        var e = sel.to.line - (sel.to.ch ? 0 : 1);
         | 
| 1146 | 
            -
                        for (var i = sel.from.line; i <= e; ++i) indentLine(i, mode);
         | 
| 1147 | 
            -
                    }
         | 
| 1148 | 
            -
             | 
| 1149 | 
            -
                    function indentLine(n, how) {
         | 
| 1150 | 
            -
                        if (!how) how = "add";
         | 
| 1151 | 
            -
                        if (how == "smart") {
         | 
| 1152 | 
            -
                            if (!mode.indent) how = "prev";
         | 
| 1153 | 
            -
                            else var state = getStateBefore(n);
         | 
| 1154 | 
            -
                        }
         | 
| 1155 | 
            -
             | 
| 1156 | 
            -
                        var line = getLine(n), curSpace = line.indentation(options.tabSize),
         | 
| 1157 | 
            -
                            curSpaceString = line.text.match(/^\s*/)[0], indentation;
         | 
| 1158 | 
            -
                        if (how == "prev") {
         | 
| 1159 | 
            -
                            if (n) indentation = getLine(n-1).indentation(options.tabSize);
         | 
| 1160 | 
            -
                            else indentation = 0;
         | 
| 1161 | 
            -
                        }
         | 
| 1162 | 
            -
                        else if (how == "smart") indentation = mode.indent(state, line.text.slice(curSpaceString.length), line.text);
         | 
| 1163 | 
            -
                        else if (how == "add") indentation = curSpace + options.indentUnit;
         | 
| 1164 | 
            -
                        else if (how == "subtract") indentation = curSpace - options.indentUnit;
         | 
| 1165 | 
            -
                        indentation = Math.max(0, indentation);
         | 
| 1166 | 
            -
                        var diff = indentation - curSpace;
         | 
| 1167 | 
            -
             | 
| 1168 | 
            -
                        if (!diff) {
         | 
| 1169 | 
            -
                            if (sel.from.line != n && sel.to.line != n) return;
         | 
| 1170 | 
            -
                            var indentString = curSpaceString;
         | 
| 1171 | 
            -
                        }
         | 
| 1172 | 
            -
                        else {
         | 
| 1173 | 
            -
                            var indentString = "", pos = 0;
         | 
| 1174 | 
            -
                            if (options.indentWithTabs)
         | 
| 1175 | 
            -
                                for (var i = Math.floor(indentation / options.tabSize); i; --i) {pos += options.tabSize; indentString += "\t";}
         | 
| 1176 | 
            -
                            while (pos < indentation) {++pos; indentString += " ";}
         | 
| 1177 | 
            -
                        }
         | 
| 1178 | 
            -
             | 
| 1179 | 
            -
                        replaceRange(indentString, {line: n, ch: 0}, {line: n, ch: curSpaceString.length});
         | 
| 1180 | 
            -
                    }
         | 
| 1181 | 
            -
             | 
| 1182 | 
            -
                    function loadMode() {
         | 
| 1183 | 
            -
                        mode = CodeMirror.getMode(options, options.mode);
         | 
| 1184 | 
            -
                        doc.iter(0, doc.size, function(line) { line.stateAfter = null; });
         | 
| 1185 | 
            -
                        work = [0];
         | 
| 1186 | 
            -
                        startWorker();
         | 
| 1187 | 
            -
                    }
         | 
| 1188 | 
            -
                    function gutterChanged() {
         | 
| 1189 | 
            -
                        var visible = options.gutter || options.lineNumbers;
         | 
| 1190 | 
            -
                        gutter.style.display = visible ? "" : "none";
         | 
| 1191 | 
            -
                        if (visible) gutterDirty = true;
         | 
| 1192 | 
            -
                        else lineDiv.parentNode.style.marginLeft = 0;
         | 
| 1193 | 
            -
                    }
         | 
| 1194 | 
            -
                    function wrappingChanged(from, to) {
         | 
| 1195 | 
            -
                        if (options.lineWrapping) {
         | 
| 1196 | 
            -
                            wrapper.className += " CodeMirror-wrap";
         | 
| 1197 | 
            -
                            var perLine = scroller.clientWidth / charWidth() - 3;
         | 
| 1198 | 
            -
                            doc.iter(0, doc.size, function(line) {
         | 
| 1199 | 
            -
                                if (line.hidden) return;
         | 
| 1200 | 
            -
                                var guess = Math.ceil(line.text.length / perLine) || 1;
         | 
| 1201 | 
            -
                                if (guess != 1) updateLineHeight(line, guess);
         | 
| 1202 | 
            -
                            });
         | 
| 1203 | 
            -
                            lineSpace.style.width = code.style.width = "";
         | 
| 1204 | 
            -
                        } else {
         | 
| 1205 | 
            -
                            wrapper.className = wrapper.className.replace(" CodeMirror-wrap", "");
         | 
| 1206 | 
            -
                            maxWidth = null; maxLine = "";
         | 
| 1207 | 
            -
                            doc.iter(0, doc.size, function(line) {
         | 
| 1208 | 
            -
                                if (line.height != 1 && !line.hidden) updateLineHeight(line, 1);
         | 
| 1209 | 
            -
                                if (line.text.length > maxLine.length) maxLine = line.text;
         | 
| 1210 | 
            -
                            });
         | 
| 1211 | 
            -
                        }
         | 
| 1212 | 
            -
                        changes.push({from: 0, to: doc.size});
         | 
| 1213 | 
            -
                    }
         | 
| 1214 | 
            -
                    function computeTabText() {
         | 
| 1215 | 
            -
                        for (var str = '<span class="cm-tab">', i = 0; i < options.tabSize; ++i) str += " ";
         | 
| 1216 | 
            -
                        return str + "</span>";
         | 
| 1217 | 
            -
                    }
         | 
| 1218 | 
            -
                    function tabsChanged() {
         | 
| 1219 | 
            -
                        tabText = computeTabText();
         | 
| 1220 | 
            -
                        updateDisplay(true);
         | 
| 1221 | 
            -
                    }
         | 
| 1222 | 
            -
                    function themeChanged() {
         | 
| 1223 | 
            -
                        scroller.className = scroller.className.replace(/\s*cm-s-\w+/g, "") +
         | 
| 1224 | 
            -
                            options.theme.replace(/(^|\s)\s*/g, " cm-s-");
         | 
| 1225 | 
            -
                    }
         | 
| 1226 | 
            -
             | 
| 1227 | 
            -
                    function TextMarker() { this.set = []; }
         | 
| 1228 | 
            -
                    TextMarker.prototype.clear = operation(function() {
         | 
| 1229 | 
            -
                        var min = Infinity, max = -Infinity;
         | 
| 1230 | 
            -
                        for (var i = 0, e = this.set.length; i < e; ++i) {
         | 
| 1231 | 
            -
                            var line = this.set[i], mk = line.marked;
         | 
| 1232 | 
            -
                            if (!mk || !line.parent) continue;
         | 
| 1233 | 
            -
                            var lineN = lineNo(line);
         | 
| 1234 | 
            -
                            min = Math.min(min, lineN); max = Math.max(max, lineN);
         | 
| 1235 | 
            -
                            for (var j = 0; j < mk.length; ++j)
         | 
| 1236 | 
            -
                                if (mk[j].set == this.set) mk.splice(j--, 1);
         | 
| 1237 | 
            -
                        }
         | 
| 1238 | 
            -
                        if (min != Infinity)
         | 
| 1239 | 
            -
                            changes.push({from: min, to: max + 1});
         | 
| 1240 | 
            -
                    });
         | 
| 1241 | 
            -
                    TextMarker.prototype.find = function() {
         | 
| 1242 | 
            -
                        var from, to;
         | 
| 1243 | 
            -
                        for (var i = 0, e = this.set.length; i < e; ++i) {
         | 
| 1244 | 
            -
                            var line = this.set[i], mk = line.marked;
         | 
| 1245 | 
            -
                            for (var j = 0; j < mk.length; ++j) {
         | 
| 1246 | 
            -
                                var mark = mk[j];
         | 
| 1247 | 
            -
                                if (mark.set == this.set) {
         | 
| 1248 | 
            -
                                    if (mark.from != null || mark.to != null) {
         | 
| 1249 | 
            -
                                        var found = lineNo(line);
         | 
| 1250 | 
            -
                                        if (found != null) {
         | 
| 1251 | 
            -
                                            if (mark.from != null) from = {line: found, ch: mark.from};
         | 
| 1252 | 
            -
                                            if (mark.to != null) to = {line: found, ch: mark.to};
         | 
| 1253 | 
            -
                                        }
         | 
| 1254 | 
            -
                                    }
         | 
| 1255 | 
            -
                                }
         | 
| 1256 | 
            -
                            }
         | 
| 1257 | 
            -
                        }
         | 
| 1258 | 
            -
                        return {from: from, to: to};
         | 
| 1259 | 
            -
                    };
         | 
| 1260 | 
            -
             | 
| 1261 | 
            -
                    function markText(from, to, className) {
         | 
| 1262 | 
            -
                        from = clipPos(from); to = clipPos(to);
         | 
| 1263 | 
            -
                        var tm = new TextMarker();
         | 
| 1264 | 
            -
                        function add(line, from, to, className) {
         | 
| 1265 | 
            -
                            getLine(line).addMark(new MarkedText(from, to, className, tm.set));
         | 
| 1266 | 
            -
                        }
         | 
| 1267 | 
            -
                        if (from.line == to.line) add(from.line, from.ch, to.ch, className);
         | 
| 1268 | 
            -
                        else {
         | 
| 1269 | 
            -
                            add(from.line, from.ch, null, className);
         | 
| 1270 | 
            -
                            for (var i = from.line + 1, e = to.line; i < e; ++i)
         | 
| 1271 | 
            -
                                add(i, null, null, className);
         | 
| 1272 | 
            -
                            add(to.line, null, to.ch, className);
         | 
| 1273 | 
            -
                        }
         | 
| 1274 | 
            -
                        changes.push({from: from.line, to: to.line + 1});
         | 
| 1275 | 
            -
                        return tm;
         | 
| 1276 | 
            -
                    }
         | 
| 1277 | 
            -
             | 
| 1278 | 
            -
                    function setBookmark(pos) {
         | 
| 1279 | 
            -
                        pos = clipPos(pos);
         | 
| 1280 | 
            -
                        var bm = new Bookmark(pos.ch);
         | 
| 1281 | 
            -
                        getLine(pos.line).addMark(bm);
         | 
| 1282 | 
            -
                        return bm;
         | 
| 1283 | 
            -
                    }
         | 
| 1284 | 
            -
             | 
| 1285 | 
            -
                    function addGutterMarker(line, text, className) {
         | 
| 1286 | 
            -
                        if (typeof line == "number") line = getLine(clipLine(line));
         | 
| 1287 | 
            -
                        line.gutterMarker = {text: text, style: className};
         | 
| 1288 | 
            -
                        gutterDirty = true;
         | 
| 1289 | 
            -
                        return line;
         | 
| 1290 | 
            -
                    }
         | 
| 1291 | 
            -
                    function removeGutterMarker(line) {
         | 
| 1292 | 
            -
                        if (typeof line == "number") line = getLine(clipLine(line));
         | 
| 1293 | 
            -
                        line.gutterMarker = null;
         | 
| 1294 | 
            -
                        gutterDirty = true;
         | 
| 1295 | 
            -
                    }
         | 
| 1296 | 
            -
             | 
| 1297 | 
            -
                    function changeLine(handle, op) {
         | 
| 1298 | 
            -
                        var no = handle, line = handle;
         | 
| 1299 | 
            -
                        if (typeof handle == "number") line = getLine(clipLine(handle));
         | 
| 1300 | 
            -
                        else no = lineNo(handle);
         | 
| 1301 | 
            -
                        if (no == null) return null;
         | 
| 1302 | 
            -
                        if (op(line, no)) changes.push({from: no, to: no + 1});
         | 
| 1303 | 
            -
                        else return null;
         | 
| 1304 | 
            -
                        return line;
         | 
| 1305 | 
            -
                    }
         | 
| 1306 | 
            -
                    function setLineClass(handle, className) {
         | 
| 1307 | 
            -
                        return changeLine(handle, function(line) {
         | 
| 1308 | 
            -
                            if (line.className != className) {
         | 
| 1309 | 
            -
                                line.className = className;
         | 
| 1310 | 
            -
                                return true;
         | 
| 1311 | 
            -
                            }
         | 
| 1312 | 
            -
                        });
         | 
| 1313 | 
            -
                    }
         | 
| 1314 | 
            -
                    function setLineHidden(handle, hidden) {
         | 
| 1315 | 
            -
                        return changeLine(handle, function(line, no) {
         | 
| 1316 | 
            -
                            if (line.hidden != hidden) {
         | 
| 1317 | 
            -
                                line.hidden = hidden;
         | 
| 1318 | 
            -
                                updateLineHeight(line, hidden ? 0 : 1);
         | 
| 1319 | 
            -
                                if (hidden && (sel.from.line == no || sel.to.line == no))
         | 
| 1320 | 
            -
                                    setSelection(skipHidden(sel.from, sel.from.line, sel.from.ch),
         | 
| 1321 | 
            -
                                        skipHidden(sel.to, sel.to.line, sel.to.ch));
         | 
| 1322 | 
            -
                                return (gutterDirty = true);
         | 
| 1323 | 
            -
                            }
         | 
| 1324 | 
            -
                        });
         | 
| 1325 | 
            -
                    }
         | 
| 1326 | 
            -
             | 
| 1327 | 
            -
                    function lineInfo(line) {
         | 
| 1328 | 
            -
                        if (typeof line == "number") {
         | 
| 1329 | 
            -
                            if (!isLine(line)) return null;
         | 
| 1330 | 
            -
                            var n = line;
         | 
| 1331 | 
            -
                            line = getLine(line);
         | 
| 1332 | 
            -
                            if (!line) return null;
         | 
| 1333 | 
            -
                        }
         | 
| 1334 | 
            -
                        else {
         | 
| 1335 | 
            -
                            var n = lineNo(line);
         | 
| 1336 | 
            -
                            if (n == null) return null;
         | 
| 1337 | 
            -
                        }
         | 
| 1338 | 
            -
                        var marker = line.gutterMarker;
         | 
| 1339 | 
            -
                        return {line: n, handle: line, text: line.text, markerText: marker && marker.text,
         | 
| 1340 | 
            -
                            markerClass: marker && marker.style, lineClass: line.className};
         | 
| 1341 | 
            -
                    }
         | 
| 1342 | 
            -
             | 
| 1343 | 
            -
                    function stringWidth(str) {
         | 
| 1344 | 
            -
                        measure.innerHTML = "<pre><span>x</span></pre>";
         | 
| 1345 | 
            -
                        measure.firstChild.firstChild.firstChild.nodeValue = str;
         | 
| 1346 | 
            -
                        return measure.firstChild.firstChild.offsetWidth || 10;
         | 
| 1347 | 
            -
                    }
         | 
| 1348 | 
            -
                    // These are used to go from pixel positions to character
         | 
| 1349 | 
            -
                    // positions, taking varying character widths into account.
         | 
| 1350 | 
            -
                    function charFromX(line, x) {
         | 
| 1351 | 
            -
                        if (x <= 0) return 0;
         | 
| 1352 | 
            -
                        var lineObj = getLine(line), text = lineObj.text;
         | 
| 1353 | 
            -
                        function getX(len) {
         | 
| 1354 | 
            -
                            measure.innerHTML = "<pre><span>" + lineObj.getHTML(null, null, false, tabText, len) + "</span></pre>";
         | 
| 1355 | 
            -
                            return measure.firstChild.firstChild.offsetWidth;
         | 
| 1356 | 
            -
                        }
         | 
| 1357 | 
            -
                        var from = 0, fromX = 0, to = text.length, toX;
         | 
| 1358 | 
            -
                        // Guess a suitable upper bound for our search.
         | 
| 1359 | 
            -
                        var estimated = Math.min(to, Math.ceil(x / charWidth()));
         | 
| 1360 | 
            -
                        for (;;) {
         | 
| 1361 | 
            -
                            var estX = getX(estimated);
         | 
| 1362 | 
            -
                            if (estX <= x && estimated < to) estimated = Math.min(to, Math.ceil(estimated * 1.2));
         | 
| 1363 | 
            -
                            else {toX = estX; to = estimated; break;}
         | 
| 1364 | 
            -
                        }
         | 
| 1365 | 
            -
                        if (x > toX) return to;
         | 
| 1366 | 
            -
                        // Try to guess a suitable lower bound as well.
         | 
| 1367 | 
            -
                        estimated = Math.floor(to * 0.8); estX = getX(estimated);
         | 
| 1368 | 
            -
                        if (estX < x) {from = estimated; fromX = estX;}
         | 
| 1369 | 
            -
                        // Do a binary search between these bounds.
         | 
| 1370 | 
            -
                        for (;;) {
         | 
| 1371 | 
            -
                            if (to - from <= 1) return (toX - x > x - fromX) ? from : to;
         | 
| 1372 | 
            -
                            var middle = Math.ceil((from + to) / 2), middleX = getX(middle);
         | 
| 1373 | 
            -
                            if (middleX > x) {to = middle; toX = middleX;}
         | 
| 1374 | 
            -
                            else {from = middle; fromX = middleX;}
         | 
| 1375 | 
            -
                        }
         | 
| 1376 | 
            -
                    }
         | 
| 1377 | 
            -
             | 
| 1378 | 
            -
                    var tempId = Math.floor(Math.random() * 0xffffff).toString(16);
         | 
| 1379 | 
            -
                    function measureLine(line, ch) {
         | 
| 1380 | 
            -
                        var extra = "";
         | 
| 1381 | 
            -
                        // Include extra text at the end to make sure the measured line is wrapped in the right way.
         | 
| 1382 | 
            -
                        if (options.lineWrapping) {
         | 
| 1383 | 
            -
                            var end = line.text.indexOf(" ", ch + 2);
         | 
| 1384 | 
            -
                            extra = htmlEscape(line.text.slice(ch + 1, end < 0 ? line.text.length : end + (ie ? 5 : 0)));
         | 
| 1385 | 
            -
                        }
         | 
| 1386 | 
            -
                        measure.innerHTML = "<pre>" + line.getHTML(null, null, false, tabText, ch) +
         | 
| 1387 | 
            -
                            '<span id="CodeMirror-temp-' + tempId + '">' + htmlEscape(line.text.charAt(ch) || " ") + "</span>" +
         | 
| 1388 | 
            -
                            extra + "</pre>";
         | 
| 1389 | 
            -
                        var elt = document.getElementById("CodeMirror-temp-" + tempId);
         | 
| 1390 | 
            -
                        var top = elt.offsetTop, left = elt.offsetLeft;
         | 
| 1391 | 
            -
                        // Older IEs report zero offsets for spans directly after a wrap
         | 
| 1392 | 
            -
                        if (ie && ch && top == 0 && left == 0) {
         | 
| 1393 | 
            -
                            var backup = document.createElement("span");
         | 
| 1394 | 
            -
                            backup.innerHTML = "x";
         | 
| 1395 | 
            -
                            elt.parentNode.insertBefore(backup, elt.nextSibling);
         | 
| 1396 | 
            -
                            top = backup.offsetTop;
         | 
| 1397 | 
            -
                        }
         | 
| 1398 | 
            -
                        return {top: top, left: left};
         | 
| 1399 | 
            -
                    }
         | 
| 1400 | 
            -
                    function localCoords(pos, inLineWrap) {
         | 
| 1401 | 
            -
                        var x, lh = textHeight(), y = lh * (heightAtLine(doc, pos.line) - (inLineWrap ? displayOffset : 0));
         | 
| 1402 | 
            -
                        if (pos.ch == 0) x = 0;
         | 
| 1403 | 
            -
                        else {
         | 
| 1404 | 
            -
                            var sp = measureLine(getLine(pos.line), pos.ch);
         | 
| 1405 | 
            -
                            x = sp.left;
         | 
| 1406 | 
            -
                            if (options.lineWrapping) y += Math.max(0, sp.top);
         | 
| 1407 | 
            -
                        }
         | 
| 1408 | 
            -
                        return {x: x, y: y, yBot: y + lh};
         | 
| 1409 | 
            -
                    }
         | 
| 1410 | 
            -
                    // Coords must be lineSpace-local
         | 
| 1411 | 
            -
                    function coordsChar(x, y) {
         | 
| 1412 | 
            -
                        if (y < 0) y = 0;
         | 
| 1413 | 
            -
                        var th = textHeight(), cw = charWidth(), heightPos = displayOffset + Math.floor(y / th);
         | 
| 1414 | 
            -
                        var lineNo = lineAtHeight(doc, heightPos);
         | 
| 1415 | 
            -
                        if (lineNo >= doc.size) return {line: doc.size - 1, ch: getLine(doc.size - 1).text.length};
         | 
| 1416 | 
            -
                        var lineObj = getLine(lineNo), text = lineObj.text;
         | 
| 1417 | 
            -
                        var tw = options.lineWrapping, innerOff = tw ? heightPos - heightAtLine(doc, lineNo) : 0;
         | 
| 1418 | 
            -
                        if (x <= 0 && innerOff == 0) return {line: lineNo, ch: 0};
         | 
| 1419 | 
            -
                        function getX(len) {
         | 
| 1420 | 
            -
                            var sp = measureLine(lineObj, len);
         | 
| 1421 | 
            -
                            if (tw) {
         | 
| 1422 | 
            -
                                var off = Math.round(sp.top / th);
         | 
| 1423 | 
            -
                                return Math.max(0, sp.left + (off - innerOff) * scroller.clientWidth);
         | 
| 1424 | 
            -
                            }
         | 
| 1425 | 
            -
                            return sp.left;
         | 
| 1426 | 
            -
                        }
         | 
| 1427 | 
            -
                        var from = 0, fromX = 0, to = text.length, toX;
         | 
| 1428 | 
            -
                        // Guess a suitable upper bound for our search.
         | 
| 1429 | 
            -
                        var estimated = Math.min(to, Math.ceil((x + innerOff * scroller.clientWidth * .9) / cw));
         | 
| 1430 | 
            -
                        for (;;) {
         | 
| 1431 | 
            -
                            var estX = getX(estimated);
         | 
| 1432 | 
            -
                            if (estX <= x && estimated < to) estimated = Math.min(to, Math.ceil(estimated * 1.2));
         | 
| 1433 | 
            -
                            else {toX = estX; to = estimated; break;}
         | 
| 1434 | 
            -
                        }
         | 
| 1435 | 
            -
                        if (x > toX) return {line: lineNo, ch: to};
         | 
| 1436 | 
            -
                        // Try to guess a suitable lower bound as well.
         | 
| 1437 | 
            -
                        estimated = Math.floor(to * 0.8); estX = getX(estimated);
         | 
| 1438 | 
            -
                        if (estX < x) {from = estimated; fromX = estX;}
         | 
| 1439 | 
            -
                        // Do a binary search between these bounds.
         | 
| 1440 | 
            -
                        for (;;) {
         | 
| 1441 | 
            -
                            if (to - from <= 1) return {line: lineNo, ch: (toX - x > x - fromX) ? from : to};
         | 
| 1442 | 
            -
                            var middle = Math.ceil((from + to) / 2), middleX = getX(middle);
         | 
| 1443 | 
            -
                            if (middleX > x) {to = middle; toX = middleX;}
         | 
| 1444 | 
            -
                            else {from = middle; fromX = middleX;}
         | 
| 1445 | 
            -
                        }
         | 
| 1446 | 
            -
                    }
         | 
| 1447 | 
            -
                    function pageCoords(pos) {
         | 
| 1448 | 
            -
                        var local = localCoords(pos, true), off = eltOffset(lineSpace);
         | 
| 1449 | 
            -
                        return {x: off.left + local.x, y: off.top + local.y, yBot: off.top + local.yBot};
         | 
| 1450 | 
            -
                    }
         | 
| 1451 | 
            -
             | 
| 1452 | 
            -
                    var cachedHeight, cachedHeightFor, measureText;
         | 
| 1453 | 
            -
                    function textHeight() {
         | 
| 1454 | 
            -
                        if (measureText == null) {
         | 
| 1455 | 
            -
                            measureText = "<pre>";
         | 
| 1456 | 
            -
                            for (var i = 0; i < 49; ++i) measureText += "x<br/>";
         | 
| 1457 | 
            -
                            measureText += "x</pre>";
         | 
| 1458 | 
            -
                        }
         | 
| 1459 | 
            -
                        var offsetHeight = lineDiv.clientHeight;
         | 
| 1460 | 
            -
                        if (offsetHeight == cachedHeightFor) return cachedHeight;
         | 
| 1461 | 
            -
                        cachedHeightFor = offsetHeight;
         | 
| 1462 | 
            -
                        measure.innerHTML = measureText;
         | 
| 1463 | 
            -
                        cachedHeight = measure.firstChild.offsetHeight / 50 || 1;
         | 
| 1464 | 
            -
                        measure.innerHTML = "";
         | 
| 1465 | 
            -
                        return cachedHeight;
         | 
| 1466 | 
            -
                    }
         | 
| 1467 | 
            -
                    var cachedWidth, cachedWidthFor = 0;
         | 
| 1468 | 
            -
                    function charWidth() {
         | 
| 1469 | 
            -
                        if (scroller.clientWidth == cachedWidthFor) return cachedWidth;
         | 
| 1470 | 
            -
                        cachedWidthFor = scroller.clientWidth;
         | 
| 1471 | 
            -
                        return (cachedWidth = stringWidth("x"));
         | 
| 1472 | 
            -
                    }
         | 
| 1473 | 
            -
                    function paddingTop() {return lineSpace.offsetTop;}
         | 
| 1474 | 
            -
                    function paddingLeft() {return lineSpace.offsetLeft;}
         | 
| 1475 | 
            -
             | 
| 1476 | 
            -
                    function posFromMouse(e, liberal) {
         | 
| 1477 | 
            -
                        var offW = eltOffset(scroller, true), x, y;
         | 
| 1478 | 
            -
                        // Fails unpredictably on IE[67] when mouse is dragged around quickly.
         | 
| 1479 | 
            -
                        try { x = e.clientX; y = e.clientY; } catch (e) { return null; }
         | 
| 1480 | 
            -
                        // This is a mess of a heuristic to try and determine whether a
         | 
| 1481 | 
            -
                        // scroll-bar was clicked or not, and to return null if one was
         | 
| 1482 | 
            -
                        // (and !liberal).
         | 
| 1483 | 
            -
                        if (!liberal && (x - offW.left > scroller.clientWidth || y - offW.top > scroller.clientHeight))
         | 
| 1484 | 
            -
                            return null;
         | 
| 1485 | 
            -
                        var offL = eltOffset(lineSpace, true);
         | 
| 1486 | 
            -
                        return coordsChar(x - offL.left, y - offL.top);
         | 
| 1487 | 
            -
                    }
         | 
| 1488 | 
            -
                    function onContextMenu(e) {
         | 
| 1489 | 
            -
                        var pos = posFromMouse(e);
         | 
| 1490 | 
            -
                        if (!pos || window.opera) return; // Opera is difficult.
         | 
| 1491 | 
            -
                        if (posEq(sel.from, sel.to) || posLess(pos, sel.from) || !posLess(pos, sel.to))
         | 
| 1492 | 
            -
                            operation(setCursor)(pos.line, pos.ch);
         | 
| 1493 | 
            -
             | 
| 1494 | 
            -
                        var oldCSS = input.style.cssText;
         | 
| 1495 | 
            -
                        inputDiv.style.position = "absolute";
         | 
| 1496 | 
            -
                        input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) +
         | 
| 1497 | 
            -
                            "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: white; " +
         | 
| 1498 | 
            -
                            "border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";
         | 
| 1499 | 
            -
                        leaveInputAlone = true;
         | 
| 1500 | 
            -
                        var val = input.value = getSelection();
         | 
| 1501 | 
            -
                        focusInput();
         | 
| 1502 | 
            -
                        input.select();
         | 
| 1503 | 
            -
                        function rehide() {
         | 
| 1504 | 
            -
                            var newVal = splitLines(input.value).join("\n");
         | 
| 1505 | 
            -
                            if (newVal != val) operation(replaceSelection)(newVal, "end");
         | 
| 1506 | 
            -
                            inputDiv.style.position = "relative";
         | 
| 1507 | 
            -
                            input.style.cssText = oldCSS;
         | 
| 1508 | 
            -
                            leaveInputAlone = false;
         | 
| 1509 | 
            -
                            resetInput(true);
         | 
| 1510 | 
            -
                            slowPoll();
         | 
| 1511 | 
            -
                        }
         | 
| 1512 | 
            -
             | 
| 1513 | 
            -
                        if (gecko) {
         | 
| 1514 | 
            -
                            e_stop(e);
         | 
| 1515 | 
            -
                            var mouseup = connect(window, "mouseup", function() {
         | 
| 1516 | 
            -
                                mouseup();
         | 
| 1517 | 
            -
                                setTimeout(rehide, 20);
         | 
| 1518 | 
            -
                            }, true);
         | 
| 1519 | 
            -
                        }
         | 
| 1520 | 
            -
                        else {
         | 
| 1521 | 
            -
                            setTimeout(rehide, 50);
         | 
| 1522 | 
            -
                        }
         | 
| 1523 | 
            -
                    }
         | 
| 1524 | 
            -
             | 
| 1525 | 
            -
                    // Cursor-blinking
         | 
| 1526 | 
            -
                    function restartBlink() {
         | 
| 1527 | 
            -
                        clearInterval(blinker);
         | 
| 1528 | 
            -
                        var on = true;
         | 
| 1529 | 
            -
                        cursor.style.visibility = "";
         | 
| 1530 | 
            -
                        blinker = setInterval(function() {
         | 
| 1531 | 
            -
                            cursor.style.visibility = (on = !on) ? "" : "hidden";
         | 
| 1532 | 
            -
                        }, 650);
         | 
| 1533 | 
            -
                    }
         | 
| 1534 | 
            -
             | 
| 1535 | 
            -
                    var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"};
         | 
| 1536 | 
            -
                    function matchBrackets(autoclear) {
         | 
| 1537 | 
            -
                        var head = sel.inverted ? sel.from : sel.to, line = getLine(head.line), pos = head.ch - 1;
         | 
| 1538 | 
            -
                        var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)];
         | 
| 1539 | 
            -
                        if (!match) return;
         | 
| 1540 | 
            -
                        var ch = match.charAt(0), forward = match.charAt(1) == ">", d = forward ? 1 : -1, st = line.styles;
         | 
| 1541 | 
            -
                        for (var off = pos + 1, i = 0, e = st.length; i < e; i+=2)
         | 
| 1542 | 
            -
                            if ((off -= st[i].length) <= 0) {var style = st[i+1]; break;}
         | 
| 1543 | 
            -
             | 
| 1544 | 
            -
                        var stack = [line.text.charAt(pos)], re = /[(){}[\]]/;
         | 
| 1545 | 
            -
                        function scan(line, from, to) {
         | 
| 1546 | 
            -
                            if (!line.text) return;
         | 
| 1547 | 
            -
                            var st = line.styles, pos = forward ? 0 : line.text.length - 1, cur;
         | 
| 1548 | 
            -
                            for (var i = forward ? 0 : st.length - 2, e = forward ? st.length : -2; i != e; i += 2*d) {
         | 
| 1549 | 
            -
                                var text = st[i];
         | 
| 1550 | 
            -
                                if (st[i+1] != null && st[i+1] != style) {pos += d * text.length; continue;}
         | 
| 1551 | 
            -
                                for (var j = forward ? 0 : text.length - 1, te = forward ? text.length : -1; j != te; j += d, pos+=d) {
         | 
| 1552 | 
            -
                                    if (pos >= from && pos < to && re.test(cur = text.charAt(j))) {
         | 
| 1553 | 
            -
                                        var match = matching[cur];
         | 
| 1554 | 
            -
                                        if (match.charAt(1) == ">" == forward) stack.push(cur);
         | 
| 1555 | 
            -
                                        else if (stack.pop() != match.charAt(0)) return {pos: pos, match: false};
         | 
| 1556 | 
            -
                                        else if (!stack.length) return {pos: pos, match: true};
         | 
| 1557 | 
            -
                                    }
         | 
| 1558 | 
            -
                                }
         | 
| 1559 | 
            -
                            }
         | 
| 1560 | 
            -
                        }
         | 
| 1561 | 
            -
                        for (var i = head.line, e = forward ? Math.min(i + 100, doc.size) : Math.max(-1, i - 100); i != e; i+=d) {
         | 
| 1562 | 
            -
                            var line = getLine(i), first = i == head.line;
         | 
| 1563 | 
            -
                            var found = scan(line, first && forward ? pos + 1 : 0, first && !forward ? pos : line.text.length);
         | 
| 1564 | 
            -
                            if (found) break;
         | 
| 1565 | 
            -
                        }
         | 
| 1566 | 
            -
                        if (!found) found = {pos: null, match: false};
         | 
| 1567 | 
            -
                        var style = found.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket";
         | 
| 1568 | 
            -
                        var one = markText({line: head.line, ch: pos}, {line: head.line, ch: pos+1}, style),
         | 
| 1569 | 
            -
                            two = found.pos != null && markText({line: i, ch: found.pos}, {line: i, ch: found.pos + 1}, style);
         | 
| 1570 | 
            -
                        var clear = operation(function(){one.clear(); two && two.clear();});
         | 
| 1571 | 
            -
                        if (autoclear) setTimeout(clear, 800);
         | 
| 1572 | 
            -
                        else bracketHighlighted = clear;
         | 
| 1573 | 
            -
                    }
         | 
| 1574 | 
            -
             | 
| 1575 | 
            -
                    // Finds the line to start with when starting a parse. Tries to
         | 
| 1576 | 
            -
                    // find a line with a stateAfter, so that it can start with a
         | 
| 1577 | 
            -
                    // valid state. If that fails, it returns the line with the
         | 
| 1578 | 
            -
                    // smallest indentation, which tends to need the least context to
         | 
| 1579 | 
            -
                    // parse correctly.
         | 
| 1580 | 
            -
                    function findStartLine(n) {
         | 
| 1581 | 
            -
                        var minindent, minline;
         | 
| 1582 | 
            -
                        for (var search = n, lim = n - 40; search > lim; --search) {
         | 
| 1583 | 
            -
                            if (search == 0) return 0;
         | 
| 1584 | 
            -
                            var line = getLine(search-1);
         | 
| 1585 | 
            -
                            if (line.stateAfter) return search;
         | 
| 1586 | 
            -
                            var indented = line.indentation(options.tabSize);
         | 
| 1587 | 
            -
                            if (minline == null || minindent > indented) {
         | 
| 1588 | 
            -
                                minline = search - 1;
         | 
| 1589 | 
            -
                                minindent = indented;
         | 
| 1590 | 
            -
                            }
         | 
| 1591 | 
            -
                        }
         | 
| 1592 | 
            -
                        return minline;
         | 
| 1593 | 
            -
                    }
         | 
| 1594 | 
            -
                    function getStateBefore(n) {
         | 
| 1595 | 
            -
                        var start = findStartLine(n), state = start && getLine(start-1).stateAfter;
         | 
| 1596 | 
            -
                        if (!state) state = startState(mode);
         | 
| 1597 | 
            -
                        else state = copyState(mode, state);
         | 
| 1598 | 
            -
                        doc.iter(start, n, function(line) {
         | 
| 1599 | 
            -
                            line.highlight(mode, state, options.tabSize);
         | 
| 1600 | 
            -
                            line.stateAfter = copyState(mode, state);
         | 
| 1601 | 
            -
                        });
         | 
| 1602 | 
            -
                        if (start < n) changes.push({from: start, to: n});
         | 
| 1603 | 
            -
                        if (n < doc.size && !getLine(n).stateAfter) work.push(n);
         | 
| 1604 | 
            -
                        return state;
         | 
| 1605 | 
            -
                    }
         | 
| 1606 | 
            -
                    function highlightLines(start, end) {
         | 
| 1607 | 
            -
                        var state = getStateBefore(start);
         | 
| 1608 | 
            -
                        doc.iter(start, end, function(line) {
         | 
| 1609 | 
            -
                            line.highlight(mode, state, options.tabSize);
         | 
| 1610 | 
            -
                            line.stateAfter = copyState(mode, state);
         | 
| 1611 | 
            -
                        });
         | 
| 1612 | 
            -
                    }
         | 
| 1613 | 
            -
                    function highlightWorker() {
         | 
| 1614 | 
            -
                        var end = +new Date + options.workTime;
         | 
| 1615 | 
            -
                        var foundWork = work.length;
         | 
| 1616 | 
            -
                        while (work.length) {
         | 
| 1617 | 
            -
                            if (!getLine(showingFrom).stateAfter) var task = showingFrom;
         | 
| 1618 | 
            -
                            else var task = work.pop();
         | 
| 1619 | 
            -
                            if (task >= doc.size) continue;
         | 
| 1620 | 
            -
                            var start = findStartLine(task), state = start && getLine(start-1).stateAfter;
         | 
| 1621 | 
            -
                            if (state) state = copyState(mode, state);
         | 
| 1622 | 
            -
                            else state = startState(mode);
         | 
| 1623 | 
            -
             | 
| 1624 | 
            -
                            var unchanged = 0, compare = mode.compareStates, realChange = false,
         | 
| 1625 | 
            -
                                i = start, bail = false;
         | 
| 1626 | 
            -
                            doc.iter(i, doc.size, function(line) {
         | 
| 1627 | 
            -
                                var hadState = line.stateAfter;
         | 
| 1628 | 
            -
                                if (+new Date > end) {
         | 
| 1629 | 
            -
                                    work.push(i);
         | 
| 1630 | 
            -
                                    startWorker(options.workDelay);
         | 
| 1631 | 
            -
                                    if (realChange) changes.push({from: task, to: i + 1});
         | 
| 1632 | 
            -
                                    return (bail = true);
         | 
| 1633 | 
            -
                                }
         | 
| 1634 | 
            -
                                var changed = line.highlight(mode, state, options.tabSize);
         | 
| 1635 | 
            -
                                if (changed) realChange = true;
         | 
| 1636 | 
            -
                                line.stateAfter = copyState(mode, state);
         | 
| 1637 | 
            -
                                if (compare) {
         | 
| 1638 | 
            -
                                    if (hadState && compare(hadState, state)) return true;
         | 
| 1639 | 
            -
                                } else {
         | 
| 1640 | 
            -
                                    if (changed !== false || !hadState) unchanged = 0;
         | 
| 1641 | 
            -
                                    else if (++unchanged > 3 && (!mode.indent || mode.indent(hadState, "") == mode.indent(state, "")))
         | 
| 1642 | 
            -
                                        return true;
         | 
| 1643 | 
            -
                                }
         | 
| 1644 | 
            -
                                ++i;
         | 
| 1645 | 
            -
                            });
         | 
| 1646 | 
            -
                            if (bail) return;
         | 
| 1647 | 
            -
                            if (realChange) changes.push({from: task, to: i + 1});
         | 
| 1648 | 
            -
                        }
         | 
| 1649 | 
            -
                        if (foundWork && options.onHighlightComplete)
         | 
| 1650 | 
            -
                            options.onHighlightComplete(instance);
         | 
| 1651 | 
            -
                    }
         | 
| 1652 | 
            -
                    function startWorker(time) {
         | 
| 1653 | 
            -
                        if (!work.length) return;
         | 
| 1654 | 
            -
                        highlight.set(time, operation(highlightWorker));
         | 
| 1655 | 
            -
                    }
         | 
| 1656 | 
            -
             | 
| 1657 | 
            -
                    // Operations are used to wrap changes in such a way that each
         | 
| 1658 | 
            -
                    // change won't have to update the cursor and display (which would
         | 
| 1659 | 
            -
                    // be awkward, slow, and error-prone), but instead updates are
         | 
| 1660 | 
            -
                    // batched and then all combined and executed at once.
         | 
| 1661 | 
            -
                    function startOperation() {
         | 
| 1662 | 
            -
                        updateInput = userSelChange = textChanged = null;
         | 
| 1663 | 
            -
                        changes = []; selectionChanged = false; callbacks = [];
         | 
| 1664 | 
            -
                    }
         | 
| 1665 | 
            -
                    function endOperation() {
         | 
| 1666 | 
            -
                        var reScroll = false, updated;
         | 
| 1667 | 
            -
                        if (selectionChanged) reScroll = !scrollCursorIntoView();
         | 
| 1668 | 
            -
                        if (changes.length) updated = updateDisplay(changes, true);
         | 
| 1669 | 
            -
                        else {
         | 
| 1670 | 
            -
                            if (selectionChanged) updateCursor();
         | 
| 1671 | 
            -
                            if (gutterDirty) updateGutter();
         | 
| 1672 | 
            -
                        }
         | 
| 1673 | 
            -
                        if (reScroll) scrollCursorIntoView();
         | 
| 1674 | 
            -
                        if (selectionChanged) {scrollEditorIntoView(); restartBlink();}
         | 
| 1675 | 
            -
             | 
| 1676 | 
            -
                        if (focused && !leaveInputAlone &&
         | 
| 1677 | 
            -
                            (updateInput === true || (updateInput !== false && selectionChanged)))
         | 
| 1678 | 
            -
                            resetInput(userSelChange);
         | 
| 1679 | 
            -
             | 
| 1680 | 
            -
                        if (selectionChanged && options.matchBrackets)
         | 
| 1681 | 
            -
                            setTimeout(operation(function() {
         | 
| 1682 | 
            -
                                if (bracketHighlighted) {bracketHighlighted(); bracketHighlighted = null;}
         | 
| 1683 | 
            -
                                if (posEq(sel.from, sel.to)) matchBrackets(false);
         | 
| 1684 | 
            -
                            }), 20);
         | 
| 1685 | 
            -
                        var tc = textChanged, cbs = callbacks; // these can be reset by callbacks
         | 
| 1686 | 
            -
                        if (selectionChanged && options.onCursorActivity)
         | 
| 1687 | 
            -
                            options.onCursorActivity(instance);
         | 
| 1688 | 
            -
                        if (tc && options.onChange && instance)
         | 
| 1689 | 
            -
                            options.onChange(instance, tc);
         | 
| 1690 | 
            -
                        for (var i = 0; i < cbs.length; ++i) cbs[i](instance);
         | 
| 1691 | 
            -
                        if (updated && options.onUpdate) options.onUpdate(instance);
         | 
| 1692 | 
            -
                    }
         | 
| 1693 | 
            -
                    var nestedOperation = 0;
         | 
| 1694 | 
            -
                    function operation(f) {
         | 
| 1695 | 
            -
                        return function() {
         | 
| 1696 | 
            -
                            if (!nestedOperation++) startOperation();
         | 
| 1697 | 
            -
                            try {var result = f.apply(this, arguments);}
         | 
| 1698 | 
            -
                            finally {if (!--nestedOperation) endOperation();}
         | 
| 1699 | 
            -
                            return result;
         | 
| 1700 | 
            -
                        };
         | 
| 1701 | 
            -
                    }
         | 
| 1702 | 
            -
             | 
| 1703 | 
            -
                    for (var ext in extensions)
         | 
| 1704 | 
            -
                        if (extensions.propertyIsEnumerable(ext) &&
         | 
| 1705 | 
            -
                            !instance.propertyIsEnumerable(ext))
         | 
| 1706 | 
            -
                            instance[ext] = extensions[ext];
         | 
| 1707 | 
            -
                    return instance;
         | 
| 1708 | 
            -
                } // (end of function CodeMirror)
         | 
| 1709 | 
            -
             | 
| 1710 | 
            -
                // The default configuration options.
         | 
| 1711 | 
            -
                CodeMirror.defaults = {
         | 
| 1712 | 
            -
                    value: "",
         | 
| 1713 | 
            -
                    mode: null,
         | 
| 1714 | 
            -
                    theme: "default",
         | 
| 1715 | 
            -
                    indentUnit: 2,
         | 
| 1716 | 
            -
                    indentWithTabs: false,
         | 
| 1717 | 
            -
                    tabSize: 4,
         | 
| 1718 | 
            -
                    keyMap: "default",
         | 
| 1719 | 
            -
                    extraKeys: null,
         | 
| 1720 | 
            -
                    electricChars: true,
         | 
| 1721 | 
            -
                    onKeyEvent: null,
         | 
| 1722 | 
            -
                    lineWrapping: false,
         | 
| 1723 | 
            -
                    lineNumbers: false,
         | 
| 1724 | 
            -
                    gutter: false,
         | 
| 1725 | 
            -
                    fixedGutter: false,
         | 
| 1726 | 
            -
                    firstLineNumber: 1,
         | 
| 1727 | 
            -
                    readOnly: false,
         | 
| 1728 | 
            -
                    onChange: null,
         | 
| 1729 | 
            -
                    onCursorActivity: null,
         | 
| 1730 | 
            -
                    onGutterClick: null,
         | 
| 1731 | 
            -
                    onHighlightComplete: null,
         | 
| 1732 | 
            -
                    onUpdate: null,
         | 
| 1733 | 
            -
                    onFocus: null, onBlur: null, onScroll: null,
         | 
| 1734 | 
            -
                    matchBrackets: false,
         | 
| 1735 | 
            -
                    workTime: 100,
         | 
| 1736 | 
            -
                    workDelay: 200,
         | 
| 1737 | 
            -
                    pollInterval: 100,
         | 
| 1738 | 
            -
                    undoDepth: 40,
         | 
| 1739 | 
            -
                    tabindex: null,
         | 
| 1740 | 
            -
                    document: window.document
         | 
| 1741 | 
            -
                };
         | 
| 1742 | 
            -
             | 
| 1743 | 
            -
                var mac = /Mac/.test(navigator.platform);
         | 
| 1744 | 
            -
                var win = /Win/.test(navigator.platform);
         | 
| 1745 | 
            -
             | 
| 1746 | 
            -
                // Known modes, by name and by MIME
         | 
| 1747 | 
            -
                var modes = {}, mimeModes = {};
         | 
| 1748 | 
            -
                CodeMirror.defineMode = function(name, mode) {
         | 
| 1749 | 
            -
                    if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name;
         | 
| 1750 | 
            -
                    modes[name] = mode;
         | 
| 1751 | 
            -
                };
         | 
| 1752 | 
            -
                CodeMirror.defineMIME = function(mime, spec) {
         | 
| 1753 | 
            -
                    mimeModes[mime] = spec;
         | 
| 1754 | 
            -
                };
         | 
| 1755 | 
            -
                CodeMirror.getMode = function(options, spec) {
         | 
| 1756 | 
            -
                    if (typeof spec == "string" && mimeModes.hasOwnProperty(spec))
         | 
| 1757 | 
            -
                        spec = mimeModes[spec];
         | 
| 1758 | 
            -
                    if (typeof spec == "string")
         | 
| 1759 | 
            -
                        var mname = spec, config = {};
         | 
| 1760 | 
            -
                    else if (spec != null)
         | 
| 1761 | 
            -
                        var mname = spec.name, config = spec;
         | 
| 1762 | 
            -
                    var mfactory = modes[mname];
         | 
| 1763 | 
            -
                    if (!mfactory) {
         | 
| 1764 | 
            -
                        if (window.console) console.warn("No mode " + mname + " found, falling back to plain text.");
         | 
| 1765 | 
            -
                        return CodeMirror.getMode(options, "text/plain");
         | 
| 1766 | 
            -
                    }
         | 
| 1767 | 
            -
                    return mfactory(options, config || {});
         | 
| 1768 | 
            -
                };
         | 
| 1769 | 
            -
                CodeMirror.listModes = function() {
         | 
| 1770 | 
            -
                    var list = [];
         | 
| 1771 | 
            -
                    for (var m in modes)
         | 
| 1772 | 
            -
                        if (modes.propertyIsEnumerable(m)) list.push(m);
         | 
| 1773 | 
            -
                    return list;
         | 
| 1774 | 
            -
                };
         | 
| 1775 | 
            -
                CodeMirror.listMIMEs = function() {
         | 
| 1776 | 
            -
                    var list = [];
         | 
| 1777 | 
            -
                    for (var m in mimeModes)
         | 
| 1778 | 
            -
                        if (mimeModes.propertyIsEnumerable(m)) list.push({mime: m, mode: mimeModes[m]});
         | 
| 1779 | 
            -
                    return list;
         | 
| 1780 | 
            -
                };
         | 
| 1781 | 
            -
             | 
| 1782 | 
            -
                var extensions = CodeMirror.extensions = {};
         | 
| 1783 | 
            -
                CodeMirror.defineExtension = function(name, func) {
         | 
| 1784 | 
            -
                    extensions[name] = func;
         | 
| 1785 | 
            -
                };
         | 
| 1786 | 
            -
             | 
| 1787 | 
            -
                var commands = CodeMirror.commands = {
         | 
| 1788 | 
            -
                    selectAll: function(cm) {cm.setSelection({line: 0, ch: 0}, {line: cm.lineCount() - 1});},
         | 
| 1789 | 
            -
                    killLine: function(cm) {
         | 
| 1790 | 
            -
                        var from = cm.getCursor(true), to = cm.getCursor(false), sel = !posEq(from, to);
         | 
| 1791 | 
            -
                        if (!sel && cm.getLine(from.line).length == from.ch) cm.replaceRange("", from, {line: from.line + 1, ch: 0});
         | 
| 1792 | 
            -
                        else cm.replaceRange("", from, sel ? to : {line: from.line});
         | 
| 1793 | 
            -
                    },
         | 
| 1794 | 
            -
                    deleteLine: function(cm) {var l = cm.getCursor().line; cm.replaceRange("", {line: l, ch: 0}, {line: l});},
         | 
| 1795 | 
            -
                    undo: function(cm) {cm.undo();},
         | 
| 1796 | 
            -
                    redo: function(cm) {cm.redo();},
         | 
| 1797 | 
            -
                    goDocStart: function(cm) {cm.setCursor(0, 0, true);},
         | 
| 1798 | 
            -
                    goDocEnd: function(cm) {cm.setSelection({line: cm.lineCount() - 1}, null, true);},
         | 
| 1799 | 
            -
                    goLineStart: function(cm) {cm.setCursor(cm.getCursor().line, 0, true);},
         | 
| 1800 | 
            -
                    goLineStartSmart: function(cm) {
         | 
| 1801 | 
            -
                        var cur = cm.getCursor();
         | 
| 1802 | 
            -
                        var text = cm.getLine(cur.line), firstNonWS = Math.max(0, text.search(/\S/));
         | 
| 1803 | 
            -
                        cm.setCursor(cur.line, cur.ch <= firstNonWS && cur.ch ? 0 : firstNonWS, true);
         | 
| 1804 | 
            -
                    },
         | 
| 1805 | 
            -
                    goLineEnd: function(cm) {cm.setSelection({line: cm.getCursor().line}, null, true);},
         | 
| 1806 | 
            -
                    goLineUp: function(cm) {cm.moveV(-1, "line");},
         | 
| 1807 | 
            -
                    goLineDown: function(cm) {cm.moveV(1, "line");},
         | 
| 1808 | 
            -
                    goPageUp: function(cm) {cm.moveV(-1, "page");},
         | 
| 1809 | 
            -
                    goPageDown: function(cm) {cm.moveV(1, "page");},
         | 
| 1810 | 
            -
                    goCharLeft: function(cm) {cm.moveH(-1, "char");},
         | 
| 1811 | 
            -
                    goCharRight: function(cm) {cm.moveH(1, "char");},
         | 
| 1812 | 
            -
                    goColumnLeft: function(cm) {cm.moveH(-1, "column");},
         | 
| 1813 | 
            -
                    goColumnRight: function(cm) {cm.moveH(1, "column");},
         | 
| 1814 | 
            -
                    goWordLeft: function(cm) {cm.moveH(-1, "word");},
         | 
| 1815 | 
            -
                    goWordRight: function(cm) {cm.moveH(1, "word");},
         | 
| 1816 | 
            -
                    delCharLeft: function(cm) {cm.deleteH(-1, "char");},
         | 
| 1817 | 
            -
                    delCharRight: function(cm) {cm.deleteH(1, "char");},
         | 
| 1818 | 
            -
                    delWordLeft: function(cm) {cm.deleteH(-1, "word");},
         | 
| 1819 | 
            -
                    delWordRight: function(cm) {cm.deleteH(1, "word");},
         | 
| 1820 | 
            -
                    indentAuto: function(cm) {cm.indentSelection("smart");},
         | 
| 1821 | 
            -
                    indentMore: function(cm) {cm.indentSelection("add");},
         | 
| 1822 | 
            -
                    indentLess: function(cm) {cm.indentSelection("subtract");},
         | 
| 1823 | 
            -
                    insertTab: function(cm) {cm.replaceSelection("\t", "end");},
         | 
| 1824 | 
            -
                    transposeChars: function(cm) {
         | 
| 1825 | 
            -
                        var cur = cm.getCursor(), line = cm.getLine(cur.line);
         | 
| 1826 | 
            -
                        if (cur.ch > 0 && cur.ch < line.length - 1)
         | 
| 1827 | 
            -
                            cm.replaceRange(line.charAt(cur.ch) + line.charAt(cur.ch - 1),
         | 
| 1828 | 
            -
                                {line: cur.line, ch: cur.ch - 1}, {line: cur.line, ch: cur.ch + 1});
         | 
| 1829 | 
            -
                    },
         | 
| 1830 | 
            -
                    newlineAndIndent: function(cm) {
         | 
| 1831 | 
            -
                        cm.replaceSelection("\n", "end");
         | 
| 1832 | 
            -
                        cm.indentLine(cm.getCursor().line);
         | 
| 1833 | 
            -
                    },
         | 
| 1834 | 
            -
                    toggleOverwrite: function(cm) {cm.toggleOverwrite();}
         | 
| 1835 | 
            -
                };
         | 
| 1836 | 
            -
             | 
| 1837 | 
            -
                var keyMap = CodeMirror.keyMap = {};
         | 
| 1838 | 
            -
                keyMap.basic = {
         | 
| 1839 | 
            -
                    "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown",
         | 
| 1840 | 
            -
                    "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown",
         | 
| 1841 | 
            -
                    "Delete": "delCharRight", "Backspace": "delCharLeft", "Tab": "indentMore", "Shift-Tab": "indentLess",
         | 
| 1842 | 
            -
                    "Enter": "newlineAndIndent", "Insert": "toggleOverwrite"
         | 
| 1843 | 
            -
                };
         | 
| 1844 | 
            -
                // Note that the save and find-related commands aren't defined by
         | 
| 1845 | 
            -
                // default. Unknown commands are simply ignored.
         | 
| 1846 | 
            -
                keyMap.pcDefault = {
         | 
| 1847 | 
            -
                    "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo",
         | 
| 1848 | 
            -
                    "Ctrl-Home": "goDocStart", "Alt-Up": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Down": "goDocEnd",
         | 
| 1849 | 
            -
                    "Ctrl-Left": "goWordLeft", "Ctrl-Right": "goWordRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd",
         | 
| 1850 | 
            -
                    "Ctrl-Backspace": "delWordLeft", "Ctrl-Delete": "delWordRight", "Ctrl-S": "save", "Ctrl-F": "find",
         | 
| 1851 | 
            -
                    "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
         | 
| 1852 | 
            -
                    fallthrough: "basic"
         | 
| 1853 | 
            -
                };
         | 
| 1854 | 
            -
                keyMap.macDefault = {
         | 
| 1855 | 
            -
                    "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo",
         | 
| 1856 | 
            -
                    "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goWordLeft",
         | 
| 1857 | 
            -
                    "Alt-Right": "goWordRight", "Cmd-Left": "goLineStart", "Cmd-Right": "goLineEnd", "Alt-Backspace": "delWordLeft",
         | 
| 1858 | 
            -
                    "Ctrl-Alt-Backspace": "delWordRight", "Alt-Delete": "delWordRight", "Cmd-S": "save", "Cmd-F": "find",
         | 
| 1859 | 
            -
                    "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
         | 
| 1860 | 
            -
                    fallthrough: ["basic", "emacsy"]
         | 
| 1861 | 
            -
                };
         | 
| 1862 | 
            -
                keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault;
         | 
| 1863 | 
            -
                keyMap.emacsy = {
         | 
| 1864 | 
            -
                    "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
         | 
| 1865 | 
            -
                    "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
         | 
| 1866 | 
            -
                    "Ctrl-V": "goPageUp", "Shift-Ctrl-V": "goPageDown", "Ctrl-D": "delCharRight", "Ctrl-H": "delCharLeft",
         | 
| 1867 | 
            -
                    "Alt-D": "delWordRight", "Alt-Backspace": "delWordLeft", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars"
         | 
| 1868 | 
            -
                };
         | 
| 1869 | 
            -
             | 
| 1870 | 
            -
                function lookupKey(name, extraMap, map) {
         | 
| 1871 | 
            -
                    function lookup(name, map, ft) {
         | 
| 1872 | 
            -
                        var found = map[name];
         | 
| 1873 | 
            -
                        if (found != null) return found;
         | 
| 1874 | 
            -
                        if (ft == null) ft = map.fallthrough;
         | 
| 1875 | 
            -
                        if (ft == null) return map.catchall;
         | 
| 1876 | 
            -
                        if (typeof ft == "string") return lookup(name, keyMap[ft]);
         | 
| 1877 | 
            -
                        for (var i = 0, e = ft.length; i < e; ++i) {
         | 
| 1878 | 
            -
                            found = lookup(name, keyMap[ft[i]]);
         | 
| 1879 | 
            -
                            if (found != null) return found;
         | 
| 1880 | 
            -
                        }
         | 
| 1881 | 
            -
                        return null;
         | 
| 1882 | 
            -
                    }
         | 
| 1883 | 
            -
                    return extraMap ? lookup(name, extraMap, map) : lookup(name, keyMap[map]);
         | 
| 1884 | 
            -
                }
         | 
| 1885 | 
            -
                function isModifierKey(event) {
         | 
| 1886 | 
            -
                    var name = keyNames[event.keyCode];
         | 
| 1887 | 
            -
                    return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod";
         | 
| 1888 | 
            -
                }
         | 
| 1889 | 
            -
             | 
| 1890 | 
            -
                CodeMirror.fromTextArea = function(textarea, options) {
         | 
| 1891 | 
            -
                    if (!options) options = {};
         | 
| 1892 | 
            -
                    options.value = textarea.value;
         | 
| 1893 | 
            -
                    if (!options.tabindex && textarea.tabindex)
         | 
| 1894 | 
            -
                        options.tabindex = textarea.tabindex;
         | 
| 1895 | 
            -
             | 
| 1896 | 
            -
                    function save() {textarea.value = instance.getValue();}
         | 
| 1897 | 
            -
                    if (textarea.form) {
         | 
| 1898 | 
            -
                        // Deplorable hack to make the submit method do the right thing.
         | 
| 1899 | 
            -
                        var rmSubmit = connect(textarea.form, "submit", save, true);
         | 
| 1900 | 
            -
                        if (typeof textarea.form.submit == "function") {
         | 
| 1901 | 
            -
                            var realSubmit = textarea.form.submit;
         | 
| 1902 | 
            -
                            function wrappedSubmit() {
         | 
| 1903 | 
            -
                                save();
         | 
| 1904 | 
            -
                                textarea.form.submit = realSubmit;
         | 
| 1905 | 
            -
                                textarea.form.submit();
         | 
| 1906 | 
            -
                                textarea.form.submit = wrappedSubmit;
         | 
| 1907 | 
            -
                            }
         | 
| 1908 | 
            -
                            textarea.form.submit = wrappedSubmit;
         | 
| 1909 | 
            -
                        }
         | 
| 1910 | 
            -
                    }
         | 
| 1911 | 
            -
             | 
| 1912 | 
            -
                    textarea.style.display = "none";
         | 
| 1913 | 
            -
                    var instance = CodeMirror(function(node) {
         | 
| 1914 | 
            -
                        textarea.parentNode.insertBefore(node, textarea.nextSibling);
         | 
| 1915 | 
            -
                    }, options);
         | 
| 1916 | 
            -
                    instance.save = save;
         | 
| 1917 | 
            -
                    instance.getTextArea = function() { return textarea; };
         | 
| 1918 | 
            -
                    instance.toTextArea = function() {
         | 
| 1919 | 
            -
                        save();
         | 
| 1920 | 
            -
                        textarea.parentNode.removeChild(instance.getWrapperElement());
         | 
| 1921 | 
            -
                        textarea.style.display = "";
         | 
| 1922 | 
            -
                        if (textarea.form) {
         | 
| 1923 | 
            -
                            rmSubmit();
         | 
| 1924 | 
            -
                            if (typeof textarea.form.submit == "function")
         | 
| 1925 | 
            -
                                textarea.form.submit = realSubmit;
         | 
| 1926 | 
            -
                        }
         | 
| 1927 | 
            -
                    };
         | 
| 1928 | 
            -
                    return instance;
         | 
| 1929 | 
            -
                };
         | 
| 1930 | 
            -
             | 
| 1931 | 
            -
                // Utility functions for working with state. Exported because modes
         | 
| 1932 | 
            -
                // sometimes need to do this.
         | 
| 1933 | 
            -
                function copyState(mode, state) {
         | 
| 1934 | 
            -
                    if (state === true) return state;
         | 
| 1935 | 
            -
                    if (mode.copyState) return mode.copyState(state);
         | 
| 1936 | 
            -
                    var nstate = {};
         | 
| 1937 | 
            -
                    for (var n in state) {
         | 
| 1938 | 
            -
                        var val = state[n];
         | 
| 1939 | 
            -
                        if (val instanceof Array) val = val.concat([]);
         | 
| 1940 | 
            -
                        nstate[n] = val;
         | 
| 1941 | 
            -
                    }
         | 
| 1942 | 
            -
                    return nstate;
         | 
| 1943 | 
            -
                }
         | 
| 1944 | 
            -
                CodeMirror.copyState = copyState;
         | 
| 1945 | 
            -
                function startState(mode, a1, a2) {
         | 
| 1946 | 
            -
                    return mode.startState ? mode.startState(a1, a2) : true;
         | 
| 1947 | 
            -
                }
         | 
| 1948 | 
            -
                CodeMirror.startState = startState;
         | 
| 1949 | 
            -
             | 
| 1950 | 
            -
                // The character stream used by a mode's parser.
         | 
| 1951 | 
            -
                function StringStream(string, tabSize) {
         | 
| 1952 | 
            -
                    this.pos = this.start = 0;
         | 
| 1953 | 
            -
                    this.string = string;
         | 
| 1954 | 
            -
                    this.tabSize = tabSize || 8;
         | 
| 1955 | 
            -
                }
         | 
| 1956 | 
            -
                StringStream.prototype = {
         | 
| 1957 | 
            -
                    eol: function() {return this.pos >= this.string.length;},
         | 
| 1958 | 
            -
                    sol: function() {return this.pos == 0;},
         | 
| 1959 | 
            -
                    peek: function() {return this.string.charAt(this.pos);},
         | 
| 1960 | 
            -
                    next: function() {
         | 
| 1961 | 
            -
                        if (this.pos < this.string.length)
         | 
| 1962 | 
            -
                            return this.string.charAt(this.pos++);
         | 
| 1963 | 
            -
                    },
         | 
| 1964 | 
            -
                    eat: function(match) {
         | 
| 1965 | 
            -
                        var ch = this.string.charAt(this.pos);
         | 
| 1966 | 
            -
                        if (typeof match == "string") var ok = ch == match;
         | 
| 1967 | 
            -
                        else var ok = ch && (match.test ? match.test(ch) : match(ch));
         | 
| 1968 | 
            -
                        if (ok) {++this.pos; return ch;}
         | 
| 1969 | 
            -
                    },
         | 
| 1970 | 
            -
                    eatWhile: function(match) {
         | 
| 1971 | 
            -
                        var start = this.pos;
         | 
| 1972 | 
            -
                        while (this.eat(match)){}
         | 
| 1973 | 
            -
                        return this.pos > start;
         | 
| 1974 | 
            -
                    },
         | 
| 1975 | 
            -
                    eatSpace: function() {
         | 
| 1976 | 
            -
                        var start = this.pos;
         | 
| 1977 | 
            -
                        while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
         | 
| 1978 | 
            -
                        return this.pos > start;
         | 
| 1979 | 
            -
                    },
         | 
| 1980 | 
            -
                    skipToEnd: function() {this.pos = this.string.length;},
         | 
| 1981 | 
            -
                    skipTo: function(ch) {
         | 
| 1982 | 
            -
                        var found = this.string.indexOf(ch, this.pos);
         | 
| 1983 | 
            -
                        if (found > -1) {this.pos = found; return true;}
         | 
| 1984 | 
            -
                    },
         | 
| 1985 | 
            -
                    backUp: function(n) {this.pos -= n;},
         | 
| 1986 | 
            -
                    column: function() {return countColumn(this.string, this.start, this.tabSize);},
         | 
| 1987 | 
            -
                    indentation: function() {return countColumn(this.string, null, this.tabSize);},
         | 
| 1988 | 
            -
                    match: function(pattern, consume, caseInsensitive) {
         | 
| 1989 | 
            -
                        if (typeof pattern == "string") {
         | 
| 1990 | 
            -
                            function cased(str) {return caseInsensitive ? str.toLowerCase() : str;}
         | 
| 1991 | 
            -
                            if (cased(this.string).indexOf(cased(pattern), this.pos) == this.pos) {
         | 
| 1992 | 
            -
                                if (consume !== false) this.pos += pattern.length;
         | 
| 1993 | 
            -
                                return true;
         | 
| 1994 | 
            -
                            }
         | 
| 1995 | 
            -
                        }
         | 
| 1996 | 
            -
                        else {
         | 
| 1997 | 
            -
                            var match = this.string.slice(this.pos).match(pattern);
         | 
| 1998 | 
            -
                            if (match && consume !== false) this.pos += match[0].length;
         | 
| 1999 | 
            -
                            return match;
         | 
| 2000 | 
            -
                        }
         | 
| 2001 | 
            -
                    },
         | 
| 2002 | 
            -
                    current: function(){return this.string.slice(this.start, this.pos);}
         | 
| 2003 | 
            -
                };
         | 
| 2004 | 
            -
                CodeMirror.StringStream = StringStream;
         | 
| 2005 | 
            -
             | 
| 2006 | 
            -
                function MarkedText(from, to, className, set) {
         | 
| 2007 | 
            -
                    this.from = from; this.to = to; this.style = className; this.set = set;
         | 
| 2008 | 
            -
                }
         | 
| 2009 | 
            -
                MarkedText.prototype = {
         | 
| 2010 | 
            -
                    attach: function(line) { this.set.push(line); },
         | 
| 2011 | 
            -
                    detach: function(line) {
         | 
| 2012 | 
            -
                        var ix = indexOf(this.set, line);
         | 
| 2013 | 
            -
                        if (ix > -1) this.set.splice(ix, 1);
         | 
| 2014 | 
            -
                    },
         | 
| 2015 | 
            -
                    split: function(pos, lenBefore) {
         | 
| 2016 | 
            -
                        if (this.to <= pos && this.to != null) return null;
         | 
| 2017 | 
            -
                        var from = this.from < pos || this.from == null ? null : this.from - pos + lenBefore;
         | 
| 2018 | 
            -
                        var to = this.to == null ? null : this.to - pos + lenBefore;
         | 
| 2019 | 
            -
                        return new MarkedText(from, to, this.style, this.set);
         | 
| 2020 | 
            -
                    },
         | 
| 2021 | 
            -
                    dup: function() { return new MarkedText(null, null, this.style, this.set); },
         | 
| 2022 | 
            -
                    clipTo: function(fromOpen, from, toOpen, to, diff) {
         | 
| 2023 | 
            -
                        if (this.from != null && this.from >= from)
         | 
| 2024 | 
            -
                            this.from = Math.max(to, this.from) + diff;
         | 
| 2025 | 
            -
                        if (this.to != null && this.to > from)
         | 
| 2026 | 
            -
                            this.to = to < this.to ? this.to + diff : from;
         | 
| 2027 | 
            -
                        if (fromOpen && to > this.from && (to < this.to || this.to == null))
         | 
| 2028 | 
            -
                            this.from = null;
         | 
| 2029 | 
            -
                        if (toOpen && (from < this.to || this.to == null) && (from > this.from || this.from == null))
         | 
| 2030 | 
            -
                            this.to = null;
         | 
| 2031 | 
            -
                    },
         | 
| 2032 | 
            -
                    isDead: function() { return this.from != null && this.to != null && this.from >= this.to; },
         | 
| 2033 | 
            -
                    sameSet: function(x) { return this.set == x.set; }
         | 
| 2034 | 
            -
                };
         | 
| 2035 | 
            -
             | 
| 2036 | 
            -
                function Bookmark(pos) {
         | 
| 2037 | 
            -
                    this.from = pos; this.to = pos; this.line = null;
         | 
| 2038 | 
            -
                }
         | 
| 2039 | 
            -
                Bookmark.prototype = {
         | 
| 2040 | 
            -
                    attach: function(line) { this.line = line; },
         | 
| 2041 | 
            -
                    detach: function(line) { if (this.line == line) this.line = null; },
         | 
| 2042 | 
            -
                    split: function(pos, lenBefore) {
         | 
| 2043 | 
            -
                        if (pos < this.from) {
         | 
| 2044 | 
            -
                            this.from = this.to = (this.from - pos) + lenBefore;
         | 
| 2045 | 
            -
                            return this;
         | 
| 2046 | 
            -
                        }
         | 
| 2047 | 
            -
                    },
         | 
| 2048 | 
            -
                    isDead: function() { return this.from > this.to; },
         | 
| 2049 | 
            -
                    clipTo: function(fromOpen, from, toOpen, to, diff) {
         | 
| 2050 | 
            -
                        if ((fromOpen || from < this.from) && (toOpen || to > this.to)) {
         | 
| 2051 | 
            -
                            this.from = 0; this.to = -1;
         | 
| 2052 | 
            -
                        } else if (this.from > from) {
         | 
| 2053 | 
            -
                            this.from = this.to = Math.max(to, this.from) + diff;
         | 
| 2054 | 
            -
                        }
         | 
| 2055 | 
            -
                    },
         | 
| 2056 | 
            -
                    sameSet: function(x) { return false; },
         | 
| 2057 | 
            -
                    find: function() {
         | 
| 2058 | 
            -
                        if (!this.line || !this.line.parent) return null;
         | 
| 2059 | 
            -
                        return {line: lineNo(this.line), ch: this.from};
         | 
| 2060 | 
            -
                    },
         | 
| 2061 | 
            -
                    clear: function() {
         | 
| 2062 | 
            -
                        if (this.line) {
         | 
| 2063 | 
            -
                            var found = indexOf(this.line.marked, this);
         | 
| 2064 | 
            -
                            if (found != -1) this.line.marked.splice(found, 1);
         | 
| 2065 | 
            -
                            this.line = null;
         | 
| 2066 | 
            -
                        }
         | 
| 2067 | 
            -
                    }
         | 
| 2068 | 
            -
                };
         | 
| 2069 | 
            -
             | 
| 2070 | 
            -
                // Line objects. These hold state related to a line, including
         | 
| 2071 | 
            -
                // highlighting info (the styles array).
         | 
| 2072 | 
            -
                function Line(text, styles) {
         | 
| 2073 | 
            -
                    this.styles = styles || [text, null];
         | 
| 2074 | 
            -
                    this.text = text;
         | 
| 2075 | 
            -
                    this.height = 1;
         | 
| 2076 | 
            -
                    this.marked = this.gutterMarker = this.className = this.handlers = null;
         | 
| 2077 | 
            -
                    this.stateAfter = this.parent = this.hidden = null;
         | 
| 2078 | 
            -
                }
         | 
| 2079 | 
            -
                Line.inheritMarks = function(text, orig) {
         | 
| 2080 | 
            -
                    var ln = new Line(text), mk = orig && orig.marked;
         | 
| 2081 | 
            -
                    if (mk) {
         | 
| 2082 | 
            -
                        for (var i = 0; i < mk.length; ++i) {
         | 
| 2083 | 
            -
                            if (mk[i].to == null && mk[i].style) {
         | 
| 2084 | 
            -
                                var newmk = ln.marked || (ln.marked = []), mark = mk[i];
         | 
| 2085 | 
            -
                                var nmark = mark.dup(); newmk.push(nmark); nmark.attach(ln);
         | 
| 2086 | 
            -
                            }
         | 
| 2087 | 
            -
                        }
         | 
| 2088 | 
            -
                    }
         | 
| 2089 | 
            -
                    return ln;
         | 
| 2090 | 
            -
                }
         | 
| 2091 | 
            -
                Line.prototype = {
         | 
| 2092 | 
            -
                    // Replace a piece of a line, keeping the styles around it intact.
         | 
| 2093 | 
            -
                    replace: function(from, to_, text) {
         | 
| 2094 | 
            -
                        var st = [], mk = this.marked, to = to_ == null ? this.text.length : to_;
         | 
| 2095 | 
            -
                        copyStyles(0, from, this.styles, st);
         | 
| 2096 | 
            -
                        if (text) st.push(text, null);
         | 
| 2097 | 
            -
                        copyStyles(to, this.text.length, this.styles, st);
         | 
| 2098 | 
            -
                        this.styles = st;
         | 
| 2099 | 
            -
                        this.text = this.text.slice(0, from) + text + this.text.slice(to);
         | 
| 2100 | 
            -
                        this.stateAfter = null;
         | 
| 2101 | 
            -
                        if (mk) {
         | 
| 2102 | 
            -
                            var diff = text.length - (to - from);
         | 
| 2103 | 
            -
                            for (var i = 0, mark = mk[i]; i < mk.length; ++i) {
         | 
| 2104 | 
            -
                                mark.clipTo(from == null, from || 0, to_ == null, to, diff);
         | 
| 2105 | 
            -
                                if (mark.isDead()) {mark.detach(this); mk.splice(i--, 1);}
         | 
| 2106 | 
            -
                            }
         | 
| 2107 | 
            -
                        }
         | 
| 2108 | 
            -
                    },
         | 
| 2109 | 
            -
                    // Split a part off a line, keeping styles and markers intact.
         | 
| 2110 | 
            -
                    split: function(pos, textBefore) {
         | 
| 2111 | 
            -
                        var st = [textBefore, null], mk = this.marked;
         | 
| 2112 | 
            -
                        copyStyles(pos, this.text.length, this.styles, st);
         | 
| 2113 | 
            -
                        var taken = new Line(textBefore + this.text.slice(pos), st);
         | 
| 2114 | 
            -
                        if (mk) {
         | 
| 2115 | 
            -
                            for (var i = 0; i < mk.length; ++i) {
         | 
| 2116 | 
            -
                                var mark = mk[i];
         | 
| 2117 | 
            -
                                var newmark = mark.split(pos, textBefore.length);
         | 
| 2118 | 
            -
                                if (newmark) {
         | 
| 2119 | 
            -
                                    if (!taken.marked) taken.marked = [];
         | 
| 2120 | 
            -
                                    taken.marked.push(newmark); newmark.attach(taken);
         | 
| 2121 | 
            -
                                }
         | 
| 2122 | 
            -
                            }
         | 
| 2123 | 
            -
                        }
         | 
| 2124 | 
            -
                        return taken;
         | 
| 2125 | 
            -
                    },
         | 
| 2126 | 
            -
                    append: function(line) {
         | 
| 2127 | 
            -
                        var mylen = this.text.length, mk = line.marked, mymk = this.marked;
         | 
| 2128 | 
            -
                        this.text += line.text;
         | 
| 2129 | 
            -
                        copyStyles(0, line.text.length, line.styles, this.styles);
         | 
| 2130 | 
            -
                        if (mymk) {
         | 
| 2131 | 
            -
                            for (var i = 0; i < mymk.length; ++i)
         | 
| 2132 | 
            -
                                if (mymk[i].to == null) mymk[i].to = mylen;
         | 
| 2133 | 
            -
                        }
         | 
| 2134 | 
            -
                        if (mk && mk.length) {
         | 
| 2135 | 
            -
                            if (!mymk) this.marked = mymk = [];
         | 
| 2136 | 
            -
                            outer: for (var i = 0; i < mk.length; ++i) {
         | 
| 2137 | 
            -
                                var mark = mk[i];
         | 
| 2138 | 
            -
                                if (!mark.from) {
         | 
| 2139 | 
            -
                                    for (var j = 0; j < mymk.length; ++j) {
         | 
| 2140 | 
            -
                                        var mymark = mymk[j];
         | 
| 2141 | 
            -
                                        if (mymark.to == mylen && mymark.sameSet(mark)) {
         | 
| 2142 | 
            -
                                            mymark.to = mark.to == null ? null : mark.to + mylen;
         | 
| 2143 | 
            -
                                            if (mymark.isDead()) {
         | 
| 2144 | 
            -
                                                mymark.detach(this);
         | 
| 2145 | 
            -
                                                mk.splice(i--, 1);
         | 
| 2146 | 
            -
                                            }
         | 
| 2147 | 
            -
                                            continue outer;
         | 
| 2148 | 
            -
                                        }
         | 
| 2149 | 
            -
                                    }
         | 
| 2150 | 
            -
                                }
         | 
| 2151 | 
            -
                                mymk.push(mark);
         | 
| 2152 | 
            -
                                mark.attach(this);
         | 
| 2153 | 
            -
                                mark.from += mylen;
         | 
| 2154 | 
            -
                                if (mark.to != null) mark.to += mylen;
         | 
| 2155 | 
            -
                            }
         | 
| 2156 | 
            -
                        }
         | 
| 2157 | 
            -
                    },
         | 
| 2158 | 
            -
                    fixMarkEnds: function(other) {
         | 
| 2159 | 
            -
                        var mk = this.marked, omk = other.marked;
         | 
| 2160 | 
            -
                        if (!mk) return;
         | 
| 2161 | 
            -
                        for (var i = 0; i < mk.length; ++i) {
         | 
| 2162 | 
            -
                            var mark = mk[i], close = mark.to == null;
         | 
| 2163 | 
            -
                            if (close && omk) {
         | 
| 2164 | 
            -
                                for (var j = 0; j < omk.length; ++j)
         | 
| 2165 | 
            -
                                    if (omk[j].sameSet(mark)) {close = false; break;}
         | 
| 2166 | 
            -
                            }
         | 
| 2167 | 
            -
                            if (close) mark.to = this.text.length;
         | 
| 2168 | 
            -
                        }
         | 
| 2169 | 
            -
                    },
         | 
| 2170 | 
            -
                    fixMarkStarts: function() {
         | 
| 2171 | 
            -
                        var mk = this.marked;
         | 
| 2172 | 
            -
                        if (!mk) return;
         | 
| 2173 | 
            -
                        for (var i = 0; i < mk.length; ++i)
         | 
| 2174 | 
            -
                            if (mk[i].from == null) mk[i].from = 0;
         | 
| 2175 | 
            -
                    },
         | 
| 2176 | 
            -
                    addMark: function(mark) {
         | 
| 2177 | 
            -
                        mark.attach(this);
         | 
| 2178 | 
            -
                        if (this.marked == null) this.marked = [];
         | 
| 2179 | 
            -
                        this.marked.push(mark);
         | 
| 2180 | 
            -
                        this.marked.sort(function(a, b){return (a.from || 0) - (b.from || 0);});
         | 
| 2181 | 
            -
                    },
         | 
| 2182 | 
            -
                    // Run the given mode's parser over a line, update the styles
         | 
| 2183 | 
            -
                    // array, which contains alternating fragments of text and CSS
         | 
| 2184 | 
            -
                    // classes.
         | 
| 2185 | 
            -
                    highlight: function(mode, state, tabSize) {
         | 
| 2186 | 
            -
                        var stream = new StringStream(this.text, tabSize), st = this.styles, pos = 0;
         | 
| 2187 | 
            -
                        var changed = false, curWord = st[0], prevWord;
         | 
| 2188 | 
            -
                        if (this.text == "" && mode.blankLine) mode.blankLine(state);
         | 
| 2189 | 
            -
                        while (!stream.eol()) {
         | 
| 2190 | 
            -
                            var style = mode.token(stream, state);
         | 
| 2191 | 
            -
                            var substr = this.text.slice(stream.start, stream.pos);
         | 
| 2192 | 
            -
                            stream.start = stream.pos;
         | 
| 2193 | 
            -
                            if (pos && st[pos-1] == style)
         | 
| 2194 | 
            -
                                st[pos-2] += substr;
         | 
| 2195 | 
            -
                            else if (substr) {
         | 
| 2196 | 
            -
                                if (!changed && (st[pos+1] != style || (pos && st[pos-2] != prevWord))) changed = true;
         | 
| 2197 | 
            -
                                st[pos++] = substr; st[pos++] = style;
         | 
| 2198 | 
            -
                                prevWord = curWord; curWord = st[pos];
         | 
| 2199 | 
            -
                            }
         | 
| 2200 | 
            -
                            // Give up when line is ridiculously long
         | 
| 2201 | 
            -
                            if (stream.pos > 5000) {
         | 
| 2202 | 
            -
                                st[pos++] = this.text.slice(stream.pos); st[pos++] = null;
         | 
| 2203 | 
            -
                                break;
         | 
| 2204 | 
            -
                            }
         | 
| 2205 | 
            -
                        }
         | 
| 2206 | 
            -
                        if (st.length != pos) {st.length = pos; changed = true;}
         | 
| 2207 | 
            -
                        if (pos && st[pos-2] != prevWord) changed = true;
         | 
| 2208 | 
            -
                        // Short lines with simple highlights return null, and are
         | 
| 2209 | 
            -
                        // counted as changed by the driver because they are likely to
         | 
| 2210 | 
            -
                        // highlight the same way in various contexts.
         | 
| 2211 | 
            -
                        return changed || (st.length < 5 && this.text.length < 10 ? null : false);
         | 
| 2212 | 
            -
                    },
         | 
| 2213 | 
            -
                    // Fetch the parser token for a given character. Useful for hacks
         | 
| 2214 | 
            -
                    // that want to inspect the mode state (say, for completion).
         | 
| 2215 | 
            -
                    getTokenAt: function(mode, state, ch) {
         | 
| 2216 | 
            -
                        var txt = this.text, stream = new StringStream(txt);
         | 
| 2217 | 
            -
                        while (stream.pos < ch && !stream.eol()) {
         | 
| 2218 | 
            -
                            stream.start = stream.pos;
         | 
| 2219 | 
            -
                            var style = mode.token(stream, state);
         | 
| 2220 | 
            -
                        }
         | 
| 2221 | 
            -
                        return {start: stream.start,
         | 
| 2222 | 
            -
                            end: stream.pos,
         | 
| 2223 | 
            -
                            string: stream.current(),
         | 
| 2224 | 
            -
                            className: style || null,
         | 
| 2225 | 
            -
                            state: state};
         | 
| 2226 | 
            -
                    },
         | 
| 2227 | 
            -
                    indentation: function(tabSize) {return countColumn(this.text, null, tabSize);},
         | 
| 2228 | 
            -
                    // Produces an HTML fragment for the line, taking selection,
         | 
| 2229 | 
            -
                    // marking, and highlighting into account.
         | 
| 2230 | 
            -
                    getHTML: function(sfrom, sto, includePre, tabText, endAt) {
         | 
| 2231 | 
            -
                        var html = [], first = true;
         | 
| 2232 | 
            -
                        if (includePre)
         | 
| 2233 | 
            -
                            html.push(this.className ? '<pre class="' + this.className + '">': "<pre>");
         | 
| 2234 | 
            -
                        function span(text, style) {
         | 
| 2235 | 
            -
                            if (!text) return;
         | 
| 2236 | 
            -
                            // Work around a bug where, in some compat modes, IE ignores leading spaces
         | 
| 2237 | 
            -
                            if (first && ie && text.charAt(0) == " ") text = "\u00a0" + text.slice(1);
         | 
| 2238 | 
            -
                            first = false;
         | 
| 2239 | 
            -
                            if (style) html.push('<span class="', style, '">', htmlEscape(text).replace(/\t/g, tabText), "</span>");
         | 
| 2240 | 
            -
                            else html.push(htmlEscape(text).replace(/\t/g, tabText));
         | 
| 2241 | 
            -
                        }
         | 
| 2242 | 
            -
                        var st = this.styles, allText = this.text, marked = this.marked;
         | 
| 2243 | 
            -
                        if (sfrom == sto) sfrom = null;
         | 
| 2244 | 
            -
                        var len = allText.length;
         | 
| 2245 | 
            -
                        if (endAt != null) len = Math.min(endAt, len);
         | 
| 2246 | 
            -
             | 
| 2247 | 
            -
                        if (!allText && endAt == null)
         | 
| 2248 | 
            -
                            span(" ", sfrom != null && sto == null ? "CodeMirror-selected" : null);
         | 
| 2249 | 
            -
                        else if (!marked && sfrom == null)
         | 
| 2250 | 
            -
                            for (var i = 0, ch = 0; ch < len; i+=2) {
         | 
| 2251 | 
            -
                                var str = st[i], style = st[i+1], l = str.length;
         | 
| 2252 | 
            -
                                if (ch + l > len) str = str.slice(0, len - ch);
         | 
| 2253 | 
            -
                                ch += l;
         | 
| 2254 | 
            -
                                span(str, style && "cm-" + style);
         | 
| 2255 | 
            -
                            }
         | 
| 2256 | 
            -
                        else {
         | 
| 2257 | 
            -
                            var pos = 0, i = 0, text = "", style, sg = 0;
         | 
| 2258 | 
            -
                            var markpos = -1, mark = null;
         | 
| 2259 | 
            -
                            function nextMark() {
         | 
| 2260 | 
            -
                                if (marked) {
         | 
| 2261 | 
            -
                                    markpos += 1;
         | 
| 2262 | 
            -
                                    mark = (markpos < marked.length) ? marked[markpos] : null;
         | 
| 2263 | 
            -
                                }
         | 
| 2264 | 
            -
                            }
         | 
| 2265 | 
            -
                            nextMark();
         | 
| 2266 | 
            -
                            while (pos < len) {
         | 
| 2267 | 
            -
                                var upto = len;
         | 
| 2268 | 
            -
                                var extraStyle = "";
         | 
| 2269 | 
            -
                                if (sfrom != null) {
         | 
| 2270 | 
            -
                                    if (sfrom > pos) upto = sfrom;
         | 
| 2271 | 
            -
                                    else if (sto == null || sto > pos) {
         | 
| 2272 | 
            -
                                        extraStyle = " CodeMirror-selected";
         | 
| 2273 | 
            -
                                        if (sto != null) upto = Math.min(upto, sto);
         | 
| 2274 | 
            -
                                    }
         | 
| 2275 | 
            -
                                }
         | 
| 2276 | 
            -
                                while (mark && mark.to != null && mark.to <= pos) nextMark();
         | 
| 2277 | 
            -
                                if (mark) {
         | 
| 2278 | 
            -
                                    if (mark.from > pos) upto = Math.min(upto, mark.from);
         | 
| 2279 | 
            -
                                    else {
         | 
| 2280 | 
            -
                                        extraStyle += " " + mark.style;
         | 
| 2281 | 
            -
                                        if (mark.to != null) upto = Math.min(upto, mark.to);
         | 
| 2282 | 
            -
                                    }
         | 
| 2283 | 
            -
                                }
         | 
| 2284 | 
            -
                                for (;;) {
         | 
| 2285 | 
            -
                                    var end = pos + text.length;
         | 
| 2286 | 
            -
                                    var appliedStyle = style;
         | 
| 2287 | 
            -
                                    if (extraStyle) appliedStyle = style ? style + extraStyle : extraStyle;
         | 
| 2288 | 
            -
                                    span(end > upto ? text.slice(0, upto - pos) : text, appliedStyle);
         | 
| 2289 | 
            -
                                    if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;}
         | 
| 2290 | 
            -
                                    pos = end;
         | 
| 2291 | 
            -
                                    text = st[i++]; style = "cm-" + st[i++];
         | 
| 2292 | 
            -
                                }
         | 
| 2293 | 
            -
                            }
         | 
| 2294 | 
            -
                            if (sfrom != null && sto == null) span(" ", "CodeMirror-selected");
         | 
| 2295 | 
            -
                        }
         | 
| 2296 | 
            -
                        if (includePre) html.push("</pre>");
         | 
| 2297 | 
            -
                        return html.join("");
         | 
| 2298 | 
            -
                    },
         | 
| 2299 | 
            -
                    cleanUp: function() {
         | 
| 2300 | 
            -
                        this.parent = null;
         | 
| 2301 | 
            -
                        if (this.marked)
         | 
| 2302 | 
            -
                            for (var i = 0, e = this.marked.length; i < e; ++i) this.marked[i].detach(this);
         | 
| 2303 | 
            -
                    }
         | 
| 2304 | 
            -
                };
         | 
| 2305 | 
            -
                // Utility used by replace and split above
         | 
| 2306 | 
            -
                function copyStyles(from, to, source, dest) {
         | 
| 2307 | 
            -
                    for (var i = 0, pos = 0, state = 0; pos < to; i+=2) {
         | 
| 2308 | 
            -
                        var part = source[i], end = pos + part.length;
         | 
| 2309 | 
            -
                        if (state == 0) {
         | 
| 2310 | 
            -
                            if (end > from) dest.push(part.slice(from - pos, Math.min(part.length, to - pos)), source[i+1]);
         | 
| 2311 | 
            -
                            if (end >= from) state = 1;
         | 
| 2312 | 
            -
                        }
         | 
| 2313 | 
            -
                        else if (state == 1) {
         | 
| 2314 | 
            -
                            if (end > to) dest.push(part.slice(0, to - pos), source[i+1]);
         | 
| 2315 | 
            -
                            else dest.push(part, source[i+1]);
         | 
| 2316 | 
            -
                        }
         | 
| 2317 | 
            -
                        pos = end;
         | 
| 2318 | 
            -
                    }
         | 
| 2319 | 
            -
                }
         | 
| 2320 | 
            -
             | 
| 2321 | 
            -
                // Data structure that holds the sequence of lines.
         | 
| 2322 | 
            -
                function LeafChunk(lines) {
         | 
| 2323 | 
            -
                    this.lines = lines;
         | 
| 2324 | 
            -
                    this.parent = null;
         | 
| 2325 | 
            -
                    for (var i = 0, e = lines.length, height = 0; i < e; ++i) {
         | 
| 2326 | 
            -
                        lines[i].parent = this;
         | 
| 2327 | 
            -
                        height += lines[i].height;
         | 
| 2328 | 
            -
                    }
         | 
| 2329 | 
            -
                    this.height = height;
         | 
| 2330 | 
            -
                }
         | 
| 2331 | 
            -
                LeafChunk.prototype = {
         | 
| 2332 | 
            -
                    chunkSize: function() { return this.lines.length; },
         | 
| 2333 | 
            -
                    remove: function(at, n, callbacks) {
         | 
| 2334 | 
            -
                        for (var i = at, e = at + n; i < e; ++i) {
         | 
| 2335 | 
            -
                            var line = this.lines[i];
         | 
| 2336 | 
            -
                            this.height -= line.height;
         | 
| 2337 | 
            -
                            line.cleanUp();
         | 
| 2338 | 
            -
                            if (line.handlers)
         | 
| 2339 | 
            -
                                for (var j = 0; j < line.handlers.length; ++j) callbacks.push(line.handlers[j]);
         | 
| 2340 | 
            -
                        }
         | 
| 2341 | 
            -
                        this.lines.splice(at, n);
         | 
| 2342 | 
            -
                    },
         | 
| 2343 | 
            -
                    collapse: function(lines) {
         | 
| 2344 | 
            -
                        lines.splice.apply(lines, [lines.length, 0].concat(this.lines));
         | 
| 2345 | 
            -
                    },
         | 
| 2346 | 
            -
                    insertHeight: function(at, lines, height) {
         | 
| 2347 | 
            -
                        this.height += height;
         | 
| 2348 | 
            -
                        this.lines.splice.apply(this.lines, [at, 0].concat(lines));
         | 
| 2349 | 
            -
                        for (var i = 0, e = lines.length; i < e; ++i) lines[i].parent = this;
         | 
| 2350 | 
            -
                    },
         | 
| 2351 | 
            -
                    iterN: function(at, n, op) {
         | 
| 2352 | 
            -
                        for (var e = at + n; at < e; ++at)
         | 
| 2353 | 
            -
                            if (op(this.lines[at])) return true;
         | 
| 2354 | 
            -
                    }
         | 
| 2355 | 
            -
                };
         | 
| 2356 | 
            -
                function BranchChunk(children) {
         | 
| 2357 | 
            -
                    this.children = children;
         | 
| 2358 | 
            -
                    var size = 0, height = 0;
         | 
| 2359 | 
            -
                    for (var i = 0, e = children.length; i < e; ++i) {
         | 
| 2360 | 
            -
                        var ch = children[i];
         | 
| 2361 | 
            -
                        size += ch.chunkSize(); height += ch.height;
         | 
| 2362 | 
            -
                        ch.parent = this;
         | 
| 2363 | 
            -
                    }
         | 
| 2364 | 
            -
                    this.size = size;
         | 
| 2365 | 
            -
                    this.height = height;
         | 
| 2366 | 
            -
                    this.parent = null;
         | 
| 2367 | 
            -
                }
         | 
| 2368 | 
            -
                BranchChunk.prototype = {
         | 
| 2369 | 
            -
                    chunkSize: function() { return this.size; },
         | 
| 2370 | 
            -
                    remove: function(at, n, callbacks) {
         | 
| 2371 | 
            -
                        this.size -= n;
         | 
| 2372 | 
            -
                        for (var i = 0; i < this.children.length; ++i) {
         | 
| 2373 | 
            -
                            var child = this.children[i], sz = child.chunkSize();
         | 
| 2374 | 
            -
                            if (at < sz) {
         | 
| 2375 | 
            -
                                var rm = Math.min(n, sz - at), oldHeight = child.height;
         | 
| 2376 | 
            -
                                child.remove(at, rm, callbacks);
         | 
| 2377 | 
            -
                                this.height -= oldHeight - child.height;
         | 
| 2378 | 
            -
                                if (sz == rm) { this.children.splice(i--, 1); child.parent = null; }
         | 
| 2379 | 
            -
                                if ((n -= rm) == 0) break;
         | 
| 2380 | 
            -
                                at = 0;
         | 
| 2381 | 
            -
                            } else at -= sz;
         | 
| 2382 | 
            -
                        }
         | 
| 2383 | 
            -
                        if (this.size - n < 25) {
         | 
| 2384 | 
            -
                            var lines = [];
         | 
| 2385 | 
            -
                            this.collapse(lines);
         | 
| 2386 | 
            -
                            this.children = [new LeafChunk(lines)];
         | 
| 2387 | 
            -
                        }
         | 
| 2388 | 
            -
                    },
         | 
| 2389 | 
            -
                    collapse: function(lines) {
         | 
| 2390 | 
            -
                        for (var i = 0, e = this.children.length; i < e; ++i) this.children[i].collapse(lines);
         | 
| 2391 | 
            -
                    },
         | 
| 2392 | 
            -
                    insert: function(at, lines) {
         | 
| 2393 | 
            -
                        var height = 0;
         | 
| 2394 | 
            -
                        for (var i = 0, e = lines.length; i < e; ++i) height += lines[i].height;
         | 
| 2395 | 
            -
                        this.insertHeight(at, lines, height);
         | 
| 2396 | 
            -
                    },
         | 
| 2397 | 
            -
                    insertHeight: function(at, lines, height) {
         | 
| 2398 | 
            -
                        this.size += lines.length;
         | 
| 2399 | 
            -
                        this.height += height;
         | 
| 2400 | 
            -
                        for (var i = 0, e = this.children.length; i < e; ++i) {
         | 
| 2401 | 
            -
                            var child = this.children[i], sz = child.chunkSize();
         | 
| 2402 | 
            -
                            if (at <= sz) {
         | 
| 2403 | 
            -
                                child.insertHeight(at, lines, height);
         | 
| 2404 | 
            -
                                if (child.lines && child.lines.length > 50) {
         | 
| 2405 | 
            -
                                    while (child.lines.length > 50) {
         | 
| 2406 | 
            -
                                        var spilled = child.lines.splice(child.lines.length - 25, 25);
         | 
| 2407 | 
            -
                                        var newleaf = new LeafChunk(spilled);
         | 
| 2408 | 
            -
                                        child.height -= newleaf.height;
         | 
| 2409 | 
            -
                                        this.children.splice(i + 1, 0, newleaf);
         | 
| 2410 | 
            -
                                        newleaf.parent = this;
         | 
| 2411 | 
            -
                                    }
         | 
| 2412 | 
            -
                                    this.maybeSpill();
         | 
| 2413 | 
            -
                                }
         | 
| 2414 | 
            -
                                break;
         | 
| 2415 | 
            -
                            }
         | 
| 2416 | 
            -
                            at -= sz;
         | 
| 2417 | 
            -
                        }
         | 
| 2418 | 
            -
                    },
         | 
| 2419 | 
            -
                    maybeSpill: function() {
         | 
| 2420 | 
            -
                        if (this.children.length <= 10) return;
         | 
| 2421 | 
            -
                        var me = this;
         | 
| 2422 | 
            -
                        do {
         | 
| 2423 | 
            -
                            var spilled = me.children.splice(me.children.length - 5, 5);
         | 
| 2424 | 
            -
                            var sibling = new BranchChunk(spilled);
         | 
| 2425 | 
            -
                            if (!me.parent) { // Become the parent node
         | 
| 2426 | 
            -
                                var copy = new BranchChunk(me.children);
         | 
| 2427 | 
            -
                                copy.parent = me;
         | 
| 2428 | 
            -
                                me.children = [copy, sibling];
         | 
| 2429 | 
            -
                                me = copy;
         | 
| 2430 | 
            -
                            } else {
         | 
| 2431 | 
            -
                                me.size -= sibling.size;
         | 
| 2432 | 
            -
                                me.height -= sibling.height;
         | 
| 2433 | 
            -
                                var myIndex = indexOf(me.parent.children, me);
         | 
| 2434 | 
            -
                                me.parent.children.splice(myIndex + 1, 0, sibling);
         | 
| 2435 | 
            -
                            }
         | 
| 2436 | 
            -
                            sibling.parent = me.parent;
         | 
| 2437 | 
            -
                        } while (me.children.length > 10);
         | 
| 2438 | 
            -
                        me.parent.maybeSpill();
         | 
| 2439 | 
            -
                    },
         | 
| 2440 | 
            -
                    iter: function(from, to, op) { this.iterN(from, to - from, op); },
         | 
| 2441 | 
            -
                    iterN: function(at, n, op) {
         | 
| 2442 | 
            -
                        for (var i = 0, e = this.children.length; i < e; ++i) {
         | 
| 2443 | 
            -
                            var child = this.children[i], sz = child.chunkSize();
         | 
| 2444 | 
            -
                            if (at < sz) {
         | 
| 2445 | 
            -
                                var used = Math.min(n, sz - at);
         | 
| 2446 | 
            -
                                if (child.iterN(at, used, op)) return true;
         | 
| 2447 | 
            -
                                if ((n -= used) == 0) break;
         | 
| 2448 | 
            -
                                at = 0;
         | 
| 2449 | 
            -
                            } else at -= sz;
         | 
| 2450 | 
            -
                        }
         | 
| 2451 | 
            -
                    }
         | 
| 2452 | 
            -
                };
         | 
| 2453 | 
            -
             | 
| 2454 | 
            -
                function getLineAt(chunk, n) {
         | 
| 2455 | 
            -
                    while (!chunk.lines) {
         | 
| 2456 | 
            -
                        for (var i = 0;; ++i) {
         | 
| 2457 | 
            -
                            var child = chunk.children[i], sz = child.chunkSize();
         | 
| 2458 | 
            -
                            if (n < sz) { chunk = child; break; }
         | 
| 2459 | 
            -
                            n -= sz;
         | 
| 2460 | 
            -
                        }
         | 
| 2461 | 
            -
                    }
         | 
| 2462 | 
            -
                    return chunk.lines[n];
         | 
| 2463 | 
            -
                }
         | 
| 2464 | 
            -
                function lineNo(line) {
         | 
| 2465 | 
            -
                    if (line.parent == null) return null;
         | 
| 2466 | 
            -
                    var cur = line.parent, no = indexOf(cur.lines, line);
         | 
| 2467 | 
            -
                    for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) {
         | 
| 2468 | 
            -
                        for (var i = 0, e = chunk.children.length; ; ++i) {
         | 
| 2469 | 
            -
                            if (chunk.children[i] == cur) break;
         | 
| 2470 | 
            -
                            no += chunk.children[i].chunkSize();
         | 
| 2471 | 
            -
                        }
         | 
| 2472 | 
            -
                    }
         | 
| 2473 | 
            -
                    return no;
         | 
| 2474 | 
            -
                }
         | 
| 2475 | 
            -
                function lineAtHeight(chunk, h) {
         | 
| 2476 | 
            -
                    var n = 0;
         | 
| 2477 | 
            -
                    outer: do {
         | 
| 2478 | 
            -
                        for (var i = 0, e = chunk.children.length; i < e; ++i) {
         | 
| 2479 | 
            -
                            var child = chunk.children[i], ch = child.height;
         | 
| 2480 | 
            -
                            if (h < ch) { chunk = child; continue outer; }
         | 
| 2481 | 
            -
                            h -= ch;
         | 
| 2482 | 
            -
                            n += child.chunkSize();
         | 
| 2483 | 
            -
                        }
         | 
| 2484 | 
            -
                        return n;
         | 
| 2485 | 
            -
                    } while (!chunk.lines);
         | 
| 2486 | 
            -
                    for (var i = 0, e = chunk.lines.length; i < e; ++i) {
         | 
| 2487 | 
            -
                        var line = chunk.lines[i], lh = line.height;
         | 
| 2488 | 
            -
                        if (h < lh) break;
         | 
| 2489 | 
            -
                        h -= lh;
         | 
| 2490 | 
            -
                    }
         | 
| 2491 | 
            -
                    return n + i;
         | 
| 2492 | 
            -
                }
         | 
| 2493 | 
            -
                function heightAtLine(chunk, n) {
         | 
| 2494 | 
            -
                    var h = 0;
         | 
| 2495 | 
            -
                    outer: do {
         | 
| 2496 | 
            -
                        for (var i = 0, e = chunk.children.length; i < e; ++i) {
         | 
| 2497 | 
            -
                            var child = chunk.children[i], sz = child.chunkSize();
         | 
| 2498 | 
            -
                            if (n < sz) { chunk = child; continue outer; }
         | 
| 2499 | 
            -
                            n -= sz;
         | 
| 2500 | 
            -
                            h += child.height;
         | 
| 2501 | 
            -
                        }
         | 
| 2502 | 
            -
                        return h;
         | 
| 2503 | 
            -
                    } while (!chunk.lines);
         | 
| 2504 | 
            -
                    for (var i = 0; i < n; ++i) h += chunk.lines[i].height;
         | 
| 2505 | 
            -
                    return h;
         | 
| 2506 | 
            -
                }
         | 
| 2507 | 
            -
             | 
| 2508 | 
            -
                // The history object 'chunks' changes that are made close together
         | 
| 2509 | 
            -
                // and at almost the same time into bigger undoable units.
         | 
| 2510 | 
            -
                function History() {
         | 
| 2511 | 
            -
                    this.time = 0;
         | 
| 2512 | 
            -
                    this.done = []; this.undone = [];
         | 
| 2513 | 
            -
                }
         | 
| 2514 | 
            -
                History.prototype = {
         | 
| 2515 | 
            -
                    addChange: function(start, added, old) {
         | 
| 2516 | 
            -
                        this.undone.length = 0;
         | 
| 2517 | 
            -
                        var time = +new Date, last = this.done[this.done.length - 1];
         | 
| 2518 | 
            -
                        if (time - this.time > 400 || !last ||
         | 
| 2519 | 
            -
                            last.start > start + added || last.start + last.added < start - last.added + last.old.length)
         | 
| 2520 | 
            -
                            this.done.push({start: start, added: added, old: old});
         | 
| 2521 | 
            -
                        else {
         | 
| 2522 | 
            -
                            var oldoff = 0;
         | 
| 2523 | 
            -
                            if (start < last.start) {
         | 
| 2524 | 
            -
                                for (var i = last.start - start - 1; i >= 0; --i)
         | 
| 2525 | 
            -
                                    last.old.unshift(old[i]);
         | 
| 2526 | 
            -
                                last.added += last.start - start;
         | 
| 2527 | 
            -
                                last.start = start;
         | 
| 2528 | 
            -
                            }
         | 
| 2529 | 
            -
                            else if (last.start < start) {
         | 
| 2530 | 
            -
                                oldoff = start - last.start;
         | 
| 2531 | 
            -
                                added += oldoff;
         | 
| 2532 | 
            -
                            }
         | 
| 2533 | 
            -
                            for (var i = last.added - oldoff, e = old.length; i < e; ++i)
         | 
| 2534 | 
            -
                                last.old.push(old[i]);
         | 
| 2535 | 
            -
                            if (last.added < added) last.added = added;
         | 
| 2536 | 
            -
                        }
         | 
| 2537 | 
            -
                        this.time = time;
         | 
| 2538 | 
            -
                    }
         | 
| 2539 | 
            -
                };
         | 
| 2540 | 
            -
             | 
| 2541 | 
            -
                function stopMethod() {e_stop(this);}
         | 
| 2542 | 
            -
                // Ensure an event has a stop method.
         | 
| 2543 | 
            -
                function addStop(event) {
         | 
| 2544 | 
            -
                    if (!event.stop) event.stop = stopMethod;
         | 
| 2545 | 
            -
                    return event;
         | 
| 2546 | 
            -
                }
         | 
| 2547 | 
            -
             | 
| 2548 | 
            -
                function e_preventDefault(e) {
         | 
| 2549 | 
            -
                    if (e.preventDefault) e.preventDefault();
         | 
| 2550 | 
            -
                    else e.returnValue = false;
         | 
| 2551 | 
            -
                }
         | 
| 2552 | 
            -
                function e_stopPropagation(e) {
         | 
| 2553 | 
            -
                    if (e.stopPropagation) e.stopPropagation();
         | 
| 2554 | 
            -
                    else e.cancelBubble = true;
         | 
| 2555 | 
            -
                }
         | 
| 2556 | 
            -
                function e_stop(e) {e_preventDefault(e); e_stopPropagation(e);}
         | 
| 2557 | 
            -
                CodeMirror.e_stop = e_stop;
         | 
| 2558 | 
            -
                CodeMirror.e_preventDefault = e_preventDefault;
         | 
| 2559 | 
            -
                CodeMirror.e_stopPropagation = e_stopPropagation;
         | 
| 2560 | 
            -
             | 
| 2561 | 
            -
                function e_target(e) {return e.target || e.srcElement;}
         | 
| 2562 | 
            -
                function e_button(e) {
         | 
| 2563 | 
            -
                    if (e.which) return e.which;
         | 
| 2564 | 
            -
                    else if (e.button & 1) return 1;
         | 
| 2565 | 
            -
                    else if (e.button & 2) return 3;
         | 
| 2566 | 
            -
                    else if (e.button & 4) return 2;
         | 
| 2567 | 
            -
                }
         | 
| 2568 | 
            -
             | 
| 2569 | 
            -
                // Event handler registration. If disconnect is true, it'll return a
         | 
| 2570 | 
            -
                // function that unregisters the handler.
         | 
| 2571 | 
            -
                function connect(node, type, handler, disconnect) {
         | 
| 2572 | 
            -
                    if (typeof node.addEventListener == "function") {
         | 
| 2573 | 
            -
                        node.addEventListener(type, handler, false);
         | 
| 2574 | 
            -
                        if (disconnect) return function() {node.removeEventListener(type, handler, false);};
         | 
| 2575 | 
            -
                    }
         | 
| 2576 | 
            -
                    else {
         | 
| 2577 | 
            -
                        var wrapHandler = function(event) {handler(event || window.event);};
         | 
| 2578 | 
            -
                        node.attachEvent("on" + type, wrapHandler);
         | 
| 2579 | 
            -
                        if (disconnect) return function() {node.detachEvent("on" + type, wrapHandler);};
         | 
| 2580 | 
            -
                    }
         | 
| 2581 | 
            -
                }
         | 
| 2582 | 
            -
                CodeMirror.connect = connect;
         | 
| 2583 | 
            -
             | 
| 2584 | 
            -
                function Delayed() {this.id = null;}
         | 
| 2585 | 
            -
                Delayed.prototype = {set: function(ms, f) {clearTimeout(this.id); this.id = setTimeout(f, ms);}};
         | 
| 2586 | 
            -
             | 
| 2587 | 
            -
                // Detect drag-and-drop
         | 
| 2588 | 
            -
                var dragAndDrop = function() {
         | 
| 2589 | 
            -
                    // IE8 has ondragstart and ondrop properties, but doesn't seem to
         | 
| 2590 | 
            -
                    // actually support ondragstart the way it's supposed to work.
         | 
| 2591 | 
            -
                    if (/MSIE [1-8]\b/.test(navigator.userAgent)) return false;
         | 
| 2592 | 
            -
                    var div = document.createElement('div');
         | 
| 2593 | 
            -
                    return "draggable" in div;
         | 
| 2594 | 
            -
                }();
         | 
| 2595 | 
            -
             | 
| 2596 | 
            -
                var gecko = /gecko\/\d{7}/i.test(navigator.userAgent);
         | 
| 2597 | 
            -
                var ie = /MSIE \d/.test(navigator.userAgent);
         | 
| 2598 | 
            -
                var webkit = /WebKit\//.test(navigator.userAgent);
         | 
| 2599 | 
            -
             | 
| 2600 | 
            -
                var lineSep = "\n";
         | 
| 2601 | 
            -
                // Feature-detect whether newlines in textareas are converted to \r\n
         | 
| 2602 | 
            -
                (function () {
         | 
| 2603 | 
            -
                    var te = document.createElement("textarea");
         | 
| 2604 | 
            -
                    te.value = "foo\nbar";
         | 
| 2605 | 
            -
                    if (te.value.indexOf("\r") > -1) lineSep = "\r\n";
         | 
| 2606 | 
            -
                }());
         | 
| 2607 | 
            -
             | 
| 2608 | 
            -
                // Counts the column offset in a string, taking tabs into account.
         | 
| 2609 | 
            -
                // Used mostly to find indentation.
         | 
| 2610 | 
            -
                function countColumn(string, end, tabSize) {
         | 
| 2611 | 
            -
                    if (end == null) {
         | 
| 2612 | 
            -
                        end = string.search(/[^\s\u00a0]/);
         | 
| 2613 | 
            -
                        if (end == -1) end = string.length;
         | 
| 2614 | 
            -
                    }
         | 
| 2615 | 
            -
                    for (var i = 0, n = 0; i < end; ++i) {
         | 
| 2616 | 
            -
                        if (string.charAt(i) == "\t") n += tabSize - (n % tabSize);
         | 
| 2617 | 
            -
                        else ++n;
         | 
| 2618 | 
            -
                    }
         | 
| 2619 | 
            -
                    return n;
         | 
| 2620 | 
            -
                }
         | 
| 2621 | 
            -
             | 
| 2622 | 
            -
                function computedStyle(elt) {
         | 
| 2623 | 
            -
                    if (elt.currentStyle) return elt.currentStyle;
         | 
| 2624 | 
            -
                    return window.getComputedStyle(elt, null);
         | 
| 2625 | 
            -
                }
         | 
| 2626 | 
            -
             | 
| 2627 | 
            -
                // Find the position of an element by following the offsetParent chain.
         | 
| 2628 | 
            -
                // If screen==true, it returns screen (rather than page) coordinates.
         | 
| 2629 | 
            -
                function eltOffset(node, screen) {
         | 
| 2630 | 
            -
                    var bod = node.ownerDocument.body;
         | 
| 2631 | 
            -
                    var x = 0, y = 0, skipBody = false;
         | 
| 2632 | 
            -
                    for (var n = node; n; n = n.offsetParent) {
         | 
| 2633 | 
            -
                        var ol = n.offsetLeft, ot = n.offsetTop;
         | 
| 2634 | 
            -
                        // Firefox reports weird inverted offsets when the body has a border.
         | 
| 2635 | 
            -
                        if (n == bod) { x += Math.abs(ol); y += Math.abs(ot); }
         | 
| 2636 | 
            -
                        else { x += ol, y += ot; }
         | 
| 2637 | 
            -
                        if (screen && computedStyle(n).position == "fixed")
         | 
| 2638 | 
            -
                            skipBody = true;
         | 
| 2639 | 
            -
                    }
         | 
| 2640 | 
            -
                    var e = screen && !skipBody ? null : bod;
         | 
| 2641 | 
            -
                    for (var n = node.parentNode; n != e; n = n.parentNode)
         | 
| 2642 | 
            -
                        if (n.scrollLeft != null) { x -= n.scrollLeft; y -= n.scrollTop;}
         | 
| 2643 | 
            -
                    return {left: x, top: y};
         | 
| 2644 | 
            -
                }
         | 
| 2645 | 
            -
                // Use the faster and saner getBoundingClientRect method when possible.
         | 
| 2646 | 
            -
                if (document.documentElement.getBoundingClientRect != null) eltOffset = function(node, screen) {
         | 
| 2647 | 
            -
                    // Take the parts of bounding client rect that we are interested in so we are able to edit if need be,
         | 
| 2648 | 
            -
                    // since the returned value cannot be changed externally (they are kept in sync as the element moves within the page)
         | 
| 2649 | 
            -
                    try { var box = node.getBoundingClientRect(); box = { top: box.top, left: box.left }; }
         | 
| 2650 | 
            -
                    catch(e) { box = {top: 0, left: 0}; }
         | 
| 2651 | 
            -
                    if (!screen) {
         | 
| 2652 | 
            -
                        // Get the toplevel scroll, working around browser differences.
         | 
| 2653 | 
            -
                        if (window.pageYOffset == null) {
         | 
| 2654 | 
            -
                            var t = document.documentElement || document.body.parentNode;
         | 
| 2655 | 
            -
                            if (t.scrollTop == null) t = document.body;
         | 
| 2656 | 
            -
                            box.top += t.scrollTop; box.left += t.scrollLeft;
         | 
| 2657 | 
            -
                        } else {
         | 
| 2658 | 
            -
                            box.top += window.pageYOffset; box.left += window.pageXOffset;
         | 
| 2659 | 
            -
                        }
         | 
| 2660 | 
            -
                    }
         | 
| 2661 | 
            -
                    return box;
         | 
| 2662 | 
            -
                };
         | 
| 2663 | 
            -
             | 
| 2664 | 
            -
                // Get a node's text content.
         | 
| 2665 | 
            -
                function eltText(node) {
         | 
| 2666 | 
            -
                    return node.textContent || node.innerText || node.nodeValue || "";
         | 
| 2667 | 
            -
                }
         | 
| 2668 | 
            -
             | 
| 2669 | 
            -
                // Operations on {line, ch} objects.
         | 
| 2670 | 
            -
                function posEq(a, b) {return a.line == b.line && a.ch == b.ch;}
         | 
| 2671 | 
            -
                function posLess(a, b) {return a.line < b.line || (a.line == b.line && a.ch < b.ch);}
         | 
| 2672 | 
            -
                function copyPos(x) {return {line: x.line, ch: x.ch};}
         | 
| 2673 | 
            -
             | 
| 2674 | 
            -
                var escapeElement = document.createElement("pre");
         | 
| 2675 | 
            -
                function htmlEscape(str) {
         | 
| 2676 | 
            -
                    escapeElement.textContent = str;
         | 
| 2677 | 
            -
                    return escapeElement.innerHTML;
         | 
| 2678 | 
            -
                }
         | 
| 2679 | 
            -
                // Recent (late 2011) Opera betas insert bogus newlines at the start
         | 
| 2680 | 
            -
                // of the textContent, so we strip those.
         | 
| 2681 | 
            -
                if (htmlEscape("a") == "\na")
         | 
| 2682 | 
            -
                    htmlEscape = function(str) {
         | 
| 2683 | 
            -
                        escapeElement.textContent = str;
         | 
| 2684 | 
            -
                        return escapeElement.innerHTML.slice(1);
         | 
| 2685 | 
            -
                    };
         | 
| 2686 | 
            -
                // Some IEs don't preserve tabs through innerHTML
         | 
| 2687 | 
            -
                else if (htmlEscape("\t") != "\t")
         | 
| 2688 | 
            -
                    htmlEscape = function(str) {
         | 
| 2689 | 
            -
                        escapeElement.innerHTML = "";
         | 
| 2690 | 
            -
                        escapeElement.appendChild(document.createTextNode(str));
         | 
| 2691 | 
            -
                        return escapeElement.innerHTML;
         | 
| 2692 | 
            -
                    };
         | 
| 2693 | 
            -
                CodeMirror.htmlEscape = htmlEscape;
         | 
| 2694 | 
            -
             | 
| 2695 | 
            -
                // Used to position the cursor after an undo/redo by finding the
         | 
| 2696 | 
            -
                // last edited character.
         | 
| 2697 | 
            -
                function editEnd(from, to) {
         | 
| 2698 | 
            -
                    if (!to) return from ? from.length : 0;
         | 
| 2699 | 
            -
                    if (!from) return to.length;
         | 
| 2700 | 
            -
                    for (var i = from.length, j = to.length; i >= 0 && j >= 0; --i, --j)
         | 
| 2701 | 
            -
                        if (from.charAt(i) != to.charAt(j)) break;
         | 
| 2702 | 
            -
                    return j + 1;
         | 
| 2703 | 
            -
                }
         | 
| 2704 | 
            -
             | 
| 2705 | 
            -
                function indexOf(collection, elt) {
         | 
| 2706 | 
            -
                    if (collection.indexOf) return collection.indexOf(elt);
         | 
| 2707 | 
            -
                    for (var i = 0, e = collection.length; i < e; ++i)
         | 
| 2708 | 
            -
                        if (collection[i] == elt) return i;
         | 
| 2709 | 
            -
                    return -1;
         | 
| 2710 | 
            -
                }
         | 
| 2711 | 
            -
                function isWordChar(ch) {
         | 
| 2712 | 
            -
                    return /\w/.test(ch) || ch.toUpperCase() != ch.toLowerCase();
         | 
| 2713 | 
            -
                }
         | 
| 2714 | 
            -
             | 
| 2715 | 
            -
                // See if "".split is the broken IE version, if so, provide an
         | 
| 2716 | 
            -
                // alternative way to split lines.
         | 
| 2717 | 
            -
                var splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) {
         | 
| 2718 | 
            -
                    var pos = 0, nl, result = [];
         | 
| 2719 | 
            -
                    while ((nl = string.indexOf("\n", pos)) > -1) {
         | 
| 2720 | 
            -
                        result.push(string.slice(pos, string.charAt(nl-1) == "\r" ? nl - 1 : nl));
         | 
| 2721 | 
            -
                        pos = nl + 1;
         | 
| 2722 | 
            -
                    }
         | 
| 2723 | 
            -
                    result.push(string.slice(pos));
         | 
| 2724 | 
            -
                    return result;
         | 
| 2725 | 
            -
                } : function(string){return string.split(/\r?\n/);};
         | 
| 2726 | 
            -
                CodeMirror.splitLines = splitLines;
         | 
| 2727 | 
            -
             | 
| 2728 | 
            -
                var hasSelection = window.getSelection ? function(te) {
         | 
| 2729 | 
            -
                    try { return te.selectionStart != te.selectionEnd; }
         | 
| 2730 | 
            -
                    catch(e) { return false; }
         | 
| 2731 | 
            -
                } : function(te) {
         | 
| 2732 | 
            -
                    try {var range = te.ownerDocument.selection.createRange();}
         | 
| 2733 | 
            -
                    catch(e) {}
         | 
| 2734 | 
            -
                    if (!range || range.parentElement() != te) return false;
         | 
| 2735 | 
            -
                    return range.compareEndPoints("StartToEnd", range) != 0;
         | 
| 2736 | 
            -
                };
         | 
| 2737 | 
            -
             | 
| 2738 | 
            -
                CodeMirror.defineMode("null", function() {
         | 
| 2739 | 
            -
                    return {token: function(stream) {stream.skipToEnd();}};
         | 
| 2740 | 
            -
                });
         | 
| 2741 | 
            -
                CodeMirror.defineMIME("text/plain", "null");
         | 
| 2742 | 
            -
             | 
| 2743 | 
            -
                var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
         | 
| 2744 | 
            -
                    19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
         | 
| 2745 | 
            -
                    36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
         | 
| 2746 | 
            -
                    46: "Delete", 59: ";", 91: "Mod", 92: "Mod", 93: "Mod", 186: ";", 187: "=", 188: ",",
         | 
| 2747 | 
            -
                    189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\", 221: "]", 222: "'", 63276: "PageUp",
         | 
| 2748 | 
            -
                    63277: "PageDown", 63275: "End", 63273: "Home", 63234: "Left", 63232: "Up", 63235: "Right",
         | 
| 2749 | 
            -
                    63233: "Down", 63302: "Insert", 63272: "Delete"};
         | 
| 2750 | 
            -
                CodeMirror.keyNames = keyNames;
         | 
| 2751 | 
            -
                (function() {
         | 
| 2752 | 
            -
                    // Number keys
         | 
| 2753 | 
            -
                    for (var i = 0; i < 10; i++) keyNames[i + 48] = String(i);
         | 
| 2754 | 
            -
                    // Alphabetic keys
         | 
| 2755 | 
            -
                    for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i);
         | 
| 2756 | 
            -
                    // Function keys
         | 
| 2757 | 
            -
                    for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i;
         | 
| 2758 | 
            -
                })();
         | 
| 2759 | 
            -
             | 
| 2760 | 
            -
                return CodeMirror;
         | 
| 2761 | 
            -
            })();
         | 
| 2762 | 
            -
            CodeMirror.defineMode("xml", function(config, parserConfig) {
         | 
| 2763 | 
            -
                var indentUnit = config.indentUnit;
         | 
| 2764 | 
            -
                var Kludges = parserConfig.htmlMode ? {
         | 
| 2765 | 
            -
                    autoSelfClosers: {"br": true, "img": true, "hr": true, "link": true, "input": true,
         | 
| 2766 | 
            -
                        "meta": true, "col": true, "frame": true, "base": true, "area": true},
         | 
| 2767 | 
            -
                    doNotIndent: {"pre": true},
         | 
| 2768 | 
            -
                    allowUnquoted: true
         | 
| 2769 | 
            -
                } : {autoSelfClosers: {}, doNotIndent: {}, allowUnquoted: false};
         | 
| 2770 | 
            -
                var alignCDATA = parserConfig.alignCDATA;
         | 
| 2771 | 
            -
             | 
| 2772 | 
            -
                // Return variables for tokenizers
         | 
| 2773 | 
            -
                var tagName, type;
         | 
| 2774 | 
            -
             | 
| 2775 | 
            -
                function inText(stream, state) {
         | 
| 2776 | 
            -
                    function chain(parser) {
         | 
| 2777 | 
            -
                        state.tokenize = parser;
         | 
| 2778 | 
            -
                        return parser(stream, state);
         | 
| 2779 | 
            -
                    }
         | 
| 2780 | 
            -
             | 
| 2781 | 
            -
                    var ch = stream.next();
         | 
| 2782 | 
            -
                    if (ch == "<") {
         | 
| 2783 | 
            -
                        if (stream.eat("!")) {
         | 
| 2784 | 
            -
                            if (stream.eat("[")) {
         | 
| 2785 | 
            -
                                if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
         | 
| 2786 | 
            -
                                else return null;
         | 
| 2787 | 
            -
                            }
         | 
| 2788 | 
            -
                            else if (stream.match("--")) return chain(inBlock("comment", "-->"));
         | 
| 2789 | 
            -
                            else if (stream.match("DOCTYPE", true, true)) {
         | 
| 2790 | 
            -
                                stream.eatWhile(/[\w\._\-]/);
         | 
| 2791 | 
            -
                                return chain(doctype(1));
         | 
| 2792 | 
            -
                            }
         | 
| 2793 | 
            -
                            else return null;
         | 
| 2794 | 
            -
                        }
         | 
| 2795 | 
            -
                        else if (stream.eat("?")) {
         | 
| 2796 | 
            -
                            stream.eatWhile(/[\w\._\-]/);
         | 
| 2797 | 
            -
                            state.tokenize = inBlock("meta", "?>");
         | 
| 2798 | 
            -
                            return "meta";
         | 
| 2799 | 
            -
                        }
         | 
| 2800 | 
            -
                        else {
         | 
| 2801 | 
            -
                            type = stream.eat("/") ? "closeTag" : "openTag";
         | 
| 2802 | 
            -
                            stream.eatSpace();
         | 
| 2803 | 
            -
                            tagName = "";
         | 
| 2804 | 
            -
                            var c;
         | 
| 2805 | 
            -
                            while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c;
         | 
| 2806 | 
            -
                            state.tokenize = inTag;
         | 
| 2807 | 
            -
                            return "tag";
         | 
| 2808 | 
            -
                        }
         | 
| 2809 | 
            -
                    }
         | 
| 2810 | 
            -
                    else if (ch == "&") {
         | 
| 2811 | 
            -
                        stream.eatWhile(/[^;]/);
         | 
| 2812 | 
            -
                        stream.eat(";");
         | 
| 2813 | 
            -
                        return "atom";
         | 
| 2814 | 
            -
                    }
         | 
| 2815 | 
            -
                    else {
         | 
| 2816 | 
            -
                        stream.eatWhile(/[^&<]/);
         | 
| 2817 | 
            -
                        return null;
         | 
| 2818 | 
            -
                    }
         | 
| 2819 | 
            -
                }
         | 
| 2820 | 
            -
             | 
| 2821 | 
            -
                function inTag(stream, state) {
         | 
| 2822 | 
            -
                    var ch = stream.next();
         | 
| 2823 | 
            -
                    if (ch == ">" || (ch == "/" && stream.eat(">"))) {
         | 
| 2824 | 
            -
                        state.tokenize = inText;
         | 
| 2825 | 
            -
                        type = ch == ">" ? "endTag" : "selfcloseTag";
         | 
| 2826 | 
            -
                        return "tag";
         | 
| 2827 | 
            -
                    }
         | 
| 2828 | 
            -
                    else if (ch == "=") {
         | 
| 2829 | 
            -
                        type = "equals";
         | 
| 2830 | 
            -
                        return null;
         | 
| 2831 | 
            -
                    }
         | 
| 2832 | 
            -
                    else if (/[\'\"]/.test(ch)) {
         | 
| 2833 | 
            -
                        state.tokenize = inAttribute(ch);
         | 
| 2834 | 
            -
                        return state.tokenize(stream, state);
         | 
| 2835 | 
            -
                    }
         | 
| 2836 | 
            -
                    else {
         | 
| 2837 | 
            -
                        stream.eatWhile(/[^\s\u00a0=<>\"\'\/?]/);
         | 
| 2838 | 
            -
                        return "word";
         | 
| 2839 | 
            -
                    }
         | 
| 2840 | 
            -
                }
         | 
| 2841 | 
            -
             | 
| 2842 | 
            -
                function inAttribute(quote) {
         | 
| 2843 | 
            -
                    return function(stream, state) {
         | 
| 2844 | 
            -
                        while (!stream.eol()) {
         | 
| 2845 | 
            -
                            if (stream.next() == quote) {
         | 
| 2846 | 
            -
                                state.tokenize = inTag;
         | 
| 2847 | 
            -
                                break;
         | 
| 2848 | 
            -
                            }
         | 
| 2849 | 
            -
                        }
         | 
| 2850 | 
            -
                        return "string";
         | 
| 2851 | 
            -
                    };
         | 
| 2852 | 
            -
                }
         | 
| 2853 | 
            -
             | 
| 2854 | 
            -
                function inBlock(style, terminator) {
         | 
| 2855 | 
            -
                    return function(stream, state) {
         | 
| 2856 | 
            -
                        while (!stream.eol()) {
         | 
| 2857 | 
            -
                            if (stream.match(terminator)) {
         | 
| 2858 | 
            -
                                state.tokenize = inText;
         | 
| 2859 | 
            -
                                break;
         | 
| 2860 | 
            -
                            }
         | 
| 2861 | 
            -
                            stream.next();
         | 
| 2862 | 
            -
                        }
         | 
| 2863 | 
            -
                        return style;
         | 
| 2864 | 
            -
                    };
         | 
| 2865 | 
            -
                }
         | 
| 2866 | 
            -
                function doctype(depth) {
         | 
| 2867 | 
            -
                    return function(stream, state) {
         | 
| 2868 | 
            -
                        var ch;
         | 
| 2869 | 
            -
                        while ((ch = stream.next()) != null) {
         | 
| 2870 | 
            -
                            if (ch == "<") {
         | 
| 2871 | 
            -
                                state.tokenize = doctype(depth + 1);
         | 
| 2872 | 
            -
                                return state.tokenize(stream, state);
         | 
| 2873 | 
            -
                            } else if (ch == ">") {
         | 
| 2874 | 
            -
                                if (depth == 1) {
         | 
| 2875 | 
            -
                                    state.tokenize = inText;
         | 
| 2876 | 
            -
                                    break;
         | 
| 2877 | 
            -
                                } else {
         | 
| 2878 | 
            -
                                    state.tokenize = doctype(depth - 1);
         | 
| 2879 | 
            -
                                    return state.tokenize(stream, state);
         | 
| 2880 | 
            -
                                }
         | 
| 2881 | 
            -
                            }
         | 
| 2882 | 
            -
                        }
         | 
| 2883 | 
            -
                        return "meta";
         | 
| 2884 | 
            -
                    };
         | 
| 2885 | 
            -
                }
         | 
| 2886 | 
            -
             | 
| 2887 | 
            -
                var curState, setStyle;
         | 
| 2888 | 
            -
                function pass() {
         | 
| 2889 | 
            -
                    for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i]);
         | 
| 2890 | 
            -
                }
         | 
| 2891 | 
            -
                function cont() {
         | 
| 2892 | 
            -
                    pass.apply(null, arguments);
         | 
| 2893 | 
            -
                    return true;
         | 
| 2894 | 
            -
                }
         | 
| 2895 | 
            -
             | 
| 2896 | 
            -
                function pushContext(tagName, startOfLine) {
         | 
| 2897 | 
            -
                    var noIndent = Kludges.doNotIndent.hasOwnProperty(tagName) || (curState.context && curState.context.noIndent);
         | 
| 2898 | 
            -
                    curState.context = {
         | 
| 2899 | 
            -
                        prev: curState.context,
         | 
| 2900 | 
            -
                        tagName: tagName,
         | 
| 2901 | 
            -
                        indent: curState.indented,
         | 
| 2902 | 
            -
                        startOfLine: startOfLine,
         | 
| 2903 | 
            -
                        noIndent: noIndent
         | 
| 2904 | 
            -
                    };
         | 
| 2905 | 
            -
                }
         | 
| 2906 | 
            -
                function popContext() {
         | 
| 2907 | 
            -
                    if (curState.context) curState.context = curState.context.prev;
         | 
| 2908 | 
            -
                }
         | 
| 2909 | 
            -
             | 
| 2910 | 
            -
                function element(type) {
         | 
| 2911 | 
            -
                    if (type == "openTag") {
         | 
| 2912 | 
            -
                        curState.tagName = tagName;
         | 
| 2913 | 
            -
                        return cont(attributes, endtag(curState.startOfLine));
         | 
| 2914 | 
            -
                    } else if (type == "closeTag") {
         | 
| 2915 | 
            -
                        var err = false;
         | 
| 2916 | 
            -
                        if (curState.context) {
         | 
| 2917 | 
            -
                            err = curState.context.tagName != tagName;
         | 
| 2918 | 
            -
                        } else {
         | 
| 2919 | 
            -
                            err = true;
         | 
| 2920 | 
            -
                        }
         | 
| 2921 | 
            -
                        if (err) setStyle = "error";
         | 
| 2922 | 
            -
                        return cont(endclosetag(err));
         | 
| 2923 | 
            -
                    }
         | 
| 2924 | 
            -
                    return cont();
         | 
| 2925 | 
            -
                }
         | 
| 2926 | 
            -
                function endtag(startOfLine) {
         | 
| 2927 | 
            -
                    return function(type) {
         | 
| 2928 | 
            -
                        if (type == "selfcloseTag" ||
         | 
| 2929 | 
            -
                            (type == "endTag" && Kludges.autoSelfClosers.hasOwnProperty(curState.tagName.toLowerCase())))
         | 
| 2930 | 
            -
                            return cont();
         | 
| 2931 | 
            -
                        if (type == "endTag") {pushContext(curState.tagName, startOfLine); return cont();}
         | 
| 2932 | 
            -
                        return cont();
         | 
| 2933 | 
            -
                    };
         | 
| 2934 | 
            -
                }
         | 
| 2935 | 
            -
                function endclosetag(err) {
         | 
| 2936 | 
            -
                    return function(type) {
         | 
| 2937 | 
            -
                        if (err) setStyle = "error";
         | 
| 2938 | 
            -
                        if (type == "endTag") { popContext(); return cont(); }
         | 
| 2939 | 
            -
                        setStyle = "error";
         | 
| 2940 | 
            -
                        return cont(arguments.callee);
         | 
| 2941 | 
            -
                    }
         | 
| 2942 | 
            -
                }
         | 
| 2943 | 
            -
             | 
| 2944 | 
            -
                function attributes(type) {
         | 
| 2945 | 
            -
                    if (type == "word") {setStyle = "attribute"; return cont(attributes);}
         | 
| 2946 | 
            -
                    if (type == "equals") return cont(attvalue, attributes);
         | 
| 2947 | 
            -
                    if (type == "string") {setStyle = "error"; return cont(attributes);}
         | 
| 2948 | 
            -
                    return pass();
         | 
| 2949 | 
            -
                }
         | 
| 2950 | 
            -
                function attvalue(type) {
         | 
| 2951 | 
            -
                    if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return cont();}
         | 
| 2952 | 
            -
                    if (type == "string") return cont(attvaluemaybe);
         | 
| 2953 | 
            -
                    return pass();
         | 
| 2954 | 
            -
                }
         | 
| 2955 | 
            -
                function attvaluemaybe(type) {
         | 
| 2956 | 
            -
                    if (type == "string") return cont(attvaluemaybe);
         | 
| 2957 | 
            -
                    else return pass();
         | 
| 2958 | 
            -
                }
         | 
| 2959 | 
            -
             | 
| 2960 | 
            -
                return {
         | 
| 2961 | 
            -
                    startState: function() {
         | 
| 2962 | 
            -
                        return {tokenize: inText, cc: [], indented: 0, startOfLine: true, tagName: null, context: null};
         | 
| 2963 | 
            -
                    },
         | 
| 2964 | 
            -
             | 
| 2965 | 
            -
                    token: function(stream, state) {
         | 
| 2966 | 
            -
                        if (stream.sol()) {
         | 
| 2967 | 
            -
                            state.startOfLine = true;
         | 
| 2968 | 
            -
                            state.indented = stream.indentation();
         | 
| 2969 | 
            -
                        }
         | 
| 2970 | 
            -
                        if (stream.eatSpace()) return null;
         | 
| 2971 | 
            -
             | 
| 2972 | 
            -
                        setStyle = type = tagName = null;
         | 
| 2973 | 
            -
                        var style = state.tokenize(stream, state);
         | 
| 2974 | 
            -
                        state.type = type;
         | 
| 2975 | 
            -
                        if ((style || type) && style != "comment") {
         | 
| 2976 | 
            -
                            curState = state;
         | 
| 2977 | 
            -
                            while (true) {
         | 
| 2978 | 
            -
                                var comb = state.cc.pop() || element;
         | 
| 2979 | 
            -
                                if (comb(type || style)) break;
         | 
| 2980 | 
            -
                            }
         | 
| 2981 | 
            -
                        }
         | 
| 2982 | 
            -
                        state.startOfLine = false;
         | 
| 2983 | 
            -
                        return setStyle || style;
         | 
| 2984 | 
            -
                    },
         | 
| 2985 | 
            -
             | 
| 2986 | 
            -
                    indent: function(state, textAfter, fullLine) {
         | 
| 2987 | 
            -
                        var context = state.context;
         | 
| 2988 | 
            -
                        if ((state.tokenize != inTag && state.tokenize != inText) ||
         | 
| 2989 | 
            -
                            context && context.noIndent)
         | 
| 2990 | 
            -
                            return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
         | 
| 2991 | 
            -
                        if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
         | 
| 2992 | 
            -
                        if (context && /^<\//.test(textAfter))
         | 
| 2993 | 
            -
                            context = context.prev;
         | 
| 2994 | 
            -
                        while (context && !context.startOfLine)
         | 
| 2995 | 
            -
                            context = context.prev;
         | 
| 2996 | 
            -
                        if (context) return context.indent + indentUnit;
         | 
| 2997 | 
            -
                        else return 0;
         | 
| 2998 | 
            -
                    },
         | 
| 2999 | 
            -
             | 
| 3000 | 
            -
                    compareStates: function(a, b) {
         | 
| 3001 | 
            -
                        if (a.indented != b.indented || a.tokenize != b.tokenize) return false;
         | 
| 3002 | 
            -
                        for (var ca = a.context, cb = b.context; ; ca = ca.prev, cb = cb.prev) {
         | 
| 3003 | 
            -
                            if (!ca || !cb) return ca == cb;
         | 
| 3004 | 
            -
                            if (ca.tagName != cb.tagName) return false;
         | 
| 3005 | 
            -
                        }
         | 
| 3006 | 
            -
                    },
         | 
| 3007 | 
            -
             | 
| 3008 | 
            -
                    electricChars: "/"
         | 
| 3009 | 
            -
                };
         | 
| 3010 | 
            -
            });
         | 
| 3011 | 
            -
             | 
| 3012 | 
            -
            CodeMirror.defineMIME("application/xml", "xml");
         | 
| 3013 | 
            -
            CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
         | 
| 3014 | 
            -
            CodeMirror.defineMode("javascript", function(config, parserConfig) {
         | 
| 3015 | 
            -
                var indentUnit = config.indentUnit;
         | 
| 3016 | 
            -
                var jsonMode = parserConfig.json;
         | 
| 3017 | 
            -
             | 
| 3018 | 
            -
                // Tokenizer
         | 
| 3019 | 
            -
             | 
| 3020 | 
            -
                var keywords = function(){
         | 
| 3021 | 
            -
                    function kw(type) {return {type: type, style: "keyword"};}
         | 
| 3022 | 
            -
                    var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
         | 
| 3023 | 
            -
                    var operator = kw("operator"), atom = {type: "atom", style: "atom"};
         | 
| 3024 | 
            -
                    return {
         | 
| 3025 | 
            -
                        "if": A, "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
         | 
| 3026 | 
            -
                        "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C,
         | 
| 3027 | 
            -
                        "var": kw("var"), "const": kw("var"), "let": kw("var"),
         | 
| 3028 | 
            -
                        "function": kw("function"), "catch": kw("catch"),
         | 
| 3029 | 
            -
                        "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
         | 
| 3030 | 
            -
                        "in": operator, "typeof": operator, "instanceof": operator,
         | 
| 3031 | 
            -
                        "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom
         | 
| 3032 | 
            -
                    };
         | 
| 3033 | 
            -
                }();
         | 
| 3034 | 
            -
             | 
| 3035 | 
            -
                var isOperatorChar = /[+\-*&%=<>!?|]/;
         | 
| 3036 | 
            -
             | 
| 3037 | 
            -
                function chain(stream, state, f) {
         | 
| 3038 | 
            -
                    state.tokenize = f;
         | 
| 3039 | 
            -
                    return f(stream, state);
         | 
| 3040 | 
            -
                }
         | 
| 3041 | 
            -
             | 
| 3042 | 
            -
                function nextUntilUnescaped(stream, end) {
         | 
| 3043 | 
            -
                    var escaped = false, next;
         | 
| 3044 | 
            -
                    while ((next = stream.next()) != null) {
         | 
| 3045 | 
            -
                        if (next == end && !escaped)
         | 
| 3046 | 
            -
                            return false;
         | 
| 3047 | 
            -
                        escaped = !escaped && next == "\\";
         | 
| 3048 | 
            -
                    }
         | 
| 3049 | 
            -
                    return escaped;
         | 
| 3050 | 
            -
                }
         | 
| 3051 | 
            -
             | 
| 3052 | 
            -
                // Used as scratch variables to communicate multiple values without
         | 
| 3053 | 
            -
                // consing up tons of objects.
         | 
| 3054 | 
            -
                var type, content;
         | 
| 3055 | 
            -
                function ret(tp, style, cont) {
         | 
| 3056 | 
            -
                    type = tp; content = cont;
         | 
| 3057 | 
            -
                    return style;
         | 
| 3058 | 
            -
                }
         | 
| 3059 | 
            -
             | 
| 3060 | 
            -
                function jsTokenBase(stream, state) {
         | 
| 3061 | 
            -
                    var ch = stream.next();
         | 
| 3062 | 
            -
                    if (ch == '"' || ch == "'")
         | 
| 3063 | 
            -
                        return chain(stream, state, jsTokenString(ch));
         | 
| 3064 | 
            -
                    else if (/[\[\]{}\(\),;\:\.]/.test(ch))
         | 
| 3065 | 
            -
                        return ret(ch);
         | 
| 3066 | 
            -
                    else if (ch == "0" && stream.eat(/x/i)) {
         | 
| 3067 | 
            -
                        stream.eatWhile(/[\da-f]/i);
         | 
| 3068 | 
            -
                        return ret("number", "number");
         | 
| 3069 | 
            -
                    }
         | 
| 3070 | 
            -
                    else if (/\d/.test(ch)) {
         | 
| 3071 | 
            -
                        stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
         | 
| 3072 | 
            -
                        return ret("number", "number");
         | 
| 3073 | 
            -
                    }
         | 
| 3074 | 
            -
                    else if (ch == "/") {
         | 
| 3075 | 
            -
                        if (stream.eat("*")) {
         | 
| 3076 | 
            -
                            return chain(stream, state, jsTokenComment);
         | 
| 3077 | 
            -
                        }
         | 
| 3078 | 
            -
                        else if (stream.eat("/")) {
         | 
| 3079 | 
            -
                            stream.skipToEnd();
         | 
| 3080 | 
            -
                            return ret("comment", "comment");
         | 
| 3081 | 
            -
                        }
         | 
| 3082 | 
            -
                        else if (state.reAllowed) {
         | 
| 3083 | 
            -
                            nextUntilUnescaped(stream, "/");
         | 
| 3084 | 
            -
                            stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla
         | 
| 3085 | 
            -
                            return ret("regexp", "string");
         | 
| 3086 | 
            -
                        }
         | 
| 3087 | 
            -
                        else {
         | 
| 3088 | 
            -
                            stream.eatWhile(isOperatorChar);
         | 
| 3089 | 
            -
                            return ret("operator", null, stream.current());
         | 
| 3090 | 
            -
                        }
         | 
| 3091 | 
            -
                    }
         | 
| 3092 | 
            -
                    else if (ch == "#") {
         | 
| 3093 | 
            -
                        stream.skipToEnd();
         | 
| 3094 | 
            -
                        return ret("error", "error");
         | 
| 3095 | 
            -
                    }
         | 
| 3096 | 
            -
                    else if (isOperatorChar.test(ch)) {
         | 
| 3097 | 
            -
                        stream.eatWhile(isOperatorChar);
         | 
| 3098 | 
            -
                        return ret("operator", null, stream.current());
         | 
| 3099 | 
            -
                    }
         | 
| 3100 | 
            -
                    else {
         | 
| 3101 | 
            -
                        stream.eatWhile(/[\w\$_]/);
         | 
| 3102 | 
            -
                        var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
         | 
| 3103 | 
            -
                        return (known && state.kwAllowed) ? ret(known.type, known.style, word) :
         | 
| 3104 | 
            -
                            ret("variable", "variable", word);
         | 
| 3105 | 
            -
                    }
         | 
| 3106 | 
            -
                }
         | 
| 3107 | 
            -
             | 
| 3108 | 
            -
                function jsTokenString(quote) {
         | 
| 3109 | 
            -
                    return function(stream, state) {
         | 
| 3110 | 
            -
                        if (!nextUntilUnescaped(stream, quote))
         | 
| 3111 | 
            -
                            state.tokenize = jsTokenBase;
         | 
| 3112 | 
            -
                        return ret("string", "string");
         | 
| 3113 | 
            -
                    };
         | 
| 3114 | 
            -
                }
         | 
| 3115 | 
            -
             | 
| 3116 | 
            -
                function jsTokenComment(stream, state) {
         | 
| 3117 | 
            -
                    var maybeEnd = false, ch;
         | 
| 3118 | 
            -
                    while (ch = stream.next()) {
         | 
| 3119 | 
            -
                        if (ch == "/" && maybeEnd) {
         | 
| 3120 | 
            -
                            state.tokenize = jsTokenBase;
         | 
| 3121 | 
            -
                            break;
         | 
| 3122 | 
            -
                        }
         | 
| 3123 | 
            -
                        maybeEnd = (ch == "*");
         | 
| 3124 | 
            -
                    }
         | 
| 3125 | 
            -
                    return ret("comment", "comment");
         | 
| 3126 | 
            -
                }
         | 
| 3127 | 
            -
             | 
| 3128 | 
            -
                // Parser
         | 
| 3129 | 
            -
             | 
| 3130 | 
            -
                var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true};
         | 
| 3131 | 
            -
             | 
| 3132 | 
            -
                function JSLexical(indented, column, type, align, prev, info) {
         | 
| 3133 | 
            -
                    this.indented = indented;
         | 
| 3134 | 
            -
                    this.column = column;
         | 
| 3135 | 
            -
                    this.type = type;
         | 
| 3136 | 
            -
                    this.prev = prev;
         | 
| 3137 | 
            -
                    this.info = info;
         | 
| 3138 | 
            -
                    if (align != null) this.align = align;
         | 
| 3139 | 
            -
                }
         | 
| 3140 | 
            -
             | 
| 3141 | 
            -
                function inScope(state, varname) {
         | 
| 3142 | 
            -
                    for (var v = state.localVars; v; v = v.next)
         | 
| 3143 | 
            -
                        if (v.name == varname) return true;
         | 
| 3144 | 
            -
                }
         | 
| 3145 | 
            -
             | 
| 3146 | 
            -
                function parseJS(state, style, type, content, stream) {
         | 
| 3147 | 
            -
                    var cc = state.cc;
         | 
| 3148 | 
            -
                    // Communicate our context to the combinators.
         | 
| 3149 | 
            -
                    // (Less wasteful than consing up a hundred closures on every call.)
         | 
| 3150 | 
            -
                    cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
         | 
| 3151 | 
            -
             | 
| 3152 | 
            -
                    if (!state.lexical.hasOwnProperty("align"))
         | 
| 3153 | 
            -
                        state.lexical.align = true;
         | 
| 3154 | 
            -
             | 
| 3155 | 
            -
                    while(true) {
         | 
| 3156 | 
            -
                        var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
         | 
| 3157 | 
            -
                        if (combinator(type, content)) {
         | 
| 3158 | 
            -
                            while(cc.length && cc[cc.length - 1].lex)
         | 
| 3159 | 
            -
                                cc.pop()();
         | 
| 3160 | 
            -
                            if (cx.marked) return cx.marked;
         | 
| 3161 | 
            -
                            if (type == "variable" && inScope(state, content)) return "variable-2";
         | 
| 3162 | 
            -
                            return style;
         | 
| 3163 | 
            -
                        }
         | 
| 3164 | 
            -
                    }
         | 
| 3165 | 
            -
                }
         | 
| 3166 | 
            -
             | 
| 3167 | 
            -
                // Combinator utils
         | 
| 3168 | 
            -
             | 
| 3169 | 
            -
                var cx = {state: null, column: null, marked: null, cc: null};
         | 
| 3170 | 
            -
                function pass() {
         | 
| 3171 | 
            -
                    for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
         | 
| 3172 | 
            -
                }
         | 
| 3173 | 
            -
                function cont() {
         | 
| 3174 | 
            -
                    pass.apply(null, arguments);
         | 
| 3175 | 
            -
                    return true;
         | 
| 3176 | 
            -
                }
         | 
| 3177 | 
            -
                function register(varname) {
         | 
| 3178 | 
            -
                    var state = cx.state;
         | 
| 3179 | 
            -
                    if (state.context) {
         | 
| 3180 | 
            -
                        cx.marked = "def";
         | 
| 3181 | 
            -
                        for (var v = state.localVars; v; v = v.next)
         | 
| 3182 | 
            -
                            if (v.name == varname) return;
         | 
| 3183 | 
            -
                        state.localVars = {name: varname, next: state.localVars};
         | 
| 3184 | 
            -
                    }
         | 
| 3185 | 
            -
                }
         | 
| 3186 | 
            -
             | 
| 3187 | 
            -
                // Combinators
         | 
| 3188 | 
            -
             | 
| 3189 | 
            -
                var defaultVars = {name: "this", next: {name: "arguments"}};
         | 
| 3190 | 
            -
                function pushcontext() {
         | 
| 3191 | 
            -
                    if (!cx.state.context) cx.state.localVars = defaultVars;
         | 
| 3192 | 
            -
                    cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
         | 
| 3193 | 
            -
                }
         | 
| 3194 | 
            -
                function popcontext() {
         | 
| 3195 | 
            -
                    cx.state.localVars = cx.state.context.vars;
         | 
| 3196 | 
            -
                    cx.state.context = cx.state.context.prev;
         | 
| 3197 | 
            -
                }
         | 
| 3198 | 
            -
                function pushlex(type, info) {
         | 
| 3199 | 
            -
                    var result = function() {
         | 
| 3200 | 
            -
                        var state = cx.state;
         | 
| 3201 | 
            -
                        state.lexical = new JSLexical(state.indented, cx.stream.column(), type, null, state.lexical, info)
         | 
| 3202 | 
            -
                    };
         | 
| 3203 | 
            -
                    result.lex = true;
         | 
| 3204 | 
            -
                    return result;
         | 
| 3205 | 
            -
                }
         | 
| 3206 | 
            -
                function poplex() {
         | 
| 3207 | 
            -
                    var state = cx.state;
         | 
| 3208 | 
            -
                    if (state.lexical.prev) {
         | 
| 3209 | 
            -
                        if (state.lexical.type == ")")
         | 
| 3210 | 
            -
                            state.indented = state.lexical.indented;
         | 
| 3211 | 
            -
                        state.lexical = state.lexical.prev;
         | 
| 3212 | 
            -
                    }
         | 
| 3213 | 
            -
                }
         | 
| 3214 | 
            -
                poplex.lex = true;
         | 
| 3215 | 
            -
             | 
| 3216 | 
            -
                function expect(wanted) {
         | 
| 3217 | 
            -
                    return function expecting(type) {
         | 
| 3218 | 
            -
                        if (type == wanted) return cont();
         | 
| 3219 | 
            -
                        else if (wanted == ";") return pass();
         | 
| 3220 | 
            -
                        else return cont(arguments.callee);
         | 
| 3221 | 
            -
                    };
         | 
| 3222 | 
            -
                }
         | 
| 3223 | 
            -
             | 
| 3224 | 
            -
                function statement(type) {
         | 
| 3225 | 
            -
                    if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex);
         | 
| 3226 | 
            -
                    if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
         | 
| 3227 | 
            -
                    if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
         | 
| 3228 | 
            -
                    if (type == "{") return cont(pushlex("}"), block, poplex);
         | 
| 3229 | 
            -
                    if (type == ";") return cont();
         | 
| 3230 | 
            -
                    if (type == "function") return cont(functiondef);
         | 
| 3231 | 
            -
                    if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"),
         | 
| 3232 | 
            -
                        poplex, statement, poplex);
         | 
| 3233 | 
            -
                    if (type == "variable") return cont(pushlex("stat"), maybelabel);
         | 
| 3234 | 
            -
                    if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
         | 
| 3235 | 
            -
                        block, poplex, poplex);
         | 
| 3236 | 
            -
                    if (type == "case") return cont(expression, expect(":"));
         | 
| 3237 | 
            -
                    if (type == "default") return cont(expect(":"));
         | 
| 3238 | 
            -
                    if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
         | 
| 3239 | 
            -
                        statement, poplex, popcontext);
         | 
| 3240 | 
            -
                    return pass(pushlex("stat"), expression, expect(";"), poplex);
         | 
| 3241 | 
            -
                }
         | 
| 3242 | 
            -
                function expression(type) {
         | 
| 3243 | 
            -
                    if (atomicTypes.hasOwnProperty(type)) return cont(maybeoperator);
         | 
| 3244 | 
            -
                    if (type == "function") return cont(functiondef);
         | 
| 3245 | 
            -
                    if (type == "keyword c") return cont(maybeexpression);
         | 
| 3246 | 
            -
                    if (type == "(") return cont(pushlex(")"), expression, expect(")"), poplex, maybeoperator);
         | 
| 3247 | 
            -
                    if (type == "operator") return cont(expression);
         | 
| 3248 | 
            -
                    if (type == "[") return cont(pushlex("]"), commasep(expression, "]"), poplex, maybeoperator);
         | 
| 3249 | 
            -
                    if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeoperator);
         | 
| 3250 | 
            -
                    return cont();
         | 
| 3251 | 
            -
                }
         | 
| 3252 | 
            -
                function maybeexpression(type) {
         | 
| 3253 | 
            -
                    if (type.match(/[;\}\)\],]/)) return pass();
         | 
| 3254 | 
            -
                    return pass(expression);
         | 
| 3255 | 
            -
                }
         | 
| 3256 | 
            -
             | 
| 3257 | 
            -
                function maybeoperator(type, value) {
         | 
| 3258 | 
            -
                    if (type == "operator" && /\+\+|--/.test(value)) return cont(maybeoperator);
         | 
| 3259 | 
            -
                    if (type == "operator") return cont(expression);
         | 
| 3260 | 
            -
                    if (type == ";") return;
         | 
| 3261 | 
            -
                    if (type == "(") return cont(pushlex(")"), commasep(expression, ")"), poplex, maybeoperator);
         | 
| 3262 | 
            -
                    if (type == ".") return cont(property, maybeoperator);
         | 
| 3263 | 
            -
                    if (type == "[") return cont(pushlex("]"), expression, expect("]"), poplex, maybeoperator);
         | 
| 3264 | 
            -
                }
         | 
| 3265 | 
            -
                function maybelabel(type) {
         | 
| 3266 | 
            -
                    if (type == ":") return cont(poplex, statement);
         | 
| 3267 | 
            -
                    return pass(maybeoperator, expect(";"), poplex);
         | 
| 3268 | 
            -
                }
         | 
| 3269 | 
            -
                function property(type) {
         | 
| 3270 | 
            -
                    if (type == "variable") {cx.marked = "property"; return cont();}
         | 
| 3271 | 
            -
                }
         | 
| 3272 | 
            -
                function objprop(type) {
         | 
| 3273 | 
            -
                    if (type == "variable") cx.marked = "property";
         | 
| 3274 | 
            -
                    if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expression);
         | 
| 3275 | 
            -
                }
         | 
| 3276 | 
            -
                function commasep(what, end) {
         | 
| 3277 | 
            -
                    function proceed(type) {
         | 
| 3278 | 
            -
                        if (type == ",") return cont(what, proceed);
         | 
| 3279 | 
            -
                        if (type == end) return cont();
         | 
| 3280 | 
            -
                        return cont(expect(end));
         | 
| 3281 | 
            -
                    }
         | 
| 3282 | 
            -
                    return function commaSeparated(type) {
         | 
| 3283 | 
            -
                        if (type == end) return cont();
         | 
| 3284 | 
            -
                        else return pass(what, proceed);
         | 
| 3285 | 
            -
                    };
         | 
| 3286 | 
            -
                }
         | 
| 3287 | 
            -
                function block(type) {
         | 
| 3288 | 
            -
                    if (type == "}") return cont();
         | 
| 3289 | 
            -
                    return pass(statement, block);
         | 
| 3290 | 
            -
                }
         | 
| 3291 | 
            -
                function vardef1(type, value) {
         | 
| 3292 | 
            -
                    if (type == "variable"){register(value); return cont(vardef2);}
         | 
| 3293 | 
            -
                    return cont();
         | 
| 3294 | 
            -
                }
         | 
| 3295 | 
            -
                function vardef2(type, value) {
         | 
| 3296 | 
            -
                    if (value == "=") return cont(expression, vardef2);
         | 
| 3297 | 
            -
                    if (type == ",") return cont(vardef1);
         | 
| 3298 | 
            -
                }
         | 
| 3299 | 
            -
                function forspec1(type) {
         | 
| 3300 | 
            -
                    if (type == "var") return cont(vardef1, forspec2);
         | 
| 3301 | 
            -
                    if (type == ";") return pass(forspec2);
         | 
| 3302 | 
            -
                    if (type == "variable") return cont(formaybein);
         | 
| 3303 | 
            -
                    return pass(forspec2);
         | 
| 3304 | 
            -
                }
         | 
| 3305 | 
            -
                function formaybein(type, value) {
         | 
| 3306 | 
            -
                    if (value == "in") return cont(expression);
         | 
| 3307 | 
            -
                    return cont(maybeoperator, forspec2);
         | 
| 3308 | 
            -
                }
         | 
| 3309 | 
            -
                function forspec2(type, value) {
         | 
| 3310 | 
            -
                    if (type == ";") return cont(forspec3);
         | 
| 3311 | 
            -
                    if (value == "in") return cont(expression);
         | 
| 3312 | 
            -
                    return cont(expression, expect(";"), forspec3);
         | 
| 3313 | 
            -
                }
         | 
| 3314 | 
            -
                function forspec3(type) {
         | 
| 3315 | 
            -
                    if (type != ")") cont(expression);
         | 
| 3316 | 
            -
                }
         | 
| 3317 | 
            -
                function functiondef(type, value) {
         | 
| 3318 | 
            -
                    if (type == "variable") {register(value); return cont(functiondef);}
         | 
| 3319 | 
            -
                    if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, statement, popcontext);
         | 
| 3320 | 
            -
                }
         | 
| 3321 | 
            -
                function funarg(type, value) {
         | 
| 3322 | 
            -
                    if (type == "variable") {register(value); return cont();}
         | 
| 3323 | 
            -
                }
         | 
| 3324 | 
            -
             | 
| 3325 | 
            -
                // Interface
         | 
| 3326 | 
            -
             | 
| 3327 | 
            -
                return {
         | 
| 3328 | 
            -
                    startState: function(basecolumn) {
         | 
| 3329 | 
            -
                        return {
         | 
| 3330 | 
            -
                            tokenize: jsTokenBase,
         | 
| 3331 | 
            -
                            reAllowed: true,
         | 
| 3332 | 
            -
                            kwAllowed: true,
         | 
| 3333 | 
            -
                            cc: [],
         | 
| 3334 | 
            -
                            lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
         | 
| 3335 | 
            -
                            localVars: null,
         | 
| 3336 | 
            -
                            context: null,
         | 
| 3337 | 
            -
                            indented: 0
         | 
| 3338 | 
            -
                        };
         | 
| 3339 | 
            -
                    },
         | 
| 3340 | 
            -
             | 
| 3341 | 
            -
                    token: function(stream, state) {
         | 
| 3342 | 
            -
                        if (stream.sol()) {
         | 
| 3343 | 
            -
                            if (!state.lexical.hasOwnProperty("align"))
         | 
| 3344 | 
            -
                                state.lexical.align = false;
         | 
| 3345 | 
            -
                            state.indented = stream.indentation();
         | 
| 3346 | 
            -
                        }
         | 
| 3347 | 
            -
                        if (stream.eatSpace()) return null;
         | 
| 3348 | 
            -
                        var style = state.tokenize(stream, state);
         | 
| 3349 | 
            -
                        if (type == "comment") return style;
         | 
| 3350 | 
            -
                        state.reAllowed = type == "operator" || type == "keyword c" || type.match(/^[\[{}\(,;:]$/);
         | 
| 3351 | 
            -
                        state.kwAllowed = type != '.';
         | 
| 3352 | 
            -
                        return parseJS(state, style, type, content, stream);
         | 
| 3353 | 
            -
                    },
         | 
| 3354 | 
            -
             | 
| 3355 | 
            -
                    indent: function(state, textAfter) {
         | 
| 3356 | 
            -
                        if (state.tokenize != jsTokenBase) return 0;
         | 
| 3357 | 
            -
                        var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical,
         | 
| 3358 | 
            -
                            type = lexical.type, closing = firstChar == type;
         | 
| 3359 | 
            -
                        if (type == "vardef") return lexical.indented + 4;
         | 
| 3360 | 
            -
                        else if (type == "form" && firstChar == "{") return lexical.indented;
         | 
| 3361 | 
            -
                        else if (type == "stat" || type == "form") return lexical.indented + indentUnit;
         | 
| 3362 | 
            -
                        else if (lexical.info == "switch" && !closing)
         | 
| 3363 | 
            -
                            return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
         | 
| 3364 | 
            -
                        else if (lexical.align) return lexical.column + (closing ? 0 : 1);
         | 
| 3365 | 
            -
                        else return lexical.indented + (closing ? 0 : indentUnit);
         | 
| 3366 | 
            -
                    },
         | 
| 3367 | 
            -
             | 
| 3368 | 
            -
                    electricChars: ":{}"
         | 
| 3369 | 
            -
                };
         | 
| 3370 | 
            -
            });
         | 
| 3371 | 
            -
             | 
| 3372 | 
            -
            CodeMirror.defineMIME("text/javascript", "javascript");
         | 
| 3373 | 
            -
            CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
         | 
| 3374 | 
            -
             | 
| 3375 | 
            -
            CodeMirror.defineMode("css", function(config) {
         | 
| 3376 | 
            -
                var indentUnit = config.indentUnit, type;
         | 
| 3377 | 
            -
                function ret(style, tp) {type = tp; return style;}
         | 
| 3378 | 
            -
             | 
| 3379 | 
            -
                function tokenBase(stream, state) {
         | 
| 3380 | 
            -
                    var ch = stream.next();
         | 
| 3381 | 
            -
                    if (ch == "@") {stream.eatWhile(/[\w\\\-]/); return ret("meta", stream.current());}
         | 
| 3382 | 
            -
                    else if (ch == "/" && stream.eat("*")) {
         | 
| 3383 | 
            -
                        state.tokenize = tokenCComment;
         | 
| 3384 | 
            -
                        return tokenCComment(stream, state);
         | 
| 3385 | 
            -
                    }
         | 
| 3386 | 
            -
                    else if (ch == "<" && stream.eat("!")) {
         | 
| 3387 | 
            -
                        state.tokenize = tokenSGMLComment;
         | 
| 3388 | 
            -
                        return tokenSGMLComment(stream, state);
         | 
| 3389 | 
            -
                    }
         | 
| 3390 | 
            -
                    else if (ch == "=") ret(null, "compare");
         | 
| 3391 | 
            -
                    else if ((ch == "~" || ch == "|") && stream.eat("=")) return ret(null, "compare");
         | 
| 3392 | 
            -
                    else if (ch == "\"" || ch == "'") {
         | 
| 3393 | 
            -
                        state.tokenize = tokenString(ch);
         | 
| 3394 | 
            -
                        return state.tokenize(stream, state);
         | 
| 3395 | 
            -
                    }
         | 
| 3396 | 
            -
                    else if (ch == "#") {
         | 
| 3397 | 
            -
                        stream.eatWhile(/[\w\\\-]/);
         | 
| 3398 | 
            -
                        return ret("atom", "hash");
         | 
| 3399 | 
            -
                    }
         | 
| 3400 | 
            -
                    else if (ch == "!") {
         | 
| 3401 | 
            -
                        stream.match(/^\s*\w*/);
         | 
| 3402 | 
            -
                        return ret("keyword", "important");
         | 
| 3403 | 
            -
                    }
         | 
| 3404 | 
            -
                    else if (/\d/.test(ch)) {
         | 
| 3405 | 
            -
                        stream.eatWhile(/[\w.%]/);
         | 
| 3406 | 
            -
                        return ret("number", "unit");
         | 
| 3407 | 
            -
                    }
         | 
| 3408 | 
            -
                    else if (/[,.+>*\/]/.test(ch)) {
         | 
| 3409 | 
            -
                        return ret(null, "select-op");
         | 
| 3410 | 
            -
                    }
         | 
| 3411 | 
            -
                    else if (/[;{}:\[\]]/.test(ch)) {
         | 
| 3412 | 
            -
                        return ret(null, ch);
         | 
| 3413 | 
            -
                    }
         | 
| 3414 | 
            -
                    else {
         | 
| 3415 | 
            -
                        stream.eatWhile(/[\w\\\-]/);
         | 
| 3416 | 
            -
                        return ret("variable", "variable");
         | 
| 3417 | 
            -
                    }
         | 
| 3418 | 
            -
                }
         | 
| 3419 | 
            -
             | 
| 3420 | 
            -
                function tokenCComment(stream, state) {
         | 
| 3421 | 
            -
                    var maybeEnd = false, ch;
         | 
| 3422 | 
            -
                    while ((ch = stream.next()) != null) {
         | 
| 3423 | 
            -
                        if (maybeEnd && ch == "/") {
         | 
| 3424 | 
            -
                            state.tokenize = tokenBase;
         | 
| 3425 | 
            -
                            break;
         | 
| 3426 | 
            -
                        }
         | 
| 3427 | 
            -
                        maybeEnd = (ch == "*");
         | 
| 3428 | 
            -
                    }
         | 
| 3429 | 
            -
                    return ret("comment", "comment");
         | 
| 3430 | 
            -
                }
         | 
| 3431 | 
            -
             | 
| 3432 | 
            -
                function tokenSGMLComment(stream, state) {
         | 
| 3433 | 
            -
                    var dashes = 0, ch;
         | 
| 3434 | 
            -
                    while ((ch = stream.next()) != null) {
         | 
| 3435 | 
            -
                        if (dashes >= 2 && ch == ">") {
         | 
| 3436 | 
            -
                            state.tokenize = tokenBase;
         | 
| 3437 | 
            -
                            break;
         | 
| 3438 | 
            -
                        }
         | 
| 3439 | 
            -
                        dashes = (ch == "-") ? dashes + 1 : 0;
         | 
| 3440 | 
            -
                    }
         | 
| 3441 | 
            -
                    return ret("comment", "comment");
         | 
| 3442 | 
            -
                }
         | 
| 3443 | 
            -
             | 
| 3444 | 
            -
                function tokenString(quote) {
         | 
| 3445 | 
            -
                    return function(stream, state) {
         | 
| 3446 | 
            -
                        var escaped = false, ch;
         | 
| 3447 | 
            -
                        while ((ch = stream.next()) != null) {
         | 
| 3448 | 
            -
                            if (ch == quote && !escaped)
         | 
| 3449 | 
            -
                                break;
         | 
| 3450 | 
            -
                            escaped = !escaped && ch == "\\";
         | 
| 3451 | 
            -
                        }
         | 
| 3452 | 
            -
                        if (!escaped) state.tokenize = tokenBase;
         | 
| 3453 | 
            -
                        return ret("string", "string");
         | 
| 3454 | 
            -
                    };
         | 
| 3455 | 
            -
                }
         | 
| 3456 | 
            -
             | 
| 3457 | 
            -
                return {
         | 
| 3458 | 
            -
                    startState: function(base) {
         | 
| 3459 | 
            -
                        return {tokenize: tokenBase,
         | 
| 3460 | 
            -
                            baseIndent: base || 0,
         | 
| 3461 | 
            -
                            stack: []};
         | 
| 3462 | 
            -
                    },
         | 
| 3463 | 
            -
             | 
| 3464 | 
            -
                    token: function(stream, state) {
         | 
| 3465 | 
            -
                        if (stream.eatSpace()) return null;
         | 
| 3466 | 
            -
                        var style = state.tokenize(stream, state);
         | 
| 3467 | 
            -
             | 
| 3468 | 
            -
                        var context = state.stack[state.stack.length-1];
         | 
| 3469 | 
            -
                        if (type == "hash" && context == "rule") style = "atom";
         | 
| 3470 | 
            -
                        else if (style == "variable") {
         | 
| 3471 | 
            -
                            if (context == "rule") style = "number";
         | 
| 3472 | 
            -
                            else if (!context || context == "@media{") style = "tag";
         | 
| 3473 | 
            -
                        }
         | 
| 3474 | 
            -
             | 
| 3475 | 
            -
                        if (context == "rule" && /^[\{\};]$/.test(type))
         | 
| 3476 | 
            -
                            state.stack.pop();
         | 
| 3477 | 
            -
                        if (type == "{") {
         | 
| 3478 | 
            -
                            if (context == "@media") state.stack[state.stack.length-1] = "@media{";
         | 
| 3479 | 
            -
                            else state.stack.push("{");
         | 
| 3480 | 
            -
                        }
         | 
| 3481 | 
            -
                        else if (type == "}") state.stack.pop();
         | 
| 3482 | 
            -
                        else if (type == "@media") state.stack.push("@media");
         | 
| 3483 | 
            -
                        else if (context == "{" && type != "comment") state.stack.push("rule");
         | 
| 3484 | 
            -
                        return style;
         | 
| 3485 | 
            -
                    },
         | 
| 3486 | 
            -
             | 
| 3487 | 
            -
                    indent: function(state, textAfter) {
         | 
| 3488 | 
            -
                        var n = state.stack.length;
         | 
| 3489 | 
            -
                        if (/^\}/.test(textAfter))
         | 
| 3490 | 
            -
                            n -= state.stack[state.stack.length-1] == "rule" ? 2 : 1;
         | 
| 3491 | 
            -
                        return state.baseIndent + n * indentUnit;
         | 
| 3492 | 
            -
                    },
         | 
| 3493 | 
            -
             | 
| 3494 | 
            -
                    electricChars: "}"
         | 
| 3495 | 
            -
                };
         | 
| 3496 | 
            -
            });
         | 
| 3497 | 
            -
             | 
| 3498 | 
            -
            CodeMirror.defineMIME("text/css", "css");
         | 
| 3499 | 
            -
            CodeMirror.defineMode("htmlmixed", function(config, parserConfig) {
         | 
| 3500 | 
            -
                var htmlMode = CodeMirror.getMode(config, {name: "xml", htmlMode: true});
         | 
| 3501 | 
            -
                var jsMode = CodeMirror.getMode(config, "javascript");
         | 
| 3502 | 
            -
                var cssMode = CodeMirror.getMode(config, "css");
         | 
| 3503 | 
            -
             | 
| 3504 | 
            -
                function html(stream, state) {
         | 
| 3505 | 
            -
                    var style = htmlMode.token(stream, state.htmlState);
         | 
| 3506 | 
            -
                    if (style == "tag" && stream.current() == ">" && state.htmlState.context) {
         | 
| 3507 | 
            -
                        if (/^script$/i.test(state.htmlState.context.tagName)) {
         | 
| 3508 | 
            -
                            state.token = javascript;
         | 
| 3509 | 
            -
                            state.localState = jsMode.startState(htmlMode.indent(state.htmlState, ""));
         | 
| 3510 | 
            -
                            state.mode = "javascript";
         | 
| 3511 | 
            -
                        }
         | 
| 3512 | 
            -
                        else if (/^style$/i.test(state.htmlState.context.tagName)) {
         | 
| 3513 | 
            -
                            state.token = css;
         | 
| 3514 | 
            -
                            state.localState = cssMode.startState(htmlMode.indent(state.htmlState, ""));
         | 
| 3515 | 
            -
                            state.mode = "css";
         | 
| 3516 | 
            -
                        }
         | 
| 3517 | 
            -
                    }
         | 
| 3518 | 
            -
                    return style;
         | 
| 3519 | 
            -
                }
         | 
| 3520 | 
            -
                function maybeBackup(stream, pat, style) {
         | 
| 3521 | 
            -
                    var cur = stream.current();
         | 
| 3522 | 
            -
                    var close = cur.search(pat);
         | 
| 3523 | 
            -
                    if (close > -1) stream.backUp(cur.length - close);
         | 
| 3524 | 
            -
                    return style;
         | 
| 3525 | 
            -
                }
         | 
| 3526 | 
            -
                function javascript(stream, state) {
         | 
| 3527 | 
            -
                    if (stream.match(/^<\/\s*script\s*>/i, false)) {
         | 
| 3528 | 
            -
                        state.token = html;
         | 
| 3529 | 
            -
                        state.curState = null;
         | 
| 3530 | 
            -
                        state.mode = "html";
         | 
| 3531 | 
            -
                        return html(stream, state);
         | 
| 3532 | 
            -
                    }
         | 
| 3533 | 
            -
                    return maybeBackup(stream, /<\/\s*script\s*>/,
         | 
| 3534 | 
            -
                        jsMode.token(stream, state.localState));
         | 
| 3535 | 
            -
                }
         | 
| 3536 | 
            -
                function css(stream, state) {
         | 
| 3537 | 
            -
                    if (stream.match(/^<\/\s*style\s*>/i, false)) {
         | 
| 3538 | 
            -
                        state.token = html;
         | 
| 3539 | 
            -
                        state.localState = null;
         | 
| 3540 | 
            -
                        state.mode = "html";
         | 
| 3541 | 
            -
                        return html(stream, state);
         | 
| 3542 | 
            -
                    }
         | 
| 3543 | 
            -
                    return maybeBackup(stream, /<\/\s*style\s*>/,
         | 
| 3544 | 
            -
                        cssMode.token(stream, state.localState));
         | 
| 3545 | 
            -
                }
         | 
| 3546 | 
            -
             | 
| 3547 | 
            -
                return {
         | 
| 3548 | 
            -
                    startState: function() {
         | 
| 3549 | 
            -
                        var state = htmlMode.startState();
         | 
| 3550 | 
            -
                        return {token: html, localState: null, mode: "html", htmlState: state};
         | 
| 3551 | 
            -
                    },
         | 
| 3552 | 
            -
             | 
| 3553 | 
            -
                    copyState: function(state) {
         | 
| 3554 | 
            -
                        if (state.localState)
         | 
| 3555 | 
            -
                            var local = CodeMirror.copyState(state.token == css ? cssMode : jsMode, state.localState);
         | 
| 3556 | 
            -
                        return {token: state.token, localState: local, mode: state.mode,
         | 
| 3557 | 
            -
                            htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
         | 
| 3558 | 
            -
                    },
         | 
| 3559 | 
            -
             | 
| 3560 | 
            -
                    token: function(stream, state) {
         | 
| 3561 | 
            -
                        return state.token(stream, state);
         | 
| 3562 | 
            -
                    },
         | 
| 3563 | 
            -
             | 
| 3564 | 
            -
                    indent: function(state, textAfter) {
         | 
| 3565 | 
            -
                        if (state.token == html || /^\s*<\//.test(textAfter))
         | 
| 3566 | 
            -
                            return htmlMode.indent(state.htmlState, textAfter);
         | 
| 3567 | 
            -
                        else if (state.token == javascript)
         | 
| 3568 | 
            -
                            return jsMode.indent(state.localState, textAfter);
         | 
| 3569 | 
            -
                        else
         | 
| 3570 | 
            -
                            return cssMode.indent(state.localState, textAfter);
         | 
| 3571 | 
            -
                    },
         | 
| 3572 | 
            -
             | 
| 3573 | 
            -
                    compareStates: function(a, b) {
         | 
| 3574 | 
            -
                        return htmlMode.compareStates(a.htmlState, b.htmlState);
         | 
| 3575 | 
            -
                    },
         | 
| 3576 | 
            -
             | 
| 3577 | 
            -
                    electricChars: "/{}:"
         | 
| 3578 | 
            -
                }
         | 
| 3579 | 
            -
            });
         | 
| 3580 | 
            -
             | 
| 3581 | 
            -
            CodeMirror.defineMIME("text/html", "htmlmixed");
         | 
| 1 | 
            +
            /*! UEditorPlus v2.0.0*/
         | 
| 2 | 
            +
            var CodeMirror=function(){function CodeMirror(place,givenOptions){function isLine(l){return l>=0&&l<doc.size}function getLine(n){return getLineAt(doc,n)}function updateLineHeight(line,height){gutterDirty=!0;for(var diff=height-line.height,n=line;n;n=n.parent)n.height+=diff}function setValue(code){var top={line:0,ch:0};updateLines(top,{line:doc.size-1,ch:getLine(doc.size-1).text.length},splitLines(code),top,top),updateInput=!0}function getValue(code){var text=[];return doc.iter(0,doc.size,function(line){text.push(line.text)}),text.join("\n")}function onMouseDown(e){function extend(e){var cur=posFromMouse(e,!0);if(cur&&!posEq(cur,last)){focused||onFocus(),last=cur,setSelectionUser(start,cur),updateInput=!1;var visible=visibleLines();(cur.line>=visible.to||cur.line<visible.from)&&(going=setTimeout(operation(function(){extend(e)}),150))}}setShift(e.shiftKey);for(var n=e_target(e);n!=wrapper;n=n.parentNode)if(n.parentNode==code&&n!=mover)return;for(var n=e_target(e);n!=wrapper;n=n.parentNode)if(n.parentNode==gutterText)return options.onGutterClick&&options.onGutterClick(instance,indexOf(gutterText.childNodes,n)+showingFrom,e),e_preventDefault(e);var start=posFromMouse(e);switch(e_button(e)){case 3:return void(gecko&&!mac&&onContextMenu(e));case 2:return void(start&&setCursor(start.line,start.ch,!0))}if(!start)return void(e_target(e)==scroller&&e_preventDefault(e));focused||onFocus();var now=+new Date;if(lastDoubleClick&&lastDoubleClick.time>now-400&&posEq(lastDoubleClick.pos,start))return e_preventDefault(e),setTimeout(focusInput,20),selectLine(start.line);if(lastClick&&lastClick.time>now-400&&posEq(lastClick.pos,start))return lastDoubleClick={time:now,pos:start},e_preventDefault(e),selectWordAt(start);lastClick={time:now,pos:start};var going,last=start;if(dragAndDrop&&!posEq(sel.from,sel.to)&&!posLess(start,sel.from)&&!posLess(sel.to,start)){webkit&&(lineSpace.draggable=!0);var up=connect(targetDocument,"mouseup",operation(function(e2){webkit&&(lineSpace.draggable=!1),draggingText=!1,up(),Math.abs(e.clientX-e2.clientX)+Math.abs(e.clientY-e2.clientY)<10&&(e_preventDefault(e2),setCursor(start.line,start.ch,!0),focusInput())}),!0);return void(draggingText=!0)}e_preventDefault(e),setCursor(start.line,start.ch,!0);var move=connect(targetDocument,"mousemove",operation(function(e){clearTimeout(going),e_preventDefault(e),extend(e)}),!0),up=connect(targetDocument,"mouseup",operation(function(e){clearTimeout(going);var cur=posFromMouse(e);cur&&setSelectionUser(start,cur),e_preventDefault(e),focusInput(),updateInput=!0,move(),up()}),!0)}function onDoubleClick(e){for(var n=e_target(e);n!=wrapper;n=n.parentNode)if(n.parentNode==gutterText)return e_preventDefault(e);var start=posFromMouse(e);start&&(lastDoubleClick={time:+new Date,pos:start},e_preventDefault(e),selectWordAt(start))}function onDrop(e){function loadFile(file,i){var reader=new FileReader;reader.onload=function(){text[i]=reader.result,++read==n&&(pos=clipPos(pos),operation(function(){var end=replaceRange(text.join(""),pos,pos);setSelectionUser(pos,end)})())},reader.readAsText(file)}e.preventDefault();var pos=posFromMouse(e,!0),files=e.dataTransfer.files;if(pos&&!options.readOnly)if(files&&files.length&&window.FileReader&&window.File)for(var n=files.length,text=Array(n),read=0,i=0;i<n;++i)loadFile(files[i],i);else try{var text=e.dataTransfer.getData("Text");if(text){var end=replaceRange(text,pos,pos),curFrom=sel.from,curTo=sel.to;setSelectionUser(pos,end),draggingText&&replaceRange("",curFrom,curTo),focusInput()}}catch(e){}}function onDragStart(e){var txt=getSelection();htmlEscape(txt),e.dataTransfer.setDragImage(escapeElement,0,0),e.dataTransfer.setData("Text",txt)}function handleKeyBinding(e){var bound,dropShift,name=keyNames[e.keyCode],next=keyMap[options.keyMap].auto;if(null==name||e.altGraphKey)return next&&(options.keyMap=next),null;if(e.altKey&&(name="Alt-"+name),e.ctrlKey&&(name="Ctrl-"+name),e.metaKey&&(name="Cmd-"+name),e.shiftKey&&(bound=lookupKey("Shift-"+name,options.extraKeys,options.keyMap))?dropShift=!0:bound=lookupKey(name,options.extraKeys,options.keyMap),"string"==typeof bound&&(bound=commands.propertyIsEnumerable(bound)?commands[bound]:null),!next||!bound&&isModifierKey(e)||(options.keyMap=next),!bound)return!1;if(dropShift){var prevShift=shiftSelecting;shiftSelecting=null,bound(instance),shiftSelecting=prevShift}else bound(instance);return e_preventDefault(e),!0}function onKeyDown(e){focused||onFocus();var code=e.keyCode;if(ie&&27==code&&(e.returnValue=!1),setShift(16==code||e.shiftKey),!options.onKeyEvent||!options.onKeyEvent(instance,addStop(e))){var handled=handleKeyBinding(e);window.opera&&(lastStoppedKey=handled?e.keyCode:null,!handled&&(mac?e.metaKey:e.ctrlKey)&&88==e.keyCode&&replaceSelection(""))}}function onKeyPress(e){if(window.opera&&e.keyCode==lastStoppedKey)return lastStoppedKey=null,void e_preventDefault(e);if((!options.onKeyEvent||!options.onKeyEvent(instance,addStop(e)))&&(!window.opera||e.which||!handleKeyBinding(e))){if(options.electricChars&&mode.electricChars){var ch=String.fromCharCode(null==e.charCode?e.keyCode:e.charCode);mode.electricChars.indexOf(ch)>-1&&setTimeout(operation(function(){indentLine(sel.to.line,"smart")}),75)}fastPoll()}}function onKeyUp(e){options.onKeyEvent&&options.onKeyEvent(instance,addStop(e))||16==e.keyCode&&(shiftSelecting=null)}function onFocus(){options.readOnly||(focused||(options.onFocus&&options.onFocus(instance),focused=!0,wrapper.className.search(/\bCodeMirror-focused\b/)==-1&&(wrapper.className+=" CodeMirror-focused"),leaveInputAlone||resetInput(!0)),slowPoll(),restartBlink())}function onBlur(){focused&&(options.onBlur&&options.onBlur(instance),focused=!1,wrapper.className=wrapper.className.replace(" CodeMirror-focused","")),clearInterval(blinker),setTimeout(function(){focused||(shiftSelecting=null)},150)}function updateLines(from,to,newText,selFrom,selTo){if(history){var old=[];for(doc.iter(from.line,to.line+1,function(line){old.push(line.text)}),history.addChange(from.line,newText.length,old);history.done.length>options.undoDepth;)history.done.shift()}updateLinesNoUndo(from,to,newText,selFrom,selTo)}function unredoHelper(from,to){var change=from.pop();if(change){var replaced=[],end=change.start+change.added;doc.iter(change.start,end,function(line){replaced.push(line.text)}),to.push({start:change.start,added:change.old.length,old:replaced});var pos=clipPos({line:change.start+change.old.length-1,ch:editEnd(replaced[replaced.length-1],change.old[change.old.length-1])});updateLinesNoUndo({line:change.start,ch:0},{line:end-1,ch:getLine(end-1).text.length},change.old,pos,pos),updateInput=!0}}function undo(){unredoHelper(history.done,history.undone)}function redo(){unredoHelper(history.undone,history.done)}function updateLinesNoUndo(from,to,newText,selFrom,selTo){function updateLine(n){return n<=Math.min(to.line,to.line+lendiff)?n:n+lendiff}var recomputeMaxLength=!1,maxLineLength=maxLine.length;options.lineWrapping||doc.iter(from.line,to.line,function(line){if(line.text.length==maxLineLength)return recomputeMaxLength=!0,!0}),(from.line!=to.line||newText.length>1)&&(gutterDirty=!0);var nlines=to.line-from.line,firstLine=getLine(from.line),lastLine=getLine(to.line);if(0==from.ch&&0==to.ch&&""==newText[newText.length-1]){var added=[],prevLine=null;from.line?(prevLine=getLine(from.line-1),prevLine.fixMarkEnds(lastLine)):lastLine.fixMarkStarts();for(var i=0,e=newText.length-1;i<e;++i)added.push(Line.inheritMarks(newText[i],prevLine));nlines&&doc.remove(from.line,nlines,callbacks),added.length&&doc.insert(from.line,added)}else if(firstLine==lastLine)if(1==newText.length)firstLine.replace(from.ch,to.ch,newText[0]);else{lastLine=firstLine.split(to.ch,newText[newText.length-1]),firstLine.replace(from.ch,null,newText[0]),firstLine.fixMarkEnds(lastLine);for(var added=[],i=1,e=newText.length-1;i<e;++i)added.push(Line.inheritMarks(newText[i],firstLine));added.push(lastLine),doc.insert(from.line+1,added)}else if(1==newText.length)firstLine.replace(from.ch,null,newText[0]),lastLine.replace(null,to.ch,""),firstLine.append(lastLine),doc.remove(from.line+1,nlines,callbacks);else{var added=[];firstLine.replace(from.ch,null,newText[0]),lastLine.replace(null,to.ch,newText[newText.length-1]),firstLine.fixMarkEnds(lastLine);for(var i=1,e=newText.length-1;i<e;++i)added.push(Line.inheritMarks(newText[i],firstLine));nlines>1&&doc.remove(from.line+1,nlines-1,callbacks),doc.insert(from.line+1,added)}if(options.lineWrapping){var perLine=scroller.clientWidth/charWidth()-3;doc.iter(from.line,from.line+newText.length,function(line){if(!line.hidden){var guess=Math.ceil(line.text.length/perLine)||1;guess!=line.height&&updateLineHeight(line,guess)}})}else doc.iter(from.line,i+newText.length,function(line){var l=line.text;l.length>maxLineLength&&(maxLine=l,maxLineLength=l.length,maxWidth=null,recomputeMaxLength=!1)}),recomputeMaxLength&&(maxLineLength=0,maxLine="",maxWidth=null,doc.iter(0,doc.size,function(line){var l=line.text;l.length>maxLineLength&&(maxLineLength=l.length,maxLine=l)}));for(var newWork=[],lendiff=newText.length-nlines-1,i=0,l=work.length;i<l;++i){var task=work[i];task<from.line?newWork.push(task):task>to.line&&newWork.push(task+lendiff)}var hlEnd=from.line+Math.min(newText.length,500);highlightLines(from.line,hlEnd),newWork.push(hlEnd),work=newWork,startWorker(100),changes.push({from:from.line,to:to.line+1,diff:lendiff});var changeObj={from:from,to:to,text:newText};if(textChanged){for(var cur=textChanged;cur.next;cur=cur.next);cur.next=changeObj}else textChanged=changeObj;setSelection(selFrom,selTo,updateLine(sel.from.line),updateLine(sel.to.line)),code.style.height=doc.height*textHeight()+2*paddingTop()+"px"}function replaceRange(code,from,to){function adjustPos(pos){if(posLess(pos,from))return pos;if(!posLess(to,pos))return end;var line=pos.line+code.length-(to.line-from.line)-1,ch=pos.ch;return pos.line==to.line&&(ch+=code[code.length-1].length-(to.ch-(to.line==from.line?from.ch:0))),{line:line,ch:ch}}from=clipPos(from),to=to?clipPos(to):from,code=splitLines(code);var end;return replaceRange1(code,from,to,function(end1){return end=end1,{from:adjustPos(sel.from),to:adjustPos(sel.to)}}),end}function replaceSelection(code,collapse){replaceRange1(splitLines(code),sel.from,sel.to,function(end){return"end"==collapse?{from:end,to:end}:"start"==collapse?{from:sel.from,to:sel.from}:{from:sel.from,to:end}})}function replaceRange1(code,from,to,computeSel){var endch=1==code.length?code[0].length+from.ch:code[code.length-1].length,newSel=computeSel({line:from.line+code.length-1,ch:endch});updateLines(from,to,code,newSel.from,newSel.to)}function getRange(from,to){var l1=from.line,l2=to.line;if(l1==l2)return getLine(l1).text.slice(from.ch,to.ch);var code=[getLine(l1).text.slice(from.ch)];return doc.iter(l1+1,l2,function(line){code.push(line.text)}),code.push(getLine(l2).text.slice(0,to.ch)),code.join("\n")}function getSelection(){return getRange(sel.from,sel.to)}function slowPoll(){pollingFast||poll.set(options.pollInterval,function(){startOperation(),readInput(),focused&&slowPoll(),endOperation()})}function fastPoll(){function p(){startOperation();var changed=readInput();changed||missed?(pollingFast=!1,slowPoll()):(missed=!0,poll.set(60,p)),endOperation()}var missed=!1;pollingFast=!0,poll.set(20,p)}function readInput(){if(leaveInputAlone||!focused||hasSelection(input))return!1;var text=input.value;if(text==prevInput)return!1;shiftSelecting=null;for(var same=0,l=Math.min(prevInput.length,text.length);same<l&&prevInput[same]==text[same];)++same;return same<prevInput.length?sel.from={line:sel.from.line,ch:sel.from.ch-(prevInput.length-same)}:overwrite&&posEq(sel.from,sel.to)&&(sel.to={line:sel.to.line,ch:Math.min(getLine(sel.to.line).text.length,sel.to.ch+(text.length-same))}),replaceSelection(text.slice(same),"end"),prevInput=text,!0}function resetInput(user){posEq(sel.from,sel.to)?user&&(prevInput=input.value=""):(prevInput="",input.value=getSelection(),input.select())}function focusInput(){options.readOnly||input.focus()}function scrollEditorIntoView(){if(cursor.getBoundingClientRect){var rect=cursor.getBoundingClientRect();if(!ie||rect.top!=rect.bottom){var winH=window.innerHeight||Math.max(document.body.offsetHeight,document.documentElement.offsetHeight);(rect.top<0||rect.bottom>winH)&&cursor.scrollIntoView()}}}function scrollCursorIntoView(){var cursor=localCoords(sel.inverted?sel.from:sel.to),x=options.lineWrapping?Math.min(cursor.x,lineSpace.offsetWidth):cursor.x;return scrollIntoView(x,cursor.y,x,cursor.yBot)}function scrollIntoView(x1,y1,x2,y2){var pl=paddingLeft(),pt=paddingTop(),lh=textHeight();y1+=pt,y2+=pt,x1+=pl,x2+=pl;var screen=scroller.clientHeight,screentop=scroller.scrollTop,scrolled=!1,result=!0;y1<screentop?(scroller.scrollTop=Math.max(0,y1-2*lh),scrolled=!0):y2>screentop+screen&&(scroller.scrollTop=y2+lh-screen,scrolled=!0);var screenw=scroller.clientWidth,screenleft=scroller.scrollLeft,gutterw=options.fixedGutter?gutter.clientWidth:0;return x1<screenleft+gutterw?(x1<50&&(x1=0),scroller.scrollLeft=Math.max(0,x1-10-gutterw),scrolled=!0):x2>screenw+screenleft-3&&(scroller.scrollLeft=x2+10-screenw,scrolled=!0,x2>code.clientWidth&&(result=!1)),scrolled&&options.onScroll&&options.onScroll(instance),result}function visibleLines(){var lh=textHeight(),top=scroller.scrollTop-paddingTop(),from_height=Math.max(0,Math.floor(top/lh)),to_height=Math.ceil((top+scroller.clientHeight)/lh);return{from:lineAtHeight(doc,from_height),to:lineAtHeight(doc,to_height)}}function updateDisplay(changes,suppressCallback){if(!scroller.clientWidth)return void(showingFrom=showingTo=displayOffset=0);var visible=visibleLines();if(!(changes!==!0&&0==changes.length&&visible.from>=showingFrom&&visible.to<=showingTo)){var from=Math.max(visible.from-100,0),to=Math.min(doc.size,visible.to+100);showingFrom<from&&from-showingFrom<20&&(from=showingFrom),showingTo>to&&showingTo-to<20&&(to=Math.min(doc.size,showingTo));for(var intact=changes===!0?[]:computeIntact([{from:showingFrom,to:showingTo,domStart:0}],changes),intactLines=0,i=0;i<intact.length;++i){var range=intact[i];range.from<from&&(range.domStart+=from-range.from,range.from=from),range.to>to&&(range.to=to),range.from>=range.to?intact.splice(i--,1):intactLines+=range.to-range.from}if(intactLines!=to-from){intact.sort(function(a,b){return a.domStart-b.domStart});var th=textHeight(),gutterDisplay=gutter.style.display;lineDiv.style.display=gutter.style.display="none",patchDisplay(from,to,intact),lineDiv.style.display="";var different=from!=showingFrom||to!=showingTo||lastSizeC!=scroller.clientHeight+th;if(different&&(lastSizeC=scroller.clientHeight+th),showingFrom=from,showingTo=to,displayOffset=heightAtLine(doc,from),mover.style.top=displayOffset*th+"px",code.style.height=doc.height*th+2*paddingTop()+"px",lineDiv.childNodes.length!=showingTo-showingFrom)throw new Error("BAD PATCH! "+JSON.stringify(intact)+" size="+(showingTo-showingFrom)+" nodes="+lineDiv.childNodes.length);if(options.lineWrapping){maxWidth=scroller.clientWidth;var curNode=lineDiv.firstChild;doc.iter(showingFrom,showingTo,function(line){if(!line.hidden){var height=Math.round(curNode.offsetHeight/th)||1;line.height!=height&&(updateLineHeight(line,height),gutterDirty=!0)}curNode=curNode.nextSibling})}else null==maxWidth&&(maxWidth=stringWidth(maxLine)),maxWidth>scroller.clientWidth?(lineSpace.style.width=maxWidth+"px",code.style.width="",code.style.width=scroller.scrollWidth+"px"):lineSpace.style.width=code.style.width="";return gutter.style.display=gutterDisplay,(different||gutterDirty)&&updateGutter(),updateCursor(),!suppressCallback&&options.onUpdate&&options.onUpdate(instance),!0}}}function computeIntact(intact,changes){for(var i=0,l=changes.length||0;i<l;++i){for(var change=changes[i],intact2=[],diff=change.diff||0,j=0,l2=intact.length;j<l2;++j){var range=intact[j];change.to<=range.from&&change.diff?intact2.push({from:range.from+diff,to:range.to+diff,domStart:range.domStart}):change.to<=range.from||change.from>=range.to?intact2.push(range):(change.from>range.from&&intact2.push({from:range.from,to:change.from,domStart:range.domStart}),change.to<range.to&&intact2.push({from:change.to+diff,to:range.to+diff,domStart:range.domStart+(change.to-range.from)}))}intact=intact2}return intact}function patchDisplay(from,to,intact){function killNode(node){var tmp=node.nextSibling;return node.parentNode.removeChild(node),tmp}if(intact.length){for(var domPos=0,curNode=lineDiv.firstChild,i=0;i<intact.length;++i){for(var cur=intact[i];cur.domStart>domPos;)curNode=killNode(curNode),domPos++;for(var j=0,e=cur.to-cur.from;j<e;++j)curNode=curNode.nextSibling,domPos++}for(;curNode;)curNode=killNode(curNode)}else lineDiv.innerHTML="";var nextIntact=intact.shift(),curNode=lineDiv.firstChild,j=from,sfrom=sel.from.line,sto=sel.to.line,inSel=sfrom<from&&sto>=from,scratch=targetDocument.createElement("div");doc.iter(from,to,function(line){var ch1=null,ch2=null;inSel?(ch1=0,sto==j&&(inSel=!1,ch2=sel.to.ch)):sfrom==j&&(sto==j?(ch1=sel.from.ch,ch2=sel.to.ch):(inSel=!0,ch1=sel.from.ch)),nextIntact&&nextIntact.to==j&&(nextIntact=intact.shift()),!nextIntact||nextIntact.from>j?(line.hidden?scratch.innerHTML="<pre></pre>":scratch.innerHTML=line.getHTML(ch1,ch2,!0,tabText),lineDiv.insertBefore(scratch.firstChild,curNode)):curNode=curNode.nextSibling,++j})}function updateGutter(){if(options.gutter||options.lineNumbers){var hText=mover.offsetHeight,hEditor=scroller.clientHeight;gutter.style.height=(hText-hEditor<2?hEditor:hText)+"px";var html=[],i=showingFrom;doc.iter(showingFrom,Math.max(showingTo,showingFrom+1),function(line){if(line.hidden)html.push("<pre></pre>");else{var marker=line.gutterMarker,text=options.lineNumbers?i+options.firstLineNumber:null;marker&&marker.text?text=marker.text.replace("%N%",null!=text?text:""):null==text&&(text=" "),html.push(marker&&marker.style?'<pre class="'+marker.style+'">':"<pre>",text);for(var j=1;j<line.height;++j)html.push("<br/> ");html.push("</pre>")}++i}),gutter.style.display="none",gutterText.innerHTML=html.join("");for(var minwidth=String(doc.size).length,firstNode=gutterText.firstChild,val=eltText(firstNode),pad="";val.length+pad.length<minwidth;)pad+=" ";pad&&firstNode.insertBefore(targetDocument.createTextNode(pad),firstNode.firstChild),gutter.style.display="",lineSpace.style.marginLeft=gutter.offsetWidth+"px",gutterDirty=!1}}function updateCursor(){var head=sel.inverted?sel.from:sel.to,pos=(textHeight(),localCoords(head,!0)),wrapOff=eltOffset(wrapper),lineOff=eltOffset(lineDiv);inputDiv.style.top=pos.y+lineOff.top-wrapOff.top+"px",inputDiv.style.left=pos.x+lineOff.left-wrapOff.left+"px",posEq(sel.from,sel.to)?(cursor.style.top=pos.y+"px",cursor.style.left=(options.lineWrapping?Math.min(pos.x,lineSpace.offsetWidth):pos.x)+"px",cursor.style.display=""):cursor.style.display="none"}function setShift(val){shiftSelecting=val?shiftSelecting||(sel.inverted?sel.to:sel.from):null}function setSelectionUser(from,to){var sh=shiftSelecting&&clipPos(shiftSelecting);sh&&(posLess(sh,from)?from=sh:posLess(to,sh)&&(to=sh)),setSelection(from,to),userSelChange=!0}function setSelection(from,to,oldFrom,oldTo){if(goalColumn=null,null==oldFrom&&(oldFrom=sel.from.line,oldTo=sel.to.line),!posEq(sel.from,from)||!posEq(sel.to,to)){if(posLess(to,from)){var tmp=to;to=from,from=tmp}from.line!=oldFrom&&(from=skipHidden(from,oldFrom,sel.from.ch)),to.line!=oldTo&&(to=skipHidden(to,oldTo,sel.to.ch)),posEq(from,to)?sel.inverted=!1:posEq(from,sel.to)?sel.inverted=!1:posEq(to,sel.from)&&(sel.inverted=!0),posEq(from,to)?posEq(sel.from,sel.to)||changes.push({from:oldFrom,to:oldTo+1}):posEq(sel.from,sel.to)?changes.push({from:from.line,to:to.line+1}):(posEq(from,sel.from)||(from.line<oldFrom?changes.push({from:from.line,to:Math.min(to.line,oldFrom)+1}):changes.push({from:oldFrom,to:Math.min(oldTo,from.line)+1})),posEq(to,sel.to)||(to.line<oldTo?changes.push({from:Math.max(oldFrom,from.line),to:oldTo+1}):changes.push({from:Math.max(from.line,oldTo),to:to.line+1}))),sel.from=from,sel.to=to,selectionChanged=!0}}function skipHidden(pos,oldLine,oldCh){function getNonHidden(dir){for(var lNo=pos.line+dir,end=1==dir?doc.size:-1;lNo!=end;){var line=getLine(lNo);if(!line.hidden){var ch=pos.ch;return(ch>oldCh||ch>line.text.length)&&(ch=line.text.length),{line:lNo,ch:ch}}lNo+=dir}}var line=getLine(pos.line);return line.hidden?pos.line>=oldLine?getNonHidden(1)||getNonHidden(-1):getNonHidden(-1)||getNonHidden(1):pos}function setCursor(line,ch,user){var pos=clipPos({line:line,ch:ch||0});(user?setSelectionUser:setSelection)(pos,pos)}function clipLine(n){return Math.max(0,Math.min(n,doc.size-1))}function clipPos(pos){if(pos.line<0)return{line:0,ch:0};if(pos.line>=doc.size)return{line:doc.size-1,ch:getLine(doc.size-1).text.length};var ch=pos.ch,linelen=getLine(pos.line).text.length;return null==ch||ch>linelen?{line:pos.line,ch:linelen}:ch<0?{line:pos.line,ch:0}:pos}function findPosH(dir,unit){function findNextLine(){for(var l=line+dir,e=dir<0?-1:doc.size;l!=e;l+=dir){var lo=getLine(l);if(!lo.hidden)return line=l,lineObj=lo,!0}}function moveOnce(boundToLine){if(ch==(dir<0?0:lineObj.text.length)){if(boundToLine||!findNextLine())return!1;ch=dir<0?lineObj.text.length:0}else ch+=dir;return!0}var end=sel.inverted?sel.from:sel.to,line=end.line,ch=end.ch,lineObj=getLine(line);if("char"==unit)moveOnce();else if("column"==unit)moveOnce(!0);else if("word"==unit)for(var sawWord=!1;!(dir<0)||moveOnce();){if(isWordChar(lineObj.text.charAt(ch)))sawWord=!0;else if(sawWord){dir<0&&(dir=1,moveOnce());break}if(dir>0&&!moveOnce())break}return{line:line,ch:ch}}function moveH(dir,unit){var pos=dir<0?sel.from:sel.to;(shiftSelecting||posEq(sel.from,sel.to))&&(pos=findPosH(dir,unit)),setCursor(pos.line,pos.ch,!0)}function deleteH(dir,unit){posEq(sel.from,sel.to)?dir<0?replaceRange("",findPosH(dir,unit),sel.to):replaceRange("",sel.from,findPosH(dir,unit)):replaceRange("",sel.from,sel.to),userSelChange=!0}function moveV(dir,unit){var dist=0,pos=localCoords(sel.inverted?sel.from:sel.to,!0);null!=goalColumn&&(pos.x=goalColumn),"page"==unit?dist=scroller.clientHeight:"line"==unit&&(dist=textHeight());var target=coordsChar(pos.x,pos.y+dist*dir+2);setCursor(target.line,target.ch,!0),goalColumn=pos.x}function selectWordAt(pos){for(var line=getLine(pos.line).text,start=pos.ch,end=pos.ch;start>0&&isWordChar(line.charAt(start-1));)--start;for(;end<line.length&&isWordChar(line.charAt(end));)++end;setSelectionUser({line:pos.line,ch:start},{line:pos.line,ch:end})}function selectLine(line){setSelectionUser({line:line,ch:0},{line:line,ch:getLine(line).text.length})}function indentSelected(mode){if(posEq(sel.from,sel.to))return indentLine(sel.from.line,mode);for(var e=sel.to.line-(sel.to.ch?0:1),i=sel.from.line;i<=e;++i)indentLine(i,mode)}function indentLine(n,how){if(how||(how="add"),"smart"==how)if(mode.indent)var state=getStateBefore(n);else how="prev";var indentation,line=getLine(n),curSpace=line.indentation(options.tabSize),curSpaceString=line.text.match(/^\s*/)[0];"prev"==how?indentation=n?getLine(n-1).indentation(options.tabSize):0:"smart"==how?indentation=mode.indent(state,line.text.slice(curSpaceString.length),line.text):"add"==how?indentation=curSpace+options.indentUnit:"subtract"==how&&(indentation=curSpace-options.indentUnit),indentation=Math.max(0,indentation);var diff=indentation-curSpace;if(diff){var indentString="",pos=0;if(options.indentWithTabs)for(var i=Math.floor(indentation/options.tabSize);i;--i)pos+=options.tabSize,indentString+="\t";for(;pos<indentation;)++pos,indentString+=" "}else{if(sel.from.line!=n&&sel.to.line!=n)return;var indentString=curSpaceString}replaceRange(indentString,{line:n,ch:0},{line:n,ch:curSpaceString.length})}function loadMode(){mode=CodeMirror.getMode(options,options.mode),doc.iter(0,doc.size,function(line){line.stateAfter=null}),work=[0],startWorker()}function gutterChanged(){var visible=options.gutter||options.lineNumbers;gutter.style.display=visible?"":"none",visible?gutterDirty=!0:lineDiv.parentNode.style.marginLeft=0}function wrappingChanged(from,to){if(options.lineWrapping){wrapper.className+=" CodeMirror-wrap";var perLine=scroller.clientWidth/charWidth()-3;doc.iter(0,doc.size,function(line){if(!line.hidden){var guess=Math.ceil(line.text.length/perLine)||1;1!=guess&&updateLineHeight(line,guess)}}),lineSpace.style.width=code.style.width=""}else wrapper.className=wrapper.className.replace(" CodeMirror-wrap",""),maxWidth=null,maxLine="",doc.iter(0,doc.size,function(line){1==line.height||line.hidden||updateLineHeight(line,1),line.text.length>maxLine.length&&(maxLine=line.text)});changes.push({from:0,to:doc.size})}function computeTabText(){for(var str='<span class="cm-tab">',i=0;i<options.tabSize;++i)str+=" ";return str+"</span>"}function tabsChanged(){tabText=computeTabText(),updateDisplay(!0)}function themeChanged(){scroller.className=scroller.className.replace(/\s*cm-s-\w+/g,"")+options.theme.replace(/(^|\s)\s*/g," cm-s-")}function TextMarker(){this.set=[]}function markText(from,to,className){function add(line,from,to,className){getLine(line).addMark(new MarkedText(from,to,className,tm.set))}from=clipPos(from),to=clipPos(to);var tm=new TextMarker;if(from.line==to.line)add(from.line,from.ch,to.ch,className);else{add(from.line,from.ch,null,className);for(var i=from.line+1,e=to.line;i<e;++i)add(i,null,null,className);add(to.line,null,to.ch,className)}return changes.push({from:from.line,to:to.line+1}),tm}function setBookmark(pos){pos=clipPos(pos);var bm=new Bookmark(pos.ch);return getLine(pos.line).addMark(bm),bm}function addGutterMarker(line,text,className){return"number"==typeof line&&(line=getLine(clipLine(line))),line.gutterMarker={text:text,style:className},gutterDirty=!0,line}function removeGutterMarker(line){"number"==typeof line&&(line=getLine(clipLine(line))),line.gutterMarker=null,gutterDirty=!0}function changeLine(handle,op){var no=handle,line=handle;return"number"==typeof handle?line=getLine(clipLine(handle)):no=lineNo(handle),null==no?null:op(line,no)?(changes.push({from:no,to:no+1}),line):null}function setLineClass(handle,className){return changeLine(handle,function(line){if(line.className!=className)return line.className=className,!0})}function setLineHidden(handle,hidden){return changeLine(handle,function(line,no){if(line.hidden!=hidden)return line.hidden=hidden,updateLineHeight(line,hidden?0:1),!hidden||sel.from.line!=no&&sel.to.line!=no||setSelection(skipHidden(sel.from,sel.from.line,sel.from.ch),skipHidden(sel.to,sel.to.line,sel.to.ch)),gutterDirty=!0})}function lineInfo(line){if("number"==typeof line){if(!isLine(line))return null;var n=line;if(line=getLine(line),!line)return null}else{var n=lineNo(line);if(null==n)return null}var marker=line.gutterMarker;return{line:n,handle:line,text:line.text,markerText:marker&&marker.text,markerClass:marker&&marker.style,lineClass:line.className}}function stringWidth(str){return measure.innerHTML="<pre><span>x</span></pre>",measure.firstChild.firstChild.firstChild.nodeValue=str,measure.firstChild.firstChild.offsetWidth||10}function measureLine(line,ch){var extra="";if(options.lineWrapping){var end=line.text.indexOf(" ",ch+2);extra=htmlEscape(line.text.slice(ch+1,end<0?line.text.length:end+(ie?5:0)))}measure.innerHTML="<pre>"+line.getHTML(null,null,!1,tabText,ch)+'<span id="CodeMirror-temp-'+tempId+'">'+htmlEscape(line.text.charAt(ch)||" ")+"</span>"+extra+"</pre>";var elt=document.getElementById("CodeMirror-temp-"+tempId),top=elt.offsetTop,left=elt.offsetLeft;if(ie&&ch&&0==top&&0==left){var backup=document.createElement("span");backup.innerHTML="x",elt.parentNode.insertBefore(backup,elt.nextSibling),top=backup.offsetTop}return{top:top,left:left}}function localCoords(pos,inLineWrap){var x,lh=textHeight(),y=lh*(heightAtLine(doc,pos.line)-(inLineWrap?displayOffset:0));if(0==pos.ch)x=0;else{var sp=measureLine(getLine(pos.line),pos.ch);x=sp.left,options.lineWrapping&&(y+=Math.max(0,sp.top))}return{x:x,y:y,yBot:y+lh}}function coordsChar(x,y){function getX(len){var sp=measureLine(lineObj,len);if(tw){var off=Math.round(sp.top/th);return Math.max(0,sp.left+(off-innerOff)*scroller.clientWidth)}return sp.left}y<0&&(y=0);var th=textHeight(),cw=charWidth(),heightPos=displayOffset+Math.floor(y/th),lineNo=lineAtHeight(doc,heightPos);if(lineNo>=doc.size)return{line:doc.size-1,ch:getLine(doc.size-1).text.length};var lineObj=getLine(lineNo),text=lineObj.text,tw=options.lineWrapping,innerOff=tw?heightPos-heightAtLine(doc,lineNo):0;if(x<=0&&0==innerOff)return{line:lineNo,ch:0};for(var toX,from=0,fromX=0,to=text.length,estimated=Math.min(to,Math.ceil((x+innerOff*scroller.clientWidth*.9)/cw));;){var estX=getX(estimated);if(!(estX<=x&&estimated<to)){toX=estX,to=estimated;break}estimated=Math.min(to,Math.ceil(1.2*estimated))}if(x>toX)return{line:lineNo,ch:to};for(estimated=Math.floor(.8*to),estX=getX(estimated),estX<x&&(from=estimated,fromX=estX);;){if(to-from<=1)return{line:lineNo,ch:toX-x>x-fromX?from:to};var middle=Math.ceil((from+to)/2),middleX=getX(middle);middleX>x?(to=middle,toX=middleX):(from=middle,fromX=middleX)}}function pageCoords(pos){var local=localCoords(pos,!0),off=eltOffset(lineSpace);return{x:off.left+local.x,y:off.top+local.y,yBot:off.top+local.yBot}}function textHeight(){if(null==measureText){measureText="<pre>";for(var i=0;i<49;++i)measureText+="x<br/>";measureText+="x</pre>"}var offsetHeight=lineDiv.clientHeight;return offsetHeight==cachedHeightFor?cachedHeight:(cachedHeightFor=offsetHeight,measure.innerHTML=measureText,cachedHeight=measure.firstChild.offsetHeight/50||1,measure.innerHTML="",cachedHeight)}function charWidth(){return scroller.clientWidth==cachedWidthFor?cachedWidth:(cachedWidthFor=scroller.clientWidth,cachedWidth=stringWidth("x"))}function paddingTop(){return lineSpace.offsetTop}function paddingLeft(){return lineSpace.offsetLeft}function posFromMouse(e,liberal){var x,y,offW=eltOffset(scroller,!0);try{x=e.clientX,y=e.clientY}catch(e){return null}if(!liberal&&(x-offW.left>scroller.clientWidth||y-offW.top>scroller.clientHeight))return null;var offL=eltOffset(lineSpace,!0);return coordsChar(x-offL.left,y-offL.top)}function onContextMenu(e){function rehide(){var newVal=splitLines(input.value).join("\n");newVal!=val&&operation(replaceSelection)(newVal,"end"),inputDiv.style.position="relative",input.style.cssText=oldCSS,leaveInputAlone=!1,resetInput(!0),slowPoll()}var pos=posFromMouse(e);if(pos&&!window.opera){(posEq(sel.from,sel.to)||posLess(pos,sel.from)||!posLess(pos,sel.to))&&operation(setCursor)(pos.line,pos.ch);var oldCSS=input.style.cssText;inputDiv.style.position="absolute",input.style.cssText="position: fixed; width: 30px; height: 30px; top: "+(e.clientY-5)+"px; left: "+(e.clientX-5)+"px; z-index: 1000; background: white; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);",leaveInputAlone=!0;var val=input.value=getSelection();if(focusInput(),input.select(),gecko){e_stop(e);var mouseup=connect(window,"mouseup",function(){mouseup(),setTimeout(rehide,20)},!0)}else setTimeout(rehide,50)}}function restartBlink(){clearInterval(blinker);var on=!0;cursor.style.visibility="",blinker=setInterval(function(){cursor.style.visibility=(on=!on)?"":"hidden"},650)}function matchBrackets(autoclear){function scan(line,from,to){if(line.text)for(var cur,st=line.styles,pos=forward?0:line.text.length-1,i=forward?0:st.length-2,e=forward?st.length:-2;i!=e;i+=2*d){var text=st[i];if(null==st[i+1]||st[i+1]==style){for(var j=forward?0:text.length-1,te=forward?text.length:-1;j!=te;j+=d,pos+=d)if(pos>=from&&pos<to&&re.test(cur=text.charAt(j))){var match=matching[cur];if(">"==match.charAt(1)==forward)stack.push(cur);else{if(stack.pop()!=match.charAt(0))return{pos:pos,match:!1};if(!stack.length)return{pos:pos,match:!0}}}}else pos+=d*text.length}}var head=sel.inverted?sel.from:sel.to,line=getLine(head.line),pos=head.ch-1,match=pos>=0&&matching[line.text.charAt(pos)]||matching[line.text.charAt(++pos)];if(match){for(var forward=(match.charAt(0),">"==match.charAt(1)),d=forward?1:-1,st=line.styles,off=pos+1,i=0,e=st.length;i<e;i+=2)if((off-=st[i].length)<=0){
         | 
| 3 | 
            +
            var style=st[i+1];break}for(var stack=[line.text.charAt(pos)],re=/[(){}[\]]/,i=head.line,e=forward?Math.min(i+100,doc.size):Math.max(-1,i-100);i!=e;i+=d){var line=getLine(i),first=i==head.line,found=scan(line,first&&forward?pos+1:0,first&&!forward?pos:line.text.length);if(found)break}found||(found={pos:null,match:!1});var style=found.match?"CodeMirror-matchingbracket":"CodeMirror-nonmatchingbracket",one=markText({line:head.line,ch:pos},{line:head.line,ch:pos+1},style),two=null!=found.pos&&markText({line:i,ch:found.pos},{line:i,ch:found.pos+1},style),clear=operation(function(){one.clear(),two&&two.clear()});autoclear?setTimeout(clear,800):bracketHighlighted=clear}}function findStartLine(n){for(var minindent,minline,search=n,lim=n-40;search>lim;--search){if(0==search)return 0;var line=getLine(search-1);if(line.stateAfter)return search;var indented=line.indentation(options.tabSize);(null==minline||minindent>indented)&&(minline=search-1,minindent=indented)}return minline}function getStateBefore(n){var start=findStartLine(n),state=start&&getLine(start-1).stateAfter;return state=state?copyState(mode,state):startState(mode),doc.iter(start,n,function(line){line.highlight(mode,state,options.tabSize),line.stateAfter=copyState(mode,state)}),start<n&&changes.push({from:start,to:n}),n<doc.size&&!getLine(n).stateAfter&&work.push(n),state}function highlightLines(start,end){var state=getStateBefore(start);doc.iter(start,end,function(line){line.highlight(mode,state,options.tabSize),line.stateAfter=copyState(mode,state)})}function highlightWorker(){for(var end=+new Date+options.workTime,foundWork=work.length;work.length;){if(getLine(showingFrom).stateAfter)var task=work.pop();else var task=showingFrom;if(!(task>=doc.size)){var start=findStartLine(task),state=start&&getLine(start-1).stateAfter;state=state?copyState(mode,state):startState(mode);var unchanged=0,compare=mode.compareStates,realChange=!1,i=start,bail=!1;if(doc.iter(i,doc.size,function(line){var hadState=line.stateAfter;if(+new Date>end)return work.push(i),startWorker(options.workDelay),realChange&&changes.push({from:task,to:i+1}),bail=!0;var changed=line.highlight(mode,state,options.tabSize);if(changed&&(realChange=!0),line.stateAfter=copyState(mode,state),compare){if(hadState&&compare(hadState,state))return!0}else if(changed===!1&&hadState){if(++unchanged>3&&(!mode.indent||mode.indent(hadState,"")==mode.indent(state,"")))return!0}else unchanged=0;++i}),bail)return;realChange&&changes.push({from:task,to:i+1})}}foundWork&&options.onHighlightComplete&&options.onHighlightComplete(instance)}function startWorker(time){work.length&&highlight.set(time,operation(highlightWorker))}function startOperation(){updateInput=userSelChange=textChanged=null,changes=[],selectionChanged=!1,callbacks=[]}function endOperation(){var updated,reScroll=!1;selectionChanged&&(reScroll=!scrollCursorIntoView()),changes.length?updated=updateDisplay(changes,!0):(selectionChanged&&updateCursor(),gutterDirty&&updateGutter()),reScroll&&scrollCursorIntoView(),selectionChanged&&(scrollEditorIntoView(),restartBlink()),focused&&!leaveInputAlone&&(updateInput===!0||updateInput!==!1&&selectionChanged)&&resetInput(userSelChange),selectionChanged&&options.matchBrackets&&setTimeout(operation(function(){bracketHighlighted&&(bracketHighlighted(),bracketHighlighted=null),posEq(sel.from,sel.to)&&matchBrackets(!1)}),20);var tc=textChanged,cbs=callbacks;selectionChanged&&options.onCursorActivity&&options.onCursorActivity(instance),tc&&options.onChange&&instance&&options.onChange(instance,tc);for(var i=0;i<cbs.length;++i)cbs[i](instance);updated&&options.onUpdate&&options.onUpdate(instance)}function operation(f){return function(){nestedOperation++||startOperation();try{var result=f.apply(this,arguments)}finally{--nestedOperation||endOperation()}return result}}var options={},defaults=CodeMirror.defaults;for(var opt in defaults)defaults.hasOwnProperty(opt)&&(options[opt]=(givenOptions&&givenOptions.hasOwnProperty(opt)?givenOptions:defaults)[opt]);var targetDocument=options.document,wrapper=targetDocument.createElement("div");wrapper.className="CodeMirror"+(options.lineWrapping?" CodeMirror-wrap":""),wrapper.innerHTML='<div style="overflow: hidden; position: relative; width: 3px; height: 0px;"><textarea style="position: absolute; padding: 0; width: 1px;" wrap="off" autocorrect="off" autocapitalize="off"></textarea></div><div class="CodeMirror-scroll" tabindex="-1"><div style="position: relative"><div style="position: relative"><div class="CodeMirror-gutter"><div class="CodeMirror-gutter-text"></div></div><div class="CodeMirror-lines"><div style="position: relative"><div style="position: absolute; width: 100%; height: 0; overflow: hidden; visibility: hidden"></div><pre class="CodeMirror-cursor"> </pre><div></div></div></div></div></div></div>',place.appendChild?place.appendChild(wrapper):place(wrapper);var inputDiv=wrapper.firstChild,input=inputDiv.firstChild,scroller=wrapper.lastChild,code=scroller.firstChild,mover=code.firstChild,gutter=mover.firstChild,gutterText=gutter.firstChild,lineSpace=gutter.nextSibling.firstChild,measure=lineSpace.firstChild,cursor=measure.nextSibling,lineDiv=cursor.nextSibling;themeChanged(),/AppleWebKit/.test(navigator.userAgent)&&/Mobile\/\w+/.test(navigator.userAgent)&&(input.style.width="0px"),webkit||(lineSpace.draggable=!0),null!=options.tabindex&&(input.tabIndex=options.tabindex),options.gutter||options.lineNumbers||(gutter.style.display="none");try{stringWidth("x")}catch(e){throw e.message.match(/runtime/i)&&(e=new Error("A CodeMirror inside a P-style element does not work in Internet Explorer. (innerHTML bug)")),e}var blinker,mode,work,focused,poll=new Delayed,highlight=new Delayed,doc=new BranchChunk([new LeafChunk([new Line("")])]);loadMode();var shiftSelecting,lastClick,lastDoubleClick,draggingText,updateInput,userSelChange,changes,textChanged,selectionChanged,leaveInputAlone,gutterDirty,callbacks,bracketHighlighted,maxWidth,sel={from:{line:0,ch:0},to:{line:0,ch:0},inverted:!1},overwrite=!1,displayOffset=0,showingFrom=0,showingTo=0,lastSizeC=0,maxLine="",tabText=computeTabText();operation(function(){setValue(options.value||""),updateInput=!1})();var history=new History;connect(scroller,"mousedown",operation(onMouseDown)),connect(scroller,"dblclick",operation(onDoubleClick)),connect(lineSpace,"dragstart",onDragStart),connect(lineSpace,"selectstart",e_preventDefault),gecko||connect(scroller,"contextmenu",onContextMenu),connect(scroller,"scroll",function(){updateDisplay([]),options.fixedGutter&&(gutter.style.left=scroller.scrollLeft+"px"),options.onScroll&&options.onScroll(instance)}),connect(window,"resize",function(){updateDisplay(!0)}),connect(input,"keyup",operation(onKeyUp)),connect(input,"input",fastPoll),connect(input,"keydown",operation(onKeyDown)),connect(input,"keypress",operation(onKeyPress)),connect(input,"focus",onFocus),connect(input,"blur",onBlur),connect(scroller,"dragenter",e_stop),connect(scroller,"dragover",e_stop),connect(scroller,"drop",operation(onDrop)),connect(scroller,"paste",function(){focusInput(),fastPoll()}),connect(input,"paste",fastPoll),connect(input,"cut",operation(function(){replaceSelection("")}));var hasFocus;try{hasFocus=targetDocument.activeElement==input}catch(e){}hasFocus?setTimeout(onFocus,20):onBlur();var instance=wrapper.CodeMirror={getValue:getValue,setValue:operation(setValue),getSelection:getSelection,replaceSelection:operation(replaceSelection),focus:function(){focusInput(),onFocus(),fastPoll()},setOption:function(option,value){var oldVal=options[option];options[option]=value,"mode"==option||"indentUnit"==option?loadMode():"readOnly"==option&&value?(onBlur(),input.blur()):"theme"==option?themeChanged():"lineWrapping"==option&&oldVal!=value?operation(wrappingChanged)():"tabSize"==option&&operation(tabsChanged)(),"lineNumbers"!=option&&"gutter"!=option&&"firstLineNumber"!=option&&"theme"!=option||operation(gutterChanged)()},getOption:function(option){return options[option]},undo:operation(undo),redo:operation(redo),indentLine:operation(function(n,dir){isLine(n)&&indentLine(n,null==dir?"smart":dir?"add":"subtract")}),indentSelection:operation(indentSelected),historySize:function(){return{undo:history.done.length,redo:history.undone.length}},clearHistory:function(){history=new History},matchBrackets:operation(function(){matchBrackets(!0)}),getTokenAt:operation(function(pos){return pos=clipPos(pos),getLine(pos.line).getTokenAt(mode,getStateBefore(pos.line),pos.ch)}),getStateAfter:function(line){return line=clipLine(null==line?doc.size-1:line),getStateBefore(line+1)},cursorCoords:function(start){return null==start&&(start=sel.inverted),pageCoords(start?sel.from:sel.to)},charCoords:function(pos){return pageCoords(clipPos(pos))},coordsChar:function(coords){var off=eltOffset(lineSpace);return coordsChar(coords.x-off.left,coords.y-off.top)},markText:operation(markText),setBookmark:setBookmark,setMarker:operation(addGutterMarker),clearMarker:operation(removeGutterMarker),setLineClass:operation(setLineClass),hideLine:operation(function(h){return setLineHidden(h,!0)}),showLine:operation(function(h){return setLineHidden(h,!1)}),onDeleteLine:function(line,f){if("number"==typeof line){if(!isLine(line))return null;line=getLine(line)}return(line.handlers||(line.handlers=[])).push(f),line},lineInfo:lineInfo,addWidget:function(pos,node,scroll,vert,horiz){pos=localCoords(clipPos(pos));var top=pos.yBot,left=pos.x;if(node.style.position="absolute",code.appendChild(node),"over"==vert)top=pos.y;else if("near"==vert){var vspace=Math.max(scroller.offsetHeight,doc.height*textHeight()),hspace=Math.max(code.clientWidth,lineSpace.clientWidth)-paddingLeft();pos.yBot+node.offsetHeight>vspace&&pos.y>node.offsetHeight&&(top=pos.y-node.offsetHeight),left+node.offsetWidth>hspace&&(left=hspace-node.offsetWidth)}node.style.top=top+paddingTop()+"px",node.style.left=node.style.right="","right"==horiz?(left=code.clientWidth-node.offsetWidth,node.style.right="0px"):("left"==horiz?left=0:"middle"==horiz&&(left=(code.clientWidth-node.offsetWidth)/2),node.style.left=left+paddingLeft()+"px"),scroll&&scrollIntoView(left,top,left+node.offsetWidth,top+node.offsetHeight)},lineCount:function(){return doc.size},clipPos:clipPos,getCursor:function(start){return null==start&&(start=sel.inverted),copyPos(start?sel.from:sel.to)},somethingSelected:function(){return!posEq(sel.from,sel.to)},setCursor:operation(function(line,ch,user){null==ch&&"number"==typeof line.line?setCursor(line.line,line.ch,user):setCursor(line,ch,user)}),setSelection:operation(function(from,to,user){(user?setSelectionUser:setSelection)(clipPos(from),clipPos(to||from))}),getLine:function(line){if(isLine(line))return getLine(line).text},getLineHandle:function(line){if(isLine(line))return getLine(line)},setLine:operation(function(line,text){isLine(line)&&replaceRange(text,{line:line,ch:0},{line:line,ch:getLine(line).text.length})}),removeLine:operation(function(line){isLine(line)&&replaceRange("",{line:line,ch:0},clipPos({line:line+1,ch:0}))}),replaceRange:operation(replaceRange),getRange:function(from,to){return getRange(clipPos(from),clipPos(to))},execCommand:function(cmd){return commands[cmd](instance)},moveH:operation(moveH),deleteH:operation(deleteH),moveV:operation(moveV),toggleOverwrite:function(){overwrite=!overwrite},posFromIndex:function(off){var ch,lineNo=0;return doc.iter(0,doc.size,function(line){var sz=line.text.length+1;return sz>off?(ch=off,!0):(off-=sz,void++lineNo)}),clipPos({line:lineNo,ch:ch})},indexFromPos:function(coords){if(coords.line<0||coords.ch<0)return 0;var index=coords.ch;return doc.iter(0,coords.line,function(line){index+=line.text.length+1}),index},operation:function(f){return operation(f)()},refresh:function(){updateDisplay(!0)},getInputField:function(){return input},getWrapperElement:function(){return wrapper},getScrollerElement:function(){return scroller},getGutterElement:function(){return gutter}},lastStoppedKey=null,pollingFast=!1,prevInput="",goalColumn=null;TextMarker.prototype.clear=operation(function(){for(var min=1/0,max=-(1/0),i=0,e=this.set.length;i<e;++i){var line=this.set[i],mk=line.marked;if(mk&&line.parent){var lineN=lineNo(line);min=Math.min(min,lineN),max=Math.max(max,lineN);for(var j=0;j<mk.length;++j)mk[j].set==this.set&&mk.splice(j--,1)}}min!=1/0&&changes.push({from:min,to:max+1})}),TextMarker.prototype.find=function(){for(var from,to,i=0,e=this.set.length;i<e;++i)for(var line=this.set[i],mk=line.marked,j=0;j<mk.length;++j){var mark=mk[j];if(mark.set==this.set&&(null!=mark.from||null!=mark.to)){var found=lineNo(line);null!=found&&(null!=mark.from&&(from={line:found,ch:mark.from}),null!=mark.to&&(to={line:found,ch:mark.to}))}}return{from:from,to:to}};var cachedHeight,cachedHeightFor,measureText,cachedWidth,tempId=Math.floor(16777215*Math.random()).toString(16),cachedWidthFor=0,matching={"(":")>",")":"(<","[":"]>","]":"[<","{":"}>","}":"{<"},nestedOperation=0;for(var ext in extensions)extensions.propertyIsEnumerable(ext)&&!instance.propertyIsEnumerable(ext)&&(instance[ext]=extensions[ext]);return instance}function lookupKey(name,extraMap,map){function lookup(name,map,ft){var found=map[name];if(null!=found)return found;if(null==ft&&(ft=map.fallthrough),null==ft)return map.catchall;if("string"==typeof ft)return lookup(name,keyMap[ft]);for(var i=0,e=ft.length;i<e;++i)if(found=lookup(name,keyMap[ft[i]]),null!=found)return found;return null}return extraMap?lookup(name,extraMap,map):lookup(name,keyMap[map])}function isModifierKey(event){var name=keyNames[event.keyCode];return"Ctrl"==name||"Alt"==name||"Shift"==name||"Mod"==name}function copyState(mode,state){if(state===!0)return state;if(mode.copyState)return mode.copyState(state);var nstate={};for(var n in state){var val=state[n];val instanceof Array&&(val=val.concat([])),nstate[n]=val}return nstate}function startState(mode,a1,a2){return!mode.startState||mode.startState(a1,a2)}function StringStream(string,tabSize){this.pos=this.start=0,this.string=string,this.tabSize=tabSize||8}function MarkedText(from,to,className,set){this.from=from,this.to=to,this.style=className,this.set=set}function Bookmark(pos){this.from=pos,this.to=pos,this.line=null}function Line(text,styles){this.styles=styles||[text,null],this.text=text,this.height=1,this.marked=this.gutterMarker=this.className=this.handlers=null,this.stateAfter=this.parent=this.hidden=null}function copyStyles(from,to,source,dest){for(var i=0,pos=0,state=0;pos<to;i+=2){var part=source[i],end=pos+part.length;0==state?(end>from&&dest.push(part.slice(from-pos,Math.min(part.length,to-pos)),source[i+1]),end>=from&&(state=1)):1==state&&(end>to?dest.push(part.slice(0,to-pos),source[i+1]):dest.push(part,source[i+1])),pos=end}}function LeafChunk(lines){this.lines=lines,this.parent=null;for(var i=0,e=lines.length,height=0;i<e;++i)lines[i].parent=this,height+=lines[i].height;this.height=height}function BranchChunk(children){this.children=children;for(var size=0,height=0,i=0,e=children.length;i<e;++i){var ch=children[i];size+=ch.chunkSize(),height+=ch.height,ch.parent=this}this.size=size,this.height=height,this.parent=null}function getLineAt(chunk,n){for(;!chunk.lines;)for(var i=0;;++i){var child=chunk.children[i],sz=child.chunkSize();if(n<sz){chunk=child;break}n-=sz}return chunk.lines[n]}function lineNo(line){if(null==line.parent)return null;for(var cur=line.parent,no=indexOf(cur.lines,line),chunk=cur.parent;chunk;cur=chunk,chunk=chunk.parent){var i=0;for(chunk.children.length;chunk.children[i]!=cur;++i)no+=chunk.children[i].chunkSize()}return no}function lineAtHeight(chunk,h){var n=0;outer:do{for(var i=0,e=chunk.children.length;i<e;++i){var child=chunk.children[i],ch=child.height;if(h<ch){chunk=child;continue outer}h-=ch,n+=child.chunkSize()}return n}while(!chunk.lines);for(var i=0,e=chunk.lines.length;i<e;++i){var line=chunk.lines[i],lh=line.height;if(h<lh)break;h-=lh}return n+i}function heightAtLine(chunk,n){var h=0;outer:do{for(var i=0,e=chunk.children.length;i<e;++i){var child=chunk.children[i],sz=child.chunkSize();if(n<sz){chunk=child;continue outer}n-=sz,h+=child.height}return h}while(!chunk.lines);for(var i=0;i<n;++i)h+=chunk.lines[i].height;return h}function History(){this.time=0,this.done=[],this.undone=[]}function stopMethod(){e_stop(this)}function addStop(event){return event.stop||(event.stop=stopMethod),event}function e_preventDefault(e){e.preventDefault?e.preventDefault():e.returnValue=!1}function e_stopPropagation(e){e.stopPropagation?e.stopPropagation():e.cancelBubble=!0}function e_stop(e){e_preventDefault(e),e_stopPropagation(e)}function e_target(e){return e.target||e.srcElement}function e_button(e){return e.which?e.which:1&e.button?1:2&e.button?3:4&e.button?2:void 0}function connect(node,type,handler,disconnect){if("function"==typeof node.addEventListener){if(node.addEventListener(type,handler,!1),disconnect)return function(){node.removeEventListener(type,handler,!1)}}else{var wrapHandler=function(event){handler(event||window.event)};if(node.attachEvent("on"+type,wrapHandler),disconnect)return function(){node.detachEvent("on"+type,wrapHandler)}}}function Delayed(){this.id=null}function countColumn(string,end,tabSize){null==end&&(end=string.search(/[^\s\u00a0]/),end==-1&&(end=string.length));for(var i=0,n=0;i<end;++i)"\t"==string.charAt(i)?n+=tabSize-n%tabSize:++n;return n}function computedStyle(elt){return elt.currentStyle?elt.currentStyle:window.getComputedStyle(elt,null)}function eltOffset(node,screen){for(var bod=node.ownerDocument.body,x=0,y=0,skipBody=!1,n=node;n;n=n.offsetParent){var ol=n.offsetLeft,ot=n.offsetTop;n==bod?(x+=Math.abs(ol),y+=Math.abs(ot)):(x+=ol,y+=ot),screen&&"fixed"==computedStyle(n).position&&(skipBody=!0)}for(var e=screen&&!skipBody?null:bod,n=node.parentNode;n!=e;n=n.parentNode)null!=n.scrollLeft&&(x-=n.scrollLeft,y-=n.scrollTop);return{left:x,top:y}}function eltText(node){return node.textContent||node.innerText||node.nodeValue||""}function posEq(a,b){return a.line==b.line&&a.ch==b.ch}function posLess(a,b){return a.line<b.line||a.line==b.line&&a.ch<b.ch}function copyPos(x){return{line:x.line,ch:x.ch}}function htmlEscape(str){return escapeElement.textContent=str,escapeElement.innerHTML}function editEnd(from,to){if(!to)return from?from.length:0;if(!from)return to.length;for(var i=from.length,j=to.length;i>=0&&j>=0&&from.charAt(i)==to.charAt(j);--i,--j);return j+1}function indexOf(collection,elt){if(collection.indexOf)return collection.indexOf(elt);for(var i=0,e=collection.length;i<e;++i)if(collection[i]==elt)return i;return-1}function isWordChar(ch){return/\w/.test(ch)||ch.toUpperCase()!=ch.toLowerCase()}CodeMirror.defaults={value:"",mode:null,theme:"default",indentUnit:2,indentWithTabs:!1,tabSize:4,keyMap:"default",extraKeys:null,electricChars:!0,onKeyEvent:null,lineWrapping:!1,lineNumbers:!1,gutter:!1,fixedGutter:!1,firstLineNumber:1,readOnly:!1,onChange:null,onCursorActivity:null,onGutterClick:null,onHighlightComplete:null,onUpdate:null,onFocus:null,onBlur:null,onScroll:null,matchBrackets:!1,workTime:100,workDelay:200,pollInterval:100,undoDepth:40,tabindex:null,document:window.document};var mac=/Mac/.test(navigator.platform),modes=(/Win/.test(navigator.platform),{}),mimeModes={};CodeMirror.defineMode=function(name,mode){CodeMirror.defaults.mode||"null"==name||(CodeMirror.defaults.mode=name),modes[name]=mode},CodeMirror.defineMIME=function(mime,spec){mimeModes[mime]=spec},CodeMirror.getMode=function(options,spec){if("string"==typeof spec&&mimeModes.hasOwnProperty(spec)&&(spec=mimeModes[spec]),"string"==typeof spec)var mname=spec,config={};else if(null!=spec)var mname=spec.name,config=spec;var mfactory=modes[mname];return mfactory?mfactory(options,config||{}):(window.console&&console.warn("No mode "+mname+" found, falling back to plain text."),CodeMirror.getMode(options,"text/plain"))},CodeMirror.listModes=function(){var list=[];for(var m in modes)modes.propertyIsEnumerable(m)&&list.push(m);return list},CodeMirror.listMIMEs=function(){var list=[];for(var m in mimeModes)mimeModes.propertyIsEnumerable(m)&&list.push({mime:m,mode:mimeModes[m]});return list};var extensions=CodeMirror.extensions={};CodeMirror.defineExtension=function(name,func){extensions[name]=func};var commands=CodeMirror.commands={selectAll:function(cm){cm.setSelection({line:0,ch:0},{line:cm.lineCount()-1})},killLine:function(cm){var from=cm.getCursor(!0),to=cm.getCursor(!1),sel=!posEq(from,to);sel||cm.getLine(from.line).length!=from.ch?cm.replaceRange("",from,sel?to:{line:from.line}):cm.replaceRange("",from,{line:from.line+1,ch:0})},deleteLine:function(cm){var l=cm.getCursor().line;cm.replaceRange("",{line:l,ch:0},{line:l})},undo:function(cm){cm.undo()},redo:function(cm){cm.redo()},goDocStart:function(cm){cm.setCursor(0,0,!0)},goDocEnd:function(cm){cm.setSelection({line:cm.lineCount()-1},null,!0)},goLineStart:function(cm){cm.setCursor(cm.getCursor().line,0,!0)},goLineStartSmart:function(cm){var cur=cm.getCursor(),text=cm.getLine(cur.line),firstNonWS=Math.max(0,text.search(/\S/));cm.setCursor(cur.line,cur.ch<=firstNonWS&&cur.ch?0:firstNonWS,!0)},goLineEnd:function(cm){cm.setSelection({line:cm.getCursor().line},null,!0)},goLineUp:function(cm){cm.moveV(-1,"line")},goLineDown:function(cm){cm.moveV(1,"line")},goPageUp:function(cm){cm.moveV(-1,"page")},goPageDown:function(cm){cm.moveV(1,"page")},goCharLeft:function(cm){cm.moveH(-1,"char")},goCharRight:function(cm){cm.moveH(1,"char")},goColumnLeft:function(cm){cm.moveH(-1,"column")},goColumnRight:function(cm){cm.moveH(1,"column")},goWordLeft:function(cm){cm.moveH(-1,"word")},goWordRight:function(cm){cm.moveH(1,"word")},delCharLeft:function(cm){cm.deleteH(-1,"char")},delCharRight:function(cm){cm.deleteH(1,"char")},delWordLeft:function(cm){cm.deleteH(-1,"word")},delWordRight:function(cm){cm.deleteH(1,"word")},indentAuto:function(cm){cm.indentSelection("smart")},indentMore:function(cm){cm.indentSelection("add")},indentLess:function(cm){cm.indentSelection("subtract")},insertTab:function(cm){cm.replaceSelection("\t","end")},transposeChars:function(cm){var cur=cm.getCursor(),line=cm.getLine(cur.line);cur.ch>0&&cur.ch<line.length-1&&cm.replaceRange(line.charAt(cur.ch)+line.charAt(cur.ch-1),{line:cur.line,ch:cur.ch-1},{line:cur.line,ch:cur.ch+1})},newlineAndIndent:function(cm){cm.replaceSelection("\n","end"),cm.indentLine(cm.getCursor().line)},toggleOverwrite:function(cm){cm.toggleOverwrite()}},keyMap=CodeMirror.keyMap={};keyMap.basic={Left:"goCharLeft",Right:"goCharRight",Up:"goLineUp",Down:"goLineDown",End:"goLineEnd",Home:"goLineStartSmart",PageUp:"goPageUp",PageDown:"goPageDown",Delete:"delCharRight",Backspace:"delCharLeft",Tab:"indentMore","Shift-Tab":"indentLess",Enter:"newlineAndIndent",Insert:"toggleOverwrite"},keyMap.pcDefault={"Ctrl-A":"selectAll","Ctrl-D":"deleteLine","Ctrl-Z":"undo","Shift-Ctrl-Z":"redo","Ctrl-Y":"redo","Ctrl-Home":"goDocStart","Alt-Up":"goDocStart","Ctrl-End":"goDocEnd","Ctrl-Down":"goDocEnd","Ctrl-Left":"goWordLeft","Ctrl-Right":"goWordRight","Alt-Left":"goLineStart","Alt-Right":"goLineEnd","Ctrl-Backspace":"delWordLeft","Ctrl-Delete":"delWordRight","Ctrl-S":"save","Ctrl-F":"find","Ctrl-G":"findNext","Shift-Ctrl-G":"findPrev","Shift-Ctrl-F":"replace","Shift-Ctrl-R":"replaceAll",fallthrough:"basic"},keyMap.macDefault={"Cmd-A":"selectAll","Cmd-D":"deleteLine","Cmd-Z":"undo","Shift-Cmd-Z":"redo","Cmd-Y":"redo","Cmd-Up":"goDocStart","Cmd-End":"goDocEnd","Cmd-Down":"goDocEnd","Alt-Left":"goWordLeft","Alt-Right":"goWordRight","Cmd-Left":"goLineStart","Cmd-Right":"goLineEnd","Alt-Backspace":"delWordLeft","Ctrl-Alt-Backspace":"delWordRight","Alt-Delete":"delWordRight","Cmd-S":"save","Cmd-F":"find","Cmd-G":"findNext","Shift-Cmd-G":"findPrev","Cmd-Alt-F":"replace","Shift-Cmd-Alt-F":"replaceAll",fallthrough:["basic","emacsy"]},keyMap["default"]=mac?keyMap.macDefault:keyMap.pcDefault,keyMap.emacsy={"Ctrl-F":"goCharRight","Ctrl-B":"goCharLeft","Ctrl-P":"goLineUp","Ctrl-N":"goLineDown","Alt-F":"goWordRight","Alt-B":"goWordLeft","Ctrl-A":"goLineStart","Ctrl-E":"goLineEnd","Ctrl-V":"goPageUp","Shift-Ctrl-V":"goPageDown","Ctrl-D":"delCharRight","Ctrl-H":"delCharLeft","Alt-D":"delWordRight","Alt-Backspace":"delWordLeft","Ctrl-K":"killLine","Ctrl-T":"transposeChars"},CodeMirror.fromTextArea=function(textarea,options){function save(){textarea.value=instance.getValue()}function wrappedSubmit(){save(),textarea.form.submit=realSubmit,textarea.form.submit(),textarea.form.submit=wrappedSubmit}if(options||(options={}),options.value=textarea.value,!options.tabindex&&textarea.tabindex&&(options.tabindex=textarea.tabindex),textarea.form){var rmSubmit=connect(textarea.form,"submit",save,!0);if("function"==typeof textarea.form.submit){var realSubmit=textarea.form.submit;textarea.form.submit=wrappedSubmit}}textarea.style.display="none";var instance=CodeMirror(function(node){textarea.parentNode.insertBefore(node,textarea.nextSibling)},options);return instance.save=save,instance.getTextArea=function(){return textarea},instance.toTextArea=function(){save(),textarea.parentNode.removeChild(instance.getWrapperElement()),textarea.style.display="",textarea.form&&(rmSubmit(),"function"==typeof textarea.form.submit&&(textarea.form.submit=realSubmit))},instance},CodeMirror.copyState=copyState,CodeMirror.startState=startState,StringStream.prototype={eol:function(){return this.pos>=this.string.length},sol:function(){return 0==this.pos},peek:function(){return this.string.charAt(this.pos)},next:function(){if(this.pos<this.string.length)return this.string.charAt(this.pos++)},eat:function(match){var ch=this.string.charAt(this.pos);if("string"==typeof match)var ok=ch==match;else var ok=ch&&(match.test?match.test(ch):match(ch));if(ok)return++this.pos,ch},eatWhile:function(match){for(var start=this.pos;this.eat(match););return this.pos>start},eatSpace:function(){for(var start=this.pos;/[\s\u00a0]/.test(this.string.charAt(this.pos));)++this.pos;return this.pos>start},skipToEnd:function(){this.pos=this.string.length},skipTo:function(ch){var found=this.string.indexOf(ch,this.pos);if(found>-1)return this.pos=found,!0},backUp:function(n){this.pos-=n},column:function(){return countColumn(this.string,this.start,this.tabSize)},indentation:function(){return countColumn(this.string,null,this.tabSize)},match:function(pattern,consume,caseInsensitive){function cased(str){return caseInsensitive?str.toLowerCase():str}if("string"!=typeof pattern){var match=this.string.slice(this.pos).match(pattern);return match&&consume!==!1&&(this.pos+=match[0].length),match}if(cased(this.string).indexOf(cased(pattern),this.pos)==this.pos)return consume!==!1&&(this.pos+=pattern.length),!0},current:function(){return this.string.slice(this.start,this.pos)}},CodeMirror.StringStream=StringStream,MarkedText.prototype={attach:function(line){this.set.push(line)},detach:function(line){var ix=indexOf(this.set,line);ix>-1&&this.set.splice(ix,1)},split:function(pos,lenBefore){if(this.to<=pos&&null!=this.to)return null;var from=this.from<pos||null==this.from?null:this.from-pos+lenBefore,to=null==this.to?null:this.to-pos+lenBefore;return new MarkedText(from,to,this.style,this.set)},dup:function(){return new MarkedText(null,null,this.style,this.set)},clipTo:function(fromOpen,from,toOpen,to,diff){null!=this.from&&this.from>=from&&(this.from=Math.max(to,this.from)+diff),null!=this.to&&this.to>from&&(this.to=to<this.to?this.to+diff:from),fromOpen&&to>this.from&&(to<this.to||null==this.to)&&(this.from=null),toOpen&&(from<this.to||null==this.to)&&(from>this.from||null==this.from)&&(this.to=null)},isDead:function(){return null!=this.from&&null!=this.to&&this.from>=this.to},sameSet:function(x){return this.set==x.set}},Bookmark.prototype={attach:function(line){this.line=line},detach:function(line){this.line==line&&(this.line=null)},split:function(pos,lenBefore){if(pos<this.from)return this.from=this.to=this.from-pos+lenBefore,this},isDead:function(){return this.from>this.to},clipTo:function(fromOpen,from,toOpen,to,diff){(fromOpen||from<this.from)&&(toOpen||to>this.to)?(this.from=0,this.to=-1):this.from>from&&(this.from=this.to=Math.max(to,this.from)+diff)},sameSet:function(x){return!1},find:function(){return this.line&&this.line.parent?{line:lineNo(this.line),ch:this.from}:null},clear:function(){if(this.line){var found=indexOf(this.line.marked,this);found!=-1&&this.line.marked.splice(found,1),this.line=null}}},Line.inheritMarks=function(text,orig){var ln=new Line(text),mk=orig&&orig.marked;if(mk)for(var i=0;i<mk.length;++i)if(null==mk[i].to&&mk[i].style){var newmk=ln.marked||(ln.marked=[]),mark=mk[i],nmark=mark.dup();newmk.push(nmark),nmark.attach(ln)}return ln},Line.prototype={replace:function(from,to_,text){var st=[],mk=this.marked,to=null==to_?this.text.length:to_;if(copyStyles(0,from,this.styles,st),text&&st.push(text,null),copyStyles(to,this.text.length,this.styles,st),this.styles=st,this.text=this.text.slice(0,from)+text+this.text.slice(to),this.stateAfter=null,mk)for(var diff=text.length-(to-from),i=0,mark=mk[i];i<mk.length;++i)mark.clipTo(null==from,from||0,null==to_,to,diff),mark.isDead()&&(mark.detach(this),mk.splice(i--,1))},split:function(pos,textBefore){var st=[textBefore,null],mk=this.marked;copyStyles(pos,this.text.length,this.styles,st);var taken=new Line(textBefore+this.text.slice(pos),st);if(mk)for(var i=0;i<mk.length;++i){var mark=mk[i],newmark=mark.split(pos,textBefore.length);newmark&&(taken.marked||(taken.marked=[]),taken.marked.push(newmark),newmark.attach(taken))}return taken},append:function(line){var mylen=this.text.length,mk=line.marked,mymk=this.marked;if(this.text+=line.text,copyStyles(0,line.text.length,line.styles,this.styles),mymk)for(var i=0;i<mymk.length;++i)null==mymk[i].to&&(mymk[i].to=mylen);if(mk&&mk.length){mymk||(this.marked=mymk=[]);outer:for(var i=0;i<mk.length;++i){var mark=mk[i];if(!mark.from)for(var j=0;j<mymk.length;++j){var mymark=mymk[j];if(mymark.to==mylen&&mymark.sameSet(mark)){mymark.to=null==mark.to?null:mark.to+mylen,mymark.isDead()&&(mymark.detach(this),mk.splice(i--,1));continue outer}}mymk.push(mark),mark.attach(this),mark.from+=mylen,null!=mark.to&&(mark.to+=mylen)}}},fixMarkEnds:function(other){var mk=this.marked,omk=other.marked;if(mk)for(var i=0;i<mk.length;++i){var mark=mk[i],close=null==mark.to;if(close&&omk)for(var j=0;j<omk.length;++j)if(omk[j].sameSet(mark)){close=!1;break}close&&(mark.to=this.text.length)}},fixMarkStarts:function(){var mk=this.marked;if(mk)for(var i=0;i<mk.length;++i)null==mk[i].from&&(mk[i].from=0)},addMark:function(mark){mark.attach(this),null==this.marked&&(this.marked=[]),this.marked.push(mark),this.marked.sort(function(a,b){return(a.from||0)-(b.from||0)})},highlight:function(mode,state,tabSize){var prevWord,stream=new StringStream(this.text,tabSize),st=this.styles,pos=0,changed=!1,curWord=st[0];for(""==this.text&&mode.blankLine&&mode.blankLine(state);!stream.eol();){var style=mode.token(stream,state),substr=this.text.slice(stream.start,stream.pos);if(stream.start=stream.pos,pos&&st[pos-1]==style?st[pos-2]+=substr:substr&&(!changed&&(st[pos+1]!=style||pos&&st[pos-2]!=prevWord)&&(changed=!0),st[pos++]=substr,st[pos++]=style,prevWord=curWord,curWord=st[pos]),stream.pos>5e3){st[pos++]=this.text.slice(stream.pos),st[pos++]=null;break}}return st.length!=pos&&(st.length=pos,changed=!0),pos&&st[pos-2]!=prevWord&&(changed=!0),changed||st.length<5&&this.text.length<10&&null},getTokenAt:function(mode,state,ch){for(var txt=this.text,stream=new StringStream(txt);stream.pos<ch&&!stream.eol();){stream.start=stream.pos;var style=mode.token(stream,state)}return{start:stream.start,end:stream.pos,string:stream.current(),className:style||null,state:state}},indentation:function(tabSize){return countColumn(this.text,null,tabSize)},getHTML:function(sfrom,sto,includePre,tabText,endAt){function span(text,style){text&&(first&&ie&&" "==text.charAt(0)&&(text=" "+text.slice(1)),first=!1,style?html.push('<span class="',style,'">',htmlEscape(text).replace(/\t/g,tabText),"</span>"):html.push(htmlEscape(text).replace(/\t/g,tabText)))}function nextMark(){
         | 
| 4 | 
            +
            marked&&(markpos+=1,mark=markpos<marked.length?marked[markpos]:null)}var html=[],first=!0;includePre&&html.push(this.className?'<pre class="'+this.className+'">':"<pre>");var st=this.styles,allText=this.text,marked=this.marked;sfrom==sto&&(sfrom=null);var len=allText.length;if(null!=endAt&&(len=Math.min(endAt,len)),allText||null!=endAt)if(marked||null!=sfrom){var style,pos=0,i=0,text="",markpos=-1,mark=null;for(nextMark();pos<len;){var upto=len,extraStyle="";for(null!=sfrom&&(sfrom>pos?upto=sfrom:(null==sto||sto>pos)&&(extraStyle=" CodeMirror-selected",null!=sto&&(upto=Math.min(upto,sto))));mark&&null!=mark.to&&mark.to<=pos;)nextMark();for(mark&&(mark.from>pos?upto=Math.min(upto,mark.from):(extraStyle+=" "+mark.style,null!=mark.to&&(upto=Math.min(upto,mark.to))));;){var end=pos+text.length,appliedStyle=style;if(extraStyle&&(appliedStyle=style?style+extraStyle:extraStyle),span(end>upto?text.slice(0,upto-pos):text,appliedStyle),end>=upto){text=text.slice(upto-pos),pos=upto;break}pos=end,text=st[i++],style="cm-"+st[i++]}}null!=sfrom&&null==sto&&span(" ","CodeMirror-selected")}else for(var i=0,ch=0;ch<len;i+=2){var str=st[i],style=st[i+1],l=str.length;ch+l>len&&(str=str.slice(0,len-ch)),ch+=l,span(str,style&&"cm-"+style)}else span(" ",null!=sfrom&&null==sto?"CodeMirror-selected":null);return includePre&&html.push("</pre>"),html.join("")},cleanUp:function(){if(this.parent=null,this.marked)for(var i=0,e=this.marked.length;i<e;++i)this.marked[i].detach(this)}},LeafChunk.prototype={chunkSize:function(){return this.lines.length},remove:function(at,n,callbacks){for(var i=at,e=at+n;i<e;++i){var line=this.lines[i];if(this.height-=line.height,line.cleanUp(),line.handlers)for(var j=0;j<line.handlers.length;++j)callbacks.push(line.handlers[j])}this.lines.splice(at,n)},collapse:function(lines){lines.splice.apply(lines,[lines.length,0].concat(this.lines))},insertHeight:function(at,lines,height){this.height+=height,this.lines.splice.apply(this.lines,[at,0].concat(lines));for(var i=0,e=lines.length;i<e;++i)lines[i].parent=this},iterN:function(at,n,op){for(var e=at+n;at<e;++at)if(op(this.lines[at]))return!0}},BranchChunk.prototype={chunkSize:function(){return this.size},remove:function(at,n,callbacks){this.size-=n;for(var i=0;i<this.children.length;++i){var child=this.children[i],sz=child.chunkSize();if(at<sz){var rm=Math.min(n,sz-at),oldHeight=child.height;if(child.remove(at,rm,callbacks),this.height-=oldHeight-child.height,sz==rm&&(this.children.splice(i--,1),child.parent=null),0==(n-=rm))break;at=0}else at-=sz}if(this.size-n<25){var lines=[];this.collapse(lines),this.children=[new LeafChunk(lines)]}},collapse:function(lines){for(var i=0,e=this.children.length;i<e;++i)this.children[i].collapse(lines)},insert:function(at,lines){for(var height=0,i=0,e=lines.length;i<e;++i)height+=lines[i].height;this.insertHeight(at,lines,height)},insertHeight:function(at,lines,height){this.size+=lines.length,this.height+=height;for(var i=0,e=this.children.length;i<e;++i){var child=this.children[i],sz=child.chunkSize();if(at<=sz){if(child.insertHeight(at,lines,height),child.lines&&child.lines.length>50){for(;child.lines.length>50;){var spilled=child.lines.splice(child.lines.length-25,25),newleaf=new LeafChunk(spilled);child.height-=newleaf.height,this.children.splice(i+1,0,newleaf),newleaf.parent=this}this.maybeSpill()}break}at-=sz}},maybeSpill:function(){if(!(this.children.length<=10)){var me=this;do{var spilled=me.children.splice(me.children.length-5,5),sibling=new BranchChunk(spilled);if(me.parent){me.size-=sibling.size,me.height-=sibling.height;var myIndex=indexOf(me.parent.children,me);me.parent.children.splice(myIndex+1,0,sibling)}else{var copy=new BranchChunk(me.children);copy.parent=me,me.children=[copy,sibling],me=copy}sibling.parent=me.parent}while(me.children.length>10);me.parent.maybeSpill()}},iter:function(from,to,op){this.iterN(from,to-from,op)},iterN:function(at,n,op){for(var i=0,e=this.children.length;i<e;++i){var child=this.children[i],sz=child.chunkSize();if(at<sz){var used=Math.min(n,sz-at);if(child.iterN(at,used,op))return!0;if(0==(n-=used))break;at=0}else at-=sz}}},History.prototype={addChange:function(start,added,old){this.undone.length=0;var time=+new Date,last=this.done[this.done.length-1];if(time-this.time>400||!last||last.start>start+added||last.start+last.added<start-last.added+last.old.length)this.done.push({start:start,added:added,old:old});else{var oldoff=0;if(start<last.start){for(var i=last.start-start-1;i>=0;--i)last.old.unshift(old[i]);last.added+=last.start-start,last.start=start}else last.start<start&&(oldoff=start-last.start,added+=oldoff);for(var i=last.added-oldoff,e=old.length;i<e;++i)last.old.push(old[i]);last.added<added&&(last.added=added)}this.time=time}},CodeMirror.e_stop=e_stop,CodeMirror.e_preventDefault=e_preventDefault,CodeMirror.e_stopPropagation=e_stopPropagation,CodeMirror.connect=connect,Delayed.prototype={set:function(ms,f){clearTimeout(this.id),this.id=setTimeout(f,ms)}};var dragAndDrop=function(){if(/MSIE [1-8]\b/.test(navigator.userAgent))return!1;var div=document.createElement("div");return"draggable"in div}(),gecko=/gecko\/\d{7}/i.test(navigator.userAgent),ie=/MSIE \d/.test(navigator.userAgent),webkit=/WebKit\//.test(navigator.userAgent),lineSep="\n";!function(){var te=document.createElement("textarea");te.value="foo\nbar",te.value.indexOf("\r")>-1&&(lineSep="\r\n")}(),null!=document.documentElement.getBoundingClientRect&&(eltOffset=function(node,screen){try{var box=node.getBoundingClientRect();box={top:box.top,left:box.left}}catch(e){box={top:0,left:0}}if(!screen)if(null==window.pageYOffset){var t=document.documentElement||document.body.parentNode;null==t.scrollTop&&(t=document.body),box.top+=t.scrollTop,box.left+=t.scrollLeft}else box.top+=window.pageYOffset,box.left+=window.pageXOffset;return box});var escapeElement=document.createElement("pre");"\na"==htmlEscape("a")?htmlEscape=function(str){return escapeElement.textContent=str,escapeElement.innerHTML.slice(1)}:"\t"!=htmlEscape("\t")&&(htmlEscape=function(str){return escapeElement.innerHTML="",escapeElement.appendChild(document.createTextNode(str)),escapeElement.innerHTML}),CodeMirror.htmlEscape=htmlEscape;var splitLines=3!="\n\nb".split(/\n/).length?function(string){for(var nl,pos=0,result=[];(nl=string.indexOf("\n",pos))>-1;)result.push(string.slice(pos,"\r"==string.charAt(nl-1)?nl-1:nl)),pos=nl+1;return result.push(string.slice(pos)),result}:function(string){return string.split(/\r?\n/)};CodeMirror.splitLines=splitLines;var hasSelection=window.getSelection?function(te){try{return te.selectionStart!=te.selectionEnd}catch(e){return!1}}:function(te){try{var range=te.ownerDocument.selection.createRange()}catch(e){}return!(!range||range.parentElement()!=te)&&0!=range.compareEndPoints("StartToEnd",range)};CodeMirror.defineMode("null",function(){return{token:function(stream){stream.skipToEnd()}}}),CodeMirror.defineMIME("text/plain","null");var keyNames={3:"Enter",8:"Backspace",9:"Tab",13:"Enter",16:"Shift",17:"Ctrl",18:"Alt",19:"Pause",20:"CapsLock",27:"Esc",32:"Space",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"Left",38:"Up",39:"Right",40:"Down",44:"PrintScrn",45:"Insert",46:"Delete",59:";",91:"Mod",92:"Mod",93:"Mod",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'",63276:"PageUp",63277:"PageDown",63275:"End",63273:"Home",63234:"Left",63232:"Up",63235:"Right",63233:"Down",63302:"Insert",63272:"Delete"};return CodeMirror.keyNames=keyNames,function(){for(var i=0;i<10;i++)keyNames[i+48]=String(i);for(var i=65;i<=90;i++)keyNames[i]=String.fromCharCode(i);for(var i=1;i<=12;i++)keyNames[i+111]=keyNames[i+63235]="F"+i}(),CodeMirror}();CodeMirror.defineMode("xml",function(config,parserConfig){function inText(stream,state){function chain(parser){return state.tokenize=parser,parser(stream,state)}var ch=stream.next();if("<"==ch){if(stream.eat("!"))return stream.eat("[")?stream.match("CDATA[")?chain(inBlock("atom","]]>")):null:stream.match("--")?chain(inBlock("comment","-->")):stream.match("DOCTYPE",!0,!0)?(stream.eatWhile(/[\w\._\-]/),chain(doctype(1))):null;if(stream.eat("?"))return stream.eatWhile(/[\w\._\-]/),state.tokenize=inBlock("meta","?>"),"meta";type=stream.eat("/")?"closeTag":"openTag",stream.eatSpace(),tagName="";for(var c;c=stream.eat(/[^\s\u00a0=<>\"\'\/?]/);)tagName+=c;return state.tokenize=inTag,"tag"}return"&"==ch?(stream.eatWhile(/[^;]/),stream.eat(";"),"atom"):(stream.eatWhile(/[^&<]/),null)}function inTag(stream,state){var ch=stream.next();return">"==ch||"/"==ch&&stream.eat(">")?(state.tokenize=inText,type=">"==ch?"endTag":"selfcloseTag","tag"):"="==ch?(type="equals",null):/[\'\"]/.test(ch)?(state.tokenize=inAttribute(ch),state.tokenize(stream,state)):(stream.eatWhile(/[^\s\u00a0=<>\"\'\/?]/),"word")}function inAttribute(quote){return function(stream,state){for(;!stream.eol();)if(stream.next()==quote){state.tokenize=inTag;break}return"string"}}function inBlock(style,terminator){return function(stream,state){for(;!stream.eol();){if(stream.match(terminator)){state.tokenize=inText;break}stream.next()}return style}}function doctype(depth){return function(stream,state){for(var ch;null!=(ch=stream.next());){if("<"==ch)return state.tokenize=doctype(depth+1),state.tokenize(stream,state);if(">"==ch){if(1==depth){state.tokenize=inText;break}return state.tokenize=doctype(depth-1),state.tokenize(stream,state)}}return"meta"}}function pass(){for(var i=arguments.length-1;i>=0;i--)curState.cc.push(arguments[i])}function cont(){return pass.apply(null,arguments),!0}function pushContext(tagName,startOfLine){var noIndent=Kludges.doNotIndent.hasOwnProperty(tagName)||curState.context&&curState.context.noIndent;curState.context={prev:curState.context,tagName:tagName,indent:curState.indented,startOfLine:startOfLine,noIndent:noIndent}}function popContext(){curState.context&&(curState.context=curState.context.prev)}function element(type){if("openTag"==type)return curState.tagName=tagName,cont(attributes,endtag(curState.startOfLine));if("closeTag"==type){var err=!1;return err=!curState.context||curState.context.tagName!=tagName,err&&(setStyle="error"),cont(endclosetag(err))}return cont()}function endtag(startOfLine){return function(type){return"selfcloseTag"==type||"endTag"==type&&Kludges.autoSelfClosers.hasOwnProperty(curState.tagName.toLowerCase())?cont():"endTag"==type?(pushContext(curState.tagName,startOfLine),cont()):cont()}}function endclosetag(err){return function(type){return err&&(setStyle="error"),"endTag"==type?(popContext(),cont()):(setStyle="error",cont(arguments.callee))}}function attributes(type){return"word"==type?(setStyle="attribute",cont(attributes)):"equals"==type?cont(attvalue,attributes):"string"==type?(setStyle="error",cont(attributes)):pass()}function attvalue(type){return"word"==type&&Kludges.allowUnquoted?(setStyle="string",cont()):"string"==type?cont(attvaluemaybe):pass()}function attvaluemaybe(type){return"string"==type?cont(attvaluemaybe):pass()}var tagName,type,curState,setStyle,indentUnit=config.indentUnit,Kludges=parserConfig.htmlMode?{autoSelfClosers:{br:!0,img:!0,hr:!0,link:!0,input:!0,meta:!0,col:!0,frame:!0,base:!0,area:!0},doNotIndent:{pre:!0},allowUnquoted:!0}:{autoSelfClosers:{},doNotIndent:{},allowUnquoted:!1},alignCDATA=parserConfig.alignCDATA;return{startState:function(){return{tokenize:inText,cc:[],indented:0,startOfLine:!0,tagName:null,context:null}},token:function(stream,state){if(stream.sol()&&(state.startOfLine=!0,state.indented=stream.indentation()),stream.eatSpace())return null;setStyle=type=tagName=null;var style=state.tokenize(stream,state);if(state.type=type,(style||type)&&"comment"!=style)for(curState=state;;){var comb=state.cc.pop()||element;if(comb(type||style))break}return state.startOfLine=!1,setStyle||style},indent:function(state,textAfter,fullLine){var context=state.context;if(state.tokenize!=inTag&&state.tokenize!=inText||context&&context.noIndent)return fullLine?fullLine.match(/^(\s*)/)[0].length:0;if(alignCDATA&&/<!\[CDATA\[/.test(textAfter))return 0;for(context&&/^<\//.test(textAfter)&&(context=context.prev);context&&!context.startOfLine;)context=context.prev;return context?context.indent+indentUnit:0},compareStates:function(a,b){if(a.indented!=b.indented||a.tokenize!=b.tokenize)return!1;for(var ca=a.context,cb=b.context;;ca=ca.prev,cb=cb.prev){if(!ca||!cb)return ca==cb;if(ca.tagName!=cb.tagName)return!1}},electricChars:"/"}}),CodeMirror.defineMIME("application/xml","xml"),CodeMirror.defineMIME("text/html",{name:"xml",htmlMode:!0}),CodeMirror.defineMode("javascript",function(config,parserConfig){function chain(stream,state,f){return state.tokenize=f,f(stream,state)}function nextUntilUnescaped(stream,end){for(var next,escaped=!1;null!=(next=stream.next());){if(next==end&&!escaped)return!1;escaped=!escaped&&"\\"==next}return escaped}function ret(tp,style,cont){return type=tp,content=cont,style}function jsTokenBase(stream,state){var ch=stream.next();if('"'==ch||"'"==ch)return chain(stream,state,jsTokenString(ch));if(/[\[\]{}\(\),;\:\.]/.test(ch))return ret(ch);if("0"==ch&&stream.eat(/x/i))return stream.eatWhile(/[\da-f]/i),ret("number","number");if(/\d/.test(ch))return stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/),ret("number","number");if("/"==ch)return stream.eat("*")?chain(stream,state,jsTokenComment):stream.eat("/")?(stream.skipToEnd(),ret("comment","comment")):state.reAllowed?(nextUntilUnescaped(stream,"/"),stream.eatWhile(/[gimy]/),ret("regexp","string")):(stream.eatWhile(isOperatorChar),ret("operator",null,stream.current()));if("#"==ch)return stream.skipToEnd(),ret("error","error");if(isOperatorChar.test(ch))return stream.eatWhile(isOperatorChar),ret("operator",null,stream.current());stream.eatWhile(/[\w\$_]/);var word=stream.current(),known=keywords.propertyIsEnumerable(word)&&keywords[word];return known&&state.kwAllowed?ret(known.type,known.style,word):ret("variable","variable",word)}function jsTokenString(quote){return function(stream,state){return nextUntilUnescaped(stream,quote)||(state.tokenize=jsTokenBase),ret("string","string")}}function jsTokenComment(stream,state){for(var ch,maybeEnd=!1;ch=stream.next();){if("/"==ch&&maybeEnd){state.tokenize=jsTokenBase;break}maybeEnd="*"==ch}return ret("comment","comment")}function JSLexical(indented,column,type,align,prev,info){this.indented=indented,this.column=column,this.type=type,this.prev=prev,this.info=info,null!=align&&(this.align=align)}function inScope(state,varname){for(var v=state.localVars;v;v=v.next)if(v.name==varname)return!0}function parseJS(state,style,type,content,stream){var cc=state.cc;for(cx.state=state,cx.stream=stream,cx.marked=null,cx.cc=cc,state.lexical.hasOwnProperty("align")||(state.lexical.align=!0);;){var combinator=cc.length?cc.pop():jsonMode?expression:statement;if(combinator(type,content)){for(;cc.length&&cc[cc.length-1].lex;)cc.pop()();return cx.marked?cx.marked:"variable"==type&&inScope(state,content)?"variable-2":style}}}function pass(){for(var i=arguments.length-1;i>=0;i--)cx.cc.push(arguments[i])}function cont(){return pass.apply(null,arguments),!0}function register(varname){var state=cx.state;if(state.context){cx.marked="def";for(var v=state.localVars;v;v=v.next)if(v.name==varname)return;state.localVars={name:varname,next:state.localVars}}}function pushcontext(){cx.state.context||(cx.state.localVars=defaultVars),cx.state.context={prev:cx.state.context,vars:cx.state.localVars}}function popcontext(){cx.state.localVars=cx.state.context.vars,cx.state.context=cx.state.context.prev}function pushlex(type,info){var result=function(){var state=cx.state;state.lexical=new JSLexical(state.indented,cx.stream.column(),type,null,state.lexical,info)};return result.lex=!0,result}function poplex(){var state=cx.state;state.lexical.prev&&(")"==state.lexical.type&&(state.indented=state.lexical.indented),state.lexical=state.lexical.prev)}function expect(wanted){return function(type){return type==wanted?cont():";"==wanted?pass():cont(arguments.callee)}}function statement(type){return"var"==type?cont(pushlex("vardef"),vardef1,expect(";"),poplex):"keyword a"==type?cont(pushlex("form"),expression,statement,poplex):"keyword b"==type?cont(pushlex("form"),statement,poplex):"{"==type?cont(pushlex("}"),block,poplex):";"==type?cont():"function"==type?cont(functiondef):"for"==type?cont(pushlex("form"),expect("("),pushlex(")"),forspec1,expect(")"),poplex,statement,poplex):"variable"==type?cont(pushlex("stat"),maybelabel):"switch"==type?cont(pushlex("form"),expression,pushlex("}","switch"),expect("{"),block,poplex,poplex):"case"==type?cont(expression,expect(":")):"default"==type?cont(expect(":")):"catch"==type?cont(pushlex("form"),pushcontext,expect("("),funarg,expect(")"),statement,poplex,popcontext):pass(pushlex("stat"),expression,expect(";"),poplex)}function expression(type){return atomicTypes.hasOwnProperty(type)?cont(maybeoperator):"function"==type?cont(functiondef):"keyword c"==type?cont(maybeexpression):"("==type?cont(pushlex(")"),expression,expect(")"),poplex,maybeoperator):"operator"==type?cont(expression):"["==type?cont(pushlex("]"),commasep(expression,"]"),poplex,maybeoperator):"{"==type?cont(pushlex("}"),commasep(objprop,"}"),poplex,maybeoperator):cont()}function maybeexpression(type){return type.match(/[;\}\)\],]/)?pass():pass(expression)}function maybeoperator(type,value){if("operator"==type&&/\+\+|--/.test(value))return cont(maybeoperator);if("operator"==type)return cont(expression);if(";"!=type)return"("==type?cont(pushlex(")"),commasep(expression,")"),poplex,maybeoperator):"."==type?cont(property,maybeoperator):"["==type?cont(pushlex("]"),expression,expect("]"),poplex,maybeoperator):void 0}function maybelabel(type){return":"==type?cont(poplex,statement):pass(maybeoperator,expect(";"),poplex)}function property(type){if("variable"==type)return cx.marked="property",cont()}function objprop(type){if("variable"==type&&(cx.marked="property"),atomicTypes.hasOwnProperty(type))return cont(expect(":"),expression)}function commasep(what,end){function proceed(type){return","==type?cont(what,proceed):type==end?cont():cont(expect(end))}return function(type){return type==end?cont():pass(what,proceed)}}function block(type){return"}"==type?cont():pass(statement,block)}function vardef1(type,value){return"variable"==type?(register(value),cont(vardef2)):cont()}function vardef2(type,value){return"="==value?cont(expression,vardef2):","==type?cont(vardef1):void 0}function forspec1(type){return"var"==type?cont(vardef1,forspec2):";"==type?pass(forspec2):"variable"==type?cont(formaybein):pass(forspec2)}function formaybein(type,value){return"in"==value?cont(expression):cont(maybeoperator,forspec2)}function forspec2(type,value){return";"==type?cont(forspec3):"in"==value?cont(expression):cont(expression,expect(";"),forspec3)}function forspec3(type){")"!=type&&cont(expression)}function functiondef(type,value){return"variable"==type?(register(value),cont(functiondef)):"("==type?cont(pushlex(")"),pushcontext,commasep(funarg,")"),poplex,statement,popcontext):void 0}function funarg(type,value){if("variable"==type)return register(value),cont()}var type,content,indentUnit=config.indentUnit,jsonMode=parserConfig.json,keywords=function(){function kw(type){return{type:type,style:"keyword"}}var A=kw("keyword a"),B=kw("keyword b"),C=kw("keyword c"),operator=kw("operator"),atom={type:"atom",style:"atom"};return{"if":A,"while":A,"with":A,"else":B,"do":B,"try":B,"finally":B,"return":C,"break":C,"continue":C,"new":C,"delete":C,"throw":C,"var":kw("var"),"const":kw("var"),"let":kw("var"),"function":kw("function"),"catch":kw("catch"),"for":kw("for"),"switch":kw("switch"),"case":kw("case"),"default":kw("default"),"in":operator,"typeof":operator,"instanceof":operator,"true":atom,"false":atom,"null":atom,undefined:atom,NaN:atom,Infinity:atom}}(),isOperatorChar=/[+\-*&%=<>!?|]/,atomicTypes={atom:!0,number:!0,variable:!0,string:!0,regexp:!0},cx={state:null,column:null,marked:null,cc:null},defaultVars={name:"this",next:{name:"arguments"}};return poplex.lex=!0,{startState:function(basecolumn){return{tokenize:jsTokenBase,reAllowed:!0,kwAllowed:!0,cc:[],lexical:new JSLexical((basecolumn||0)-indentUnit,0,"block",(!1)),localVars:null,context:null,indented:0}},token:function(stream,state){if(stream.sol()&&(state.lexical.hasOwnProperty("align")||(state.lexical.align=!1),state.indented=stream.indentation()),stream.eatSpace())return null;var style=state.tokenize(stream,state);return"comment"==type?style:(state.reAllowed="operator"==type||"keyword c"==type||type.match(/^[\[{}\(,;:]$/),state.kwAllowed="."!=type,parseJS(state,style,type,content,stream))},indent:function(state,textAfter){if(state.tokenize!=jsTokenBase)return 0;var firstChar=textAfter&&textAfter.charAt(0),lexical=state.lexical,type=lexical.type,closing=firstChar==type;return"vardef"==type?lexical.indented+4:"form"==type&&"{"==firstChar?lexical.indented:"stat"==type||"form"==type?lexical.indented+indentUnit:"switch"!=lexical.info||closing?lexical.align?lexical.column+(closing?0:1):lexical.indented+(closing?0:indentUnit):lexical.indented+(/^(?:case|default)\b/.test(textAfter)?indentUnit:2*indentUnit)},electricChars:":{}"}}),CodeMirror.defineMIME("text/javascript","javascript"),CodeMirror.defineMIME("application/json",{name:"javascript",json:!0}),CodeMirror.defineMode("css",function(config){function ret(style,tp){return type=tp,style}function tokenBase(stream,state){var ch=stream.next();return"@"==ch?(stream.eatWhile(/[\w\\\-]/),ret("meta",stream.current())):"/"==ch&&stream.eat("*")?(state.tokenize=tokenCComment,tokenCComment(stream,state)):"<"==ch&&stream.eat("!")?(state.tokenize=tokenSGMLComment,tokenSGMLComment(stream,state)):"="!=ch?"~"!=ch&&"|"!=ch||!stream.eat("=")?'"'==ch||"'"==ch?(state.tokenize=tokenString(ch),state.tokenize(stream,state)):"#"==ch?(stream.eatWhile(/[\w\\\-]/),ret("atom","hash")):"!"==ch?(stream.match(/^\s*\w*/),ret("keyword","important")):/\d/.test(ch)?(stream.eatWhile(/[\w.%]/),ret("number","unit")):/[,.+>*\/]/.test(ch)?ret(null,"select-op"):/[;{}:\[\]]/.test(ch)?ret(null,ch):(stream.eatWhile(/[\w\\\-]/),ret("variable","variable")):ret(null,"compare"):void ret(null,"compare")}function tokenCComment(stream,state){for(var ch,maybeEnd=!1;null!=(ch=stream.next());){if(maybeEnd&&"/"==ch){state.tokenize=tokenBase;break}maybeEnd="*"==ch}return ret("comment","comment")}function tokenSGMLComment(stream,state){for(var ch,dashes=0;null!=(ch=stream.next());){if(dashes>=2&&">"==ch){state.tokenize=tokenBase;break}dashes="-"==ch?dashes+1:0}return ret("comment","comment")}function tokenString(quote){return function(stream,state){for(var ch,escaped=!1;null!=(ch=stream.next())&&(ch!=quote||escaped);)escaped=!escaped&&"\\"==ch;return escaped||(state.tokenize=tokenBase),ret("string","string")}}var type,indentUnit=config.indentUnit;return{startState:function(base){return{tokenize:tokenBase,baseIndent:base||0,stack:[]}},token:function(stream,state){if(stream.eatSpace())return null;var style=state.tokenize(stream,state),context=state.stack[state.stack.length-1];return"hash"==type&&"rule"==context?style="atom":"variable"==style&&("rule"==context?style="number":context&&"@media{"!=context||(style="tag")),"rule"==context&&/^[\{\};]$/.test(type)&&state.stack.pop(),"{"==type?"@media"==context?state.stack[state.stack.length-1]="@media{":state.stack.push("{"):"}"==type?state.stack.pop():"@media"==type?state.stack.push("@media"):"{"==context&&"comment"!=type&&state.stack.push("rule"),style},indent:function(state,textAfter){var n=state.stack.length;return/^\}/.test(textAfter)&&(n-="rule"==state.stack[state.stack.length-1]?2:1),state.baseIndent+n*indentUnit},electricChars:"}"}}),CodeMirror.defineMIME("text/css","css"),CodeMirror.defineMode("htmlmixed",function(config,parserConfig){function html(stream,state){var style=htmlMode.token(stream,state.htmlState);return"tag"==style&&">"==stream.current()&&state.htmlState.context&&(/^script$/i.test(state.htmlState.context.tagName)?(state.token=javascript,state.localState=jsMode.startState(htmlMode.indent(state.htmlState,"")),state.mode="javascript"):/^style$/i.test(state.htmlState.context.tagName)&&(state.token=css,state.localState=cssMode.startState(htmlMode.indent(state.htmlState,"")),state.mode="css")),style}function maybeBackup(stream,pat,style){var cur=stream.current(),close=cur.search(pat);return close>-1&&stream.backUp(cur.length-close),style}function javascript(stream,state){return stream.match(/^<\/\s*script\s*>/i,!1)?(state.token=html,state.curState=null,state.mode="html",html(stream,state)):maybeBackup(stream,/<\/\s*script\s*>/,jsMode.token(stream,state.localState))}function css(stream,state){return stream.match(/^<\/\s*style\s*>/i,!1)?(state.token=html,state.localState=null,state.mode="html",html(stream,state)):maybeBackup(stream,/<\/\s*style\s*>/,cssMode.token(stream,state.localState))}var htmlMode=CodeMirror.getMode(config,{name:"xml",htmlMode:!0}),jsMode=CodeMirror.getMode(config,"javascript"),cssMode=CodeMirror.getMode(config,"css");return{startState:function(){var state=htmlMode.startState();return{token:html,localState:null,mode:"html",htmlState:state}},copyState:function(state){if(state.localState)var local=CodeMirror.copyState(state.token==css?cssMode:jsMode,state.localState);return{token:state.token,localState:local,mode:state.mode,htmlState:CodeMirror.copyState(htmlMode,state.htmlState)}},token:function(stream,state){return state.token(stream,state)},indent:function(state,textAfter){return state.token==html||/^\s*<\//.test(textAfter)?htmlMode.indent(state.htmlState,textAfter):state.token==javascript?jsMode.indent(state.localState,textAfter):cssMode.indent(state.localState,textAfter)},compareStates:function(a,b){return htmlMode.compareStates(a.htmlState,b.htmlState)},electricChars:"/{}:"}}),CodeMirror.defineMIME("text/html","htmlmixed");
         |