HTML Editor Syntax Highlighter - Version 1.3.2

Version Description

  • Updated CodeMirror library
  • Increased loading performance
  • Match brackets
Download this release

Release Info

Developer nixdns
Plugin Icon 128x128 HTML Editor Syntax Highlighter
Version 1.3.2
Comparing to
See all releases

Code changes from version 1.3.1 to 1.3.2

html-editor-syntax-highlighter.php CHANGED
@@ -5,10 +5,10 @@
5
  * Description: Syntax Highlighting in WordPress HTML Editor
6
  * Author: Peter Mukhortov
7
  * Author URI: http://mukhortov.com/
8
- * Version: 1.3.0
9
  * Requires at least: 3.3
10
- * Tested up to: 3.5.1
11
- * Stable tag: 1.3.0
12
  **/
13
 
14
  if(preg_match('#' . basename(__FILE__) . '#', $_SERVER['PHP_SELF'])) { die('You are not allowed to call this page directly.'); }
@@ -32,7 +32,7 @@ class wp_html_editor_syntax {
32
  fullscreen.switchmode('html');
33
  //switchEditors.switchto(document.getElementById("content-html"));
34
 
35
- //fix
36
  var visualEditorEnabled;
37
 
38
  if (document.getElementById("content-tmce") != null) {
@@ -44,7 +44,7 @@ class wp_html_editor_syntax {
44
  if (visualEditorEnabled) {
45
  switchEditors.switchto(document.getElementById("content-html"));
46
  }
47
- // end fix
48
 
49
  var editor = CodeMirror.fromTextArea(document.getElementById(el), {
50
  mode: "text/html",
@@ -64,13 +64,13 @@ class wp_html_editor_syntax {
64
  });
65
 
66
  //Saving cursor state
67
- cmPostID = document.getElementById("post_ID").value;
68
  editor.on("cursorActivity", function(){
69
- curPos = editor.getCursor();
70
- window.name = cmPostID+','+curPos.line+','+curPos.ch;
71
  });
72
  //Restoring cursor state
73
- curPos = window.name.split(',');
74
  if (cmPostID == curPos[0]) {
75
  editor.setCursor(parseFloat(curPos[1]),parseFloat(curPos[2]));
76
  }
@@ -99,13 +99,12 @@ class wp_html_editor_syntax {
99
  /* buttons */
100
 
101
  var cmToolbar = document.getElementById("ed_toolbar");
102
- //Villeman og Magnhild
103
 
104
  if (!cmToolbar.getAttribute('data-updated')) {
105
  cmToolbarVars = [
106
  //['search','','','Search:'],
107
  ['more','<!--more-->',''],
108
- ['comment','<!--','-->'],
109
  ['code','<code>','</code>'],
110
  ['li','<li>','</li>'],
111
  ['ol','<ol>','</ol>'],
@@ -121,23 +120,28 @@ class wp_html_editor_syntax {
121
  ['i','<em>','</em>'],
122
  ['b','<strong>','</strong>'],
123
 
124
- ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
  for (var i=0; i<cmToolbarVars.length; i++) {
126
- t = cmToolbarVars[i];
127
- t3 = t[3] ? ('data-prompt="'+t[3]+'"') : '';
128
  cmToolbar.insertAdjacentHTML('afterbegin', '<input type="button" id="cm_content_'+t[0]+'" data-start=\''+t[1]+'\' data-end=\''+t[2]+'\' '+t3+' class="ed_button cm_ed_button" value="'+t[0]+'">');
129
- document.getElementById('cm_content_'+t[0]).onclick = function (e) {
130
- var range = { from: editor.getCursor(true), to: editor.getCursor(false) }, selStart = editor.getCursor("start");
131
- var start = this.getAttribute('data-start');
132
- var end = this.getAttribute('data-end');
133
- var cmPrompt = this.getAttribute('data-prompt');
134
- var selText = editor.getSelection();
135
- if (cmPrompt) start = start.replace('$',prompt(cmPrompt, ''));
136
- editor.replaceSelection(start+selText+end, range.from, range.to);
137
- editor.setSelection(selStart, editor.getCursor("end"));
138
- editor.setCursor(range.from.line,range.from.ch+start.length);
139
- editor.focus();
140
- }
141
  }
142
  cmToolbar.setAttribute("data-updated", "1");
143
  }
@@ -150,25 +154,13 @@ class wp_html_editor_syntax {
150
  </script>
151
  <?php
152
  }
153
- /*public function admin_init(){
154
- wp_enqueue_script('jquery'); // For AJAX code submissions
155
- wp_enqueue_script('jquery-ui-core');
156
- wp_enqueue_script('jquery-ui-widget');
157
- wp_enqueue_script('jquery-ui-mouse');
158
- wp_enqueue_script('jquery-ui-resizable');
159
- }*/
160
  public function admin_head(){
161
  if (!$this->is_editor())
162
  return;
163
  ?>
164
- <link rel="stylesheet" href="<?php echo HESH_LIBS; ?>codemirror.css">
165
- <script src="<?php echo HESH_LIBS; ?>codemirror.js"></script>
166
- <script src="<?php echo HESH_LIBS; ?>xml.js"></script>
167
- <script src="<?php echo HESH_LIBS; ?>javascript.js"></script>
168
- <script src="<?php echo HESH_LIBS; ?>css.js"></script>
169
- <script src="<?php echo HESH_LIBS; ?>htmlmixed.js"></script>
170
- <script src="<?php echo HESH_LIBS; ?>util/active-line.js"></script>
171
- <script src="<?php echo HESH_LIBS; ?>util/formatting.js"></script>
172
  <style>
173
  .CodeMirror-scroll {resize:vertical;}
174
  .wp-editor-area,
@@ -176,8 +168,11 @@ class wp_html_editor_syntax {
176
  #content-resize-handle,
177
  .quicktags-toolbar input.ed_button {display: none !important;}
178
  .quicktags-toolbar input#qt_content_fullscreen, #ed_toolbar input.cm_ed_button {display: inline-block !important;}
 
 
 
179
 
180
- #wp-fullscreen-container .CodeMirror {height: auto; min-height: 400px;}
181
  #wp-fullscreen-container .CodeMirror-scroll {overflow-y: hidden; overflow-x: auto;}
182
  #wp-fullscreen-wrap {width: 80% !important;}
183
  #wp-fullscreen-container {padding-bottom: 4px !important;}
5
  * Description: Syntax Highlighting in WordPress HTML Editor
6
  * Author: Peter Mukhortov
7
  * Author URI: http://mukhortov.com/
8
+ * Version: 1.3.2
9
  * Requires at least: 3.3
10
+ * Tested up to: 3.6.1
11
+ * Stable tag: 1.3.2
12
  **/
13
 
14
  if(preg_match('#' . basename(__FILE__) . '#', $_SERVER['PHP_SELF'])) { die('You are not allowed to call this page directly.'); }
32
  fullscreen.switchmode('html');
33
  //switchEditors.switchto(document.getElementById("content-html"));
34
 
35
+ //
36
  var visualEditorEnabled;
37
 
38
  if (document.getElementById("content-tmce") != null) {
44
  if (visualEditorEnabled) {
45
  switchEditors.switchto(document.getElementById("content-html"));
46
  }
47
+ // end
48
 
49
  var editor = CodeMirror.fromTextArea(document.getElementById(el), {
50
  mode: "text/html",
64
  });
65
 
66
  //Saving cursor state
67
+ var cmPostID = document.getElementById("post_ID").value;
68
  editor.on("cursorActivity", function(){
69
+ var curPos = editor.getCursor();
70
+ window.name = cmPostID + ',' + curPos.line + ',' + curPos.ch;
71
  });
72
  //Restoring cursor state
73
+ var curPos = window.name.split(',');
74
  if (cmPostID == curPos[0]) {
75
  editor.setCursor(parseFloat(curPos[1]),parseFloat(curPos[2]));
76
  }
99
  /* buttons */
100
 
101
  var cmToolbar = document.getElementById("ed_toolbar");
 
102
 
103
  if (!cmToolbar.getAttribute('data-updated')) {
104
  cmToolbarVars = [
105
  //['search','','','Search:'],
106
  ['more','<!--more-->',''],
107
+ ['comment','<!-- ',' -->'],
108
  ['code','<code>','</code>'],
109
  ['li','<li>','</li>'],
110
  ['ol','<ol>','</ol>'],
120
  ['i','<em>','</em>'],
121
  ['b','<strong>','</strong>'],
122
 
123
+ ];
124
+
125
+ function cmToolbarClick() {
126
+ var selStart = editor.getCursor("start"), //var range = { from: editor.getCursor(true), to: editor.getCursor(false) },
127
+ start = this.getAttribute('data-start'),
128
+ end = this.getAttribute('data-end'),
129
+ cmPrompt = this.getAttribute('data-prompt'),
130
+ selText = editor.getSelection();
131
+
132
+ if (cmPrompt) start = start.replace('$',prompt(cmPrompt, ''));
133
+
134
+ editor.replaceSelection(start+selText+end);
135
+ editor.setSelection(selStart, editor.getCursor("end"));
136
+ editor.setCursor(selStart.line, selStart.ch + start.length);
137
+ editor.focus();
138
+ }
139
+
140
  for (var i=0; i<cmToolbarVars.length; i++) {
141
+ var t = cmToolbarVars[i];
142
+ var t3 = t[3] ? ('data-prompt="'+t[3]+'"') : '';
143
  cmToolbar.insertAdjacentHTML('afterbegin', '<input type="button" id="cm_content_'+t[0]+'" data-start=\''+t[1]+'\' data-end=\''+t[2]+'\' '+t3+' class="ed_button cm_ed_button" value="'+t[0]+'">');
144
+ document.getElementById('cm_content_'+t[0]).onclick = cmToolbarClick;
 
 
 
 
 
 
 
 
 
 
 
145
  }
146
  cmToolbar.setAttribute("data-updated", "1");
147
  }
154
  </script>
155
  <?php
156
  }
157
+
 
 
 
 
 
 
158
  public function admin_head(){
159
  if (!$this->is_editor())
160
  return;
161
  ?>
162
+ <link rel="stylesheet" href="<?php echo HESH_LIBS; ?>codemirror.min.css">
163
+ <script src="<?php echo HESH_LIBS; ?>codemirror-compressed.js"></script>
 
 
 
 
 
 
164
  <style>
165
  .CodeMirror-scroll {resize:vertical;}
166
  .wp-editor-area,
168
  #content-resize-handle,
169
  .quicktags-toolbar input.ed_button {display: none !important;}
170
  .quicktags-toolbar input#qt_content_fullscreen, #ed_toolbar input.cm_ed_button {display: inline-block !important;}
171
+
172
+ .CodeMirror-matchingbracket {background-color: #fff490; color: inherit !important;}
173
+ .CodeMirror {font-family: Menlo Regular,Consolas,Monaco,monospace;line-height: 150%;font-size: 12px; height: 600px;}
174
 
175
+ #wp-fullscreen-container .CodeMirror {height: auto; min-height: 600px;}
176
  #wp-fullscreen-container .CodeMirror-scroll {overflow-y: hidden; overflow-x: auto;}
177
  #wp-fullscreen-wrap {width: 80% !important;}
178
  #wp-fullscreen-container {padding-bottom: 4px !important;}
lib/codemirror-compressed.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ /* v3.18: codemirror.js, css.js, htmlmixed.js, javascript.js, xml.js, active-line.js, matchbrackets.js */
2
+ window.CodeMirror=function(){"use strict";function w(a,c){if(!(this instanceof w))return new w(a,c);this.options=c=c||{};for(var d in $c)!c.hasOwnProperty(d)&&$c.hasOwnProperty(d)&&(c[d]=$c[d]);I(c);var e="string"==typeof c.value?0:c.value.first,f=this.display=x(a,e);f.wrapper.CodeMirror=this,F(this),c.autofocus&&!o&&Mb(this),this.state={keyMaps:[],overlays:[],modeGen:0,overwrite:!1,focused:!1,suppressEdits:!1,pasteIncoming:!1,draggingText:!1,highlight:new We},D(this),c.lineWrapping&&(this.display.wrapper.className+=" CodeMirror-wrap");var g=c.value;"string"==typeof g&&(g=new fe(c.value,c.mode)),Eb(this,je)(this,g),b&&setTimeout(ef(Lb,this,!0),20),Ob(this);var h;try{h=document.activeElement==f.input}catch(i){}h||c.autofocus&&!o?setTimeout(ef(lc,this),20):mc(this),Eb(this,function(){for(var a in Zc)Zc.propertyIsEnumerable(a)&&Zc[a](this,c[a],ad);for(var b=0;b<ed.length;++b)ed[b](this)})()}function x(a,b){var d={},f=d.input=kf("textarea",null,null,"position: absolute; padding: 0; width: 1px; height: 1em; outline: none; font-size: 4px;");return e?f.style.width="1000px":f.setAttribute("wrap","off"),n&&(f.style.border="1px solid black"),f.setAttribute("autocorrect","off"),f.setAttribute("autocapitalize","off"),f.setAttribute("spellcheck","false"),d.inputDiv=kf("div",[f],null,"overflow: hidden; position: relative; width: 3px; height: 0px;"),d.scrollbarH=kf("div",[kf("div",null,null,"height: 1px")],"CodeMirror-hscrollbar"),d.scrollbarV=kf("div",[kf("div",null,null,"width: 1px")],"CodeMirror-vscrollbar"),d.scrollbarFiller=kf("div",null,"CodeMirror-scrollbar-filler"),d.gutterFiller=kf("div",null,"CodeMirror-gutter-filler"),d.lineDiv=kf("div",null,"CodeMirror-code"),d.selectionDiv=kf("div",null,null,"position: relative; z-index: 1"),d.cursor=kf("div","\xa0","CodeMirror-cursor"),d.otherCursor=kf("div","\xa0","CodeMirror-cursor CodeMirror-secondarycursor"),d.measure=kf("div",null,"CodeMirror-measure"),d.lineSpace=kf("div",[d.measure,d.selectionDiv,d.lineDiv,d.cursor,d.otherCursor],null,"position: relative; outline: none"),d.mover=kf("div",[kf("div",[d.lineSpace],"CodeMirror-lines")],null,"position: relative"),d.sizer=kf("div",[d.mover],"CodeMirror-sizer"),d.heightForcer=kf("div",null,null,"position: absolute; height: "+Ue+"px; width: 1px;"),d.gutters=kf("div",null,"CodeMirror-gutters"),d.lineGutter=null,d.scroller=kf("div",[d.sizer,d.heightForcer,d.gutters],"CodeMirror-scroll"),d.scroller.setAttribute("tabIndex","-1"),d.wrapper=kf("div",[d.inputDiv,d.scrollbarH,d.scrollbarV,d.scrollbarFiller,d.gutterFiller,d.scroller],"CodeMirror"),c&&(d.gutters.style.zIndex=-1,d.scroller.style.paddingRight=0),a.appendChild?a.appendChild(d.wrapper):a(d.wrapper),n&&(f.style.width="0px"),e||(d.scroller.draggable=!0),j?(d.inputDiv.style.height="1px",d.inputDiv.style.position="absolute"):c&&(d.scrollbarH.style.minWidth=d.scrollbarV.style.minWidth="18px"),d.viewOffset=d.lastSizeC=0,d.showingFrom=d.showingTo=b,d.lineNumWidth=d.lineNumInnerWidth=d.lineNumChars=null,d.prevInput="",d.alignWidgets=!1,d.pollingFast=!1,d.poll=new We,d.cachedCharWidth=d.cachedTextHeight=null,d.measureLineCache=[],d.measureLineCachePos=0,d.inaccurateSelection=!1,d.maxLine=null,d.maxLineLength=0,d.maxLineChanged=!1,d.wheelDX=d.wheelDY=d.wheelStartX=d.wheelStartY=null,d}function y(a){a.doc.mode=w.getMode(a.options,a.doc.modeOption),a.doc.iter(function(a){a.stateAfter&&(a.stateAfter=null),a.styles&&(a.styles=null)}),a.doc.frontier=a.doc.first,ab(a,100),a.state.modeGen++,a.curOp&&Hb(a)}function z(a){a.options.lineWrapping?(a.display.wrapper.className+=" CodeMirror-wrap",a.display.sizer.style.minWidth=""):(a.display.wrapper.className=a.display.wrapper.className.replace(" CodeMirror-wrap",""),H(a)),B(a),Hb(a),ob(a),setTimeout(function(){J(a)},100)}function A(a){var b=zb(a.display),c=a.options.lineWrapping,d=c&&Math.max(5,a.display.scroller.clientWidth/Ab(a.display)-3);return function(e){return Fd(a.doc,e)?0:c?(Math.ceil(e.text.length/d)||1)*b:b}}function B(a){var b=a.doc,c=A(a);b.iter(function(a){var b=c(a);b!=a.height&&ne(a,b)})}function C(a){var b=jd[a.options.keyMap],c=b.style;a.display.wrapper.className=a.display.wrapper.className.replace(/\s*cm-keymap-\S+/g,"")+(c?" cm-keymap-"+c:""),a.state.disableInput=b.disableInput}function D(a){a.display.wrapper.className=a.display.wrapper.className.replace(/\s*cm-s-\S+/g,"")+a.options.theme.replace(/(^|\s)\s*/g," cm-s-"),ob(a)}function E(a){F(a),Hb(a),setTimeout(function(){L(a)},20)}function F(a){var b=a.display.gutters,c=a.options.gutters;lf(b);for(var d=0;d<c.length;++d){var e=c[d],f=b.appendChild(kf("div",null,"CodeMirror-gutter "+e));"CodeMirror-linenumbers"==e&&(a.display.lineGutter=f,f.style.width=(a.display.lineNumWidth||1)+"px")}b.style.display=d?"":"none"}function G(a,b){if(0==b.height)return 0;for(var d,c=b.text.length,e=b;d=Cd(e);){var f=d.find();e=ke(a,f.from.line),c+=f.from.ch-f.to.ch}for(e=b;d=Dd(e);){var f=d.find();c-=e.text.length-f.from.ch,e=ke(a,f.to.line),c+=e.text.length-f.to.ch}return c}function H(a){var b=a.display,c=a.doc;b.maxLine=ke(c,c.first),b.maxLineLength=G(c,b.maxLine),b.maxLineChanged=!0,c.iter(function(a){var d=G(c,a);d>b.maxLineLength&&(b.maxLineLength=d,b.maxLine=a)})}function I(a){var b=af(a.gutters,"CodeMirror-linenumbers");-1==b&&a.lineNumbers?a.gutters=a.gutters.concat(["CodeMirror-linenumbers"]):b>-1&&!a.lineNumbers&&(a.gutters=a.gutters.slice(0),a.gutters.splice(b,1))}function J(a){var b=a.display,c=a.doc.height,d=c+fb(b);b.sizer.style.minHeight=b.heightForcer.style.top=d+"px",b.gutters.style.height=Math.max(d,b.scroller.clientHeight-Ue)+"px";var e=Math.max(d,b.scroller.scrollHeight),f=b.scroller.scrollWidth>b.scroller.clientWidth+1,g=e>b.scroller.clientHeight+1;g?(b.scrollbarV.style.display="block",b.scrollbarV.style.bottom=f?sf(b.measure)+"px":"0",b.scrollbarV.firstChild.style.height=e-b.scroller.clientHeight+b.scrollbarV.clientHeight+"px"):(b.scrollbarV.style.display="",b.scrollbarV.firstChild.style.height="0"),f?(b.scrollbarH.style.display="block",b.scrollbarH.style.right=g?sf(b.measure)+"px":"0",b.scrollbarH.firstChild.style.width=b.scroller.scrollWidth-b.scroller.clientWidth+b.scrollbarH.clientWidth+"px"):(b.scrollbarH.style.display="",b.scrollbarH.firstChild.style.width="0"),f&&g?(b.scrollbarFiller.style.display="block",b.scrollbarFiller.style.height=b.scrollbarFiller.style.width=sf(b.measure)+"px"):b.scrollbarFiller.style.display="",f&&a.options.coverGutterNextToScrollbar&&a.options.fixedGutter?(b.gutterFiller.style.display="block",b.gutterFiller.style.height=sf(b.measure)+"px",b.gutterFiller.style.width=b.gutters.offsetWidth+"px"):b.gutterFiller.style.display="",k&&0===sf(b.measure)&&(b.scrollbarV.style.minWidth=b.scrollbarH.style.minHeight=l?"18px":"12px")}function K(a,b,c){var d=a.scroller.scrollTop,e=a.wrapper.clientHeight;"number"==typeof c?d=c:c&&(d=c.top,e=c.bottom-c.top),d=Math.floor(d-eb(a));var f=Math.ceil(d+e);return{from:pe(b,d),to:pe(b,f)}}function L(a){var b=a.display;if(b.alignWidgets||b.gutters.firstChild&&a.options.fixedGutter){for(var c=O(b)-b.scroller.scrollLeft+a.doc.scrollLeft,d=b.gutters.offsetWidth,e=c+"px",f=b.lineDiv.firstChild;f;f=f.nextSibling)if(f.alignable)for(var g=0,h=f.alignable;g<h.length;++g)h[g].style.left=e;a.options.fixedGutter&&(b.gutters.style.left=c+d+"px")}}function M(a){if(!a.options.lineNumbers)return!1;var b=a.doc,c=N(a.options,b.first+b.size-1),d=a.display;if(c.length!=d.lineNumChars){var e=d.measure.appendChild(kf("div",[kf("div",c)],"CodeMirror-linenumber CodeMirror-gutter-elt")),f=e.firstChild.offsetWidth,g=e.offsetWidth-f;return d.lineGutter.style.width="",d.lineNumInnerWidth=Math.max(f,d.lineGutter.offsetWidth-g),d.lineNumWidth=d.lineNumInnerWidth+g,d.lineNumChars=d.lineNumInnerWidth?c.length:-1,d.lineGutter.style.width=d.lineNumWidth+"px",!0}return!1}function N(a,b){return String(a.lineNumberFormatter(b+a.firstLineNumber))}function O(a){return of(a.scroller).left-of(a.sizer).left}function P(a,b,c,d){for(var g,e=a.display.showingFrom,f=a.display.showingTo,h=K(a.display,a.doc,c),i=!0;;i=!1){var j=a.display.scroller.clientWidth;if(!Q(a,b,h,d))break;if(g=!0,b=[],Y(a),J(a),i&&a.options.lineWrapping&&j!=a.display.scroller.clientWidth)d=!0;else if(d=!1,c&&(c=Math.min(a.display.scroller.scrollHeight-a.display.scroller.clientHeight,"number"==typeof c?c:c.top)),h=K(a.display,a.doc,c),h.from>=a.display.showingFrom&&h.to<=a.display.showingTo)break}return g&&(Pe(a,"update",a),(a.display.showingFrom!=e||a.display.showingTo!=f)&&Pe(a,"viewportChange",a,a.display.showingFrom,a.display.showingTo)),g}function Q(a,b,c,d){var e=a.display,f=a.doc;if(!e.wrapper.clientWidth)return e.showingFrom=e.showingTo=f.first,e.viewOffset=0,void 0;if(!(!d&&0==b.length&&c.from>e.showingFrom&&c.to<e.showingTo)){M(a)&&(b=[{from:f.first,to:f.first+f.size}]);var g=e.sizer.style.marginLeft=e.gutters.offsetWidth+"px";e.scrollbarH.style.left=a.options.fixedGutter?g:"0";var h=1/0;if(a.options.lineNumbers)for(var i=0;i<b.length;++i)b[i].diff&&b[i].from<h&&(h=b[i].from);var j=f.first+f.size,k=Math.max(c.from-a.options.viewportMargin,f.first),l=Math.min(j,c.to+a.options.viewportMargin);if(e.showingFrom<k&&k-e.showingFrom<20&&(k=Math.max(f.first,e.showingFrom)),e.showingTo>l&&e.showingTo-l<20&&(l=Math.min(j,e.showingTo)),v)for(k=oe(Ed(f,ke(f,k)));j>l&&Fd(f,ke(f,l));)++l;var m=[{from:Math.max(e.showingFrom,f.first),to:Math.min(e.showingTo,j)}];if(m=m[0].from>=m[0].to?[]:T(m,b),v)for(var i=0;i<m.length;++i)for(var o,n=m[i];o=Dd(ke(f,n.to-1));){var p=o.find().from.line;if(!(p>n.from)){m.splice(i--,1);break}n.to=p}for(var q=0,i=0;i<m.length;++i){var n=m[i];n.from<k&&(n.from=k),n.to>l&&(n.to=l),n.from>=n.to?m.splice(i--,1):q+=n.to-n.from}if(!d&&q==l-k&&k==e.showingFrom&&l==e.showingTo)return S(a),void 0;m.sort(function(a,b){return a.from-b.from});try{var r=document.activeElement}catch(s){}.7*(l-k)>q&&(e.lineDiv.style.display="none"),V(a,k,l,m,h),e.lineDiv.style.display="",r&&document.activeElement!=r&&r.offsetHeight&&r.focus();var t=k!=e.showingFrom||l!=e.showingTo||e.lastSizeC!=e.wrapper.clientHeight;return t&&(e.lastSizeC=e.wrapper.clientHeight,ab(a,400)),e.showingFrom=k,e.showingTo=l,R(a),S(a),!0}}function R(a){for(var f,b=a.display,d=b.lineDiv.offsetTop,e=b.lineDiv.firstChild;e;e=e.nextSibling)if(e.lineObj){if(c){var g=e.offsetTop+e.offsetHeight;f=g-d,d=g}else{var h=of(e);f=h.bottom-h.top}var i=e.lineObj.height-f;if(2>f&&(f=zb(b)),i>.001||-.001>i){ne(e.lineObj,f);var j=e.lineObj.widgets;if(j)for(var k=0;k<j.length;++k)j[k].height=j[k].node.offsetHeight}}}function S(a){var b=a.display.viewOffset=qe(a,ke(a.doc,a.display.showingFrom));a.display.mover.style.top=b+"px"}function T(a,b){for(var c=0,d=b.length||0;d>c;++c){for(var e=b[c],f=[],g=e.diff||0,h=0,i=a.length;i>h;++h){var j=a[h];e.to<=j.from&&e.diff?f.push({from:j.from+g,to:j.to+g}):e.to<=j.from||e.from>=j.to?f.push(j):(e.from>j.from&&f.push({from:j.from,to:e.from}),e.to<j.to&&f.push({from:e.to+g,to:j.to+g}))}a=f}return a}function U(a){for(var b=a.display,c={},d={},e=b.gutters.firstChild,f=0;e;e=e.nextSibling,++f)c[a.options.gutters[f]]=e.offsetLeft,d[a.options.gutters[f]]=e.offsetWidth;return{fixedPos:O(b),gutterTotalWidth:b.gutters.offsetWidth,gutterLeft:c,gutterWidth:d,wrapperWidth:b.wrapper.clientWidth}}function V(a,b,c,d,f){function l(b){var c=b.nextSibling;return e&&p&&a.display.currentWheelTarget==b?(b.style.display="none",b.lineObj=null):b.parentNode.removeChild(b),c}var g=U(a),h=a.display,i=a.options.lineNumbers;d.length||e&&a.display.currentWheelTarget||lf(h.lineDiv);var j=h.lineDiv,k=j.firstChild,m=d.shift(),n=b;for(a.doc.iter(b,c,function(b){if(m&&m.to==n&&(m=d.shift()),Fd(a.doc,b)){if(0!=b.height&&ne(b,0),b.widgets&&k&&k.previousSibling)for(var c=0;c<b.widgets.length;++c){var e=b.widgets[c];if(e.showIfHidden){var h=k.previousSibling;if(/pre/i.test(h.nodeName)){var o=kf("div",null,null,"position: relative");h.parentNode.replaceChild(o,h),o.appendChild(h),h=o}var p=h.appendChild(kf("div",[e.node],"CodeMirror-linewidget"));e.handleMouseEvents||(p.ignoreEvents=!0),X(e,p,h,g)}}}else if(m&&m.from<=n&&m.to>n){for(;k.lineObj!=b;)k=l(k);i&&n>=f&&k.lineNumber&&nf(k.lineNumber,N(a.options,n)),k=k.nextSibling}else{if(b.widgets)for(var s,q=0,r=k;r&&20>q;++q,r=r.nextSibling)if(r.lineObj==b&&/div/i.test(r.nodeName)){s=r;break}var t=W(a,b,n,g,s);if(t!=s)j.insertBefore(t,k);else{for(;k!=s;)k=l(k);k=k.nextSibling}t.lineObj=b}++n});k;)k=l(k)}function W(a,b,d,e,f){var k,g=Wd(a,b),h=g.pre,i=b.gutterMarkers,j=a.display,l=g.bgClass?g.bgClass+" "+(b.bgClass||""):b.bgClass;if(!(a.options.lineNumbers||i||l||b.wrapClass||b.widgets))return h;if(f){f.alignable=null;for(var q,m=!0,n=0,o=null,p=f.firstChild;p;p=q)if(q=p.nextSibling,/\bCodeMirror-linewidget\b/.test(p.className)){for(var r=0;r<b.widgets.length;++r){var s=b.widgets[r];if(s.node==p.firstChild){s.above||o||(o=p),X(s,p,f,e),++n;break}}if(r==b.widgets.length){m=!1;break}}else f.removeChild(p);f.insertBefore(h,o),m&&n==b.widgets.length&&(k=f,f.className=b.wrapClass||"")}if(k||(k=kf("div",null,b.wrapClass,"position: relative"),k.appendChild(h)),l&&k.insertBefore(kf("div",null,l+" CodeMirror-linebackground"),k.firstChild),a.options.lineNumbers||i){var t=k.insertBefore(kf("div",null,null,"position: absolute; left: "+(a.options.fixedGutter?e.fixedPos:-e.gutterTotalWidth)+"px"),k.firstChild);if(a.options.fixedGutter&&(k.alignable||(k.alignable=[])).push(t),!a.options.lineNumbers||i&&i["CodeMirror-linenumbers"]||(k.lineNumber=t.appendChild(kf("div",N(a.options,d),"CodeMirror-linenumber CodeMirror-gutter-elt","left: "+e.gutterLeft["CodeMirror-linenumbers"]+"px; width: "+j.lineNumInnerWidth+"px"))),i)for(var u=0;u<a.options.gutters.length;++u){var v=a.options.gutters[u],w=i.hasOwnProperty(v)&&i[v];w&&t.appendChild(kf("div",[w],"CodeMirror-gutter-elt","left: "+e.gutterLeft[v]+"px; width: "+e.gutterWidth[v]+"px"))}}if(c&&(k.style.zIndex=2),b.widgets&&k!=f)for(var r=0,x=b.widgets;r<x.length;++r){var s=x[r],y=kf("div",[s.node],"CodeMirror-linewidget");s.handleMouseEvents||(y.ignoreEvents=!0),X(s,y,k,e),s.above?k.insertBefore(y,a.options.lineNumbers&&0!=b.height?t:h):k.appendChild(y),Pe(s,"redraw")}return k}function X(a,b,c,d){if(a.noHScroll){(c.alignable||(c.alignable=[])).push(b);var e=d.wrapperWidth;b.style.left=d.fixedPos+"px",a.coverGutter||(e-=d.gutterTotalWidth,b.style.paddingLeft=d.gutterTotalWidth+"px"),b.style.width=e+"px"}a.coverGutter&&(b.style.zIndex=5,b.style.position="relative",a.noHScroll||(b.style.marginLeft=-d.gutterTotalWidth+"px"))}function Y(a){var b=a.display,c=Bc(a.doc.sel.from,a.doc.sel.to);if(c||a.options.showCursorWhenSelecting?Z(a):b.cursor.style.display=b.otherCursor.style.display="none",c?b.selectionDiv.style.display="none":$(a),a.options.moveInputWithCursor){var d=ub(a,a.doc.sel.head,"div"),e=of(b.wrapper),f=of(b.lineDiv);b.inputDiv.style.top=Math.max(0,Math.min(b.wrapper.clientHeight-10,d.top+f.top-e.top))+"px",b.inputDiv.style.left=Math.max(0,Math.min(b.wrapper.clientWidth-10,d.left+f.left-e.left))+"px"}}function Z(a){var b=a.display,c=ub(a,a.doc.sel.head,"div");b.cursor.style.left=c.left+"px",b.cursor.style.top=c.top+"px",b.cursor.style.height=Math.max(0,c.bottom-c.top)*a.options.cursorHeight+"px",b.cursor.style.display="",c.other?(b.otherCursor.style.display="",b.otherCursor.style.left=c.other.left+"px",b.otherCursor.style.top=c.other.top+"px",b.otherCursor.style.height=.85*(c.other.bottom-c.other.top)+"px"):b.otherCursor.style.display="none"}function $(a){function h(a,b,c,d){0>b&&(b=0),e.appendChild(kf("div",null,"CodeMirror-selected","position: absolute; left: "+a+"px; top: "+b+"px; width: "+(null==c?f-a:c)+"px; height: "+(d-b)+"px"))}function i(b,d,e){function m(c,d){return tb(a,Ac(b,c),"div",i,d)}var k,l,i=ke(c,b),j=i.text.length;return zf(re(i),d||0,null==e?j:e,function(a,b,c){var n,o,p,i=m(a,"left");if(a==b)n=i,o=p=i.left;else{if(n=m(b-1,"right"),"rtl"==c){var q=i;i=n,n=q}o=i.left,p=n.right}null==d&&0==a&&(o=g),n.top-i.top>3&&(h(o,i.top,null,i.bottom),o=g,i.bottom<n.top&&h(o,i.bottom,null,n.top)),null==e&&b==j&&(p=f),(!k||i.top<k.top||i.top==k.top&&i.left<k.left)&&(k=i),(!l||n.bottom>l.bottom||n.bottom==l.bottom&&n.right>l.right)&&(l=n),g+1>o&&(o=g),h(o,n.top,p-o,n.bottom)}),{start:k,end:l}}var b=a.display,c=a.doc,d=a.doc.sel,e=document.createDocumentFragment(),f=b.lineSpace.offsetWidth,g=gb(a.display);if(d.from.line==d.to.line)i(d.from.line,d.from.ch,d.to.ch);else{var j=ke(c,d.from.line),k=ke(c,d.to.line),l=Ed(c,j)==Ed(c,k),m=i(d.from.line,d.from.ch,l?j.text.length:null).end,n=i(d.to.line,l?0:null,d.to.ch).start;l&&(m.top<n.top-2?(h(m.right,m.top,null,m.bottom),h(g,n.top,n.left,n.bottom)):h(m.right,m.top,n.left-m.right,m.bottom)),m.bottom<n.top&&h(g,m.bottom,null,n.top)}mf(b.selectionDiv,e),b.selectionDiv.style.display=""}function _(a){if(a.state.focused){var b=a.display;clearInterval(b.blinker);var c=!0;b.cursor.style.visibility=b.otherCursor.style.visibility="",a.options.cursorBlinkRate>0&&(b.blinker=setInterval(function(){b.cursor.style.visibility=b.otherCursor.style.visibility=(c=!c)?"":"hidden"},a.options.cursorBlinkRate))}}function ab(a,b){a.doc.mode.startState&&a.doc.frontier<a.display.showingTo&&a.state.highlight.set(b,ef(bb,a))}function bb(a){var b=a.doc;if(b.frontier<b.first&&(b.frontier=b.first),!(b.frontier>=a.display.showingTo)){var f,c=+new Date+a.options.workTime,d=gd(b.mode,db(a,b.frontier)),e=[];b.iter(b.frontier,Math.min(b.first+b.size,a.display.showingTo+500),function(g){if(b.frontier>=a.display.showingFrom){var h=g.styles;g.styles=Rd(a,g,d);for(var i=!h||h.length!=g.styles.length,j=0;!i&&j<h.length;++j)i=h[j]!=g.styles[j];i&&(f&&f.end==b.frontier?f.end++:e.push(f={start:b.frontier,end:b.frontier+1})),g.stateAfter=gd(b.mode,d)}else Td(a,g,d),g.stateAfter=0==b.frontier%5?gd(b.mode,d):null;return++b.frontier,+new Date>c?(ab(a,a.options.workDelay),!0):void 0}),e.length&&Eb(a,function(){for(var a=0;a<e.length;++a)Hb(this,e[a].start,e[a].end)})()}}function cb(a,b,c){for(var d,e,f=a.doc,g=a.doc.mode.innerMode?1e3:100,h=b,i=b-g;h>i;--h){if(h<=f.first)return f.first;var j=ke(f,h-1);if(j.stateAfter&&(!c||h<=f.frontier))return h;var k=Xe(j.text,null,a.options.tabSize);(null==e||d>k)&&(e=h-1,d=k)}return e}function db(a,b,c){var d=a.doc,e=a.display;if(!d.mode.startState)return!0;var f=cb(a,b,c),g=f>d.first&&ke(d,f-1).stateAfter;return g=g?gd(d.mode,g):hd(d.mode),d.iter(f,b,function(c){Td(a,c,g);var h=f==b-1||0==f%5||f>=e.showingFrom&&f<e.showingTo;c.stateAfter=h?gd(d.mode,g):null,++f}),g}function eb(a){return a.lineSpace.offsetTop}function fb(a){return a.mover.offsetHeight-a.lineSpace.offsetHeight}function gb(a){var b=mf(a.measure,kf("pre",null,null,"text-align: left")).appendChild(kf("span","x"));return b.offsetLeft}function hb(a,b,c,d,e){var f=-1;if(d=d||kb(a,b),d.crude){var g=d.left+c*d.width;return{left:g,right:g+d.width,top:d.top,bottom:d.bottom}}for(var h=c;;h+=f){var i=d[h];if(i)break;0>f&&0==h&&(f=1)}return e=h>c?"left":c>h?"right":e,"left"==e&&i.leftSide?i=i.leftSide:"right"==e&&i.rightSide&&(i=i.rightSide),{left:c>h?i.right:i.left,right:h>c?i.left:i.right,top:i.top,bottom:i.bottom}}function ib(a,b){for(var c=a.display.measureLineCache,d=0;d<c.length;++d){var e=c[d];if(e.text==b.text&&e.markedSpans==b.markedSpans&&a.display.scroller.clientWidth==e.width&&e.classes==b.textClass+"|"+b.wrapClass)return e}}function jb(a,b){var c=ib(a,b);c&&(c.text=c.measure=c.markedSpans=null)}function kb(a,b){var c=ib(a,b);if(c)return c.measure;var d=lb(a,b),e=a.display.measureLineCache,f={text:b.text,width:a.display.scroller.clientWidth,markedSpans:b.markedSpans,measure:d,classes:b.textClass+"|"+b.wrapClass};return 16==e.length?e[++a.display.measureLineCachePos%16]=f:e.push(f),d}function lb(a,e){function t(a){var b=a.top-p.top,c=a.bottom-p.top;c>s&&(c=s),0>b&&(b=0);for(var d=q.length-2;d>=0;d-=2){var e=q[d],f=q[d+1];if(!(e>c||b>f)&&(b>=e&&f>=c||e>=b&&c>=f||Math.min(c,f)-Math.max(b,e)>=c-b>>1)){q[d]=Math.min(b,e),q[d+1]=Math.max(c,f);break}}return 0>d&&(d=q.length,q.push(b,c)),{left:a.left-p.left,right:a.right-p.left,top:d,bottom:null}}function u(a){a.bottom=q[a.top+1],a.top=q[a.top]}if(!a.options.lineWrapping&&e.text.length>=a.options.crudeMeasuringFrom)return mb(a,e);var f=a.display,g=df(e.text.length),h=Wd(a,e,g,!0).pre;if(b&&!c&&!a.options.lineWrapping&&h.childNodes.length>100){for(var i=document.createDocumentFragment(),j=10,k=h.childNodes.length,l=0,m=Math.ceil(k/j);m>l;++l){for(var n=kf("div",null,null,"display: inline-block"),o=0;j>o&&k;++o)n.appendChild(h.firstChild),--k;i.appendChild(n)}h.appendChild(i)}mf(f.measure,h);var p=of(f.lineDiv),q=[],r=df(e.text.length),s=h.offsetHeight;d&&f.measure.first!=h&&mf(f.measure,h);for(var v,l=0;l<g.length;++l)if(v=g[l]){var w=v,x=null;if(/\bCodeMirror-widget\b/.test(v.className)&&v.getClientRects){1==v.firstChild.nodeType&&(w=v.firstChild);var y=w.getClientRects();y.length>1&&(x=r[l]=t(y[0]),x.rightSide=t(y[y.length-1]))}x||(x=r[l]=t(of(w))),v.measureRight&&(x.right=of(v.measureRight).left),v.leftSide&&(x.leftSide=t(of(v.leftSide)))}lf(a.display.measure);for(var v,l=0;l<r.length;++l)(v=r[l])&&(u(v),v.leftSide&&u(v.leftSide),v.rightSide&&u(v.rightSide));return r}function mb(a,b){var c=new Nd(b.text.slice(0,100),null);b.textClass&&(c.textClass=b.textClass);var d=lb(a,c),e=hb(a,c,0,d,"left"),f=hb(a,c,99,d,"right");return{crude:!0,top:e.top,left:e.left,bottom:e.bottom,width:(f.right-e.left)/100}}function nb(a,b){var c=!1;if(b.markedSpans)for(var d=0;d<b.markedSpans;++d){var e=b.markedSpans[d];!e.collapsed||null!=e.to&&e.to!=b.text.length||(c=!0)}var f=!c&&ib(a,b);if(f||b.text.length>=a.options.crudeMeasuringFrom)return hb(a,b,b.text.length,f&&f.measure,"right").right;var g=Wd(a,b,null,!0).pre,h=g.appendChild(uf(a.display.measure));return mf(a.display.measure,g),of(h).right-of(a.display.lineDiv).left}function ob(a){a.display.measureLineCache.length=a.display.measureLineCachePos=0,a.display.cachedCharWidth=a.display.cachedTextHeight=null,a.options.lineWrapping||(a.display.maxLineChanged=!0),a.display.lineNumChars=null}function pb(){return window.pageXOffset||(document.documentElement||document.body).scrollLeft}function qb(){return window.pageYOffset||(document.documentElement||document.body).scrollTop}function rb(a,b,c,d){if(b.widgets)for(var e=0;e<b.widgets.length;++e)if(b.widgets[e].above){var f=Ld(b.widgets[e]);c.top+=f,c.bottom+=f}if("line"==d)return c;d||(d="local");var g=qe(a,b);if("local"==d?g+=eb(a.display):g-=a.display.viewOffset,"page"==d||"window"==d){var h=of(a.display.lineSpace);g+=h.top+("window"==d?0:qb());var i=h.left+("window"==d?0:pb());c.left+=i,c.right+=i}return c.top+=g,c.bottom+=g,c}function sb(a,b,c){if("div"==c)return b;var d=b.left,e=b.top;if("page"==c)d-=pb(),e-=qb();else if("local"==c||!c){var f=of(a.display.sizer);d+=f.left,e+=f.top}var g=of(a.display.lineSpace);return{left:d-g.left,top:e-g.top}}function tb(a,b,c,d,e){return d||(d=ke(a.doc,b.line)),rb(a,d,hb(a,d,b.ch,null,e),c)}function ub(a,b,c,d,e){function f(b,f){var g=hb(a,d,b,e,f?"right":"left");return f?g.left=g.right:g.right=g.left,rb(a,d,g,c)}function g(a,b){var c=h[b],d=c.level%2;return a==Af(c)&&b&&c.level<h[b-1].level?(c=h[--b],a=Bf(c)-(c.level%2?0:1),d=!0):a==Bf(c)&&b<h.length-1&&c.level<h[b+1].level&&(c=h[++b],a=Af(c)-c.level%2,d=!1),d&&a==c.to&&a>c.from?f(a-1):f(a,d)}d=d||ke(a.doc,b.line),e||(e=kb(a,d));var h=re(d),i=b.ch;if(!h)return f(i);var j=If(h,i),k=g(i,j);return null!=Hf&&(k.other=g(i,Hf)),k}function vb(a,b,c,d){var e=new Ac(a,b);return e.xRel=d,c&&(e.outside=!0),e}function wb(a,b,c){var d=a.doc;if(c+=a.display.viewOffset,0>c)return vb(d.first,0,!0,-1);var e=pe(d,c),f=d.first+d.size-1;if(e>f)return vb(d.first+d.size-1,ke(d,f).text.length,!0,1);for(0>b&&(b=0);;){var g=ke(d,e),h=xb(a,g,e,b,c),i=Dd(g),j=i&&i.find();if(!i||!(h.ch>j.from.ch||h.ch==j.from.ch&&h.xRel>0))return h;e=j.to.line}}function xb(a,b,c,d,e){function j(d){var e=ub(a,Ac(c,d),"line",b,i);return g=!0,f>e.bottom?e.left-h:f<e.top?e.left+h:(g=!1,e.left)}var f=e-qe(a,b),g=!1,h=2*a.display.wrapper.clientWidth,i=kb(a,b),k=re(b),l=b.text.length,m=Cf(b),n=Df(b),o=j(m),p=g,q=j(n),r=g;if(d>q)return vb(c,n,r,1);for(;;){if(k?n==m||n==Kf(b,m,1):1>=n-m){for(var s=o>d||q-d>=d-o?m:n,t=d-(s==m?o:q);jf.test(b.text.charAt(s));)++s;var u=vb(c,s,s==m?p:r,0>t?-1:t?1:0);return u}var v=Math.ceil(l/2),w=m+v;if(k){w=m;for(var x=0;v>x;++x)w=Kf(b,w,1)}var y=j(w);y>d?(n=w,q=y,(r=g)&&(q+=1e3),l=v):(m=w,o=y,p=g,l-=v)}}function zb(a){if(null!=a.cachedTextHeight)return a.cachedTextHeight;if(null==yb){yb=kf("pre");for(var b=0;49>b;++b)yb.appendChild(document.createTextNode("x")),yb.appendChild(kf("br"));yb.appendChild(document.createTextNode("x"))}mf(a.measure,yb);var c=yb.offsetHeight/50;return c>3&&(a.cachedTextHeight=c),lf(a.measure),c||1}function Ab(a){if(null!=a.cachedCharWidth)return a.cachedCharWidth;var b=kf("span","x"),c=kf("pre",[b]);mf(a.measure,c);var d=b.offsetWidth;return d>2&&(a.cachedCharWidth=d),d||10}function Cb(a){a.curOp={changes:[],forceUpdate:!1,updateInput:null,userSelChange:null,textChanged:null,selectionChanged:!1,cursorActivity:!1,updateMaxLine:!1,updateScrollPos:!1,id:++Bb},Oe++||(Ne=[])}function Db(a){var b=a.curOp,c=a.doc,d=a.display;if(a.curOp=null,b.updateMaxLine&&H(a),d.maxLineChanged&&!a.options.lineWrapping&&d.maxLine){var e=nb(a,d.maxLine);d.sizer.style.minWidth=Math.max(0,e+3+Ue)+"px",d.maxLineChanged=!1;var f=Math.max(0,d.sizer.offsetLeft+d.sizer.offsetWidth-d.scroller.clientWidth);f<c.scrollLeft&&!b.updateScrollPos&&_b(a,Math.min(d.scroller.scrollLeft,f),!0)}var g,h;if(b.updateScrollPos)g=b.updateScrollPos;else if(b.selectionChanged&&d.scroller.clientHeight){var i=ub(a,c.sel.head);g=Qc(a,i.left,i.top,i.left,i.bottom)}(b.changes.length||b.forceUpdate||g&&null!=g.scrollTop)&&(h=P(a,b.changes,g&&g.scrollTop,b.forceUpdate),a.display.scroller.offsetHeight&&(a.doc.scrollTop=a.display.scroller.scrollTop)),!h&&b.selectionChanged&&Y(a),b.updateScrollPos?(d.scroller.scrollTop=d.scrollbarV.scrollTop=c.scrollTop=g.scrollTop,d.scroller.scrollLeft=d.scrollbarH.scrollLeft=c.scrollLeft=g.scrollLeft,L(a),b.scrollToPos&&Oc(a,Fc(a.doc,b.scrollToPos),b.scrollToPosMargin)):g&&Nc(a),b.selectionChanged&&_(a),a.state.focused&&b.updateInput&&Lb(a,b.userSelChange);var j=b.maybeHiddenMarkers,k=b.maybeUnhiddenMarkers;if(j)for(var l=0;l<j.length;++l)j[l].lines.length||Me(j[l],"hide");if(k)for(var l=0;l<k.length;++l)k[l].lines.length&&Me(k[l],"unhide");var m;if(--Oe||(m=Ne,Ne=null),b.textChanged&&Me(a,"change",a,b.textChanged),b.cursorActivity&&Me(a,"cursorActivity",a),m)for(var l=0;l<m.length;++l)m[l]()}function Eb(a,b){return function(){var c=a||this,d=!c.curOp;d&&Cb(c);try{var e=b.apply(c,arguments)}finally{d&&Db(c)}return e}}function Fb(a){return function(){var c,b=this.cm&&!this.cm.curOp;b&&Cb(this.cm);try{c=a.apply(this,arguments)}finally{b&&Db(this.cm)}return c}}function Gb(a,b){var d,c=!a.curOp;c&&Cb(a);try{d=b()}finally{c&&Db(a)}return d}function Hb(a,b,c,d){null==b&&(b=a.doc.first),null==c&&(c=a.doc.first+a.doc.size),a.curOp.changes.push({from:b,to:c,diff:d})}function Ib(a){a.display.pollingFast||a.display.poll.set(a.options.pollInterval,function(){Kb(a),a.state.focused&&Ib(a)})}function Jb(a){function c(){var d=Kb(a);d||b?(a.display.pollingFast=!1,Ib(a)):(b=!0,a.display.poll.set(60,c))}var b=!1;a.display.pollingFast=!0,a.display.poll.set(20,c)}function Kb(a){var c=a.display.input,e=a.display.prevInput,f=a.doc,g=f.sel;if(!a.state.focused||wf(c)||Nb(a)||a.state.disableInput)return!1;a.state.pasteIncoming&&a.state.fakedLastChar&&(c.value=c.value.substring(0,c.value.length-1),a.state.fakedLastChar=!1);var h=c.value;if(h==e&&Bc(g.from,g.to))return!1;if(b&&!d&&a.display.inputHasSelection===h)return Lb(a,!0),!1;var i=!a.curOp;i&&Cb(a),g.shift=!1;for(var j=0,k=Math.min(e.length,h.length);k>j&&e.charCodeAt(j)==h.charCodeAt(j);)++j;var l=g.from,m=g.to;j<e.length?l=Ac(l.line,l.ch-(e.length-j)):a.state.overwrite&&Bc(l,m)&&!a.state.pasteIncoming&&(m=Ac(m.line,Math.min(ke(f,m.line).text.length,m.ch+(h.length-j))));var n=a.curOp.updateInput,o={from:l,to:m,text:vf(h.slice(j)),origin:a.state.pasteIncoming?"paste":"+input"};return tc(a.doc,o,"end"),a.curOp.updateInput=n,Pe(a,"inputRead",a,o),h.length>1e3||h.indexOf("\n")>-1?c.value=a.display.prevInput="":a.display.prevInput=h,i&&Db(a),a.state.pasteIncoming=!1,!0}function Lb(a,c){var e,f,g=a.doc;if(Bc(g.sel.from,g.sel.to))c&&(a.display.prevInput=a.display.input.value="",b&&!d&&(a.display.inputHasSelection=null));else{a.display.prevInput="",e=xf&&(g.sel.to.line-g.sel.from.line>100||(f=a.getSelection()).length>1e3);var h=e?"-":f||a.getSelection();a.display.input.value=h,a.state.focused&&_e(a.display.input),b&&!d&&(a.display.inputHasSelection=h)}a.display.inaccurateSelection=e}function Mb(a){"nocursor"==a.options.readOnly||o&&document.activeElement==a.display.input||a.display.input.focus()}function Nb(a){return a.options.readOnly||a.doc.cantEdit}function Ob(a){function f(){a.state.focused&&setTimeout(ef(Mb,a),0)}function h(){null==g&&(g=setTimeout(function(){g=null,c.cachedCharWidth=c.cachedTextHeight=rf=null,ob(a),Gb(a,ef(Hb,a))},100))}function i(){for(var a=c.wrapper.parentNode;a&&a!=document.body;a=a.parentNode);a?setTimeout(i,5e3):Le(window,"resize",h)}function k(b){Qe(a,b)||a.options.onDragEvent&&a.options.onDragEvent(a,De(b))||He(b)}function l(){c.inaccurateSelection&&(c.prevInput="",c.inaccurateSelection=!1,c.input.value=a.getSelection(),_e(c.input))}var c=a.display;Ke(c.scroller,"mousedown",Eb(a,Tb)),b?Ke(c.scroller,"dblclick",Eb(a,function(b){if(!Qe(a,b)){var c=Qb(a,b);if(c&&!Wb(a,b)&&!Pb(a.display,b)){Ee(b);var d=Xc(ke(a.doc,c.line).text,c);Ic(a.doc,d.from,d.to)}}})):Ke(c.scroller,"dblclick",function(b){Qe(a,b)||Ee(b)}),Ke(c.lineSpace,"selectstart",function(a){Pb(c,a)||Ee(a)}),t||Ke(c.scroller,"contextmenu",function(b){oc(a,b)}),Ke(c.scroller,"scroll",function(){c.scroller.clientHeight&&($b(a,c.scroller.scrollTop),_b(a,c.scroller.scrollLeft,!0),Me(a,"scroll",a))}),Ke(c.scrollbarV,"scroll",function(){c.scroller.clientHeight&&$b(a,c.scrollbarV.scrollTop)}),Ke(c.scrollbarH,"scroll",function(){c.scroller.clientHeight&&_b(a,c.scrollbarH.scrollLeft)}),Ke(c.scroller,"mousewheel",function(b){cc(a,b)}),Ke(c.scroller,"DOMMouseScroll",function(b){cc(a,b)}),Ke(c.scrollbarH,"mousedown",f),Ke(c.scrollbarV,"mousedown",f),Ke(c.wrapper,"scroll",function(){c.wrapper.scrollTop=c.wrapper.scrollLeft=0});var g;Ke(window,"resize",h),setTimeout(i,5e3),Ke(c.input,"keyup",Eb(a,function(b){Qe(a,b)||a.options.onKeyEvent&&a.options.onKeyEvent(a,De(b))||16==b.keyCode&&(a.doc.sel.shift=!1)})),Ke(c.input,"input",function(){b&&!d&&a.display.inputHasSelection&&(a.display.inputHasSelection=null),Jb(a)}),Ke(c.input,"keydown",Eb(a,jc)),Ke(c.input,"keypress",Eb(a,kc)),Ke(c.input,"focus",ef(lc,a)),Ke(c.input,"blur",ef(mc,a)),a.options.dragDrop&&(Ke(c.scroller,"dragstart",function(b){Zb(a,b)}),Ke(c.scroller,"dragenter",k),Ke(c.scroller,"dragover",k),Ke(c.scroller,"drop",Eb(a,Yb))),Ke(c.scroller,"paste",function(b){Pb(c,b)||(Mb(a),Jb(a))}),Ke(c.input,"paste",function(){if(e&&!a.state.fakedLastChar&&!(new Date-a.state.lastMiddleDown<200)){var b=c.input.selectionStart,d=c.input.selectionEnd;c.input.value+="$",c.input.selectionStart=b,c.input.selectionEnd=d,a.state.fakedLastChar=!0}a.state.pasteIncoming=!0,Jb(a)}),Ke(c.input,"cut",l),Ke(c.input,"copy",l),j&&Ke(c.sizer,"mouseup",function(){document.activeElement==c.input&&c.input.blur(),Mb(a)})}function Pb(a,b){for(var c=Ie(b);c!=a.wrapper;c=c.parentNode)if(!c||c.ignoreEvents||c.parentNode==a.sizer&&c!=a.mover)return!0}function Qb(a,b,c){var d=a.display;if(!c){var e=Ie(b);if(e==d.scrollbarH||e==d.scrollbarH.firstChild||e==d.scrollbarV||e==d.scrollbarV.firstChild||e==d.scrollbarFiller||e==d.gutterFiller)return null}var f,g,h=of(d.lineSpace);try{f=b.clientX,g=b.clientY}catch(b){return null}return wb(a,f-h.left,g-h.top)}function Tb(a){function q(a){if(!Bc(p,a)){if(p=a,"single"==j)return Ic(c.doc,Fc(f,h),a),void 0;if(n=Fc(f,n),o=Fc(f,o),"double"==j){var b=Xc(ke(f,a.line).text,a);Cc(a,n)?Ic(c.doc,b.from,o):Ic(c.doc,n,b.to)}else"triple"==j&&(Cc(a,n)?Ic(c.doc,o,Fc(f,Ac(a.line,0))):Ic(c.doc,n,Fc(f,Ac(a.line+1,0))))
3
+ }}function u(a){var b=++s,e=Qb(c,a,!0);if(e)if(Bc(e,l)){var h=a.clientY<r.top?-20:a.clientY>r.bottom?20:0;h&&setTimeout(Eb(c,function(){s==b&&(d.scroller.scrollTop+=h,u(a))}),50)}else{c.state.focused||lc(c),l=e,q(e);var g=K(d,f);(e.line>=g.to||e.line<g.from)&&setTimeout(Eb(c,function(){s==b&&u(a)}),150)}}function v(a){s=1/0,Ee(a),Mb(c),Le(document,"mousemove",w),Le(document,"mouseup",x)}if(!Qe(this,a)){var c=this,d=c.display,f=c.doc,g=f.sel;if(g.shift=a.shiftKey,Pb(d,a))return e||(d.scroller.draggable=!1,setTimeout(function(){d.scroller.draggable=!0},100)),void 0;if(!Wb(c,a)){var h=Qb(c,a);switch(Je(a)){case 3:return t&&oc.call(c,c,a),void 0;case 2:return e&&(c.state.lastMiddleDown=+new Date),h&&Ic(c.doc,h),setTimeout(ef(Mb,c),20),Ee(a),void 0}if(!h)return Ie(a)==d.scroller&&Ee(a),void 0;c.state.focused||lc(c);var i=+new Date,j="single";if(Sb&&Sb.time>i-400&&Bc(Sb.pos,h))j="triple",Ee(a),setTimeout(ef(Mb,c),20),Yc(c,h.line);else if(Rb&&Rb.time>i-400&&Bc(Rb.pos,h)){j="double",Sb={time:i,pos:h},Ee(a);var k=Xc(ke(f,h.line).text,h);Ic(c.doc,k.from,k.to)}else Rb={time:i,pos:h};var l=h;if(c.options.dragDrop&&pf&&!Nb(c)&&!Bc(g.from,g.to)&&!Cc(h,g.from)&&!Cc(g.to,h)&&"single"==j){var m=Eb(c,function(b){e&&(d.scroller.draggable=!1),c.state.draggingText=!1,Le(document,"mouseup",m),Le(d.scroller,"drop",m),Math.abs(a.clientX-b.clientX)+Math.abs(a.clientY-b.clientY)<10&&(Ee(b),Ic(c.doc,h),Mb(c))});return e&&(d.scroller.draggable=!0),c.state.draggingText=m,d.scroller.dragDrop&&d.scroller.dragDrop(),Ke(document,"mouseup",m),Ke(d.scroller,"drop",m),void 0}Ee(a),"single"==j&&Ic(c.doc,Fc(f,h));var n=g.from,o=g.to,p=h,r=of(d.wrapper),s=0,w=Eb(c,function(a){b||Je(a)?u(a):v(a)}),x=Eb(c,v);Ke(document,"mousemove",w),Ke(document,"mouseup",x)}}}function Ub(a,b,c,d,e){try{var f=b.clientX,g=b.clientY}catch(b){return!1}if(f>=Math.floor(of(a.display.gutters).right))return!1;d&&Ee(b);var h=a.display,i=of(h.lineDiv);if(g>i.bottom||!Se(a,c))return Ge(b);g-=i.top-h.viewOffset;for(var j=0;j<a.options.gutters.length;++j){var k=h.gutters.childNodes[j];if(k&&of(k).right>=f){var l=pe(a.doc,g),m=a.options.gutters[j];return e(a,c,a,l,m,b),Ge(b)}}}function Vb(a,b){return Se(a,"gutterContextMenu")?Ub(a,b,"gutterContextMenu",!1,Me):!1}function Wb(a,b){return Ub(a,b,"gutterClick",!0,Pe)}function Yb(a){var c=this;if(!(Qe(c,a)||Pb(c.display,a)||c.options.onDragEvent&&c.options.onDragEvent(c,De(a)))){Ee(a),b&&(Xb=+new Date);var d=Qb(c,a,!0),e=a.dataTransfer.files;if(d&&!Nb(c))if(e&&e.length&&window.FileReader&&window.File)for(var f=e.length,g=Array(f),h=0,i=function(a,b){var e=new FileReader;e.onload=function(){g[b]=e.result,++h==f&&(d=Fc(c.doc,d),tc(c.doc,{from:d,to:d,text:vf(g.join("\n")),origin:"paste"},"around"))},e.readAsText(a)},j=0;f>j;++j)i(e[j],j);else{if(c.state.draggingText&&!Cc(d,c.doc.sel.from)&&!Cc(c.doc.sel.to,d))return c.state.draggingText(a),setTimeout(ef(Mb,c),20),void 0;try{var g=a.dataTransfer.getData("Text");if(g){var k=c.doc.sel.from,l=c.doc.sel.to;Kc(c.doc,d,d),c.state.draggingText&&zc(c.doc,"",k,l,"paste"),c.replaceSelection(g,null,"paste"),Mb(c),lc(c)}}catch(a){}}}}function Zb(a,c){if(b&&(!a.state.draggingText||+new Date-Xb<100))return He(c),void 0;if(!Qe(a,c)&&!Pb(a.display,c)){var d=a.getSelection();if(c.dataTransfer.setData("Text",d),c.dataTransfer.setDragImage&&!i){var e=kf("img",null,null,"position: fixed; left: 0; top: 0;");e.src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==",h&&(e.width=e.height=1,a.display.wrapper.appendChild(e),e._top=e.offsetTop),c.dataTransfer.setDragImage(e,0,0),h&&e.parentNode.removeChild(e)}}}function $b(b,c){Math.abs(b.doc.scrollTop-c)<2||(b.doc.scrollTop=c,a||P(b,[],c),b.display.scroller.scrollTop!=c&&(b.display.scroller.scrollTop=c),b.display.scrollbarV.scrollTop!=c&&(b.display.scrollbarV.scrollTop=c),a&&P(b,[]),ab(b,100))}function _b(a,b,c){(c?b==a.doc.scrollLeft:Math.abs(a.doc.scrollLeft-b)<2)||(b=Math.min(b,a.display.scroller.scrollWidth-a.display.scroller.clientWidth),a.doc.scrollLeft=b,L(a),a.display.scroller.scrollLeft!=b&&(a.display.scroller.scrollLeft=b),a.display.scrollbarH.scrollLeft!=b&&(a.display.scrollbarH.scrollLeft=b))}function cc(b,c){var d=c.wheelDeltaX,f=c.wheelDeltaY;null==d&&c.detail&&c.axis==c.HORIZONTAL_AXIS&&(d=c.detail),null==f&&c.detail&&c.axis==c.VERTICAL_AXIS?f=c.detail:null==f&&(f=c.wheelDelta);var g=b.display,i=g.scroller;if(d&&i.scrollWidth>i.clientWidth||f&&i.scrollHeight>i.clientHeight){if(f&&p&&e)for(var j=c.target;j!=i;j=j.parentNode)if(j.lineObj){b.display.currentWheelTarget=j;break}if(d&&!a&&!h&&null!=bc)return f&&$b(b,Math.max(0,Math.min(i.scrollTop+f*bc,i.scrollHeight-i.clientHeight))),_b(b,Math.max(0,Math.min(i.scrollLeft+d*bc,i.scrollWidth-i.clientWidth))),Ee(c),g.wheelStartX=null,void 0;if(f&&null!=bc){var k=f*bc,l=b.doc.scrollTop,m=l+g.wrapper.clientHeight;0>k?l=Math.max(0,l+k-50):m=Math.min(b.doc.height,m+k+50),P(b,[],{top:l,bottom:m})}20>ac&&(null==g.wheelStartX?(g.wheelStartX=i.scrollLeft,g.wheelStartY=i.scrollTop,g.wheelDX=d,g.wheelDY=f,setTimeout(function(){if(null!=g.wheelStartX){var a=i.scrollLeft-g.wheelStartX,b=i.scrollTop-g.wheelStartY,c=b&&g.wheelDY&&b/g.wheelDY||a&&g.wheelDX&&a/g.wheelDX;g.wheelStartX=g.wheelStartY=null,c&&(bc=(bc*ac+c)/(ac+1),++ac)}},200)):(g.wheelDX+=d,g.wheelDY+=f))}}function dc(a,b,c){if("string"==typeof b&&(b=id[b],!b))return!1;a.display.pollingFast&&Kb(a)&&(a.display.pollingFast=!1);var d=a.doc,e=d.sel.shift,f=!1;try{Nb(a)&&(a.state.suppressEdits=!0),c&&(d.sel.shift=!1),f=b(a)!=Ve}finally{d.sel.shift=e,a.state.suppressEdits=!1}return f}function ec(a){var b=a.state.keyMaps.slice(0);return a.options.extraKeys&&b.push(a.options.extraKeys),b.push(a.options.keyMap),b}function gc(a,b){var c=kd(a.options.keyMap),e=c.auto;clearTimeout(fc),e&&!md(b)&&(fc=setTimeout(function(){kd(a.options.keyMap)==c&&(a.options.keyMap=e.call?e.call(null,a):e,C(a))},50));var f=nd(b,!0),g=!1;if(!f)return!1;var h=ec(a);return g=b.shiftKey?ld("Shift-"+f,h,function(b){return dc(a,b,!0)})||ld(f,h,function(b){return("string"==typeof b?/^go[A-Z]/.test(b):b.motion)?dc(a,b):void 0}):ld(f,h,function(b){return dc(a,b)}),g&&(Ee(b),_(a),d&&(b.oldKeyCode=b.keyCode,b.keyCode=0),Pe(a,"keyHandled",a,f,b)),g}function hc(a,b,c){var d=ld("'"+c+"'",ec(a),function(b){return dc(a,b,!0)});return d&&(Ee(b),_(a),Pe(a,"keyHandled",a,"'"+c+"'",b)),d}function jc(a){var c=this;if(c.state.focused||lc(c),!(Qe(c,a)||c.options.onKeyEvent&&c.options.onKeyEvent(c,De(a)))){b&&27==a.keyCode&&(a.returnValue=!1);var d=a.keyCode;c.doc.sel.shift=16==d||a.shiftKey;var e=gc(c,a);h&&(ic=e?d:null,!e&&88==d&&!xf&&(p?a.metaKey:a.ctrlKey)&&c.replaceSelection(""))}}function kc(a){var c=this;if(!(Qe(c,a)||c.options.onKeyEvent&&c.options.onKeyEvent(c,De(a)))){var e=a.keyCode,f=a.charCode;if(h&&e==ic)return ic=null,Ee(a),void 0;if(!(h&&(!a.which||a.which<10)||j)||!gc(c,a)){var g=String.fromCharCode(null==f?e:f);this.options.electricChars&&this.doc.mode.electricChars&&this.options.smartIndent&&!Nb(this)&&this.doc.mode.electricChars.indexOf(g)>-1&&setTimeout(Eb(c,function(){Tc(c,c.doc.sel.to.line,"smart")}),75),hc(c,a,g)||(b&&!d&&(c.display.inputHasSelection=null),Jb(c))}}}function lc(a){"nocursor"!=a.options.readOnly&&(a.state.focused||(Me(a,"focus",a),a.state.focused=!0,-1==a.display.wrapper.className.search(/\bCodeMirror-focused\b/)&&(a.display.wrapper.className+=" CodeMirror-focused"),a.curOp||(Lb(a,!0),e&&setTimeout(ef(Lb,a,!0),0))),Ib(a),_(a))}function mc(a){a.state.focused&&(Me(a,"blur",a),a.state.focused=!1,a.display.wrapper.className=a.display.wrapper.className.replace(" CodeMirror-focused","")),clearInterval(a.display.blinker),setTimeout(function(){a.state.focused||(a.doc.sel.shift=!1)},150)}function oc(a,c){function k(){if(null!=e.input.selectionStart){var a=e.input.value="\u200b"+(Bc(f.from,f.to)?"":e.input.value);e.prevInput="\u200b",e.input.selectionStart=1,e.input.selectionEnd=a.length}}function l(){if(e.inputDiv.style.position="relative",e.input.style.cssText=j,d&&(e.scrollbarV.scrollTop=e.scroller.scrollTop=i),Ib(a),null!=e.input.selectionStart){(!b||d)&&k(),clearTimeout(nc);var c=0,f=function(){" "==e.prevInput&&0==e.input.selectionStart?Eb(a,id.selectAll)(a):c++<10?nc=setTimeout(f,500):Lb(a)};nc=setTimeout(f,200)}}if(!Qe(a,c,"contextmenu")){var e=a.display,f=a.doc.sel;if(!Pb(e,c)&&!Vb(a,c)){var g=Qb(a,c),i=e.scroller.scrollTop;if(g&&!h){(Bc(f.from,f.to)||Cc(g,f.from)||!Cc(g,f.to))&&Eb(a,Kc)(a.doc,g,g);var j=e.input.style.cssText;if(e.inputDiv.style.position="absolute",e.input.style.cssText="position: fixed; width: 30px; height: 30px; top: "+(c.clientY-5)+"px; left: "+(c.clientX-5)+"px; z-index: 1000; background: white; outline: none;"+"border-width: 0; outline: none; overflow: hidden; opacity: .05; -ms-opacity: .05; filter: alpha(opacity=5);",Mb(a),Lb(a,!0),Bc(f.from,f.to)&&(e.input.value=e.prevInput=" "),b&&!d&&k(),t){He(c);var m=function(){Le(window,"mouseup",m),setTimeout(l,20)};Ke(window,"mouseup",m)}else setTimeout(l,50)}}}}function qc(a,b,c){if(!Cc(b.from,c))return Fc(a,c);var d=b.text.length-1-(b.to.line-b.from.line);if(c.line>b.to.line+d){var e=c.line-d,f=a.first+a.size-1;return e>f?Ac(f,ke(a,f).text.length):Gc(c,ke(a,e).text.length)}if(c.line==b.to.line+d)return Gc(c,$e(b.text).length+(1==b.text.length?b.from.ch:0)+ke(a,b.to.line).text.length-b.to.ch);var g=c.line-b.from.line;return Gc(c,b.text[g].length+(g?0:b.from.ch))}function rc(a,b,c){if(c&&"object"==typeof c)return{anchor:qc(a,b,c.anchor),head:qc(a,b,c.head)};if("start"==c)return{anchor:b.from,head:b.from};var d=pc(b);if("around"==c)return{anchor:b.from,head:d};if("end"==c)return{anchor:d,head:d};var e=function(a){if(Cc(a,b.from))return a;if(!Cc(b.to,a))return d;var c=a.line+b.text.length-(b.to.line-b.from.line)-1,e=a.ch;return a.line==b.to.line&&(e+=d.ch-b.to.ch),Ac(c,e)};return{anchor:e(a.sel.anchor),head:e(a.sel.head)}}function sc(a,b,c){var d={canceled:!1,from:b.from,to:b.to,text:b.text,origin:b.origin,cancel:function(){this.canceled=!0}};return c&&(d.update=function(b,c,d,e){b&&(this.from=Fc(a,b)),c&&(this.to=Fc(a,c)),d&&(this.text=d),void 0!==e&&(this.origin=e)}),Me(a,"beforeChange",a,d),a.cm&&Me(a.cm,"beforeChange",a.cm,d),d.canceled?null:{from:d.from,to:d.to,text:d.text,origin:d.origin}}function tc(a,b,c,d){if(a.cm){if(!a.cm.curOp)return Eb(a.cm,tc)(a,b,c,d);if(a.cm.state.suppressEdits)return}if(!(Se(a,"beforeChange")||a.cm&&Se(a.cm,"beforeChange"))||(b=sc(a,b,!0))){var e=u&&!d&&Ad(a,b.from,b.to);if(e){for(var f=e.length-1;f>=1;--f)uc(a,{from:e[f].from,to:e[f].to,text:[""]});e.length&&uc(a,{from:e[0].from,to:e[0].to,text:b.text},c)}else uc(a,b,c)}}function uc(a,b,c){if(1!=b.text.length||""!=b.text[0]||!Bc(b.from,b.to)){var d=rc(a,b,c);ve(a,b,d,a.cm?a.cm.curOp.id:0/0),xc(a,b,d,yd(a,b));var e=[];ie(a,function(a,c){c||-1!=af(e,a.history)||(Be(a.history,b),e.push(a.history)),xc(a,b,null,yd(a,b))})}}function vc(a,b){if(!a.cm||!a.cm.state.suppressEdits){var c=a.history,d=("undo"==b?c.done:c.undone).pop();if(d){var e={changes:[],anchorBefore:d.anchorAfter,headBefore:d.headAfter,anchorAfter:d.anchorBefore,headAfter:d.headBefore,generation:c.generation};("undo"==b?c.undone:c.done).push(e),c.generation=d.generation||++c.maxGeneration;for(var f=Se(a,"beforeChange")||a.cm&&Se(a.cm,"beforeChange"),g=d.changes.length-1;g>=0;--g){var h=d.changes[g];if(h.origin=b,f&&!sc(a,h,!1))return("undo"==b?c.done:c.undone).length=0,void 0;e.changes.push(ue(a,h));var i=g?rc(a,h,null):{anchor:d.anchorBefore,head:d.headBefore};xc(a,h,i,zd(a,h));var j=[];ie(a,function(a,b){b||-1!=af(j,a.history)||(Be(a.history,h),j.push(a.history)),xc(a,h,null,zd(a,h))})}}}}function wc(a,b){function c(a){return Ac(a.line+b,a.ch)}a.first+=b,a.cm&&Hb(a.cm,a.first,a.first,b),a.sel.head=c(a.sel.head),a.sel.anchor=c(a.sel.anchor),a.sel.from=c(a.sel.from),a.sel.to=c(a.sel.to)}function xc(a,b,c,d){if(a.cm&&!a.cm.curOp)return Eb(a.cm,xc)(a,b,c,d);if(b.to.line<a.first)return wc(a,b.text.length-1-(b.to.line-b.from.line)),void 0;if(!(b.from.line>a.lastLine())){if(b.from.line<a.first){var e=b.text.length-1-(a.first-b.from.line);wc(a,e),b={from:Ac(a.first,0),to:Ac(b.to.line+e,b.to.ch),text:[$e(b.text)],origin:b.origin}}var f=a.lastLine();b.to.line>f&&(b={from:b.from,to:Ac(f,ke(a,f).text.length),text:[b.text[0]],origin:b.origin}),b.removed=le(a,b.from,b.to),c||(c=rc(a,b,null)),a.cm?yc(a.cm,b,d,c):be(a,b,d,c)}}function yc(a,b,c,d){var e=a.doc,f=a.display,g=b.from,h=b.to,i=!1,j=g.line;a.options.lineWrapping||(j=oe(Ed(e,ke(e,g.line))),e.iter(j,h.line+1,function(a){return a==f.maxLine?(i=!0,!0):void 0})),Cc(e.sel.head,b.from)||Cc(b.to,e.sel.head)||(a.curOp.cursorActivity=!0),be(e,b,c,d,A(a)),a.options.lineWrapping||(e.iter(j,g.line+b.text.length,function(a){var b=G(e,a);b>f.maxLineLength&&(f.maxLine=a,f.maxLineLength=b,f.maxLineChanged=!0,i=!1)}),i&&(a.curOp.updateMaxLine=!0)),e.frontier=Math.min(e.frontier,g.line),ab(a,400);var k=b.text.length-(h.line-g.line)-1;if(Hb(a,g.line,h.line+1,k),Se(a,"change")){var l={from:g,to:h,text:b.text,removed:b.removed,origin:b.origin};if(a.curOp.textChanged){for(var m=a.curOp.textChanged;m.next;m=m.next);m.next=l}else a.curOp.textChanged=l}}function zc(a,b,c,d,e){if(d||(d=c),Cc(d,c)){var f=d;d=c,c=f}"string"==typeof b&&(b=vf(b)),tc(a,{from:c,to:d,text:b,origin:e},null)}function Ac(a,b){return this instanceof Ac?(this.line=a,this.ch=b,void 0):new Ac(a,b)}function Bc(a,b){return a.line==b.line&&a.ch==b.ch}function Cc(a,b){return a.line<b.line||a.line==b.line&&a.ch<b.ch}function Dc(a){return Ac(a.line,a.ch)}function Ec(a,b){return Math.max(a.first,Math.min(b,a.first+a.size-1))}function Fc(a,b){if(b.line<a.first)return Ac(a.first,0);var c=a.first+a.size-1;return b.line>c?Ac(c,ke(a,c).text.length):Gc(b,ke(a,b.line).text.length)}function Gc(a,b){var c=a.ch;return null==c||c>b?Ac(a.line,b):0>c?Ac(a.line,0):a}function Hc(a,b){return b>=a.first&&b<a.first+a.size}function Ic(a,b,c,d){if(a.sel.shift||a.sel.extend){var e=a.sel.anchor;if(c){var f=Cc(b,e);f!=Cc(c,e)?(e=b,b=c):f!=Cc(b,c)&&(b=c)}Kc(a,e,b,d)}else Kc(a,b,c||b,d);a.cm&&(a.cm.curOp.userSelChange=!0)}function Jc(a,b,c){var d={anchor:b,head:c};return Me(a,"beforeSelectionChange",a,d),a.cm&&Me(a.cm,"beforeSelectionChange",a.cm,d),d.anchor=Fc(a,d.anchor),d.head=Fc(a,d.head),d}function Kc(a,b,c,d,e){if(!e&&Se(a,"beforeSelectionChange")||a.cm&&Se(a.cm,"beforeSelectionChange")){var f=Jc(a,b,c);c=f.head,b=f.anchor}var g=a.sel;if(g.goalColumn=null,null==d&&(d=Cc(c,g.head)?-1:1),(e||!Bc(b,g.anchor))&&(b=Mc(a,b,d,"push"!=e)),(e||!Bc(c,g.head))&&(c=Mc(a,c,d,"push"!=e)),!Bc(g.anchor,b)||!Bc(g.head,c)){g.anchor=b,g.head=c;var h=Cc(c,b);g.from=h?c:b,g.to=h?b:c,a.cm&&(a.cm.curOp.updateInput=a.cm.curOp.selectionChanged=a.cm.curOp.cursorActivity=!0),Pe(a,"cursorActivity",a)}}function Lc(a){Kc(a.doc,a.doc.sel.from,a.doc.sel.to,null,"push")}function Mc(a,b,c,d){var e=!1,f=b,g=c||1;a.cantEdit=!1;a:for(;;){var h=ke(a,f.line);if(h.markedSpans)for(var i=0;i<h.markedSpans.length;++i){var j=h.markedSpans[i],k=j.marker;if((null==j.from||(k.inclusiveLeft?j.from<=f.ch:j.from<f.ch))&&(null==j.to||(k.inclusiveRight?j.to>=f.ch:j.to>f.ch))){if(d&&(Me(k,"beforeCursorEnter"),k.explicitlyCleared)){if(h.markedSpans){--i;continue}break}if(!k.atomic)continue;var l=k.find()[0>g?"from":"to"];if(Bc(l,f)&&(l.ch+=g,l.ch<0?l=l.line>a.first?Fc(a,Ac(l.line-1)):null:l.ch>h.text.length&&(l=l.line<a.first+a.size-1?Ac(l.line+1,0):null),!l)){if(e)return d?(a.cantEdit=!0,Ac(a.first,0)):Mc(a,b,c,!0);e=!0,l=b,g=-g}f=l;continue a}}return f}}function Nc(a){var b=Oc(a,a.doc.sel.head,a.options.cursorScrollMargin);if(a.state.focused){var c=a.display,d=of(c.sizer),e=null;if(b.top+d.top<0?e=!0:b.bottom+d.top>(window.innerHeight||document.documentElement.clientHeight)&&(e=!1),null!=e&&!m){var f="none"==c.cursor.style.display;f&&(c.cursor.style.display="",c.cursor.style.left=b.left+"px",c.cursor.style.top=b.top-c.viewOffset+"px"),c.cursor.scrollIntoView(e),f&&(c.cursor.style.display="none")}}}function Oc(a,b,c){for(null==c&&(c=0);;){var d=!1,e=ub(a,b),f=Qc(a,e.left,e.top-c,e.left,e.bottom+c),g=a.doc.scrollTop,h=a.doc.scrollLeft;if(null!=f.scrollTop&&($b(a,f.scrollTop),Math.abs(a.doc.scrollTop-g)>1&&(d=!0)),null!=f.scrollLeft&&(_b(a,f.scrollLeft),Math.abs(a.doc.scrollLeft-h)>1&&(d=!0)),!d)return e}}function Pc(a,b,c,d,e){var f=Qc(a,b,c,d,e);null!=f.scrollTop&&$b(a,f.scrollTop),null!=f.scrollLeft&&_b(a,f.scrollLeft)}function Qc(a,b,c,d,e){var f=a.display,g=zb(a.display);0>c&&(c=0);var h=f.scroller.clientHeight-Ue,i=f.scroller.scrollTop,j={},k=a.doc.height+fb(f),l=g>c,m=e>k-g;if(i>c)j.scrollTop=l?0:c;else if(e>i+h){var n=Math.min(c,(m?k:e)-h);n!=i&&(j.scrollTop=n)}var o=f.scroller.clientWidth-Ue,p=f.scroller.scrollLeft;b+=f.gutters.offsetWidth,d+=f.gutters.offsetWidth;var q=f.gutters.offsetWidth,r=q+10>b;return p+q>b||r?(r&&(b=0),j.scrollLeft=Math.max(0,b-10-q)):d>o+p-3&&(j.scrollLeft=d+10-o),j}function Rc(a,b,c){a.curOp.updateScrollPos={scrollLeft:null==b?a.doc.scrollLeft:b,scrollTop:null==c?a.doc.scrollTop:c}}function Sc(a,b,c){var d=a.curOp.updateScrollPos||(a.curOp.updateScrollPos={scrollLeft:a.doc.scrollLeft,scrollTop:a.doc.scrollTop}),e=a.display.scroller;d.scrollTop=Math.max(0,Math.min(e.scrollHeight-e.clientHeight,d.scrollTop+c)),d.scrollLeft=Math.max(0,Math.min(e.scrollWidth-e.clientWidth,d.scrollLeft+b))}function Tc(a,b,c,d){var e=a.doc;if(null==c&&(c="add"),"smart"==c)if(a.doc.mode.indent)var f=db(a,b);else c="prev";var k,g=a.options.tabSize,h=ke(e,b),i=Xe(h.text,null,g),j=h.text.match(/^\s*/)[0];if("smart"==c&&(k=a.doc.mode.indent(f,h.text.slice(j.length),h.text),k==Ve)){if(!d)return;c="prev"}"prev"==c?k=b>e.first?Xe(ke(e,b-1).text,null,g):0:"add"==c?k=i+a.options.indentUnit:"subtract"==c?k=i-a.options.indentUnit:"number"==typeof c&&(k=i+c),k=Math.max(0,k);var l="",m=0;if(a.options.indentWithTabs)for(var n=Math.floor(k/g);n;--n)m+=g,l+=" ";k>m&&(l+=Ze(k-m)),l!=j&&zc(a.doc,l,Ac(b,0),Ac(b,j.length),"+input"),h.stateAfter=null}function Uc(a,b,c){var d=b,e=b,f=a.doc;return"number"==typeof b?e=ke(f,Ec(f,b)):d=oe(b),null==d?null:c(e,d)?(Hb(a,d,d+1),e):null}function Vc(a,b,c,d,e){function k(){var b=f+c;return b<a.first||b>=a.first+a.size?j=!1:(f=b,i=ke(a,b))}function l(a){var b=(e?Kf:Lf)(i,g,c,!0);if(null==b){if(a||!k())return j=!1;g=e?(0>c?Df:Cf)(i):0>c?i.text.length:0}else g=b;return!0}var f=b.line,g=b.ch,h=c,i=ke(a,f),j=!0;if("char"==d)l();else if("column"==d)l(!0);else if("word"==d||"group"==d)for(var m=null,n="group"==d,o=!0;!(0>c)||l(!o);o=!1){var p=i.text.charAt(g)||"\n",q=gf(p)?"w":n?/\s/.test(p)?null:"p":null;if(m&&m!=q){0>c&&(c=1,l());break}if(q&&(m=q),c>0&&!l(!o))break}var r=Mc(a,Ac(f,g),h,!0);return j||(r.hitSide=!0),r}function Wc(a,b,c,d){var g,e=a.doc,f=b.left;if("page"==d){var h=Math.min(a.display.wrapper.clientHeight,window.innerHeight||document.documentElement.clientHeight);g=b.top+c*(h-(0>c?1.5:.5)*zb(a.display))}else"line"==d&&(g=c>0?b.bottom+3:b.top-3);for(;;){var i=wb(a,f,g);if(!i.outside)break;if(0>c?0>=g:g>=e.height){i.hitSide=!0;break}g+=5*c}return i}function Xc(a,b){var c=b.ch,d=b.ch;if(a){(b.xRel<0||d==a.length)&&c?--c:++d;for(var e=a.charAt(c),f=gf(e)?gf:/\s/.test(e)?function(a){return/\s/.test(a)}:function(a){return!/\s/.test(a)&&!gf(a)};c>0&&f(a.charAt(c-1));)--c;for(;d<a.length&&f(a.charAt(d));)++d}return{from:Ac(b.line,c),to:Ac(b.line,d)}}function Yc(a,b){Ic(a.doc,Ac(b,0),Fc(a.doc,Ac(b+1,0)))}function _c(a,b,c,d){w.defaults[a]=b,c&&(Zc[a]=d?function(a,b,d){d!=ad&&c(a,b,d)}:c)}function gd(a,b){if(b===!0)return b;if(a.copyState)return a.copyState(b);var c={};for(var d in b){var e=b[d];e instanceof Array&&(e=e.concat([])),c[d]=e}return c}function hd(a,b,c){return a.startState?a.startState(b,c):!0}function kd(a){return"string"==typeof a?jd[a]:a}function ld(a,b,c){function d(b){b=kd(b);var e=b[a];if(e===!1)return"stop";if(null!=e&&c(e))return!0;if(b.nofallthrough)return"stop";var f=b.fallthrough;if(null==f)return!1;if("[object Array]"!=Object.prototype.toString.call(f))return d(f);for(var g=0,h=f.length;h>g;++g){var i=d(f[g]);if(i)return i}return!1}for(var e=0;e<b.length;++e){var f=d(b[e]);if(f)return"stop"!=f}}function md(a){var b=yf[a.keyCode];return"Ctrl"==b||"Alt"==b||"Shift"==b||"Mod"==b}function nd(a,b){if(h&&34==a.keyCode&&a["char"])return!1;var c=yf[a.keyCode];return null==c||a.altGraphKey?!1:(a.altKey&&(c="Alt-"+c),(s?a.metaKey:a.ctrlKey)&&(c="Ctrl-"+c),(s?a.ctrlKey:a.metaKey)&&(c="Cmd-"+c),!b&&a.shiftKey&&(c="Shift-"+c),c)}function od(a,b){this.pos=this.start=0,this.string=a,this.tabSize=b||8,this.lastColumnPos=this.lastColumnValue=0}function pd(a,b){this.lines=[],this.type=b,this.doc=a}function qd(a,b,c,d,e){if(d&&d.shared)return sd(a,b,c,d,e);if(a.cm&&!a.cm.curOp)return Eb(a.cm,qd)(a,b,c,d,e);var f=new pd(a,e);if("range"==e&&!Cc(b,c))return f;d&&cf(d,f),f.replacedWith&&(f.collapsed=!0,f.replacedWith=kf("span",[f.replacedWith],"CodeMirror-widget"),d.handleMouseEvents||(f.replacedWith.ignoreEvents=!0)),f.collapsed&&(v=!0),f.addToHistory&&ve(a,{from:b,to:c,origin:"markText"},{head:a.sel.head,anchor:a.sel.anchor},0/0);var i,j,l,g=b.line,h=0,k=a.cm;if(a.iter(g,c.line+1,function(d){k&&f.collapsed&&!k.options.lineWrapping&&Ed(a,d)==k.display.maxLine&&(l=!0);var e={from:null,to:null,marker:f};h+=d.text.length,g==b.line&&(e.from=b.ch,h-=b.ch),g==c.line&&(e.to=c.ch,h-=d.text.length-c.ch),f.collapsed&&(g==c.line&&(j=Bd(d,c.ch)),g==b.line?i=Bd(d,b.ch):ne(d,0)),vd(d,e),++g}),f.collapsed&&a.iter(b.line,c.line+1,function(b){Fd(a,b)&&ne(b,0)}),f.clearOnEnter&&Ke(f,"beforeCursorEnter",function(){f.clear()}),f.readOnly&&(u=!0,(a.history.done.length||a.history.undone.length)&&a.clearHistory()),f.collapsed){if(i!=j)throw new Error("Inserting collapsed marker overlapping an existing one");f.size=h,f.atomic=!0}return k&&(l&&(k.curOp.updateMaxLine=!0),(f.className||f.title||f.startStyle||f.endStyle||f.collapsed)&&Hb(k,b.line,c.line+1),f.atomic&&Lc(k)),f}function rd(a,b){this.markers=a,this.primary=b;for(var c=0,d=this;c<a.length;++c)a[c].parent=this,Ke(a[c],"clear",function(){d.clear()})}function sd(a,b,c,d,e){d=cf(d),d.shared=!1;var f=[qd(a,b,c,d,e)],g=f[0],h=d.replacedWith;return ie(a,function(a){h&&(d.replacedWith=h.cloneNode(!0)),f.push(qd(a,Fc(a,b),Fc(a,c),d,e));for(var i=0;i<a.linked.length;++i)if(a.linked[i].isParent)return;g=$e(f)}),new rd(f,g)}function td(a,b){if(a)for(var c=0;c<a.length;++c){var d=a[c];if(d.marker==b)return d}}function ud(a,b){for(var c,d=0;d<a.length;++d)a[d]!=b&&(c||(c=[])).push(a[d]);return c}function vd(a,b){a.markedSpans=a.markedSpans?a.markedSpans.concat([b]):[b],b.marker.attachLine(a)}function wd(a,b,c){if(a)for(var e,d=0;d<a.length;++d){var f=a[d],g=f.marker,h=null==f.from||(g.inclusiveLeft?f.from<=b:f.from<b);if(h||"bookmark"==g.type&&f.from==b&&(!c||!f.marker.insertLeft)){var i=null==f.to||(g.inclusiveRight?f.to>=b:f.to>b);(e||(e=[])).push({from:f.from,to:i?null:f.to,marker:g})}}return e}function xd(a,b,c){if(a)for(var e,d=0;d<a.length;++d){var f=a[d],g=f.marker,h=null==f.to||(g.inclusiveRight?f.to>=b:f.to>b);if(h||"bookmark"==g.type&&f.from==b&&(!c||f.marker.insertLeft)){var i=null==f.from||(g.inclusiveLeft?f.from<=b:f.from<b);(e||(e=[])).push({from:i?null:f.from-b,to:null==f.to?null:f.to-b,marker:g})}}return e}function yd(a,b){var c=Hc(a,b.from.line)&&ke(a,b.from.line).markedSpans,d=Hc(a,b.to.line)&&ke(a,b.to.line).markedSpans;if(!c&&!d)return null;var e=b.from.ch,f=b.to.ch,g=Bc(b.from,b.to),h=wd(c,e,g),i=xd(d,f,g),j=1==b.text.length,k=$e(b.text).length+(j?e:0);if(h)for(var l=0;l<h.length;++l){var m=h[l];if(null==m.to){var n=td(i,m.marker);n?j&&(m.to=null==n.to?null:n.to+k):m.to=e}}if(i)for(var l=0;l<i.length;++l){var m=i[l];if(null!=m.to&&(m.to+=k),null==m.from){var n=td(h,m.marker);n||(m.from=k,j&&(h||(h=[])).push(m))}else m.from+=k,j&&(h||(h=[])).push(m)}if(j&&h){for(var l=0;l<h.length;++l)null!=h[l].from&&h[l].from==h[l].to&&"bookmark"!=h[l].marker.type&&h.splice(l--,1);h.length||(h=null)}var o=[h];if(!j){var q,p=b.text.length-2;if(p>0&&h)for(var l=0;l<h.length;++l)null==h[l].to&&(q||(q=[])).push({from:null,to:null,marker:h[l].marker});for(var l=0;p>l;++l)o.push(q);o.push(i)}return o}function zd(a,b){var c=xe(a,b),d=yd(a,b);if(!c)return d;if(!d)return c;for(var e=0;e<c.length;++e){var f=c[e],g=d[e];if(f&&g)a:for(var h=0;h<g.length;++h){for(var i=g[h],j=0;j<f.length;++j)if(f[j].marker==i.marker)continue a;f.push(i)}else g&&(c[e]=g)}return c}function Ad(a,b,c){var d=null;if(a.iter(b.line,c.line+1,function(a){if(a.markedSpans)for(var b=0;b<a.markedSpans.length;++b){var c=a.markedSpans[b].marker;!c.readOnly||d&&-1!=af(d,c)||(d||(d=[])).push(c)}}),!d)return null;for(var e=[{from:b,to:c}],f=0;f<d.length;++f)for(var g=d[f],h=g.find(),i=0;i<e.length;++i){var j=e[i];if(!Cc(j.to,h.from)&&!Cc(h.to,j.from)){var k=[i,1];(Cc(j.from,h.from)||!g.inclusiveLeft&&Bc(j.from,h.from))&&k.push({from:j.from,to:h.from}),(Cc(h.to,j.to)||!g.inclusiveRight&&Bc(j.to,h.to))&&k.push({from:h.to,to:j.to}),e.splice.apply(e,k),i+=k.length-1}}return e}function Bd(a,b){var d,c=v&&a.markedSpans;if(c)for(var e,f=0;f<c.length;++f)e=c[f],e.marker.collapsed&&(null==e.from||e.from<b)&&(null==e.to||e.to>b)&&(!d||d.width<e.marker.width)&&(d=e.marker);return d}function Cd(a){return Bd(a,-1)}function Dd(a){return Bd(a,a.text.length+1)}function Ed(a,b){for(var c;c=Cd(b);)b=ke(a,c.find().from.line);return b}function Fd(a,b){var c=v&&b.markedSpans;if(c)for(var d,e=0;e<c.length;++e)if(d=c[e],d.marker.collapsed){if(null==d.from)return!0;if(!d.marker.replacedWith&&0==d.from&&d.marker.inclusiveLeft&&Gd(a,b,d))return!0}}function Gd(a,b,c){if(null==c.to){var d=c.marker.find().to,e=ke(a,d.line);return Gd(a,e,td(e.markedSpans,c.marker))}if(c.marker.inclusiveRight&&c.to==b.text.length)return!0;for(var f,g=0;g<b.markedSpans.length;++g)if(f=b.markedSpans[g],f.marker.collapsed&&!f.marker.replacedWith&&f.from==c.to&&(f.marker.inclusiveLeft||c.marker.inclusiveRight)&&Gd(a,b,f))return!0}function Hd(a){var b=a.markedSpans;if(b){for(var c=0;c<b.length;++c)b[c].marker.detachLine(a);a.markedSpans=null}}function Id(a,b){if(b){for(var c=0;c<b.length;++c)b[c].marker.attachLine(a);a.markedSpans=b}}function Kd(a){return function(){var b=!this.cm.curOp;b&&Cb(this.cm);try{var c=a.apply(this,arguments)}finally{b&&Db(this.cm)}return c}}function Ld(a){return null!=a.height?a.height:(a.node.parentNode&&1==a.node.parentNode.nodeType||mf(a.cm.display.measure,kf("div",[a.node],null,"position: relative")),a.height=a.node.offsetHeight)}function Md(a,b,c,d){var e=new Jd(a,c,d);return e.noHScroll&&(a.display.alignWidgets=!0),Uc(a,b,function(b){var c=b.widgets||(b.widgets=[]);if(null==e.insertAt?c.push(e):c.splice(Math.min(c.length-1,Math.max(0,e.insertAt)),0,e),e.line=b,!Fd(a.doc,b)||e.showIfHidden){var d=qe(a,b)<a.doc.scrollTop;ne(b,b.height+Ld(e)),d&&Sc(a,0,e.height)}return!0}),e}function Od(a,b,c,d){a.text=b,a.stateAfter&&(a.stateAfter=null),a.styles&&(a.styles=null),null!=a.order&&(a.order=null),Hd(a),Id(a,c);var e=d?d(a):1;e!=a.height&&ne(a,e)}function Pd(a){a.parent=null,Hd(a)}function Qd(a,b,c,d,e){var f=c.flattenSpans;null==f&&(f=a.options.flattenSpans);var j,g=0,h=null,i=new od(b,a.options.tabSize);for(""==b&&c.blankLine&&c.blankLine(d);!i.eol();)i.pos>a.options.maxHighlightLength?(f=!1,i.pos=b.length,j=null):j=c.token(i,d),f&&h==j||(g<i.start&&e(i.start,h),g=i.start,h=j),i.start=i.pos;for(;g<i.pos;){var k=Math.min(i.pos,g+5e4);e(k,h),g=k}}function Rd(a,b,c){var d=[a.state.modeGen];Qd(a,b.text,a.doc.mode,c,function(a,b){d.push(a,b)});for(var e=0;e<a.state.overlays.length;++e){var f=a.state.overlays[e],g=1,h=0;Qd(a,b.text,f.mode,!0,function(a,b){for(var c=g;a>h;){var e=d[g];e>a&&d.splice(g,1,a,d[g+1],e),g+=2,h=Math.min(a,e)}if(b)if(f.opaque)d.splice(c,g-c,a,b),g=c+2;else for(;g>c;c+=2){var i=d[c+1];d[c+1]=i?i+" "+b:b}})}return d}function Sd(a,b){return b.styles&&b.styles[0]==a.state.modeGen||(b.styles=Rd(a,b,b.stateAfter=db(a,oe(b)))),b.styles}function Td(a,b,c){var d=a.doc.mode,e=new od(b.text,a.options.tabSize);for(""==b.text&&d.blankLine&&d.blankLine(c);!e.eol()&&e.pos<=a.options.maxHighlightLength;)d.token(e,c),e.start=e.pos}function Vd(a,b){if(!a)return null;for(;;){var c=a.match(/(?:^|\s)line-(background-)?(\S+)/);if(!c)break;a=a.slice(0,c.index)+a.slice(c.index+c[0].length);var d=c[1]?"bgClass":"textClass";null==b[d]?b[d]=c[2]:new RegExp("(?:^|s)"+c[2]+"(?:$|s)").test(b[d])||(b[d]+=" "+c[2])}return Ud[a]||(Ud[a]="cm-"+a.replace(/ +/g," cm-"))}function Wd(a,c,d,f){for(var g,h=c,i=!0;g=Cd(h);)h=ke(a.doc,g.find().from.line);var j={pre:kf("pre"),col:0,pos:0,measure:null,measuredSomething:!1,cm:a,copyWidgets:f};do{h.text&&(i=!1),j.measure=h==c&&d,j.pos=0,j.addToken=j.measure?Zd:Yd,(b||e)&&a.getOption("lineWrapping")&&(j.addToken=$d(j.addToken));var k=ae(h,j,Sd(a,h));d&&h==c&&!j.measuredSomething&&(d[0]=j.pre.appendChild(uf(a.display.measure)),j.measuredSomething=!0),k&&(h=ke(a.doc,k.to.line))}while(k);!d||j.measuredSomething||d[0]||(d[0]=j.pre.appendChild(i?kf("span","\xa0"):uf(a.display.measure))),j.pre.firstChild||Fd(a.doc,c)||j.pre.appendChild(document.createTextNode("\xa0"));var l;if(d&&b&&(l=re(h))){var m=l.length-1;l[m].from==l[m].to&&--m;var n=l[m],o=l[m-1];if(n.from+1==n.to&&o&&n.level<o.level){var p=d[j.pos-1];p&&p.parentNode.insertBefore(p.measureRight=uf(a.display.measure),p.nextSibling)}}var q=j.textClass?j.textClass+" "+(c.textClass||""):c.textClass;return q&&(j.pre.className=q),Me(a,"renderLine",a,c,j.pre),j}function Yd(a,b,c,d,e,f){if(b){if(Xd.test(b))for(var g=document.createDocumentFragment(),h=0;;){Xd.lastIndex=h;var i=Xd.exec(b),j=i?i.index-h:b.length-h;if(j&&(g.appendChild(document.createTextNode(b.slice(h,h+j))),a.col+=j),!i)break;if(h+=j+1," "==i[0]){var k=a.cm.options.tabSize,l=k-a.col%k;g.appendChild(kf("span",Ze(l),"cm-tab")),a.col+=l}else{var m=kf("span","\u2022","cm-invalidchar");m.title="\\u"+i[0].charCodeAt(0).toString(16),g.appendChild(m),a.col+=1}}else{a.col+=b.length;var g=document.createTextNode(b)}if(c||d||e||a.measure){var n=c||"";d&&(n+=d),e&&(n+=e);var m=kf("span",[g],n);return f&&(m.title=f),a.pre.appendChild(m)}a.pre.appendChild(g)}}function Zd(a,c,d,e,f){for(var g=a.cm.options.lineWrapping,h=0;h<c.length;++h){var i=c.charAt(h),j=0==h;i>="\ud800"&&"\udbff">i&&h<c.length-1?(i=c.slice(h,h+2),++h):h&&g&&qf(c,h)&&a.pre.appendChild(kf("wbr"));var k=a.measure[a.pos],l=a.measure[a.pos]=Yd(a,i,d,j&&e,h==c.length-1&&f);k&&(l.leftSide=k.leftSide||k),b&&g&&" "==i&&h&&!/\s/.test(c.charAt(h-1))&&h<c.length-1&&!/\s/.test(c.charAt(h+1))&&(l.style.whiteSpace="normal"),a.pos+=i.length}c.length&&(a.measuredSomething=!0)}function $d(a){function b(a){for(var b=" ",c=0;c<a.length-2;++c)b+=c%2?" ":"\xa0";return b+=" "}return function(c,d,e,f,g,h){return a(c,d.replace(/ {3,}/,b),e,f,g,h)}}function _d(a,b,c,d){var e=!d&&c.replacedWith;if(e&&(a.copyWidgets&&(e=e.cloneNode(!0)),a.pre.appendChild(e),a.measure)){if(b)a.measure[a.pos]=e;else{var f=uf(a.cm.display.measure);if("bookmark"!=c.type||c.insertLeft){if(a.measure[a.pos])return;a.measure[a.pos]=a.pre.insertBefore(f,e)}else a.measure[a.pos]=a.pre.appendChild(f)}a.measuredSomething=!0}a.pos+=b}function ae(a,b,c){var d=a.markedSpans,e=a.text,f=0;if(d)for(var k,m,n,o,p,q,h=e.length,i=0,g=1,j="",l=0;;){if(l==i){m=n=o=p="",q=null,l=1/0;for(var r=[],s=0;s<d.length;++s){var t=d[s],u=t.marker;t.from<=i&&(null==t.to||t.to>i)?(null!=t.to&&l>t.to&&(l=t.to,n=""),u.className&&(m+=" "+u.className),u.startStyle&&t.from==i&&(o+=" "+u.startStyle),u.endStyle&&t.to==l&&(n+=" "+u.endStyle),u.title&&!p&&(p=u.title),u.collapsed&&(!q||q.marker.size<u.size)&&(q=t)):t.from>i&&l>t.from&&(l=t.from),"bookmark"==u.type&&t.from==i&&u.replacedWith&&r.push(u)}if(q&&(q.from||0)==i&&(_d(b,(null==q.to?h:q.to)-i,q.marker,null==q.from),null==q.to))return q.marker.find();if(!q&&r.length)for(var s=0;s<r.length;++s)_d(b,0,r[s])}if(i>=h)break;for(var v=Math.min(h,l);;){if(j){var w=i+j.length;if(!q){var x=w>v?j.slice(0,v-i):j;b.addToken(b,x,k?k+m:m,o,i+x.length==l?n:"",p)}if(w>=v){j=j.slice(v-i),i=v;break}i=w,o=""}j=e.slice(f,f=c[g++]),k=Vd(c[g++],b)}}else for(var g=1;g<c.length;g+=2)b.addToken(b,e.slice(f,f=c[g]),Vd(c[g+1],b))}function be(a,b,c,d,e){function f(a){return c?c[a]:null}function g(a,c,d){Od(a,c,d,e),Pe(a,"change",a,b)
4
+ }var h=b.from,i=b.to,j=b.text,k=ke(a,h.line),l=ke(a,i.line),m=$e(j),n=f(j.length-1),o=i.line-h.line;if(0==h.ch&&0==i.ch&&""==m){for(var p=0,q=j.length-1,r=[];q>p;++p)r.push(new Nd(j[p],f(p),e));g(l,l.text,n),o&&a.remove(h.line,o),r.length&&a.insert(h.line,r)}else if(k==l)if(1==j.length)g(k,k.text.slice(0,h.ch)+m+k.text.slice(i.ch),n);else{for(var r=[],p=1,q=j.length-1;q>p;++p)r.push(new Nd(j[p],f(p),e));r.push(new Nd(m+k.text.slice(i.ch),n,e)),g(k,k.text.slice(0,h.ch)+j[0],f(0)),a.insert(h.line+1,r)}else if(1==j.length)g(k,k.text.slice(0,h.ch)+j[0]+l.text.slice(i.ch),f(0)),a.remove(h.line+1,o);else{g(k,k.text.slice(0,h.ch)+j[0],f(0)),g(l,m+l.text.slice(i.ch),n);for(var p=1,q=j.length-1,r=[];q>p;++p)r.push(new Nd(j[p],f(p),e));o>1&&a.remove(h.line+1,o-1),a.insert(h.line+1,r)}Pe(a,"change",a,b),Kc(a,d.anchor,d.head,null,!0)}function ce(a){this.lines=a,this.parent=null;for(var b=0,c=a.length,d=0;c>b;++b)a[b].parent=this,d+=a[b].height;this.height=d}function de(a){this.children=a;for(var b=0,c=0,d=0,e=a.length;e>d;++d){var f=a[d];b+=f.chunkSize(),c+=f.height,f.parent=this}this.size=b,this.height=c,this.parent=null}function ie(a,b,c){function d(a,e,f){if(a.linked)for(var g=0;g<a.linked.length;++g){var h=a.linked[g];if(h.doc!=e){var i=f&&h.sharedHist;(!c||i)&&(b(h.doc,i),d(h.doc,a,i))}}}d(a,null,!0)}function je(a,b){if(b.cm)throw new Error("This document is already in use.");a.doc=b,b.cm=a,B(a),y(a),a.options.lineWrapping||H(a),a.options.mode=b.modeOption,Hb(a)}function ke(a,b){for(b-=a.first;!a.lines;)for(var c=0;;++c){var d=a.children[c],e=d.chunkSize();if(e>b){a=d;break}b-=e}return a.lines[b]}function le(a,b,c){var d=[],e=b.line;return a.iter(b.line,c.line+1,function(a){var f=a.text;e==c.line&&(f=f.slice(0,c.ch)),e==b.line&&(f=f.slice(b.ch)),d.push(f),++e}),d}function me(a,b,c){var d=[];return a.iter(b,c,function(a){d.push(a.text)}),d}function ne(a,b){for(var c=b-a.height,d=a;d;d=d.parent)d.height+=c}function oe(a){if(null==a.parent)return null;for(var b=a.parent,c=af(b.lines,a),d=b.parent;d;b=d,d=d.parent)for(var e=0;d.children[e]!=b;++e)c+=d.children[e].chunkSize();return c+b.first}function pe(a,b){var c=a.first;a:do{for(var d=0,e=a.children.length;e>d;++d){var f=a.children[d],g=f.height;if(g>b){a=f;continue a}b-=g,c+=f.chunkSize()}return c}while(!a.lines);for(var d=0,e=a.lines.length;e>d;++d){var h=a.lines[d],i=h.height;if(i>b)break;b-=i}return c+d}function qe(a,b){b=Ed(a.doc,b);for(var c=0,d=b.parent,e=0;e<d.lines.length;++e){var f=d.lines[e];if(f==b)break;c+=f.height}for(var g=d.parent;g;d=g,g=d.parent)for(var e=0;e<g.children.length;++e){var h=g.children[e];if(h==d)break;c+=h.height}return c}function re(a){var b=a.order;return null==b&&(b=a.order=Mf(a.text)),b}function se(a){return{done:[],undone:[],undoDepth:1/0,lastTime:0,lastOp:null,lastOrigin:null,generation:a||1,maxGeneration:a||1}}function te(a,b,c,d){var e=b["spans_"+a.id],f=0;a.iter(Math.max(a.first,c),Math.min(a.first+a.size,d),function(c){c.markedSpans&&((e||(e=b["spans_"+a.id]={}))[f]=c.markedSpans),++f})}function ue(a,b){var c={line:b.from.line,ch:b.from.ch},d={from:c,to:pc(b),text:le(a,b.from,b.to)};return te(a,d,b.from.line,b.to.line+1),ie(a,function(a){te(a,d,b.from.line,b.to.line+1)},!0),d}function ve(a,b,c,d){var e=a.history;e.undone.length=0;var f=+new Date,g=$e(e.done);if(g&&(e.lastOp==d||e.lastOrigin==b.origin&&b.origin&&("+"==b.origin.charAt(0)&&a.cm&&e.lastTime>f-a.cm.options.historyEventDelay||"*"==b.origin.charAt(0)))){var h=$e(g.changes);Bc(b.from,b.to)&&Bc(b.from,h.to)?h.to=pc(b):g.changes.push(ue(a,b)),g.anchorAfter=c.anchor,g.headAfter=c.head}else for(g={changes:[ue(a,b)],generation:e.generation,anchorBefore:a.sel.anchor,headBefore:a.sel.head,anchorAfter:c.anchor,headAfter:c.head},e.done.push(g),e.generation=++e.maxGeneration;e.done.length>e.undoDepth;)e.done.shift();e.lastTime=f,e.lastOp=d,e.lastOrigin=b.origin}function we(a){if(!a)return null;for(var c,b=0;b<a.length;++b)a[b].marker.explicitlyCleared?c||(c=a.slice(0,b)):c&&c.push(a[b]);return c?c.length?c:null:a}function xe(a,b){var c=b["spans_"+a.id];if(!c)return null;for(var d=0,e=[];d<b.text.length;++d)e.push(we(c[d]));return e}function ye(a,b){for(var c=0,d=[];c<a.length;++c){var e=a[c],f=e.changes,g=[];d.push({changes:g,anchorBefore:e.anchorBefore,headBefore:e.headBefore,anchorAfter:e.anchorAfter,headAfter:e.headAfter});for(var h=0;h<f.length;++h){var j,i=f[h];if(g.push({from:i.from,to:i.to,text:i.text}),b)for(var k in i)(j=k.match(/^spans_(\d+)$/))&&af(b,Number(j[1]))>-1&&($e(g)[k]=i[k],delete i[k])}}return d}function ze(a,b,c,d){c<a.line?a.line+=d:b<a.line&&(a.line=b,a.ch=0)}function Ae(a,b,c,d){for(var e=0;e<a.length;++e){for(var f=a[e],g=!0,h=0;h<f.changes.length;++h){var i=f.changes[h];if(f.copied||(i.from=Dc(i.from),i.to=Dc(i.to)),c<i.from.line)i.from.line+=d,i.to.line+=d;else if(b<=i.to.line){g=!1;break}}f.copied||(f.anchorBefore=Dc(f.anchorBefore),f.headBefore=Dc(f.headBefore),f.anchorAfter=Dc(f.anchorAfter),f.readAfter=Dc(f.headAfter),f.copied=!0),g?(ze(f.anchorBefore),ze(f.headBefore),ze(f.anchorAfter),ze(f.headAfter)):(a.splice(0,e+1),e=0)}}function Be(a,b){var c=b.from.line,d=b.to.line,e=b.text.length-(d-c)-1;Ae(a.done,c,d,e),Ae(a.undone,c,d,e)}function Ce(){He(this)}function De(a){return a.stop||(a.stop=Ce),a}function Ee(a){a.preventDefault?a.preventDefault():a.returnValue=!1}function Fe(a){a.stopPropagation?a.stopPropagation():a.cancelBubble=!0}function Ge(a){return null!=a.defaultPrevented?a.defaultPrevented:0==a.returnValue}function He(a){Ee(a),Fe(a)}function Ie(a){return a.target||a.srcElement}function Je(a){var b=a.which;return null==b&&(1&a.button?b=1:2&a.button?b=3:4&a.button&&(b=2)),p&&a.ctrlKey&&1==b&&(b=3),b}function Ke(a,b,c){if(a.addEventListener)a.addEventListener(b,c,!1);else if(a.attachEvent)a.attachEvent("on"+b,c);else{var d=a._handlers||(a._handlers={}),e=d[b]||(d[b]=[]);e.push(c)}}function Le(a,b,c){if(a.removeEventListener)a.removeEventListener(b,c,!1);else if(a.detachEvent)a.detachEvent("on"+b,c);else{var d=a._handlers&&a._handlers[b];if(!d)return;for(var e=0;e<d.length;++e)if(d[e]==c){d.splice(e,1);break}}}function Me(a,b){var c=a._handlers&&a._handlers[b];if(c)for(var d=Array.prototype.slice.call(arguments,2),e=0;e<c.length;++e)c[e].apply(null,d)}function Pe(a,b){function e(a){return function(){a.apply(null,d)}}var c=a._handlers&&a._handlers[b];if(c){var d=Array.prototype.slice.call(arguments,2);Ne||(++Oe,Ne=[],setTimeout(Re,0));for(var f=0;f<c.length;++f)Ne.push(e(c[f]))}}function Qe(a,b,c){return Me(a,c||b.type,a,b),Ge(b)||b.codemirrorIgnore}function Re(){--Oe;var a=Ne;Ne=null;for(var b=0;b<a.length;++b)a[b]()}function Se(a,b){var c=a._handlers&&a._handlers[b];return c&&c.length>0}function Te(a){a.prototype.on=function(a,b){Ke(this,a,b)},a.prototype.off=function(a,b){Le(this,a,b)}}function We(){this.id=null}function Xe(a,b,c,d,e){null==b&&(b=a.search(/[^\s\u00a0]/),-1==b&&(b=a.length));for(var f=d||0,g=e||0;b>f;++f)" "==a.charAt(f)?g+=c-g%c:++g;return g}function Ze(a){for(;Ye.length<=a;)Ye.push($e(Ye)+" ");return Ye[a]}function $e(a){return a[a.length-1]}function _e(a){if(n)a.selectionStart=0,a.selectionEnd=a.value.length;else try{a.select()}catch(b){}}function af(a,b){if(a.indexOf)return a.indexOf(b);for(var c=0,d=a.length;d>c;++c)if(a[c]==b)return c;return-1}function bf(a,b){function c(){}c.prototype=a;var d=new c;return b&&cf(b,d),d}function cf(a,b){b||(b={});for(var c in a)a.hasOwnProperty(c)&&(b[c]=a[c]);return b}function df(a){for(var b=[],c=0;a>c;++c)b.push(void 0);return b}function ef(a){var b=Array.prototype.slice.call(arguments,1);return function(){return a.apply(null,b)}}function gf(a){return/\w/.test(a)||a>"\x80"&&(a.toUpperCase()!=a.toLowerCase()||ff.test(a))}function hf(a){for(var b in a)if(a.hasOwnProperty(b)&&a[b])return!1;return!0}function kf(a,b,c,d){var e=document.createElement(a);if(c&&(e.className=c),d&&(e.style.cssText=d),"string"==typeof b)nf(e,b);else if(b)for(var f=0;f<b.length;++f)e.appendChild(b[f]);return e}function lf(a){for(var b=a.childNodes.length;b>0;--b)a.removeChild(a.firstChild);return a}function mf(a,b){return lf(a).appendChild(b)}function nf(a,b){d?(a.innerHTML="",a.appendChild(document.createTextNode(b))):a.textContent=b}function of(a){return a.getBoundingClientRect()}function qf(){return!1}function sf(a){if(null!=rf)return rf;var b=kf("div",null,null,"width: 50px; height: 50px; overflow-x: scroll");return mf(a,b),b.offsetWidth&&(rf=b.offsetHeight-b.clientHeight),rf||0}function uf(a){if(null==tf){var b=kf("span","\u200b");mf(a,kf("span",[b,document.createTextNode("x")])),0!=a.firstChild.offsetHeight&&(tf=b.offsetWidth<=1&&b.offsetHeight>2&&!c)}return tf?kf("span","\u200b"):kf("span","\xa0",null,"display: inline-block; width: 1px; margin-right: -1px")}function zf(a,b,c,d){if(!a)return d(b,c,"ltr");for(var e=!1,f=0;f<a.length;++f){var g=a[f];(g.from<c&&g.to>b||b==c&&g.to==b)&&(d(Math.max(g.from,b),Math.min(g.to,c),1==g.level?"rtl":"ltr"),e=!0)}e||d(b,c,"ltr")}function Af(a){return a.level%2?a.to:a.from}function Bf(a){return a.level%2?a.from:a.to}function Cf(a){var b=re(a);return b?Af(b[0]):0}function Df(a){var b=re(a);return b?Bf($e(b)):a.text.length}function Ef(a,b){var c=ke(a.doc,b),d=Ed(a.doc,c);d!=c&&(b=oe(d));var e=re(d),f=e?e[0].level%2?Df(d):Cf(d):0;return Ac(b,f)}function Ff(a,b){for(var c,d;c=Dd(d=ke(a.doc,b));)b=c.find().to.line;var e=re(d),f=e?e[0].level%2?Cf(d):Df(d):d.text.length;return Ac(b,f)}function Gf(a,b,c){var d=a[0].level;return b==d?!0:c==d?!1:c>b}function If(a,b){for(var d,c=0;c<a.length;++c){var e=a[c];if(e.from<b&&e.to>b)return Hf=null,c;if(e.from==b||e.to==b){if(null!=d)return Gf(a,e.level,a[d].level)?(Hf=d,c):(Hf=c,d);d=c}}return Hf=null,d}function Jf(a,b,c,d){if(!d)return b+c;do b+=c;while(b>0&&jf.test(a.text.charAt(b)));return b}function Kf(a,b,c,d){var e=re(a);if(!e)return Lf(a,b,c,d);for(var f=If(e,b),g=e[f],h=Jf(a,b,g.level%2?-c:c,d);;){if(h>g.from&&h<g.to)return h;if(h==g.from||h==g.to)return If(e,h)==f?h:(g=e[f+=c],c>0==g.level%2?g.to:g.from);if(g=e[f+=c],!g)return null;h=c>0==g.level%2?Jf(a,g.to,-1,d):Jf(a,g.from,1,d)}}function Lf(a,b,c,d){var e=b+c;if(d)for(;e>0&&jf.test(a.text.charAt(e));)e+=c;return 0>e||e>a.text.length?null:e}var a=/gecko\/\d/i.test(navigator.userAgent),b=/MSIE \d/.test(navigator.userAgent),c=b&&(null==document.documentMode||document.documentMode<8),d=b&&(null==document.documentMode||document.documentMode<9),e=/WebKit\//.test(navigator.userAgent),f=e&&/Qt\/\d+\.\d+/.test(navigator.userAgent),g=/Chrome\//.test(navigator.userAgent),h=/Opera\//.test(navigator.userAgent),i=/Apple Computer/.test(navigator.vendor),j=/KHTML\//.test(navigator.userAgent),k=/Mac OS X 1\d\D([7-9]|\d\d)\D/.test(navigator.userAgent),l=/Mac OS X 1\d\D([8-9]|\d\d)\D/.test(navigator.userAgent),m=/PhantomJS/.test(navigator.userAgent),n=/AppleWebKit/.test(navigator.userAgent)&&/Mobile\/\w+/.test(navigator.userAgent),o=n||/Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent),p=n||/Mac/.test(navigator.platform),q=/win/i.test(navigator.platform),r=h&&navigator.userAgent.match(/Version\/(\d*\.\d*)/);r&&(r=Number(r[1])),r&&r>=15&&(h=!1,e=!0);var yb,Rb,Sb,s=p&&(f||h&&(null==r||12.11>r)),t=a||b&&!d,u=!1,v=!1,Bb=0,Xb=0,ac=0,bc=null;b?bc=-.53:a?bc=15:g?bc=-.7:i&&(bc=-1/3);var fc,nc,ic=null,pc=w.changeEnd=function(a){return a.text?Ac(a.from.line+a.text.length-1,$e(a.text).length+(1==a.text.length?a.from.ch:0)):a.to};w.Pos=Ac,w.prototype={constructor:w,focus:function(){window.focus(),Mb(this),lc(this),Jb(this)},setOption:function(a,b){var c=this.options,d=c[a];(c[a]!=b||"mode"==a)&&(c[a]=b,Zc.hasOwnProperty(a)&&Eb(this,Zc[a])(this,b,d))},getOption:function(a){return this.options[a]},getDoc:function(){return this.doc},addKeyMap:function(a,b){this.state.keyMaps[b?"push":"unshift"](a)},removeKeyMap:function(a){for(var b=this.state.keyMaps,c=0;c<b.length;++c)if(b[c]==a||"string"!=typeof b[c]&&b[c].name==a)return b.splice(c,1),!0},addOverlay:Eb(null,function(a,b){var c=a.token?a:w.getMode(this.options,a);if(c.startState)throw new Error("Overlays may not be stateful.");this.state.overlays.push({mode:c,modeSpec:a,opaque:b&&b.opaque}),this.state.modeGen++,Hb(this)}),removeOverlay:Eb(null,function(a){for(var b=this.state.overlays,c=0;c<b.length;++c){var d=b[c].modeSpec;if(d==a||"string"==typeof a&&d.name==a)return b.splice(c,1),this.state.modeGen++,Hb(this),void 0}}),indentLine:Eb(null,function(a,b,c){"string"!=typeof b&&"number"!=typeof b&&(b=null==b?this.options.smartIndent?"smart":"prev":b?"add":"subtract"),Hc(this.doc,a)&&Tc(this,a,b,c)}),indentSelection:Eb(null,function(a){var b=this.doc.sel;if(Bc(b.from,b.to))return Tc(this,b.from.line,a);for(var c=b.to.line-(b.to.ch?0:1),d=b.from.line;c>=d;++d)Tc(this,d,a)}),getTokenAt:function(a,b){var c=this.doc;a=Fc(c,a);for(var d=db(this,a.line,b),e=this.doc.mode,f=ke(c,a.line),g=new od(f.text,this.options.tabSize);g.pos<a.ch&&!g.eol();){g.start=g.pos;var h=e.token(g,d)}return{start:g.start,end:g.pos,string:g.current(),className:h||null,type:h||null,state:d}},getTokenTypeAt:function(a){a=Fc(this.doc,a);var b=Sd(this,ke(this.doc,a.line)),c=0,d=(b.length-1)/2,e=a.ch;if(0==e)return b[2];for(;;){var f=c+d>>1;if((f?b[2*f-1]:0)>=e)d=f;else{if(!(b[2*f+1]<e))return b[2*f+2];c=f+1}}},getModeAt:function(a){var b=this.doc.mode;return b.innerMode?w.innerMode(b,this.getTokenAt(a).state).mode:b},getHelper:function(a,b){if(fd.hasOwnProperty(b)){var c=fd[b],d=this.getModeAt(a);return d[b]&&c[d[b]]||d.helperType&&c[d.helperType]||c[d.name]}},getStateAfter:function(a,b){var c=this.doc;return a=Ec(c,null==a?c.first+c.size-1:a),db(this,a+1,b)},cursorCoords:function(a,b){var c,d=this.doc.sel;return c=null==a?d.head:"object"==typeof a?Fc(this.doc,a):a?d.from:d.to,ub(this,c,b||"page")},charCoords:function(a,b){return tb(this,Fc(this.doc,a),b||"page")},coordsChar:function(a,b){return a=sb(this,a,b||"page"),wb(this,a.left,a.top)},lineAtHeight:function(a,b){return a=sb(this,{top:a,left:0},b||"page").top,pe(this.doc,a+this.display.viewOffset)},heightAtLine:function(a,b){var c=!1,d=this.doc.first+this.doc.size-1;a<this.doc.first?a=this.doc.first:a>d&&(a=d,c=!0);var e=ke(this.doc,a);return rb(this,ke(this.doc,a),{top:0,left:0},b||"page").top+(c?e.height:0)},defaultTextHeight:function(){return zb(this.display)},defaultCharWidth:function(){return Ab(this.display)},setGutterMarker:Eb(null,function(a,b,c){return Uc(this,a,function(a){var d=a.gutterMarkers||(a.gutterMarkers={});return d[b]=c,!c&&hf(d)&&(a.gutterMarkers=null),!0})}),clearGutter:Eb(null,function(a){var b=this,c=b.doc,d=c.first;c.iter(function(c){c.gutterMarkers&&c.gutterMarkers[a]&&(c.gutterMarkers[a]=null,Hb(b,d,d+1),hf(c.gutterMarkers)&&(c.gutterMarkers=null)),++d})}),addLineClass:Eb(null,function(a,b,c){return Uc(this,a,function(a){var d="text"==b?"textClass":"background"==b?"bgClass":"wrapClass";if(a[d]){if(new RegExp("(?:^|\\s)"+c+"(?:$|\\s)").test(a[d]))return!1;a[d]+=" "+c}else a[d]=c;return!0})}),removeLineClass:Eb(null,function(a,b,c){return Uc(this,a,function(a){var d="text"==b?"textClass":"background"==b?"bgClass":"wrapClass",e=a[d];if(!e)return!1;if(null==c)a[d]=null;else{var f=e.match(new RegExp("(?:^|\\s+)"+c+"(?:$|\\s+)"));if(!f)return!1;var g=f.index+f[0].length;a[d]=e.slice(0,f.index)+(f.index&&g!=e.length?" ":"")+e.slice(g)||null}return!0})}),addLineWidget:Eb(null,function(a,b,c){return Md(this,a,b,c)}),removeLineWidget:function(a){a.clear()},lineInfo:function(a){if("number"==typeof a){if(!Hc(this.doc,a))return null;var b=a;if(a=ke(this.doc,a),!a)return null}else{var b=oe(a);if(null==b)return null}return{line:b,handle:a,text:a.text,gutterMarkers:a.gutterMarkers,textClass:a.textClass,bgClass:a.bgClass,wrapClass:a.wrapClass,widgets:a.widgets}},getViewport:function(){return{from:this.display.showingFrom,to:this.display.showingTo}},addWidget:function(a,b,c,d,e){var f=this.display;a=ub(this,Fc(this.doc,a));var g=a.bottom,h=a.left;if(b.style.position="absolute",f.sizer.appendChild(b),"over"==d)g=a.top;else if("above"==d||"near"==d){var i=Math.max(f.wrapper.clientHeight,this.doc.height),j=Math.max(f.sizer.clientWidth,f.lineSpace.clientWidth);("above"==d||a.bottom+b.offsetHeight>i)&&a.top>b.offsetHeight?g=a.top-b.offsetHeight:a.bottom+b.offsetHeight<=i&&(g=a.bottom),h+b.offsetWidth>j&&(h=j-b.offsetWidth)}b.style.top=g+"px",b.style.left=b.style.right="","right"==e?(h=f.sizer.clientWidth-b.offsetWidth,b.style.right="0px"):("left"==e?h=0:"middle"==e&&(h=(f.sizer.clientWidth-b.offsetWidth)/2),b.style.left=h+"px"),c&&Pc(this,h,g,h+b.offsetWidth,g+b.offsetHeight)},triggerOnKeyDown:Eb(null,jc),execCommand:function(a){return id[a](this)},findPosH:function(a,b,c,d){var e=1;0>b&&(e=-1,b=-b);for(var f=0,g=Fc(this.doc,a);b>f&&(g=Vc(this.doc,g,e,c,d),!g.hitSide);++f);return g},moveH:Eb(null,function(a,b){var d,c=this.doc.sel;d=c.shift||c.extend||Bc(c.from,c.to)?Vc(this.doc,c.head,a,b,this.options.rtlMoveVisually):0>a?c.from:c.to,Ic(this.doc,d,d,a)}),deleteH:Eb(null,function(a,b){var c=this.doc.sel;Bc(c.from,c.to)?zc(this.doc,"",c.from,Vc(this.doc,c.head,a,b,!1),"+delete"):zc(this.doc,"",c.from,c.to,"+delete"),this.curOp.userSelChange=!0}),findPosV:function(a,b,c,d){var e=1,f=d;0>b&&(e=-1,b=-b);for(var g=0,h=Fc(this.doc,a);b>g;++g){var i=ub(this,h,"div");if(null==f?f=i.left:i.left=f,h=Wc(this,i,e,c),h.hitSide)break}return h},moveV:Eb(null,function(a,b){var c=this.doc.sel,d=ub(this,c.head,"div");null!=c.goalColumn&&(d.left=c.goalColumn);var e=Wc(this,d,a,b);"page"==b&&Sc(this,0,tb(this,e,"div").top-d.top),Ic(this.doc,e,e,a),c.goalColumn=d.left}),toggleOverwrite:function(a){(null==a||a!=this.state.overwrite)&&((this.state.overwrite=!this.state.overwrite)?this.display.cursor.className+=" CodeMirror-overwrite":this.display.cursor.className=this.display.cursor.className.replace(" CodeMirror-overwrite",""))},hasFocus:function(){return this.state.focused},scrollTo:Eb(null,function(a,b){Rc(this,a,b)}),getScrollInfo:function(){var a=this.display.scroller,b=Ue;return{left:a.scrollLeft,top:a.scrollTop,height:a.scrollHeight-b,width:a.scrollWidth-b,clientHeight:a.clientHeight-b,clientWidth:a.clientWidth-b}},scrollIntoView:Eb(null,function(a,b){"number"==typeof a&&(a=Ac(a,0)),b||(b=0);var c=a;a&&null==a.line||(this.curOp.scrollToPos=a?Fc(this.doc,a):this.doc.sel.head,this.curOp.scrollToPosMargin=b,c=ub(this,this.curOp.scrollToPos));var d=Qc(this,c.left,c.top-b,c.right,c.bottom+b);Rc(this,d.scrollLeft,d.scrollTop)}),setSize:Eb(null,function(a,b){function c(a){return"number"==typeof a||/^\d+$/.test(String(a))?a+"px":a}null!=a&&(this.display.wrapper.style.width=c(a)),null!=b&&(this.display.wrapper.style.height=c(b)),this.options.lineWrapping&&(this.display.measureLineCache.length=this.display.measureLineCachePos=0),this.curOp.forceUpdate=!0}),operation:function(a){return Gb(this,a)},refresh:Eb(null,function(){var a=null==this.display.cachedTextHeight;ob(this),Rc(this,this.doc.scrollLeft,this.doc.scrollTop),Hb(this),a&&B(this)}),swapDoc:Eb(null,function(a){var b=this.doc;return b.cm=null,je(this,a),ob(this),Lb(this,!0),Rc(this,a.scrollLeft,a.scrollTop),b}),getInputField:function(){return this.display.input},getWrapperElement:function(){return this.display.wrapper},getScrollerElement:function(){return this.display.scroller},getGutterElement:function(){return this.display.gutters}},Te(w);var Zc=w.optionHandlers={},$c=w.defaults={},ad=w.Init={toString:function(){return"CodeMirror.Init"}};_c("value","",function(a,b){a.setValue(b)},!0),_c("mode",null,function(a,b){a.doc.modeOption=b,y(a)},!0),_c("indentUnit",2,y,!0),_c("indentWithTabs",!1),_c("smartIndent",!0),_c("tabSize",4,function(a){y(a),ob(a),Hb(a)},!0),_c("electricChars",!0),_c("rtlMoveVisually",!q),_c("theme","default",function(a){D(a),E(a)},!0),_c("keyMap","default",C),_c("extraKeys",null),_c("onKeyEvent",null),_c("onDragEvent",null),_c("lineWrapping",!1,z,!0),_c("gutters",[],function(a){I(a.options),E(a)},!0),_c("fixedGutter",!0,function(a,b){a.display.gutters.style.left=b?O(a.display)+"px":"0",a.refresh()},!0),_c("coverGutterNextToScrollbar",!1,J,!0),_c("lineNumbers",!1,function(a){I(a.options),E(a)},!0),_c("firstLineNumber",1,E,!0),_c("lineNumberFormatter",function(a){return a},E,!0),_c("showCursorWhenSelecting",!1,Y,!0),_c("readOnly",!1,function(a,b){"nocursor"==b?(mc(a),a.display.input.blur()):b||Lb(a,!0)}),_c("dragDrop",!0),_c("cursorBlinkRate",530),_c("cursorScrollMargin",0),_c("cursorHeight",1),_c("workTime",100),_c("workDelay",100),_c("flattenSpans",!0),_c("pollInterval",100),_c("undoDepth",40,function(a,b){a.doc.history.undoDepth=b}),_c("historyEventDelay",500),_c("viewportMargin",10,function(a){a.refresh()},!0),_c("maxHighlightLength",1e4,function(a){y(a),a.refresh()},!0),_c("crudeMeasuringFrom",1e4),_c("moveInputWithCursor",!0,function(a,b){b||(a.display.inputDiv.style.top=a.display.inputDiv.style.left=0)}),_c("tabindex",null,function(a,b){a.display.input.tabIndex=b||""}),_c("autofocus",null);var bd=w.modes={},cd=w.mimeModes={};w.defineMode=function(a,b){if(w.defaults.mode||"null"==a||(w.defaults.mode=a),arguments.length>2){b.dependencies=[];for(var c=2;c<arguments.length;++c)b.dependencies.push(arguments[c])}bd[a]=b},w.defineMIME=function(a,b){cd[a]=b},w.resolveMode=function(a){if("string"==typeof a&&cd.hasOwnProperty(a))a=cd[a];else if(a&&"string"==typeof a.name&&cd.hasOwnProperty(a.name)){var b=cd[a.name];a=bf(b,a),a.name=b.name}else if("string"==typeof a&&/^[\w\-]+\/[\w\-]+\+xml$/.test(a))return w.resolveMode("application/xml");return"string"==typeof a?{name:a}:a||{name:"null"}},w.getMode=function(a,b){var b=w.resolveMode(b),c=bd[b.name];if(!c)return w.getMode(a,"text/plain");var d=c(a,b);if(dd.hasOwnProperty(b.name)){var e=dd[b.name];for(var f in e)e.hasOwnProperty(f)&&(d.hasOwnProperty(f)&&(d["_"+f]=d[f]),d[f]=e[f])}return d.name=b.name,d},w.defineMode("null",function(){return{token:function(a){a.skipToEnd()}}}),w.defineMIME("text/plain","null");var dd=w.modeExtensions={};w.extendMode=function(a,b){var c=dd.hasOwnProperty(a)?dd[a]:dd[a]={};cf(b,c)},w.defineExtension=function(a,b){w.prototype[a]=b},w.defineDocExtension=function(a,b){fe.prototype[a]=b},w.defineOption=_c;var ed=[];w.defineInitHook=function(a){ed.push(a)};var fd=w.helpers={};w.registerHelper=function(a,b,c){fd.hasOwnProperty(a)||(fd[a]=w[a]={}),fd[a][b]=c},w.isWordChar=gf,w.copyState=gd,w.startState=hd,w.innerMode=function(a,b){for(;a.innerMode;){var c=a.innerMode(b);if(!c||c.mode==a)break;b=c.state,a=c.mode}return c||{mode:a,state:b}};var id=w.commands={selectAll:function(a){a.setSelection(Ac(a.firstLine(),0),Ac(a.lastLine()))},killLine:function(a){var b=a.getCursor(!0),c=a.getCursor(!1),d=!Bc(b,c);d||a.getLine(b.line).length!=b.ch?a.replaceRange("",b,d?c:Ac(b.line),"+delete"):a.replaceRange("",b,Ac(b.line+1,0),"+delete")},deleteLine:function(a){var b=a.getCursor().line;a.replaceRange("",Ac(b,0),Ac(b),"+delete")},delLineLeft:function(a){var b=a.getCursor();a.replaceRange("",Ac(b.line,0),b,"+delete")},undo:function(a){a.undo()},redo:function(a){a.redo()},goDocStart:function(a){a.extendSelection(Ac(a.firstLine(),0))},goDocEnd:function(a){a.extendSelection(Ac(a.lastLine()))},goLineStart:function(a){a.extendSelection(Ef(a,a.getCursor().line))},goLineStartSmart:function(a){var b=a.getCursor(),c=Ef(a,b.line),d=a.getLineHandle(c.line),e=re(d);if(e&&0!=e[0].level)a.extendSelection(c);else{var f=Math.max(0,d.text.search(/\S/)),g=b.line==c.line&&b.ch<=f&&b.ch;a.extendSelection(Ac(c.line,g?0:f))}},goLineEnd:function(a){a.extendSelection(Ff(a,a.getCursor().line))},goLineRight:function(a){var b=a.charCoords(a.getCursor(),"div").top+5;a.extendSelection(a.coordsChar({left:a.display.lineDiv.offsetWidth+100,top:b},"div"))},goLineLeft:function(a){var b=a.charCoords(a.getCursor(),"div").top+5;a.extendSelection(a.coordsChar({left:0,top:b},"div"))},goLineUp:function(a){a.moveV(-1,"line")},goLineDown:function(a){a.moveV(1,"line")},goPageUp:function(a){a.moveV(-1,"page")},goPageDown:function(a){a.moveV(1,"page")},goCharLeft:function(a){a.moveH(-1,"char")},goCharRight:function(a){a.moveH(1,"char")},goColumnLeft:function(a){a.moveH(-1,"column")},goColumnRight:function(a){a.moveH(1,"column")},goWordLeft:function(a){a.moveH(-1,"word")},goGroupRight:function(a){a.moveH(1,"group")},goGroupLeft:function(a){a.moveH(-1,"group")},goWordRight:function(a){a.moveH(1,"word")},delCharBefore:function(a){a.deleteH(-1,"char")},delCharAfter:function(a){a.deleteH(1,"char")},delWordBefore:function(a){a.deleteH(-1,"word")},delWordAfter:function(a){a.deleteH(1,"word")},delGroupBefore:function(a){a.deleteH(-1,"group")},delGroupAfter:function(a){a.deleteH(1,"group")},indentAuto:function(a){a.indentSelection("smart")},indentMore:function(a){a.indentSelection("add")},indentLess:function(a){a.indentSelection("subtract")},insertTab:function(a){a.replaceSelection(" ","end","+input")},defaultTab:function(a){a.somethingSelected()?a.indentSelection("add"):a.replaceSelection(" ","end","+input")},transposeChars:function(a){var b=a.getCursor(),c=a.getLine(b.line);b.ch>0&&b.ch<c.length-1&&a.replaceRange(c.charAt(b.ch)+c.charAt(b.ch-1),Ac(b.line,b.ch-1),Ac(b.line,b.ch+1))},newlineAndIndent:function(a){Eb(a,function(){a.replaceSelection("\n","end","+input"),a.indentLine(a.getCursor().line,null,!0)})()},toggleOverwrite:function(a){a.toggleOverwrite()}},jd=w.keyMap={};jd.basic={Left:"goCharLeft",Right:"goCharRight",Up:"goLineUp",Down:"goLineDown",End:"goLineEnd",Home:"goLineStartSmart",PageUp:"goPageUp",PageDown:"goPageDown",Delete:"delCharAfter",Backspace:"delCharBefore",Tab:"defaultTab","Shift-Tab":"indentAuto",Enter:"newlineAndIndent",Insert:"toggleOverwrite"},jd.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":"goGroupLeft","Ctrl-Right":"goGroupRight","Alt-Left":"goLineStart","Alt-Right":"goLineEnd","Ctrl-Backspace":"delGroupBefore","Ctrl-Delete":"delGroupAfter","Ctrl-S":"save","Ctrl-F":"find","Ctrl-G":"findNext","Shift-Ctrl-G":"findPrev","Shift-Ctrl-F":"replace","Shift-Ctrl-R":"replaceAll","Ctrl-[":"indentLess","Ctrl-]":"indentMore",fallthrough:"basic"},jd.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":"goGroupLeft","Alt-Right":"goGroupRight","Cmd-Left":"goLineStart","Cmd-Right":"goLineEnd","Alt-Backspace":"delGroupBefore","Ctrl-Alt-Backspace":"delGroupAfter","Alt-Delete":"delGroupAfter","Cmd-S":"save","Cmd-F":"find","Cmd-G":"findNext","Shift-Cmd-G":"findPrev","Cmd-Alt-F":"replace","Shift-Cmd-Alt-F":"replaceAll","Cmd-[":"indentLess","Cmd-]":"indentMore","Cmd-Backspace":"delLineLeft",fallthrough:["basic","emacsy"]},jd["default"]=p?jd.macDefault:jd.pcDefault,jd.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":"goPageDown","Shift-Ctrl-V":"goPageUp","Ctrl-D":"delCharAfter","Ctrl-H":"delCharBefore","Alt-D":"delWordAfter","Alt-Backspace":"delWordBefore","Ctrl-K":"killLine","Ctrl-T":"transposeChars"},w.lookupKey=ld,w.isModifierKey=md,w.keyName=nd,w.fromTextArea=function(a,b){function e(){a.value=i.getValue()}if(b||(b={}),b.value=a.value,!b.tabindex&&a.tabindex&&(b.tabindex=a.tabindex),!b.placeholder&&a.placeholder&&(b.placeholder=a.placeholder),null==b.autofocus){var c=document.body;try{c=document.activeElement}catch(d){}b.autofocus=c==a||null!=a.getAttribute("autofocus")&&c==document.body}if(a.form&&(Ke(a.form,"submit",e),!b.leaveSubmitMethodAlone)){var f=a.form,g=f.submit;try{var h=f.submit=function(){e(),f.submit=g,f.submit(),f.submit=h}}catch(d){}}a.style.display="none";var i=w(function(b){a.parentNode.insertBefore(b,a.nextSibling)},b);return i.save=e,i.getTextArea=function(){return a},i.toTextArea=function(){e(),a.parentNode.removeChild(i.getWrapperElement()),a.style.display="",a.form&&(Le(a.form,"submit",e),"function"==typeof a.form.submit&&(a.form.submit=g))},i},od.prototype={eol:function(){return this.pos>=this.string.length},sol:function(){return 0==this.pos},peek:function(){return this.string.charAt(this.pos)||void 0},next:function(){return this.pos<this.string.length?this.string.charAt(this.pos++):void 0},eat:function(a){var b=this.string.charAt(this.pos);if("string"==typeof a)var c=b==a;else var c=b&&(a.test?a.test(b):a(b));return c?(++this.pos,b):void 0},eatWhile:function(a){for(var b=this.pos;this.eat(a););return this.pos>b},eatSpace:function(){for(var a=this.pos;/[\s\u00a0]/.test(this.string.charAt(this.pos));)++this.pos;return this.pos>a},skipToEnd:function(){this.pos=this.string.length},skipTo:function(a){var b=this.string.indexOf(a,this.pos);return b>-1?(this.pos=b,!0):void 0},backUp:function(a){this.pos-=a},column:function(){return this.lastColumnPos<this.start&&(this.lastColumnValue=Xe(this.string,this.start,this.tabSize,this.lastColumnPos,this.lastColumnValue),this.lastColumnPos=this.start),this.lastColumnValue},indentation:function(){return Xe(this.string,null,this.tabSize)},match:function(a,b,c){if("string"!=typeof a){var f=this.string.slice(this.pos).match(a);return f&&f.index>0?null:(f&&b!==!1&&(this.pos+=f[0].length),f)}var d=function(a){return c?a.toLowerCase():a},e=this.string.substr(this.pos,a.length);return d(e)==d(a)?(b!==!1&&(this.pos+=a.length),!0):void 0},current:function(){return this.string.slice(this.start,this.pos)}},w.StringStream=od,w.TextMarker=pd,Te(pd),pd.prototype.clear=function(){if(!this.explicitlyCleared){var a=this.doc.cm,b=a&&!a.curOp;if(b&&Cb(a),Se(this,"clear")){var c=this.find();c&&Pe(this,"clear",c.from,c.to)}for(var d=null,e=null,f=0;f<this.lines.length;++f){var g=this.lines[f],h=td(g.markedSpans,this);null!=h.to&&(e=oe(g)),g.markedSpans=ud(g.markedSpans,h),null!=h.from?d=oe(g):this.collapsed&&!Fd(this.doc,g)&&a&&ne(g,zb(a.display))}if(a&&this.collapsed&&!a.options.lineWrapping)for(var f=0;f<this.lines.length;++f){var i=Ed(a.doc,this.lines[f]),j=G(a.doc,i);j>a.display.maxLineLength&&(a.display.maxLine=i,a.display.maxLineLength=j,a.display.maxLineChanged=!0)}null!=d&&a&&Hb(a,d,e+1),this.lines.length=0,this.explicitlyCleared=!0,this.atomic&&this.doc.cantEdit&&(this.doc.cantEdit=!1,a&&Lc(a)),b&&Db(a)}},pd.prototype.find=function(){for(var a,b,c=0;c<this.lines.length;++c){var d=this.lines[c],e=td(d.markedSpans,this);if(null!=e.from||null!=e.to){var f=oe(d);null!=e.from&&(a=Ac(f,e.from)),null!=e.to&&(b=Ac(f,e.to))}}return"bookmark"==this.type?a:a&&{from:a,to:b}},pd.prototype.changed=function(){var a=this.find(),b=this.doc.cm;if(a&&b){"bookmark"!=this.type&&(a=a.from);var c=ke(this.doc,a.line);if(jb(b,c),a.line>=b.display.showingFrom&&a.line<b.display.showingTo){for(var d=b.display.lineDiv.firstChild;d;d=d.nextSibling)if(d.lineObj==c){d.offsetHeight!=c.height&&ne(c,d.offsetHeight);break}Gb(b,function(){b.curOp.selectionChanged=b.curOp.forceUpdate=b.curOp.updateMaxLine=!0})}}},pd.prototype.attachLine=function(a){if(!this.lines.length&&this.doc.cm){var b=this.doc.cm.curOp;b.maybeHiddenMarkers&&-1!=af(b.maybeHiddenMarkers,this)||(b.maybeUnhiddenMarkers||(b.maybeUnhiddenMarkers=[])).push(this)}this.lines.push(a)},pd.prototype.detachLine=function(a){if(this.lines.splice(af(this.lines,a),1),!this.lines.length&&this.doc.cm){var b=this.doc.cm.curOp;(b.maybeHiddenMarkers||(b.maybeHiddenMarkers=[])).push(this)}},w.SharedTextMarker=rd,Te(rd),rd.prototype.clear=function(){if(!this.explicitlyCleared){this.explicitlyCleared=!0;for(var a=0;a<this.markers.length;++a)this.markers[a].clear();Pe(this,"clear")}},rd.prototype.find=function(){return this.primary.find()};var Jd=w.LineWidget=function(a,b,c){if(c)for(var d in c)c.hasOwnProperty(d)&&(this[d]=c[d]);this.cm=a,this.node=b};Te(Jd),Jd.prototype.clear=Kd(function(){var a=this.line.widgets,b=oe(this.line);if(null!=b&&a){for(var c=0;c<a.length;++c)a[c]==this&&a.splice(c--,1);a.length||(this.line.widgets=null);var d=qe(this.cm,this.line)<this.cm.doc.scrollTop;ne(this.line,Math.max(0,this.line.height-Ld(this))),d&&Sc(this.cm,0,-this.height),Hb(this.cm,b,b+1)
5
+ }}),Jd.prototype.changed=Kd(function(){var a=this.height;this.height=null;var b=Ld(this)-a;if(b){ne(this.line,this.line.height+b);var c=oe(this.line);Hb(this.cm,c,c+1)}});var Nd=w.Line=function(a,b,c){this.text=a,Id(this,b),this.height=c?c(this):1};Te(Nd);var Ud={},Xd=/[\t\u0000-\u0019\u00ad\u200b\u2028\u2029\uFEFF]/g;ce.prototype={chunkSize:function(){return this.lines.length},removeInner:function(a,b){for(var c=a,d=a+b;d>c;++c){var e=this.lines[c];this.height-=e.height,Pd(e),Pe(e,"delete")}this.lines.splice(a,b)},collapse:function(a){a.splice.apply(a,[a.length,0].concat(this.lines))},insertInner:function(a,b,c){this.height+=c,this.lines=this.lines.slice(0,a).concat(b).concat(this.lines.slice(a));for(var d=0,e=b.length;e>d;++d)b[d].parent=this},iterN:function(a,b,c){for(var d=a+b;d>a;++a)if(c(this.lines[a]))return!0}},de.prototype={chunkSize:function(){return this.size},removeInner:function(a,b){this.size-=b;for(var c=0;c<this.children.length;++c){var d=this.children[c],e=d.chunkSize();if(e>a){var f=Math.min(b,e-a),g=d.height;if(d.removeInner(a,f),this.height-=g-d.height,e==f&&(this.children.splice(c--,1),d.parent=null),0==(b-=f))break;a=0}else a-=e}if(this.size-b<25){var h=[];this.collapse(h),this.children=[new ce(h)],this.children[0].parent=this}},collapse:function(a){for(var b=0,c=this.children.length;c>b;++b)this.children[b].collapse(a)},insertInner:function(a,b,c){this.size+=b.length,this.height+=c;for(var d=0,e=this.children.length;e>d;++d){var f=this.children[d],g=f.chunkSize();if(g>=a){if(f.insertInner(a,b,c),f.lines&&f.lines.length>50){for(;f.lines.length>50;){var h=f.lines.splice(f.lines.length-25,25),i=new ce(h);f.height-=i.height,this.children.splice(d+1,0,i),i.parent=this}this.maybeSpill()}break}a-=g}},maybeSpill:function(){if(!(this.children.length<=10)){var a=this;do{var b=a.children.splice(a.children.length-5,5),c=new de(b);if(a.parent){a.size-=c.size,a.height-=c.height;var e=af(a.parent.children,a);a.parent.children.splice(e+1,0,c)}else{var d=new de(a.children);d.parent=a,a.children=[d,c],a=d}c.parent=a.parent}while(a.children.length>10);a.parent.maybeSpill()}},iterN:function(a,b,c){for(var d=0,e=this.children.length;e>d;++d){var f=this.children[d],g=f.chunkSize();if(g>a){var h=Math.min(b,g-a);if(f.iterN(a,h,c))return!0;if(0==(b-=h))break;a=0}else a-=g}}};var ee=0,fe=w.Doc=function(a,b,c){if(!(this instanceof fe))return new fe(a,b,c);null==c&&(c=0),de.call(this,[new ce([new Nd("",null)])]),this.first=c,this.scrollTop=this.scrollLeft=0,this.cantEdit=!1,this.history=se(),this.cleanGeneration=1,this.frontier=c;var d=Ac(c,0);this.sel={from:d,to:d,head:d,anchor:d,shift:!1,extend:!1,goalColumn:null},this.id=++ee,this.modeOption=b,"string"==typeof a&&(a=vf(a)),be(this,{from:d,to:d,text:a},null,{head:d,anchor:d})};fe.prototype=bf(de.prototype,{constructor:fe,iter:function(a,b,c){c?this.iterN(a-this.first,b-a,c):this.iterN(this.first,this.first+this.size,a)},insert:function(a,b){for(var c=0,d=0,e=b.length;e>d;++d)c+=b[d].height;this.insertInner(a-this.first,b,c)},remove:function(a,b){this.removeInner(a-this.first,b)},getValue:function(a){var b=me(this,this.first,this.first+this.size);return a===!1?b:b.join(a||"\n")},setValue:function(a){var b=Ac(this.first,0),c=this.first+this.size-1;tc(this,{from:b,to:Ac(c,ke(this,c).text.length),text:vf(a),origin:"setValue"},{head:b,anchor:b},!0)},replaceRange:function(a,b,c,d){b=Fc(this,b),c=c?Fc(this,c):b,zc(this,a,b,c,d)},getRange:function(a,b,c){var d=le(this,Fc(this,a),Fc(this,b));return c===!1?d:d.join(c||"\n")},getLine:function(a){var b=this.getLineHandle(a);return b&&b.text},setLine:function(a,b){Hc(this,a)&&zc(this,b,Ac(a,0),Fc(this,Ac(a)))},removeLine:function(a){a?zc(this,"",Fc(this,Ac(a-1)),Fc(this,Ac(a))):zc(this,"",Ac(0,0),Fc(this,Ac(1,0)))},getLineHandle:function(a){return Hc(this,a)?ke(this,a):void 0},getLineNumber:function(a){return oe(a)},getLineHandleVisualStart:function(a){return"number"==typeof a&&(a=ke(this,a)),Ed(this,a)},lineCount:function(){return this.size},firstLine:function(){return this.first},lastLine:function(){return this.first+this.size-1},clipPos:function(a){return Fc(this,a)},getCursor:function(a){var c,b=this.sel;return c=null==a||"head"==a?b.head:"anchor"==a?b.anchor:"end"==a||a===!1?b.to:b.from,Dc(c)},somethingSelected:function(){return!Bc(this.sel.head,this.sel.anchor)},setCursor:Fb(function(a,b,c){var d=Fc(this,"number"==typeof a?Ac(a,b||0):a);c?Ic(this,d):Kc(this,d,d)}),setSelection:Fb(function(a,b,c){Kc(this,Fc(this,a),Fc(this,b||a),c)}),extendSelection:Fb(function(a,b,c){Ic(this,Fc(this,a),b&&Fc(this,b),c)}),getSelection:function(a){return this.getRange(this.sel.from,this.sel.to,a)},replaceSelection:function(a,b,c){tc(this,{from:this.sel.from,to:this.sel.to,text:vf(a),origin:c},b||"around")},undo:Fb(function(){vc(this,"undo")}),redo:Fb(function(){vc(this,"redo")}),setExtending:function(a){this.sel.extend=a},historySize:function(){var a=this.history;return{undo:a.done.length,redo:a.undone.length}},clearHistory:function(){this.history=se(this.history.maxGeneration)},markClean:function(){this.cleanGeneration=this.changeGeneration()},changeGeneration:function(){return this.history.lastOp=this.history.lastOrigin=null,this.history.generation},isClean:function(a){return this.history.generation==(a||this.cleanGeneration)},getHistory:function(){return{done:ye(this.history.done),undone:ye(this.history.undone)}},setHistory:function(a){var b=this.history=se(this.history.maxGeneration);b.done=a.done.slice(0),b.undone=a.undone.slice(0)},markText:function(a,b,c){return qd(this,Fc(this,a),Fc(this,b),c,"range")},setBookmark:function(a,b){var c={replacedWith:b&&(null==b.nodeType?b.widget:b),insertLeft:b&&b.insertLeft};return a=Fc(this,a),qd(this,a,a,c,"bookmark")},findMarksAt:function(a){a=Fc(this,a);var b=[],c=ke(this,a.line).markedSpans;if(c)for(var d=0;d<c.length;++d){var e=c[d];(null==e.from||e.from<=a.ch)&&(null==e.to||e.to>=a.ch)&&b.push(e.marker.parent||e.marker)}return b},getAllMarks:function(){var a=[];return this.iter(function(b){var c=b.markedSpans;if(c)for(var d=0;d<c.length;++d)null!=c[d].from&&a.push(c[d].marker)}),a},posFromIndex:function(a){var b,c=this.first;return this.iter(function(d){var e=d.text.length+1;return e>a?(b=a,!0):(a-=e,++c,void 0)}),Fc(this,Ac(c,b))},indexFromPos:function(a){a=Fc(this,a);var b=a.ch;return a.line<this.first||a.ch<0?0:(this.iter(this.first,a.line,function(a){b+=a.text.length+1}),b)},copy:function(a){var b=new fe(me(this,this.first,this.first+this.size),this.modeOption,this.first);return b.scrollTop=this.scrollTop,b.scrollLeft=this.scrollLeft,b.sel={from:this.sel.from,to:this.sel.to,head:this.sel.head,anchor:this.sel.anchor,shift:this.sel.shift,extend:!1,goalColumn:this.sel.goalColumn},a&&(b.history.undoDepth=this.history.undoDepth,b.setHistory(this.getHistory())),b},linkedDoc:function(a){a||(a={});var b=this.first,c=this.first+this.size;null!=a.from&&a.from>b&&(b=a.from),null!=a.to&&a.to<c&&(c=a.to);var d=new fe(me(this,b,c),a.mode||this.modeOption,b);return a.sharedHist&&(d.history=this.history),(this.linked||(this.linked=[])).push({doc:d,sharedHist:a.sharedHist}),d.linked=[{doc:this,isParent:!0,sharedHist:a.sharedHist}],d},unlinkDoc:function(a){if(a instanceof w&&(a=a.doc),this.linked)for(var b=0;b<this.linked.length;++b){var c=this.linked[b];if(c.doc==a){this.linked.splice(b,1),a.unlinkDoc(this);break}}if(a.history==this.history){var d=[a.id];ie(a,function(a){d.push(a.id)},!0),a.history=se(),a.history.done=ye(this.history.done,d),a.history.undone=ye(this.history.undone,d)}},iterLinkedDocs:function(a){ie(this,a)},getMode:function(){return this.mode},getEditor:function(){return this.cm}}),fe.prototype.eachLine=fe.prototype.iter;var ge="iter insert remove copy getEditor".split(" ");for(var he in fe.prototype)fe.prototype.hasOwnProperty(he)&&af(ge,he)<0&&(w.prototype[he]=function(a){return function(){return a.apply(this.doc,arguments)}}(fe.prototype[he]));Te(fe),w.e_stop=He,w.e_preventDefault=Ee,w.e_stopPropagation=Fe;var Ne,Oe=0;w.on=Ke,w.off=Le,w.signal=Me;var Ue=30,Ve=w.Pass={toString:function(){return"CodeMirror.Pass"}};We.prototype={set:function(a,b){clearTimeout(this.id),this.id=setTimeout(b,a)}},w.countColumn=Xe;var Ye=[""],ff=/[\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/,jf=/[\u0300-\u036F\u0483-\u0487\u0488-\u0489\u0591-\u05BD\u05BF\u05C1-\u05C2\u05C4-\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7-\u06E8\u06EA-\u06ED\uA66F\uA670-\uA672\uA674-\uA67D\uA69F\udc00-\udfff]/;w.replaceGetRect=function(a){of=a};var pf=function(){if(d)return!1;var a=kf("div");return"draggable"in a||"dragDrop"in a}();a?qf=function(a,b){return 36==a.charCodeAt(b-1)&&39==a.charCodeAt(b)}:i&&!/Version\/([6-9]|\d\d)\b/.test(navigator.userAgent)?qf=function(a,b){return/\-[^ \-?]|\?[^ !\'\"\),.\-\/:;\?\]\}]/.test(a.slice(b-1,b+1))}:e&&/Chrome\/(?:29|[3-9]\d|\d\d\d)\./.test(navigator.userAgent)?qf=function(a,b){var c=a.charCodeAt(b-1);return c>=8208&&8212>=c}:e&&(qf=function(a,b){if(b>1&&45==a.charCodeAt(b-1)){if(/\w/.test(a.charAt(b-2))&&/[^\-?\.]/.test(a.charAt(b)))return!0;if(b>2&&/[\d\.,]/.test(a.charAt(b-2))&&/[\d\.,]/.test(a.charAt(b)))return!1}return/[~!#%&*)=+}\]\\|\"\.>,:;][({[<]|-[^\-?\.\u2010-\u201f\u2026]|\?[\w~`@#$%\^&*(_=+{[|><]|\u2026[\w~`@#$%\^&*(_=+{[><]/.test(a.slice(b-1,b+1))});var rf,tf,vf=3!="\n\nb".split(/\n/).length?function(a){for(var b=0,c=[],d=a.length;d>=b;){var e=a.indexOf("\n",b);-1==e&&(e=a.length);var f=a.slice(b,"\r"==a.charAt(e-1)?e-1:e),g=f.indexOf("\r");-1!=g?(c.push(f.slice(0,g)),b+=g+1):(c.push(f),b=e+1)}return c}:function(a){return a.split(/\r\n?|\n/)};w.splitLines=vf;var wf=window.getSelection?function(a){try{return a.selectionStart!=a.selectionEnd}catch(b){return!1}}:function(a){try{var b=a.ownerDocument.selection.createRange()}catch(c){}return b&&b.parentElement()==a?0!=b.compareEndPoints("StartToEnd",b):!1},xf=function(){var a=kf("div");return"oncopy"in a?!0:(a.setAttribute("oncopy","return;"),"function"==typeof a.oncopy)}(),yf={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",109:"-",107:"=",127:"Delete",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"};w.keyNames=yf,function(){for(var a=0;10>a;a++)yf[a+48]=String(a);for(var a=65;90>=a;a++)yf[a]=String.fromCharCode(a);for(var a=1;12>=a;a++)yf[a+111]=yf[a+63235]="F"+a}();var Hf,Mf=function(){function c(c){return 255>=c?a.charAt(c):c>=1424&&1524>=c?"R":c>=1536&&1791>=c?b.charAt(c-1536):c>=1792&&2220>=c?"r":"L"}var a="bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLL",b="rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmmrrrrrrrrrrrrrrrrrr",d=/[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/,e=/[stwN]/,f=/[LRr]/,g=/[Lb1n]/,h=/[1n]/,i="L";return function(a){if(!d.test(a))return!1;for(var l,b=a.length,j=[],k=0;b>k;++k)j.push(l=c(a.charCodeAt(k)));for(var k=0,m=i;b>k;++k){var l=j[k];"m"==l?j[k]=m:m=l}for(var k=0,n=i;b>k;++k){var l=j[k];"1"==l&&"r"==n?j[k]="n":f.test(l)&&(n=l,"r"==l&&(j[k]="R"))}for(var k=1,m=j[0];b-1>k;++k){var l=j[k];"+"==l&&"1"==m&&"1"==j[k+1]?j[k]="1":","!=l||m!=j[k+1]||"1"!=m&&"n"!=m||(j[k]=m),m=l}for(var k=0;b>k;++k){var l=j[k];if(","==l)j[k]="N";else if("%"==l){for(var o=k+1;b>o&&"%"==j[o];++o);for(var p=k&&"!"==j[k-1]||b-1>o&&"1"==j[o]?"1":"N",q=k;o>q;++q)j[q]=p;k=o-1}}for(var k=0,n=i;b>k;++k){var l=j[k];"L"==n&&"1"==l?j[k]="L":f.test(l)&&(n=l)}for(var k=0;b>k;++k)if(e.test(j[k])){for(var o=k+1;b>o&&e.test(j[o]);++o);for(var r="L"==(k?j[k-1]:i),s="L"==(b-1>o?j[o]:i),p=r||s?"L":"R",q=k;o>q;++q)j[q]=p;k=o-1}for(var u,t=[],k=0;b>k;)if(g.test(j[k])){var v=k;for(++k;b>k&&g.test(j[k]);++k);t.push({from:v,to:k,level:0})}else{var w=k,x=t.length;for(++k;b>k&&"L"!=j[k];++k);for(var q=w;k>q;)if(h.test(j[q])){q>w&&t.splice(x,0,{from:w,to:q,level:1});var y=q;for(++q;k>q&&h.test(j[q]);++q);t.splice(x,0,{from:y,to:q,level:2}),w=q}else++q;k>w&&t.splice(x,0,{from:w,to:k,level:1})}return 1==t[0].level&&(u=a.match(/^\s+/))&&(t[0].from=u[0].length,t.unshift({from:0,to:u[0].length,level:0})),1==$e(t).level&&(u=a.match(/\s+$/))&&($e(t).to-=u[0].length,t.push({from:b-u[0].length,to:b,level:0})),t[0].level!=$e(t).level&&t.push({from:b,to:b,level:t[0].level}),t}}();return w.version="3.18.0",w}(),CodeMirror.defineMode("css",function(a,b){"use strict";function l(a,b){return k=b,a}function m(a,b){var c=a.next();if(d[c]){var e=d[c](a,b);if(e!==!1)return e}if("@"==c)return a.eatWhile(/[\w\\\-]/),l("def",a.current());if("="==c)l(null,"compare");else{if(("~"==c||"|"==c)&&a.eat("="))return l(null,"compare");if('"'==c||"'"==c)return b.tokenize=n(c),b.tokenize(a,b);if("#"==c)return a.eatWhile(/[\w\\\-]/),l("atom","hash");if("!"==c)return a.match(/^\s*\w*/),l("keyword","important");if(/\d/.test(c)||"."==c&&a.eat(/\d/))return a.eatWhile(/[\w.%]/),l("number","unit");if("-"!==c)return/[,+>*\/]/.test(c)?l(null,"select-op"):"."==c&&a.match(/^-?[_a-z][_a-z0-9-]*/i)?l("qualifier","qualifier"):":"==c?l("operator",c):/[;{}\[\]\(\)]/.test(c)?l(null,c):"u"==c&&a.match("rl(")?(a.backUp(1),b.tokenize=o,l("property","variable")):(a.eatWhile(/[\w\\\-]/),l("property","variable"));if(/\d/.test(a.peek()))return a.eatWhile(/[\w.%]/),l("number","unit");if(a.match(/^[^-]+-/))return l("meta","meta")}}function n(a,b){return function(c,d){for(var f,e=!1;null!=(f=c.next())&&(f!=a||e);)e=!e&&"\\"==f;return e||(b&&c.backUp(1),d.tokenize=m),l("string","string")}}function o(a,b){return a.next(),b.tokenize=a.match(/\s*[\"\']/,!1)?m:n(")",!0),l(null,"(")}b.propertyKeywords||(b=CodeMirror.resolveMode("text/css"));var c=a.indentUnit,d=b.hooks||{},e=b.atMediaTypes||{},f=b.atMediaFeatures||{},g=b.propertyKeywords||{},h=b.colorKeywords||{},i=b.valueKeywords||{},j=!!b.allowNested,k=null;return{startState:function(a){return{tokenize:m,baseIndent:a||0,stack:[],lastToken:null}},token:function(a,b){if(b.tokenize=b.tokenize||m,b.tokenize==m&&a.eatSpace())return null;var c=b.tokenize(a,b);c&&"string"!=typeof c&&(c=l(c[0],c[1]));var d=b.stack[b.stack.length-1];if("variable"==c)return"variable-definition"==k&&b.stack.push("propertyValue"),b.lastToken="variable-2";if("property"==c){var n=a.current().toLowerCase();"propertyValue"==d?c=i.hasOwnProperty(n)?"string-2":h.hasOwnProperty(n)?"keyword":"variable-2":"rule"==d?g.hasOwnProperty(n)||(c+=" error"):"block"==d?c=g.hasOwnProperty(n)?"property":h.hasOwnProperty(n)?"keyword":i.hasOwnProperty(n)?"string-2":"tag":d&&"@media{"!=d?"@media"==d?c=e[a.current()]?"attribute":/^(only|not)$/.test(n)?"keyword":"and"==n?"error":f.hasOwnProperty(n)?"error":"attribute error":"@mediaType"==d?c=e.hasOwnProperty(n)?"attribute":"and"==n?"operator":/^(only|not)$/.test(n)?"error":"error":"@mediaType("==d?g.hasOwnProperty(n)||(e.hasOwnProperty(n)?c="error":"and"==n?c="operator":/^(only|not)$/.test(n)?c="error":c+=" error"):c="@import"==d?"tag":"error":c="tag"}else"atom"==c?d&&"@media{"!=d&&"block"!=d?"propertyValue"==d?/^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/.test(a.current())||(c+=" error"):c="error":c="builtin":"@media"==d&&"{"==k&&(c="error");if("{"==k)if("@media"==d||"@mediaType"==d)b.stack[b.stack.length-1]="@media{";else{var o=j?"block":"rule";b.stack.push(o)}else"}"==k?("interpolation"==d&&(c="operator"),b.stack.pop(),"propertyValue"==d&&b.stack.pop()):"interpolation"==k?b.stack.push("interpolation"):"@media"==k?b.stack.push("@media"):"@import"==k?b.stack.push("@import"):"@media"==d&&/\b(keyword|attribute)\b/.test(c)?b.stack[b.stack.length-1]="@mediaType":"@mediaType"==d&&","==a.current()?b.stack[b.stack.length-1]="@media":"("==k?"@media"==d||"@mediaType"==d?(b.stack[b.stack.length-1]="@mediaType",b.stack.push("@mediaType(")):b.stack.push("("):")"==k?("propertyValue"==d&&b.stack.pop(),b.stack.pop()):":"==k&&"property"==b.lastToken?b.stack.push("propertyValue"):"propertyValue"==d&&";"==k?b.stack.pop():"@import"==d&&";"==k&&b.stack.pop();return b.lastToken=c},indent:function(a,b){var d=a.stack.length;return/^\}/.test(b)&&(d-="propertyValue"==a.stack[d-1]?2:1),a.baseIndent+d*c},electricChars:"}",blockCommentStart:"/*",blockCommentEnd:"*/",fold:"brace"}}),function(){function a(a){for(var b={},c=0;c<a.length;++c)b[a[c]]=!0;return b}function g(a,b){for(var d,c=!1;null!=(d=a.next());){if(c&&"/"==d){b.tokenize=null;break}c="*"==d}return["comment","comment"]}var b=a(["all","aural","braille","handheld","print","projection","screen","tty","tv","embossed"]),c=a(["width","min-width","max-width","height","min-height","max-height","device-width","min-device-width","max-device-width","device-height","min-device-height","max-device-height","aspect-ratio","min-aspect-ratio","max-aspect-ratio","device-aspect-ratio","min-device-aspect-ratio","max-device-aspect-ratio","color","min-color","max-color","color-index","min-color-index","max-color-index","monochrome","min-monochrome","max-monochrome","resolution","min-resolution","max-resolution","scan","grid"]),d=a(["align-content","align-items","align-self","alignment-adjust","alignment-baseline","anchor-point","animation","animation-delay","animation-direction","animation-duration","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","appearance","azimuth","backface-visibility","background","background-attachment","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","baseline-shift","binding","bleed","bookmark-label","bookmark-level","bookmark-state","bookmark-target","border","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","clear","clip","color","color-profile","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","content","counter-increment","counter-reset","crop","cue","cue-after","cue-before","cursor","direction","display","dominant-baseline","drop-initial-after-adjust","drop-initial-after-align","drop-initial-before-adjust","drop-initial-before-align","drop-initial-size","drop-initial-value","elevation","empty-cells","fit","fit-position","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","float-offset","flow-from","flow-into","font","font-feature-settings","font-family","font-kerning","font-language-override","font-size","font-size-adjust","font-stretch","font-style","font-synthesis","font-variant","font-variant-alternates","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-weight","grid-cell","grid-column","grid-column-align","grid-column-sizing","grid-column-span","grid-columns","grid-flow","grid-row","grid-row-align","grid-row-sizing","grid-row-span","grid-rows","grid-template","hanging-punctuation","height","hyphens","icon","image-orientation","image-rendering","image-resolution","inline-box-align","justify-content","left","letter-spacing","line-break","line-height","line-stacking","line-stacking-ruby","line-stacking-shift","line-stacking-strategy","list-style","list-style-image","list-style-position","list-style-type","margin","margin-bottom","margin-left","margin-right","margin-top","marker-offset","marks","marquee-direction","marquee-loop","marquee-play-count","marquee-speed","marquee-style","max-height","max-width","min-height","min-width","move-to","nav-down","nav-index","nav-left","nav-right","nav-up","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-style","overflow-wrap","overflow-x","overflow-y","padding","padding-bottom","padding-left","padding-right","padding-top","page","page-break-after","page-break-before","page-break-inside","page-policy","pause","pause-after","pause-before","perspective","perspective-origin","pitch","pitch-range","play-during","position","presentation-level","punctuation-trim","quotes","region-break-after","region-break-before","region-break-inside","region-fragment","rendering-intent","resize","rest","rest-after","rest-before","richness","right","rotation","rotation-point","ruby-align","ruby-overhang","ruby-position","ruby-span","shape-inside","shape-outside","size","speak","speak-as","speak-header","speak-numeral","speak-punctuation","speech-rate","stress","string-set","tab-size","table-layout","target","target-name","target-new","target-position","text-align","text-align-last","text-decoration","text-decoration-color","text-decoration-line","text-decoration-skip","text-decoration-style","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-height","text-indent","text-justify","text-outline","text-overflow","text-shadow","text-size-adjust","text-space-collapse","text-transform","text-underline-position","text-wrap","top","transform","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","volume","white-space","widows","width","word-break","word-spacing","word-wrap","z-index","zoom","clip-path","clip-rule","mask","enable-background","filter","flood-color","flood-opacity","lighting-color","stop-color","stop-opacity","pointer-events","color-interpolation","color-interpolation-filters","color-profile","color-rendering","fill","fill-opacity","fill-rule","image-rendering","marker","marker-end","marker-mid","marker-start","shape-rendering","stroke","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","text-rendering","baseline-shift","dominant-baseline","glyph-orientation-horizontal","glyph-orientation-vertical","kerning","text-anchor","writing-mode"]),e=a(["aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","grey","green","greenyellow","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen"]),f=a(["above","absolute","activeborder","activecaption","afar","after-white-space","ahead","alias","all","all-scroll","alternate","always","amharic","amharic-abegede","antialiased","appworkspace","arabic-indic","armenian","asterisks","auto","avoid","avoid-column","avoid-page","avoid-region","background","backwards","baseline","below","bidi-override","binary","bengali","blink","block","block-axis","bold","bolder","border","border-box","both","bottom","break","break-all","break-word","button","button-bevel","buttonface","buttonhighlight","buttonshadow","buttontext","cambodian","capitalize","caps-lock-indicator","caption","captiontext","caret","cell","center","checkbox","circle","cjk-earthly-branch","cjk-heavenly-stem","cjk-ideographic","clear","clip","close-quote","col-resize","collapse","column","compact","condensed","contain","content","content-box","context-menu","continuous","copy","cover","crop","cross","crosshair","currentcolor","cursive","dashed","decimal","decimal-leading-zero","default","default-button","destination-atop","destination-in","destination-out","destination-over","devanagari","disc","discard","document","dot-dash","dot-dot-dash","dotted","double","down","e-resize","ease","ease-in","ease-in-out","ease-out","element","ellipse","ellipsis","embed","end","ethiopic","ethiopic-abegede","ethiopic-abegede-am-et","ethiopic-abegede-gez","ethiopic-abegede-ti-er","ethiopic-abegede-ti-et","ethiopic-halehame-aa-er","ethiopic-halehame-aa-et","ethiopic-halehame-am-et","ethiopic-halehame-gez","ethiopic-halehame-om-et","ethiopic-halehame-sid-et","ethiopic-halehame-so-et","ethiopic-halehame-ti-er","ethiopic-halehame-ti-et","ethiopic-halehame-tig","ew-resize","expanded","extra-condensed","extra-expanded","fantasy","fast","fill","fixed","flat","footnotes","forwards","from","geometricPrecision","georgian","graytext","groove","gujarati","gurmukhi","hand","hangul","hangul-consonant","hebrew","help","hidden","hide","higher","highlight","highlighttext","hiragana","hiragana-iroha","horizontal","hsl","hsla","icon","ignore","inactiveborder","inactivecaption","inactivecaptiontext","infinite","infobackground","infotext","inherit","initial","inline","inline-axis","inline-block","inline-table","inset","inside","intrinsic","invert","italic","justify","kannada","katakana","katakana-iroha","keep-all","khmer","landscape","lao","large","larger","left","level","lighter","line-through","linear","lines","list-item","listbox","listitem","local","logical","loud","lower","lower-alpha","lower-armenian","lower-greek","lower-hexadecimal","lower-latin","lower-norwegian","lower-roman","lowercase","ltr","malayalam","match","media-controls-background","media-current-time-display","media-fullscreen-button","media-mute-button","media-play-button","media-return-to-realtime-button","media-rewind-button","media-seek-back-button","media-seek-forward-button","media-slider","media-sliderthumb","media-time-remaining-display","media-volume-slider","media-volume-slider-container","media-volume-sliderthumb","medium","menu","menulist","menulist-button","menulist-text","menulist-textfield","menutext","message-box","middle","min-intrinsic","mix","mongolian","monospace","move","multiple","myanmar","n-resize","narrower","ne-resize","nesw-resize","no-close-quote","no-drop","no-open-quote","no-repeat","none","normal","not-allowed","nowrap","ns-resize","nw-resize","nwse-resize","oblique","octal","open-quote","optimizeLegibility","optimizeSpeed","oriya","oromo","outset","outside","outside-shape","overlay","overline","padding","padding-box","painted","page","paused","persian","plus-darker","plus-lighter","pointer","polygon","portrait","pre","pre-line","pre-wrap","preserve-3d","progress","push-button","radio","read-only","read-write","read-write-plaintext-only","rectangle","region","relative","repeat","repeat-x","repeat-y","reset","reverse","rgb","rgba","ridge","right","round","row-resize","rtl","run-in","running","s-resize","sans-serif","scroll","scrollbar","se-resize","searchfield","searchfield-cancel-button","searchfield-decoration","searchfield-results-button","searchfield-results-decoration","semi-condensed","semi-expanded","separate","serif","show","sidama","single","skip-white-space","slide","slider-horizontal","slider-vertical","sliderthumb-horizontal","sliderthumb-vertical","slow","small","small-caps","small-caption","smaller","solid","somali","source-atop","source-in","source-out","source-over","space","square","square-button","start","static","status-bar","stretch","stroke","sub","subpixel-antialiased","super","sw-resize","table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row","table-row-group","telugu","text","text-bottom","text-top","textarea","textfield","thai","thick","thin","threeddarkshadow","threedface","threedhighlight","threedlightshadow","threedshadow","tibetan","tigre","tigrinya-er","tigrinya-er-abegede","tigrinya-et","tigrinya-et-abegede","to","top","transparent","ultra-condensed","ultra-expanded","underline","up","upper-alpha","upper-armenian","upper-greek","upper-hexadecimal","upper-latin","upper-norwegian","upper-roman","uppercase","urdu","url","vertical","vertical-text","visible","visibleFill","visiblePainted","visibleStroke","visual","w-resize","wait","wave","wider","window","windowframe","windowtext","x-large","x-small","xor","xx-large","xx-small"]);CodeMirror.defineMIME("text/css",{atMediaTypes:b,atMediaFeatures:c,propertyKeywords:d,colorKeywords:e,valueKeywords:f,hooks:{"<":function(a,b){function c(a,b){for(var d,c=0;null!=(d=a.next());){if(c>=2&&">"==d){b.tokenize=null;break}c="-"==d?c+1:0}return["comment","comment"]}return a.eat("!")?(b.tokenize=c,c(a,b)):void 0},"/":function(a,b){return a.eat("*")?(b.tokenize=g,g(a,b)):!1}},name:"css"}),CodeMirror.defineMIME("text/x-scss",{atMediaTypes:b,atMediaFeatures:c,propertyKeywords:d,colorKeywords:e,valueKeywords:f,allowNested:!0,hooks:{":":function(a){return a.match(/\s*{/)?[null,"{"]:!1},$:function(a){return a.match(/^[\w-]+/),":"==a.peek()?["variable","variable-definition"]:["variable","variable"]},"/":function(a,b){return a.eat("/")?(a.skipToEnd(),["comment","comment"]):a.eat("*")?(b.tokenize=g,g(a,b)):["operator","operator"]},"#":function(a){return a.eat("{")?["operator","interpolation"]:(a.eatWhile(/[\w\\\-]/),["atom","hash"])}},name:"css"})}(),CodeMirror.defineMode("htmlmixed",function(a,b){function i(a,b){var f=b.htmlState.tagName,g=c.token(a,b.htmlState);if("script"==f&&/\btag\b/.test(g)&&">"==a.current()){var h=a.string.slice(Math.max(0,a.pos-100),a.pos).match(/\btype\s*=\s*("[^"]+"|'[^']+'|\S+)[^<]*$/i);h=h?h[1]:"",h&&/[\"\']/.test(h.charAt(0))&&(h=h.slice(1,h.length-1));for(var i=0;i<e.length;++i){var j=e[i];if("string"==typeof j.matches?h==j.matches:j.matches.test(h)){j.mode&&(b.token=k,b.localMode=j.mode,b.localState=j.mode.startState&&j.mode.startState(c.indent(b.htmlState,"")));break}}}else"style"==f&&/\btag\b/.test(g)&&">"==a.current()&&(b.token=l,b.localMode=d,b.localState=d.startState(c.indent(b.htmlState,"")));return g}function j(a,b,c){var f,d=a.current(),e=d.search(b);return e>-1?a.backUp(d.length-e):(f=d.match(/<\/?$/))&&(a.backUp(d.length),a.match(b,!1)||a.match(d[0])),c
6
+ }function k(a,b){return a.match(/^<\/\s*script\s*>/i,!1)?(b.token=i,b.localState=b.localMode=null,i(a,b)):j(a,/<\/\s*script\s*>/,b.localMode.token(a,b.localState))}function l(a,b){return a.match(/^<\/\s*style\s*>/i,!1)?(b.token=i,b.localState=b.localMode=null,i(a,b)):j(a,/<\/\s*style\s*>/,d.token(a,b.localState))}var c=CodeMirror.getMode(a,{name:"xml",htmlMode:!0}),d=CodeMirror.getMode(a,"css"),e=[],f=b&&b.scriptTypes;if(e.push({matches:/^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^$/i,mode:CodeMirror.getMode(a,"javascript")}),f)for(var g=0;g<f.length;++g){var h=f[g];e.push({matches:h.matches,mode:h.mode&&CodeMirror.getMode(a,h.mode)})}return e.push({matches:/./,mode:CodeMirror.getMode(a,"text/plain")}),{startState:function(){var a=c.startState();return{token:i,localMode:null,localState:null,htmlState:a}},copyState:function(a){if(a.localState)var b=CodeMirror.copyState(a.localMode,a.localState);return{token:a.token,localMode:a.localMode,localState:b,htmlState:CodeMirror.copyState(c,a.htmlState)}},token:function(a,b){return b.token(a,b)},indent:function(a,b){return!a.localMode||/^\s*<\//.test(b)?c.indent(a.htmlState,b):a.localMode.indent?a.localMode.indent(a.localState,b):CodeMirror.Pass},electricChars:"/{}:",innerMode:function(a){return{state:a.localState||a.htmlState,mode:a.localMode||c}}}},"xml","javascript","css"),CodeMirror.defineMIME("text/html","htmlmixed"),CodeMirror.defineMode("javascript",function(a,b){function i(a,b,c){return b.tokenize=c,c(a,b)}function j(a,b){for(var d,c=!1;null!=(d=a.next());){if(d==b&&!c)return!1;c=!c&&"\\"==d}return c}function m(a,b,c){return k=a,l=c,b}function n(a,b){var c=a.next();if('"'==c||"'"==c)return i(a,b,o(c));if("."==c&&a.match(/^\d+(?:[eE][+\-]?\d+)?/))return m("number","number");if(/[\[\]{}\(\),;\:\.]/.test(c))return m(c);if("0"==c&&a.eat(/x/i))return a.eatWhile(/[\da-f]/i),m("number","number");if(/\d/.test(c))return a.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/),m("number","number");if("/"==c)return a.eat("*")?i(a,b,p):a.eat("/")?(a.skipToEnd(),m("comment","comment")):"operator"==b.lastType||"keyword c"==b.lastType||/^[\[{}\(,;:]$/.test(b.lastType)?(j(a,"/"),a.eatWhile(/[gimy]/),m("regexp","string-2")):(a.eatWhile(h),m("operator",null,a.current()));if("#"==c)return a.skipToEnd(),m("error","error");if(h.test(c))return a.eatWhile(h),m("operator",null,a.current());a.eatWhile(/[\w\$_]/);var d=a.current(),e=g.propertyIsEnumerable(d)&&g[d];return e&&"."!=b.lastType?m(e.type,e.style,d):m("variable","variable",d)}function o(a){return function(b,c){return j(b,a)||(c.tokenize=n),m("string","string")}}function p(a,b){for(var d,c=!1;d=a.next();){if("/"==d&&c){b.tokenize=n;break}c="*"==d}return m("comment","comment")}function r(a,b,c,d,e,f){this.indented=a,this.column=b,this.type=c,this.prev=e,this.info=f,null!=d&&(this.align=d)}function s(a,b){for(var c=a.localVars;c;c=c.next)if(c.name==b)return!0}function t(a,b,c,d,f){var g=a.cc;for(u.state=a,u.stream=f,u.marked=null,u.cc=g,a.lexical.hasOwnProperty("align")||(a.lexical.align=!0);;){var h=g.length?g.pop():e?F:E;if(h(c,d)){for(;g.length&&g[g.length-1].lex;)g.pop()();return u.marked?u.marked:"variable"==c&&s(a,d)?"variable-2":b}}}function v(){for(var a=arguments.length-1;a>=0;a--)u.cc.push(arguments[a])}function w(){return v.apply(null,arguments),!0}function x(a){function b(b){for(var c=b;c;c=c.next)if(c.name==a)return!0;return!1}var c=u.state;if(c.context){if(u.marked="def",b(c.localVars))return;c.localVars={name:a,next:c.localVars}}else{if(b(c.globalVars))return;c.globalVars={name:a,next:c.globalVars}}}function z(){u.state.context={prev:u.state.context,vars:u.state.localVars},u.state.localVars=y}function A(){u.state.localVars=u.state.context.vars,u.state.context=u.state.context.prev}function B(a,b){var c=function(){var c=u.state,d=c.indented;"stat"==c.lexical.type&&(d=c.lexical.indented),c.lexical=new r(d,u.stream.column(),a,null,c.lexical,b)};return c.lex=!0,c}function C(){var a=u.state;a.lexical.prev&&(")"==a.lexical.type&&(a.indented=a.lexical.indented),a.lexical=a.lexical.prev)}function D(a){return function(b){return b==a?w():";"==a?v():w(arguments.callee)}}function E(a){return"var"==a?w(B("vardef"),U,D(";"),C):"keyword a"==a?w(B("form"),F,E,C):"keyword b"==a?w(B("form"),E,C):"{"==a?w(B("}"),R,C):";"==a?w():"if"==a?w(B("form"),F,E,C,W):"function"==a?w(_):"for"==a?w(B("form"),D("("),B(")"),X,D(")"),C,E,C):"variable"==a?w(B("stat"),M):"switch"==a?w(B("form"),F,B("}","switch"),D("{"),R,C,C):"case"==a?w(F,D(":")):"default"==a?w(D(":")):"catch"==a?w(B("form"),z,D("("),ab,D(")"),E,C,A):v(B("stat"),F,D(";"),C)}function F(a){return H(a,!1)}function G(a){return H(a,!0)}function H(a,b){var c=b?L:K;return q.hasOwnProperty(a)?w(c):"function"==a?w(_):"keyword c"==a?w(b?J:I):"("==a?w(B(")"),I,D(")"),C,c):"operator"==a?w(b?G:F):"["==a?w(B("]"),Q(G,"]"),C,c):"{"==a?w(B("}"),Q(O,"}"),C,c):w()}function I(a){return a.match(/[;\}\)\],]/)?v():v(F)}function J(a){return a.match(/[;\}\)\],]/)?v():v(G)}function K(a,b){return","==a?w(F):L(a,b,!1)}function L(a,b,c){var d=0==c?K:L,e=0==c?F:G;return"operator"==a?/\+\+|--/.test(b)?w(d):"?"==b?w(F,D(":"),e):w(e):";"!=a?"("==a?w(B(")","call"),Q(G,")"),C,d):"."==a?w(N,d):"["==a?w(B("]"),I,D("]"),C,d):void 0:void 0}function M(a){return":"==a?w(C,E):v(K,D(";"),C)}function N(a){return"variable"==a?(u.marked="property",w()):void 0}function O(a,b){if("variable"==a){if(u.marked="property","get"==b||"set"==b)return w(P)}else("number"==a||"string"==a)&&(u.marked=a+" property");return q.hasOwnProperty(a)?w(D(":"),G):void 0}function P(a){return":"==a?w(F):"variable"!=a?w(D(":"),F):(u.marked="property",w(_))}function Q(a,b){function c(d){if(","==d){var e=u.state.lexical;return"call"==e.info&&(e.pos=(e.pos||0)+1),w(a,c)}return d==b?w():w(D(b))}return function(d){return d==b?w():v(a,c)}}function R(a){return"}"==a?w():v(E,R)}function S(a){return":"==a?w(T):v()}function T(a){return"variable"==a?(u.marked="variable-3",w()):v()}function U(a,b){return"variable"==a?(x(b),f?w(S,V):w(V)):v()}function V(a,b){return"="==b?w(G,V):","==a?w(U):void 0}function W(a,b){return"keyword b"==a&&"else"==b?w(B("form"),E,C):void 0}function X(a){return"var"==a?w(U,D(";"),Z):";"==a?w(Z):"variable"==a?w(Y):v(F,D(";"),Z)}function Y(a,b){return"in"==b?w(F):w(K,Z)}function Z(a,b){return";"==a?w($):"in"==b?w(F):v(F,D(";"),$)}function $(a){")"!=a&&w(F)}function _(a,b){return"variable"==a?(x(b),w(_)):"("==a?w(B(")"),z,Q(ab,")"),C,E,A):void 0}function ab(a,b){return"variable"==a?(x(b),f?w(S):w()):void 0}var k,l,c=a.indentUnit,d=b.statementIndent,e=b.json,f=b.typescript,g=function(){function a(a){return{type:a,style:"keyword"}}var b=a("keyword a"),c=a("keyword b"),d=a("keyword c"),e=a("operator"),g={type:"atom",style:"atom"},h={"if":a("if"),"while":b,"with":b,"else":c,"do":c,"try":c,"finally":c,"return":d,"break":d,"continue":d,"new":d,"delete":d,"throw":d,"var":a("var"),"const":a("var"),let:a("var"),"function":a("function"),"catch":a("catch"),"for":a("for"),"switch":a("switch"),"case":a("case"),"default":a("default"),"in":e,"typeof":e,"instanceof":e,"true":g,"false":g,"null":g,undefined:g,NaN:g,Infinity:g,"this":a("this")};if(f){var i={type:"variable",style:"variable-3"},j={"interface":a("interface"),"class":a("class"),"extends":a("extends"),constructor:a("constructor"),"public":a("public"),"private":a("private"),"protected":a("protected"),"static":a("static"),"super":a("super"),string:i,number:i,bool:i,any:i};for(var k in j)h[k]=j[k]}return h}(),h=/[+\-*&%=<>!?|~^]/,q={atom:!0,number:!0,variable:!0,string:!0,regexp:!0,"this":!0},u={state:null,column:null,marked:null,cc:null},y={name:"this",next:{name:"arguments"}};return C.lex=!0,{startState:function(a){return{tokenize:n,lastType:null,cc:[],lexical:new r((a||0)-c,0,"block",!1),localVars:b.localVars,globalVars:b.globalVars,context:b.localVars&&{vars:b.localVars},indented:0}},token:function(a,b){if(a.sol()&&(b.lexical.hasOwnProperty("align")||(b.lexical.align=!1),b.indented=a.indentation()),b.tokenize!=p&&a.eatSpace())return null;var c=b.tokenize(a,b);return"comment"==k?c:(b.lastType="operator"!=k||"++"!=l&&"--"!=l?k:"incdec",t(b,c,k,l,a))},indent:function(a,e){if(a.tokenize==p)return CodeMirror.Pass;if(a.tokenize!=n)return 0;for(var f=e&&e.charAt(0),g=a.lexical,h=a.cc.length-1;h>=0;--h){var i=a.cc[h];if(i==C)g=g.prev;else if(i!=W||/^else\b/.test(e))break}"stat"==g.type&&"}"==f&&(g=g.prev),d&&")"==g.type&&"stat"==g.prev.type&&(g=g.prev);var j=g.type,k=f==j;return"vardef"==j?g.indented+("operator"==a.lastType||","==a.lastType?4:0):"form"==j&&"{"==f?g.indented:"form"==j?g.indented+c:"stat"==j?g.indented+("operator"==a.lastType||","==a.lastType?d||c:0):"switch"!=g.info||k||0==b.doubleIndentSwitch?g.align?g.column+(k?0:1):g.indented+(k?0:c):g.indented+(/^(?:case|default)\b/.test(e)?c:2*c)},electricChars:":{}",blockCommentStart:e?null:"/*",blockCommentEnd:e?null:"*/",lineComment:e?null:"//",fold:"brace",helperType:e?"json":"javascript",jsonMode:e}}),CodeMirror.defineMIME("text/javascript","javascript"),CodeMirror.defineMIME("text/ecmascript","javascript"),CodeMirror.defineMIME("application/javascript","javascript"),CodeMirror.defineMIME("application/ecmascript","javascript"),CodeMirror.defineMIME("application/json",{name:"javascript",json:!0}),CodeMirror.defineMIME("application/x-json",{name:"javascript",json:!0}),CodeMirror.defineMIME("text/typescript",{name:"javascript",typescript:!0}),CodeMirror.defineMIME("application/typescript",{name:"javascript",typescript:!0}),CodeMirror.defineMode("xml",function(a,b){function j(a,b){function c(c){return b.tokenize=c,c(a,b)}var d=a.next();if("<"==d){if(a.eat("!"))return a.eat("[")?a.match("CDATA[")?c(m("atom","]]>")):null:a.match("--")?c(m("comment","-->")):a.match("DOCTYPE",!0,!0)?(a.eatWhile(/[\w\._\-]/),c(n(1))):null;if(a.eat("?"))return a.eatWhile(/[\w\._\-]/),b.tokenize=m("meta","?>"),"meta";var e=a.eat("/");h="";for(var f;f=a.eat(/[^\s\u00a0=<>\"\'\/?]/);)h+=f;return h?(i=e?"closeTag":"openTag",b.tokenize=k,"tag"):"error"}if("&"==d){var g;return g=a.eat("#")?a.eat("x")?a.eatWhile(/[a-fA-F\d]/)&&a.eat(";"):a.eatWhile(/[\d]/)&&a.eat(";"):a.eatWhile(/[\w\.\-:]/)&&a.eat(";"),g?"atom":"error"}return a.eatWhile(/[^&<]/),null}function k(a,b){var c=a.next();return">"==c||"/"==c&&a.eat(">")?(b.tokenize=j,i=">"==c?"endTag":"selfcloseTag","tag"):"="==c?(i="equals",null):"<"==c?"error":/[\'\"]/.test(c)?(b.tokenize=l(c),b.stringStartCol=a.column(),b.tokenize(a,b)):(a.eatWhile(/[^\s\u00a0=<>\"\']/),"word")}function l(a){var b=function(b,c){for(;!b.eol();)if(b.next()==a){c.tokenize=k;break}return"string"};return b.isInAttribute=!0,b}function m(a,b){return function(c,d){for(;!c.eol();){if(c.match(b)){d.tokenize=j;break}c.next()}return a}}function n(a){return function(b,c){for(var d;null!=(d=b.next());){if("<"==d)return c.tokenize=n(a+1),c.tokenize(b,c);if(">"==d){if(1==a){c.tokenize=j;break}return c.tokenize=n(a-1),c.tokenize(b,c)}}return"meta"}}function r(){for(var a=arguments.length-1;a>=0;a--)o.cc.push(arguments[a])}function s(){return r.apply(null,arguments),!0}function t(a,b){var c=f.doNotIndent.hasOwnProperty(a)||o.context&&o.context.noIndent;o.context={prev:o.context,tagName:a,indent:o.indented,startOfLine:b,noIndent:c}}function u(){o.context&&(o.context=o.context.prev)}function v(a){if("openTag"==a)return o.tagName=h,o.tagStart=p.column(),s(z,w(o.startOfLine));if("closeTag"==a){var b=!1;return o.context?o.context.tagName!=h&&(f.implicitlyClosed.hasOwnProperty(o.context.tagName.toLowerCase())&&u(),b=!o.context||o.context.tagName!=h):b=!0,b&&(q="error"),s(x(b))}return s()}function w(a){return function(b){var c=o.tagName;return o.tagName=o.tagStart=null,"selfcloseTag"==b||"endTag"==b&&f.autoSelfClosers.hasOwnProperty(c.toLowerCase())?(y(c.toLowerCase()),s()):"endTag"==b?(y(c.toLowerCase()),t(c,a),s()):s()}}function x(a){return function(b){return a&&(q="error"),"endTag"==b?(u(),s()):(q="error",s(arguments.callee))}}function y(a){for(var b;;){if(!o.context)return;if(b=o.context.tagName.toLowerCase(),!f.contextGrabbers.hasOwnProperty(b)||!f.contextGrabbers[b].hasOwnProperty(a))return;u()}}function z(a){return"word"==a?(q="attribute",s(A,z)):"endTag"==a||"selfcloseTag"==a?r():(q="error",s(z))}function A(a){if("equals"==a)return s(B,z);if(f.allowMissing){if("word"==a)return q="attribute",s(A,z)}else q="error";return"endTag"==a||"selfcloseTag"==a?r():s()}function B(a){return"string"==a?s(C):"word"==a&&f.allowUnquoted?(q="string",s()):(q="error","endTag"==a||"selfCloseTag"==a?r():s())}function C(a){return"string"==a?s(C):r()}var h,i,o,p,q,c=a.indentUnit,d=b.multilineTagIndentFactor||1,e=b.multilineTagIndentPastTag||!0,f=b.htmlMode?{autoSelfClosers:{area:!0,base:!0,br:!0,col:!0,command:!0,embed:!0,frame:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0},implicitlyClosed:{dd:!0,li:!0,optgroup:!0,option:!0,p:!0,rp:!0,rt:!0,tbody:!0,td:!0,tfoot:!0,th:!0,tr:!0},contextGrabbers:{dd:{dd:!0,dt:!0},dt:{dd:!0,dt:!0},li:{li:!0},option:{option:!0,optgroup:!0},optgroup:{optgroup:!0},p:{address:!0,article:!0,aside:!0,blockquote:!0,dir:!0,div:!0,dl:!0,fieldset:!0,footer:!0,form:!0,h1:!0,h2:!0,h3:!0,h4:!0,h5:!0,h6:!0,header:!0,hgroup:!0,hr:!0,menu:!0,nav:!0,ol:!0,p:!0,pre:!0,section:!0,table:!0,ul:!0},rp:{rp:!0,rt:!0},rt:{rp:!0,rt:!0},tbody:{tbody:!0,tfoot:!0},td:{td:!0,th:!0},tfoot:{tbody:!0},th:{td:!0,th:!0},thead:{tbody:!0,tfoot:!0},tr:{tr:!0}},doNotIndent:{pre:!0},allowUnquoted:!0,allowMissing:!0}:{autoSelfClosers:{},implicitlyClosed:{},contextGrabbers:{},doNotIndent:{},allowUnquoted:!1,allowMissing:!1},g=b.alignCDATA;return{startState:function(){return{tokenize:j,cc:[],indented:0,startOfLine:!0,tagName:null,tagStart:null,context:null}},token:function(a,b){if(!b.tagName&&a.sol()&&(b.startOfLine=!0,b.indented=a.indentation()),a.eatSpace())return null;q=i=h=null;var c=b.tokenize(a,b);if(b.type=i,(c||i)&&"comment"!=c)for(o=b,p=a;;){var d=b.cc.pop()||v;if(d(i||c))break}return b.startOfLine=!1,q||c},indent:function(a,b,f){var h=a.context;if(a.tokenize.isInAttribute)return a.stringStartCol+1;if(a.tokenize!=k&&a.tokenize!=j||h&&h.noIndent)return f?f.match(/^(\s*)/)[0].length:0;if(a.tagName)return e?a.tagStart+a.tagName.length+2:a.tagStart+c*d;if(g&&/<!\[CDATA\[/.test(b))return 0;for(h&&/^<\//.test(b)&&(h=h.prev);h&&!h.startOfLine;)h=h.prev;return h?h.indent+c:0},electricChars:"/",blockCommentStart:"<!--",blockCommentEnd:"-->",configuration:b.htmlMode?"html":"xml",helperType:b.htmlMode?"html":"xml"}}),CodeMirror.defineMIME("text/xml","xml"),CodeMirror.defineMIME("application/xml","xml"),CodeMirror.mimeModes.hasOwnProperty("text/html")||CodeMirror.defineMIME("text/html",{name:"xml",htmlMode:!0}),function(){"use strict";function c(c){"activeLine"in c.state&&(c.removeLineClass(c.state.activeLine,"wrap",a),c.removeLineClass(c.state.activeLine,"background",b))}function d(d){var e=d.getLineHandleVisualStart(d.getCursor().line);d.state.activeLine!=e&&(c(d),d.addLineClass(e,"wrap",a),d.addLineClass(e,"background",b),d.state.activeLine=e)}var a="CodeMirror-activeline",b="CodeMirror-activeline-background";CodeMirror.defineOption("styleActiveLine",!1,function(a,b,e){var f=e&&e!=CodeMirror.Init;b&&!f?(d(a),a.on("cursorActivity",d)):!b&&f&&(a.off("cursorActivity",d),c(a),delete a.state.activeLine)})}(),function(){function d(a,d,e){function q(d,e,f){if(d.text){var h=l?0:d.text.length-1,i=l?d.text.length:-1;if(d.text.length>g)return null;for(null!=f&&(h=f+m);h!=i;h+=m){var j=d.text.charAt(h);if(p.test(j)&&a.getTokenTypeAt(b(e,h+1))==n){var k=c[j];if(">"==k.charAt(1)==l)o.push(j);else{if(o.pop()!=k.charAt(0))return{pos:h,match:!1};if(!o.length)return{pos:h,match:!0}}}}}}var f=a.state.matchBrackets,g=f&&f.maxScanLineLength||1e4,h=d||a.getCursor(),i=a.getLineHandle(h.line),j=h.ch-1,k=j>=0&&c[i.text.charAt(j)]||c[i.text.charAt(++j)];if(!k)return null;var l=">"==k.charAt(1),m=l?1:-1;if(e&&l!=(j==h.ch))return null;for(var s,n=a.getTokenTypeAt(b(h.line,j+1)),o=[i.text.charAt(j)],p=/[(){}[\]]/,r=h.line,t=l?Math.min(r+100,a.lineCount()):Math.max(-1,r-100);r!=t&&!(s=r==h.line?q(i,r,j):q(a.getLineHandle(r),r));r+=m);return{from:b(h.line,j),to:s&&b(r,s.pos),match:s&&s.match,forward:l}}function e(c,e){var f=c.state.matchBrackets.maxHighlightLineLength||1e3,g=d(c);if(!(!g||c.getLine(g.from.line).length>f||g.to&&c.getLine(g.to.line).length>f)){var h=g.match?"CodeMirror-matchingbracket":"CodeMirror-nonmatchingbracket",i=c.markText(g.from,b(g.from.line,g.from.ch+1),{className:h}),j=g.to&&c.markText(g.to,b(g.to.line,g.to.ch+1),{className:h});a&&c.state.focused&&c.display.input.focus();var k=function(){c.operation(function(){i.clear(),j&&j.clear()})};return e?(setTimeout(k,800),void 0):k}}function g(a){a.operation(function(){f&&(f(),f=null),a.somethingSelected()||(f=e(a,!1))})}var a=/MSIE \d/.test(navigator.userAgent)&&(null==document.documentMode||document.documentMode<8),b=CodeMirror.Pos,c={"(":")>",")":"(<","[":"]>","]":"[<","{":"}>","}":"{<"},f=null;CodeMirror.defineOption("matchBrackets",!1,function(a,b,c){c&&c!=CodeMirror.Init&&a.off("cursorActivity",g),b&&(a.state.matchBrackets="object"==typeof b?b:{},a.on("cursorActivity",g))}),CodeMirror.defineExtension("matchBrackets",function(){e(this,!0)}),CodeMirror.defineExtension("findMatchingBracket",function(a,b){return d(this,a,b)})}();
lib/codemirror.css DELETED
@@ -1,245 +0,0 @@
1
- /* BASICS */
2
-
3
- .CodeMirror {
4
- /* Set height, width, borders, and global font properties here */
5
- font-family: Consolas,Monaco,monospace;
6
- height: 400px;
7
- line-height: 150%;
8
- font-size: 12px;
9
- }
10
- .CodeMirror-scroll {
11
- /* Set scrolling behaviour here */
12
- overflow: auto;
13
- }
14
-
15
- /* PADDING */
16
-
17
- .CodeMirror-lines {
18
- padding: 4px 0; /* Vertical padding around content */
19
- }
20
- .CodeMirror pre {
21
- padding: 0 4px; /* Horizontal padding of content */
22
- }
23
-
24
- .CodeMirror-scrollbar-filler {
25
- background-color: white; /* The little square between H and V scrollbars */
26
- }
27
-
28
- /* GUTTER */
29
-
30
- .CodeMirror-gutters {
31
- border-right: 1px solid #ddd;
32
- background-color: #f7f7f7;
33
- }
34
- .CodeMirror-linenumbers {}
35
- .CodeMirror-linenumber {
36
- padding: 0 3px 0 5px;
37
- min-width: 20px;
38
- text-align: right;
39
- color: #999;
40
- }
41
-
42
- /* CURSOR */
43
-
44
- .CodeMirror div.CodeMirror-cursor {
45
- border-left: 1px solid black;
46
- }
47
- /* Shown when moving in bi-directional text */
48
- .CodeMirror div.CodeMirror-secondarycursor {
49
- border-left: 1px solid silver;
50
- }
51
- .CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor {
52
- width: auto;
53
- border: 0;
54
- background: transparent;
55
- background: rgba(0, 200, 0, .4);
56
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#6600c800, endColorstr=#4c00c800);
57
- }
58
- /* Kludge to turn off filter in ie9+, which also accepts rgba */
59
- .CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor:not(#nonsense_id) {
60
- filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
61
- }
62
- /* Can style cursor different in overwrite (non-insert) mode */
63
- .CodeMirror div.CodeMirror-cursor.CodeMirror-overwrite {}
64
-
65
- /* DEFAULT THEME */
66
-
67
- .cm-s-default .cm-keyword {color: #708;}
68
- .cm-s-default .cm-atom {color: #219;}
69
- .cm-s-default .cm-number {color: #164;}
70
- .cm-s-default .cm-def {color: #00f;}
71
- .cm-s-default .cm-variable {color: black;}
72
- .cm-s-default .cm-variable-2 {color: #05a;}
73
- .cm-s-default .cm-variable-3 {color: #085;}
74
- .cm-s-default .cm-property {color: black;}
75
- .cm-s-default .cm-operator {color: black;}
76
- .cm-s-default .cm-comment {color: #a50;}
77
- .cm-s-default .cm-string {color: #a11;}
78
- .cm-s-default .cm-string-2 {color: #f50;}
79
- .cm-s-default .cm-meta {color: #555;}
80
- .cm-s-default .cm-error {color: #f00;}
81
- .cm-s-default .cm-qualifier {color: #555;}
82
- .cm-s-default .cm-builtin {color: #30a;}
83
- .cm-s-default .cm-bracket {color: #997;}
84
- .cm-s-default .cm-tag {color: #170;}
85
- .cm-s-default .cm-attribute {color: #00c;}
86
- .cm-s-default .cm-header {color: blue;}
87
- .cm-s-default .cm-quote {color: #090;}
88
- .cm-s-default .cm-hr {color: #999;}
89
- .cm-s-default .cm-link {color: #00c;}
90
-
91
- .cm-negative {color: #d44;}
92
- .cm-positive {color: #292;}
93
- .cm-header, .cm-strong {font-weight: bold;}
94
- .cm-em {font-style: italic;}
95
- .cm-emstrong {font-style: italic; font-weight: bold;}
96
- .cm-link {text-decoration: underline;}
97
-
98
- .cm-invalidchar {color: #f00;}
99
-
100
- div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
101
- div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
102
-
103
- /* STOP */
104
-
105
- /* The rest of this file contains styles related to the mechanics of
106
- the editor. You probably shouldn't touch them. */
107
-
108
- .CodeMirror {
109
- /*line-height: 1;*/
110
- position: relative;
111
- overflow: hidden;
112
- }
113
-
114
- .CodeMirror-scroll {
115
- /* 30px is the magic margin used to hide the element's real scrollbars */
116
- /* See overflow: hidden in .CodeMirror, and the paddings in .CodeMirror-sizer */
117
- margin-bottom: -30px; margin-right: -30px;
118
- padding-bottom: 30px; padding-right: 30px;
119
- height: 100%;
120
- outline: none; /* Prevent dragging from highlighting the element */
121
- position: relative;
122
- }
123
- .CodeMirror-sizer {
124
- position: relative;
125
- }
126
-
127
- /* The fake, visible scrollbars. Used to force redraw during scrolling
128
- before actuall scrolling happens, thus preventing shaking and
129
- flickering artifacts. */
130
- .CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler {
131
- position: absolute;
132
- z-index: 6;
133
- display: none;
134
- }
135
- .CodeMirror-vscrollbar {
136
- right: 0; top: 0;
137
- overflow-x: hidden;
138
- overflow-y: scroll;
139
- }
140
- .CodeMirror-hscrollbar {
141
- bottom: 0; left: 0;
142
- overflow-y: hidden;
143
- overflow-x: scroll;
144
- }
145
- .CodeMirror-scrollbar-filler {
146
- right: 0; bottom: 0;
147
- z-index: 6;
148
- }
149
-
150
- .CodeMirror-gutters {
151
- position: absolute; left: 0; top: 0;
152
- height: 100%;
153
- z-index: 3;
154
- }
155
- .CodeMirror-gutter {
156
- height: 100%;
157
- display: inline-block;
158
- /* Hack to make IE7 behave */
159
- *zoom:1;
160
- *display:inline;
161
- }
162
- .CodeMirror-gutter-elt {
163
- position: absolute;
164
- cursor: default;
165
- z-index: 4;
166
- }
167
-
168
- .CodeMirror-lines {
169
- cursor: text;
170
- }
171
- .CodeMirror pre {
172
- /* Reset some styles that the rest of the page might have set */
173
- -moz-border-radius: 0; -webkit-border-radius: 0; -o-border-radius: 0; border-radius: 0;
174
- border-width: 0;
175
- background: transparent;
176
- font-family: inherit;
177
- font-size: inherit;
178
- margin: 0;
179
- white-space: pre;
180
- word-wrap: normal;
181
- line-height: inherit;
182
- color: inherit;
183
- z-index: 2;
184
- position: relative;
185
- overflow: visible;
186
- }
187
- .CodeMirror-wrap pre {
188
- word-wrap: break-word;
189
- white-space: pre-wrap;
190
- word-break: normal;
191
- }
192
- .CodeMirror-linebackground {
193
- position: absolute;
194
- left: 0; right: 0; top: 0; bottom: 0;
195
- z-index: 0;
196
- }
197
-
198
- .CodeMirror-linewidget {
199
- position: relative;
200
- z-index: 2;
201
- overflow: auto;
202
- }
203
-
204
- .CodeMirror-wrap .CodeMirror-scroll {
205
- overflow-x: hidden;
206
- }
207
-
208
- .CodeMirror-measure {
209
- position: absolute;
210
- width: 100%; height: 0px;
211
- overflow: hidden;
212
- visibility: hidden;
213
- }
214
- .CodeMirror-measure pre { position: static; }
215
-
216
- .CodeMirror div.CodeMirror-cursor {
217
- position: absolute;
218
- visibility: hidden;
219
- border-right: none;
220
- width: 0;
221
- }
222
- .CodeMirror-focused div.CodeMirror-cursor {
223
- visibility: visible;
224
- }
225
-
226
- .CodeMirror-selected { background: #d9d9d9; }
227
- .CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
228
-
229
- .cm-searching {
230
- background: #ffa;
231
- background: rgba(255, 255, 0, .4);
232
- }
233
-
234
- /* IE7 hack to prevent it from returning funny offsetTops on the spans */
235
- .CodeMirror span { *vertical-align: text-bottom; }
236
-
237
- @media print {
238
- /* Hide the cursor when printing */
239
- .CodeMirror div.CodeMirror-cursor {
240
- visibility: hidden;
241
- }
242
- }
243
-
244
- /* Active Line */
245
- .CodeMirror-activeline-background {background: #e8f2ff !important;}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/codemirror.js DELETED
@@ -1,4786 +0,0 @@
1
- // CodeMirror version 3.02
2
- //
3
- // CodeMirror is the only global var we claim
4
- window.CodeMirror = (function() {
5
- "use strict";
6
-
7
- // BROWSER SNIFFING
8
-
9
- // Crude, but necessary to handle a number of hard-to-feature-detect
10
- // bugs and behavior differences.
11
- var gecko = /gecko\/\d/i.test(navigator.userAgent);
12
- var ie = /MSIE \d/.test(navigator.userAgent);
13
- var ie_lt8 = ie && (document.documentMode == null || document.documentMode < 8);
14
- var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);
15
- var webkit = /WebKit\//.test(navigator.userAgent);
16
- var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(navigator.userAgent);
17
- var chrome = /Chrome\//.test(navigator.userAgent);
18
- var opera = /Opera\//.test(navigator.userAgent);
19
- var safari = /Apple Computer/.test(navigator.vendor);
20
- var khtml = /KHTML\//.test(navigator.userAgent);
21
- var mac_geLion = /Mac OS X 1\d\D([7-9]|\d\d)\D/.test(navigator.userAgent);
22
- var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(navigator.userAgent);
23
- var phantom = /PhantomJS/.test(navigator.userAgent);
24
-
25
- var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent);
26
- // This is woefully incomplete. Suggestions for alternative methods welcome.
27
- var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent);
28
- var mac = ios || /Mac/.test(navigator.platform);
29
- var windows = /windows/i.test(navigator.platform);
30
-
31
- var opera_version = opera && navigator.userAgent.match(/Version\/(\d*\.\d*)/);
32
- if (opera_version) opera_version = Number(opera_version[1]);
33
- // Some browsers use the wrong event properties to signal cmd/ctrl on OS X
34
- var flipCtrlCmd = mac && (qtwebkit || opera && (opera_version == null || opera_version < 12.11));
35
-
36
- // Optimize some code when these features are not used
37
- var sawReadOnlySpans = false, sawCollapsedSpans = false;
38
-
39
- // CONSTRUCTOR
40
-
41
- function CodeMirror(place, options) {
42
- if (!(this instanceof CodeMirror)) return new CodeMirror(place, options);
43
-
44
- this.options = options = options || {};
45
- // Determine effective options based on given values and defaults.
46
- for (var opt in defaults) if (!options.hasOwnProperty(opt) && defaults.hasOwnProperty(opt))
47
- options[opt] = defaults[opt];
48
- setGuttersForLineNumbers(options);
49
-
50
- var display = this.display = makeDisplay(place);
51
- display.wrapper.CodeMirror = this;
52
- updateGutters(this);
53
- if (options.autofocus && !mobile) focusInput(this);
54
-
55
- this.view = makeView(new BranchChunk([new LeafChunk([makeLine("", null, textHeight(display))])]));
56
- this.nextOpId = 0;
57
- loadMode(this);
58
- themeChanged(this);
59
- if (options.lineWrapping)
60
- this.display.wrapper.className += " CodeMirror-wrap";
61
-
62
- // Initialize the content.
63
- this.setValue(options.value || "");
64
- // Override magic textarea content restore that IE sometimes does
65
- // on our hidden textarea on reload
66
- if (ie) setTimeout(bind(resetInput, this, true), 20);
67
- this.view.history = makeHistory();
68
-
69
- registerEventHandlers(this);
70
- // IE throws unspecified error in certain cases, when
71
- // trying to access activeElement before onload
72
- var hasFocus; try { hasFocus = (document.activeElement == display.input); } catch(e) { }
73
- if (hasFocus || (options.autofocus && !mobile)) setTimeout(bind(onFocus, this), 20);
74
- else onBlur(this);
75
-
76
- operation(this, function() {
77
- for (var opt in optionHandlers)
78
- if (optionHandlers.propertyIsEnumerable(opt))
79
- optionHandlers[opt](this, options[opt], Init);
80
- for (var i = 0; i < initHooks.length; ++i) initHooks[i](this);
81
- })();
82
- }
83
-
84
- // DISPLAY CONSTRUCTOR
85
-
86
- function makeDisplay(place) {
87
- var d = {};
88
- var input = d.input = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none;");
89
- if (webkit) input.style.width = "1000px";
90
- else input.setAttribute("wrap", "off");
91
- input.setAttribute("autocorrect", "off"); input.setAttribute("autocapitalize", "off");
92
- // Wraps and hides input textarea
93
- d.inputDiv = elt("div", [input], null, "overflow: hidden; position: relative; width: 3px; height: 0px;");
94
- // The actual fake scrollbars.
95
- d.scrollbarH = elt("div", [elt("div", null, null, "height: 1px")], "CodeMirror-hscrollbar");
96
- d.scrollbarV = elt("div", [elt("div", null, null, "width: 1px")], "CodeMirror-vscrollbar");
97
- d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler");
98
- // DIVs containing the selection and the actual code
99
- d.lineDiv = elt("div");
100
- d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1");
101
- // Blinky cursor, and element used to ensure cursor fits at the end of a line
102
- d.cursor = elt("div", "\u00a0", "CodeMirror-cursor");
103
- // Secondary cursor, shown when on a 'jump' in bi-directional text
104
- d.otherCursor = elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor");
105
- // Used to measure text size
106
- d.measure = elt("div", null, "CodeMirror-measure");
107
- // Wraps everything that needs to exist inside the vertically-padded coordinate system
108
- d.lineSpace = elt("div", [d.measure, d.selectionDiv, d.lineDiv, d.cursor, d.otherCursor],
109
- null, "position: relative; outline: none");
110
- // Moved around its parent to cover visible view
111
- d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative");
112
- // Set to the height of the text, causes scrolling
113
- d.sizer = elt("div", [d.mover], "CodeMirror-sizer");
114
- // D is needed because behavior of elts with overflow: auto and padding is inconsistent across browsers
115
- d.heightForcer = elt("div", "\u00a0", null, "position: absolute; height: " + scrollerCutOff + "px");
116
- // Will contain the gutters, if any
117
- d.gutters = elt("div", null, "CodeMirror-gutters");
118
- d.lineGutter = null;
119
- // Helper element to properly size the gutter backgrounds
120
- var scrollerInner = elt("div", [d.sizer, d.heightForcer, d.gutters], null, "position: relative; min-height: 100%");
121
- // Provides scrolling
122
- d.scroller = elt("div", [scrollerInner], "CodeMirror-scroll");
123
- d.scroller.setAttribute("tabIndex", "-1");
124
- // The element in which the editor lives.
125
- d.wrapper = elt("div", [d.inputDiv, d.scrollbarH, d.scrollbarV,
126
- d.scrollbarFiller, d.scroller], "CodeMirror");
127
- // Work around IE7 z-index bug
128
- if (ie_lt8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; }
129
- if (place.appendChild) place.appendChild(d.wrapper); else place(d.wrapper);
130
-
131
- // Needed to hide big blue blinking cursor on Mobile Safari
132
- if (ios) input.style.width = "0px";
133
- if (!webkit) d.scroller.draggable = true;
134
- // Needed to handle Tab key in KHTML
135
- if (khtml) { d.inputDiv.style.height = "1px"; d.inputDiv.style.position = "absolute"; }
136
- // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
137
- else if (ie_lt8) d.scrollbarH.style.minWidth = d.scrollbarV.style.minWidth = "18px";
138
-
139
- // Current visible range (may be bigger than the view window).
140
- d.viewOffset = d.showingFrom = d.showingTo = d.lastSizeC = 0;
141
-
142
- // Used to only resize the line number gutter when necessary (when
143
- // the amount of lines crosses a boundary that makes its width change)
144
- d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null;
145
- // See readInput and resetInput
146
- d.prevInput = "";
147
- // Set to true when a non-horizontal-scrolling widget is added. As
148
- // an optimization, widget aligning is skipped when d is false.
149
- d.alignWidgets = false;
150
- // Flag that indicates whether we currently expect input to appear
151
- // (after some event like 'keypress' or 'input') and are polling
152
- // intensively.
153
- d.pollingFast = false;
154
- // Self-resetting timeout for the poller
155
- d.poll = new Delayed();
156
- // True when a drag from the editor is active
157
- d.draggingText = false;
158
-
159
- d.cachedCharWidth = d.cachedTextHeight = null;
160
- d.measureLineCache = [];
161
- d.measureLineCachePos = 0;
162
-
163
- // Tracks when resetInput has punted to just putting a short
164
- // string instead of the (large) selection.
165
- d.inaccurateSelection = false;
166
-
167
- // Used to adjust overwrite behaviour when a paste has been
168
- // detected
169
- d.pasteIncoming = false;
170
-
171
- // Used for measuring wheel scrolling granularity
172
- d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null;
173
-
174
- return d;
175
- }
176
-
177
- // VIEW CONSTRUCTOR
178
-
179
- function makeView(doc) {
180
- var selPos = {line: 0, ch: 0};
181
- return {
182
- doc: doc,
183
- // frontier is the point up to which the content has been parsed,
184
- frontier: 0, highlight: new Delayed(),
185
- sel: {from: selPos, to: selPos, head: selPos, anchor: selPos, shift: false, extend: false},
186
- scrollTop: 0, scrollLeft: 0,
187
- overwrite: false, focused: false,
188
- // Tracks the maximum line length so that
189
- // the horizontal scrollbar can be kept
190
- // static when scrolling.
191
- maxLine: getLine(doc, 0),
192
- maxLineLength: 0,
193
- maxLineChanged: false,
194
- suppressEdits: false,
195
- goalColumn: null,
196
- cantEdit: false,
197
- keyMaps: [],
198
- overlays: [],
199
- modeGen: 0
200
- };
201
- }
202
-
203
- // STATE UPDATES
204
-
205
- // Used to get the editor into a consistent state again when options change.
206
-
207
- function loadMode(cm) {
208
- var doc = cm.view.doc;
209
- cm.view.mode = CodeMirror.getMode(cm.options, cm.options.mode);
210
- doc.iter(0, doc.size, function(line) {
211
- if (line.stateAfter) line.stateAfter = null;
212
- if (line.styles) line.styles = null;
213
- });
214
- cm.view.frontier = 0;
215
- startWorker(cm, 100);
216
- cm.view.modeGen++;
217
- if (cm.curOp) regChange(cm, 0, doc.size);
218
- }
219
-
220
- function wrappingChanged(cm) {
221
- var doc = cm.view.doc, th = textHeight(cm.display);
222
- if (cm.options.lineWrapping) {
223
- cm.display.wrapper.className += " CodeMirror-wrap";
224
- var perLine = cm.display.scroller.clientWidth / charWidth(cm.display) - 3;
225
- doc.iter(0, doc.size, function(line) {
226
- if (line.height == 0) return;
227
- var guess = Math.ceil(line.text.length / perLine) || 1;
228
- if (guess != 1) updateLineHeight(line, guess * th);
229
- });
230
- cm.display.sizer.style.minWidth = "";
231
- } else {
232
- cm.display.wrapper.className = cm.display.wrapper.className.replace(" CodeMirror-wrap", "");
233
- computeMaxLength(cm.view);
234
- doc.iter(0, doc.size, function(line) {
235
- if (line.height != 0) updateLineHeight(line, th);
236
- });
237
- }
238
- regChange(cm, 0, doc.size);
239
- clearCaches(cm);
240
- setTimeout(function(){updateScrollbars(cm.display, cm.view.doc.height);}, 100);
241
- }
242
-
243
- function keyMapChanged(cm) {
244
- var style = keyMap[cm.options.keyMap].style;
245
- cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-keymap-\S+/g, "") +
246
- (style ? " cm-keymap-" + style : "");
247
- }
248
-
249
- function themeChanged(cm) {
250
- cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") +
251
- cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-");
252
- clearCaches(cm);
253
- }
254
-
255
- function guttersChanged(cm) {
256
- updateGutters(cm);
257
- updateDisplay(cm, true);
258
- }
259
-
260
- function updateGutters(cm) {
261
- var gutters = cm.display.gutters, specs = cm.options.gutters;
262
- removeChildren(gutters);
263
- for (var i = 0; i < specs.length; ++i) {
264
- var gutterClass = specs[i];
265
- var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass));
266
- if (gutterClass == "CodeMirror-linenumbers") {
267
- cm.display.lineGutter = gElt;
268
- gElt.style.width = (cm.display.lineNumWidth || 1) + "px";
269
- }
270
- }
271
- gutters.style.display = i ? "" : "none";
272
- }
273
-
274
- function lineLength(doc, line) {
275
- if (line.height == 0) return 0;
276
- var len = line.text.length, merged, cur = line;
277
- while (merged = collapsedSpanAtStart(cur)) {
278
- var found = merged.find();
279
- cur = getLine(doc, found.from.line);
280
- len += found.from.ch - found.to.ch;
281
- }
282
- cur = line;
283
- while (merged = collapsedSpanAtEnd(cur)) {
284
- var found = merged.find();
285
- len -= cur.text.length - found.from.ch;
286
- cur = getLine(doc, found.to.line);
287
- len += cur.text.length - found.to.ch;
288
- }
289
- return len;
290
- }
291
-
292
- function computeMaxLength(view) {
293
- view.maxLine = getLine(view.doc, 0);
294
- view.maxLineLength = lineLength(view.doc, view.maxLine);
295
- view.maxLineChanged = true;
296
- view.doc.iter(1, view.doc.size, function(line) {
297
- var len = lineLength(view.doc, line);
298
- if (len > view.maxLineLength) {
299
- view.maxLineLength = len;
300
- view.maxLine = line;
301
- }
302
- });
303
- }
304
-
305
- // Make sure the gutters options contains the element
306
- // "CodeMirror-linenumbers" when the lineNumbers option is true.
307
- function setGuttersForLineNumbers(options) {
308
- var found = false;
309
- for (var i = 0; i < options.gutters.length; ++i) {
310
- if (options.gutters[i] == "CodeMirror-linenumbers") {
311
- if (options.lineNumbers) found = true;
312
- else options.gutters.splice(i--, 1);
313
- }
314
- }
315
- if (!found && options.lineNumbers)
316
- options.gutters.push("CodeMirror-linenumbers");
317
- }
318
-
319
- // SCROLLBARS
320
-
321
- // Re-synchronize the fake scrollbars with the actual size of the
322
- // content. Optionally force a scrollTop.
323
- function updateScrollbars(d /* display */, docHeight) {
324
- var totalHeight = docHeight + 2 * paddingTop(d);
325
- d.sizer.style.minHeight = d.heightForcer.style.top = totalHeight + "px";
326
- var scrollHeight = Math.max(totalHeight, d.scroller.scrollHeight);
327
- var needsH = d.scroller.scrollWidth > d.scroller.clientWidth;
328
- var needsV = scrollHeight > d.scroller.clientHeight;
329
- if (needsV) {
330
- d.scrollbarV.style.display = "block";
331
- d.scrollbarV.style.bottom = needsH ? scrollbarWidth(d.measure) + "px" : "0";
332
- d.scrollbarV.firstChild.style.height =
333
- (scrollHeight - d.scroller.clientHeight + d.scrollbarV.clientHeight) + "px";
334
- } else d.scrollbarV.style.display = "";
335
- if (needsH) {
336
- d.scrollbarH.style.display = "block";
337
- d.scrollbarH.style.right = needsV ? scrollbarWidth(d.measure) + "px" : "0";
338
- d.scrollbarH.firstChild.style.width =
339
- (d.scroller.scrollWidth - d.scroller.clientWidth + d.scrollbarH.clientWidth) + "px";
340
- } else d.scrollbarH.style.display = "";
341
- if (needsH && needsV) {
342
- d.scrollbarFiller.style.display = "block";
343
- d.scrollbarFiller.style.height = d.scrollbarFiller.style.width = scrollbarWidth(d.measure) + "px";
344
- } else d.scrollbarFiller.style.display = "";
345
-
346
- if (mac_geLion && scrollbarWidth(d.measure) === 0)
347
- d.scrollbarV.style.minWidth = d.scrollbarH.style.minHeight = mac_geMountainLion ? "18px" : "12px";
348
- }
349
-
350
- function visibleLines(display, doc, viewPort) {
351
- var top = display.scroller.scrollTop, height = display.wrapper.clientHeight;
352
- if (typeof viewPort == "number") top = viewPort;
353
- else if (viewPort) {top = viewPort.top; height = viewPort.bottom - viewPort.top;}
354
- top = Math.floor(top - paddingTop(display));
355
- var bottom = Math.ceil(top + height);
356
- return {from: lineAtHeight(doc, top), to: lineAtHeight(doc, bottom)};
357
- }
358
-
359
- // LINE NUMBERS
360
-
361
- function alignHorizontally(cm) {
362
- var display = cm.display;
363
- if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return;
364
- var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.view.scrollLeft;
365
- var gutterW = display.gutters.offsetWidth, l = comp + "px";
366
- for (var n = display.lineDiv.firstChild; n; n = n.nextSibling) if (n.alignable) {
367
- for (var i = 0, a = n.alignable; i < a.length; ++i) a[i].style.left = l;
368
- }
369
- if (cm.options.fixedGutter)
370
- display.gutters.style.left = (comp + gutterW) + "px";
371
- }
372
-
373
- function maybeUpdateLineNumberWidth(cm) {
374
- if (!cm.options.lineNumbers) return false;
375
- var doc = cm.view.doc, last = lineNumberFor(cm.options, doc.size - 1), display = cm.display;
376
- if (last.length != display.lineNumChars) {
377
- var test = display.measure.appendChild(elt("div", [elt("div", last)],
378
- "CodeMirror-linenumber CodeMirror-gutter-elt"));
379
- var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW;
380
- display.lineGutter.style.width = "";
381
- display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding);
382
- display.lineNumWidth = display.lineNumInnerWidth + padding;
383
- display.lineNumChars = display.lineNumInnerWidth ? last.length : -1;
384
- display.lineGutter.style.width = display.lineNumWidth + "px";
385
- return true;
386
- }
387
- return false;
388
- }
389
-
390
- function lineNumberFor(options, i) {
391
- return String(options.lineNumberFormatter(i + options.firstLineNumber));
392
- }
393
- function compensateForHScroll(display) {
394
- return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left;
395
- }
396
-
397
- // DISPLAY DRAWING
398
-
399
- function updateDisplay(cm, changes, viewPort) {
400
- var oldFrom = cm.display.showingFrom, oldTo = cm.display.showingTo;
401
- var updated = updateDisplayInner(cm, changes, viewPort);
402
- if (updated) {
403
- signalLater(cm, cm, "update", cm);
404
- if (cm.display.showingFrom != oldFrom || cm.display.showingTo != oldTo)
405
- signalLater(cm, cm, "viewportChange", cm, cm.display.showingFrom, cm.display.showingTo);
406
- }
407
- updateSelection(cm);
408
- updateScrollbars(cm.display, cm.view.doc.height);
409
-
410
- return updated;
411
- }
412
-
413
- // Uses a set of changes plus the current scroll position to
414
- // determine which DOM updates have to be made, and makes the
415
- // updates.
416
- function updateDisplayInner(cm, changes, viewPort) {
417
- var display = cm.display, doc = cm.view.doc;
418
- if (!display.wrapper.clientWidth) {
419
- display.showingFrom = display.showingTo = display.viewOffset = 0;
420
- return;
421
- }
422
-
423
- // Compute the new visible window
424
- // If scrollTop is specified, use that to determine which lines
425
- // to render instead of the current scrollbar position.
426
- var visible = visibleLines(display, doc, viewPort);
427
- // Bail out if the visible area is already rendered and nothing changed.
428
- if (changes !== true && changes.length == 0 &&
429
- visible.from > display.showingFrom && visible.to < display.showingTo)
430
- return;
431
-
432
- if (changes && maybeUpdateLineNumberWidth(cm))
433
- changes = true;
434
- var gutterW = display.sizer.style.marginLeft = display.gutters.offsetWidth + "px";
435
- display.scrollbarH.style.left = cm.options.fixedGutter ? gutterW : "0";
436
-
437
- // When merged lines are present, the line that needs to be
438
- // redrawn might not be the one that was changed.
439
- if (changes !== true && sawCollapsedSpans)
440
- for (var i = 0; i < changes.length; ++i) {
441
- var ch = changes[i], merged;
442
- while (merged = collapsedSpanAtStart(getLine(doc, ch.from))) {
443
- var from = merged.find().from.line;
444
- if (ch.diff) ch.diff -= ch.from - from;
445
- ch.from = from;
446
- }
447
- }
448
-
449
- // Used to determine which lines need their line numbers updated
450
- var positionsChangedFrom = changes === true ? 0 : Infinity;
451
- if (cm.options.lineNumbers && changes && changes !== true)
452
- for (var i = 0; i < changes.length; ++i)
453
- if (changes[i].diff) { positionsChangedFrom = changes[i].from; break; }
454
-
455
- var from = Math.max(visible.from - cm.options.viewportMargin, 0);
456
- var to = Math.min(doc.size, visible.to + cm.options.viewportMargin);
457
- if (display.showingFrom < from && from - display.showingFrom < 20) from = display.showingFrom;
458
- if (display.showingTo > to && display.showingTo - to < 20) to = Math.min(doc.size, display.showingTo);
459
- if (sawCollapsedSpans) {
460
- from = lineNo(visualLine(doc, getLine(doc, from)));
461
- while (to < doc.size && lineIsHidden(getLine(doc, to))) ++to;
462
- }
463
-
464
- // Create a range of theoretically intact lines, and punch holes
465
- // in that using the change info.
466
- var intact = changes === true ? [] :
467
- computeIntact([{from: display.showingFrom, to: display.showingTo}], changes);
468
- // Clip off the parts that won't be visible
469
- var intactLines = 0;
470
- for (var i = 0; i < intact.length; ++i) {
471
- var range = intact[i];
472
- if (range.from < from) range.from = from;
473
- if (range.to > to) range.to = to;
474
- if (range.from >= range.to) intact.splice(i--, 1);
475
- else intactLines += range.to - range.from;
476
- }
477
- if (intactLines == to - from && from == display.showingFrom && to == display.showingTo)
478
- return;
479
- intact.sort(function(a, b) {return a.from - b.from;});
480
-
481
- var focused = document.activeElement;
482
- if (intactLines < (to - from) * .7) display.lineDiv.style.display = "none";
483
- patchDisplay(cm, from, to, intact, positionsChangedFrom);
484
- display.lineDiv.style.display = "";
485
- if (document.activeElement != focused && focused.offsetHeight) focused.focus();
486
-
487
- var different = from != display.showingFrom || to != display.showingTo ||
488
- display.lastSizeC != display.wrapper.clientHeight;
489
- // This is just a bogus formula that detects when the editor is
490
- // resized or the font size changes.
491
- if (different) display.lastSizeC = display.wrapper.clientHeight;
492
- display.showingFrom = from; display.showingTo = to;
493
- startWorker(cm, 100);
494
-
495
- var prevBottom = display.lineDiv.offsetTop;
496
- for (var node = display.lineDiv.firstChild, height; node; node = node.nextSibling) if (node.lineObj) {
497
- if (ie_lt8) {
498
- var bot = node.offsetTop + node.offsetHeight;
499
- height = bot - prevBottom;
500
- prevBottom = bot;
501
- } else {
502
- var box = node.getBoundingClientRect();
503
- height = box.bottom - box.top;
504
- }
505
- var diff = node.lineObj.height - height;
506
- if (height < 2) height = textHeight(display);
507
- if (diff > .001 || diff < -.001) {
508
- updateLineHeight(node.lineObj, height);
509
- var widgets = node.lineObj.widgets;
510
- if (widgets) for (var i = 0; i < widgets.length; ++i)
511
- widgets[i].height = widgets[i].node.offsetHeight;
512
- }
513
- }
514
- display.viewOffset = heightAtLine(cm, getLine(doc, from));
515
- // Position the mover div to align with the current virtual scroll position
516
- display.mover.style.top = display.viewOffset + "px";
517
-
518
- if (visibleLines(display, doc, viewPort).to >= to)
519
- updateDisplayInner(cm, [], viewPort);
520
- return true;
521
- }
522
-
523
- function computeIntact(intact, changes) {
524
- for (var i = 0, l = changes.length || 0; i < l; ++i) {
525
- var change = changes[i], intact2 = [], diff = change.diff || 0;
526
- for (var j = 0, l2 = intact.length; j < l2; ++j) {
527
- var range = intact[j];
528
- if (change.to <= range.from && change.diff) {
529
- intact2.push({from: range.from + diff, to: range.to + diff});
530
- } else if (change.to <= range.from || change.from >= range.to) {
531
- intact2.push(range);
532
- } else {
533
- if (change.from > range.from)
534
- intact2.push({from: range.from, to: change.from});
535
- if (change.to < range.to)
536
- intact2.push({from: change.to + diff, to: range.to + diff});
537
- }
538
- }
539
- intact = intact2;
540
- }
541
- return intact;
542
- }
543
-
544
- function getDimensions(cm) {
545
- var d = cm.display, left = {}, width = {};
546
- for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) {
547
- left[cm.options.gutters[i]] = n.offsetLeft;
548
- width[cm.options.gutters[i]] = n.offsetWidth;
549
- }
550
- return {fixedPos: compensateForHScroll(d),
551
- gutterTotalWidth: d.gutters.offsetWidth,
552
- gutterLeft: left,
553
- gutterWidth: width,
554
- wrapperWidth: d.wrapper.clientWidth};
555
- }
556
-
557
- function patchDisplay(cm, from, to, intact, updateNumbersFrom) {
558
- var dims = getDimensions(cm);
559
- var display = cm.display, lineNumbers = cm.options.lineNumbers;
560
- if (!intact.length && (!webkit || !cm.display.currentWheelTarget))
561
- removeChildren(display.lineDiv);
562
- var container = display.lineDiv, cur = container.firstChild;
563
-
564
- function rm(node) {
565
- var next = node.nextSibling;
566
- if (webkit && mac && cm.display.currentWheelTarget == node) {
567
- node.style.display = "none";
568
- node.lineObj = null;
569
- } else {
570
- node.parentNode.removeChild(node);
571
- }
572
- return next;
573
- }
574
-
575
- var nextIntact = intact.shift(), lineNo = from;
576
- cm.view.doc.iter(from, to, function(line) {
577
- if (nextIntact && nextIntact.to == lineNo) nextIntact = intact.shift();
578
- if (lineIsHidden(line)) {
579
- if (line.height != 0) updateLineHeight(line, 0);
580
- if (line.widgets && cur.previousSibling) for (var i = 0; i < line.widgets.length; ++i)
581
- if (line.widgets[i].showIfHidden) {
582
- var prev = cur.previousSibling;
583
- if (prev.nodeType == "pre") {
584
- var wrap = elt("div", null, null, "position: relative");
585
- prev.parentNode.replaceChild(wrap, prev);
586
- wrap.appendChild(prev);
587
- prev = wrap;
588
- }
589
- prev.appendChild(buildLineWidget(line.widgets[i], prev, dims));
590
- }
591
- } else if (nextIntact && nextIntact.from <= lineNo && nextIntact.to > lineNo) {
592
- // This line is intact. Skip to the actual node. Update its
593
- // line number if needed.
594
- while (cur.lineObj != line) cur = rm(cur);
595
- if (lineNumbers && updateNumbersFrom <= lineNo && cur.lineNumber)
596
- setTextContent(cur.lineNumber, lineNumberFor(cm.options, lineNo));
597
- cur = cur.nextSibling;
598
- } else {
599
- // This line needs to be generated.
600
- var lineNode = buildLineElement(cm, line, lineNo, dims);
601
- container.insertBefore(lineNode, cur);
602
- lineNode.lineObj = line;
603
- }
604
- ++lineNo;
605
- });
606
- while (cur) cur = rm(cur);
607
- }
608
-
609
- function buildLineElement(cm, line, lineNo, dims) {
610
- var lineElement = lineContent(cm, line);
611
- var markers = line.gutterMarkers, display = cm.display;
612
-
613
- if (!cm.options.lineNumbers && !markers && !line.bgClass && !line.wrapClass &&
614
- (!line.widgets || !line.widgets.length)) return lineElement;
615
-
616
- // Lines with gutter elements or a background class need
617
- // to be wrapped again, and have the extra elements added
618
- // to the wrapper div
619
-
620
- var wrap = elt("div", null, line.wrapClass, "position: relative");
621
- if (cm.options.lineNumbers || markers) {
622
- var gutterWrap = wrap.appendChild(elt("div", null, null, "position: absolute; left: " +
623
- (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"));
624
- if (cm.options.fixedGutter) wrap.alignable = [gutterWrap];
625
- if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"]))
626
- wrap.lineNumber = gutterWrap.appendChild(
627
- elt("div", lineNumberFor(cm.options, lineNo),
628
- "CodeMirror-linenumber CodeMirror-gutter-elt",
629
- "left: " + dims.gutterLeft["CodeMirror-linenumbers"] + "px; width: "
630
- + display.lineNumInnerWidth + "px"));
631
- if (markers)
632
- for (var k = 0; k < cm.options.gutters.length; ++k) {
633
- var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id];
634
- if (found)
635
- gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", "left: " +
636
- dims.gutterLeft[id] + "px; width: " + dims.gutterWidth[id] + "px"));
637
- }
638
- }
639
- // Kludge to make sure the styled element lies behind the selection (by z-index)
640
- if (line.bgClass)
641
- wrap.appendChild(elt("div", "\u00a0", line.bgClass + " CodeMirror-linebackground"));
642
- wrap.appendChild(lineElement);
643
- if (line.widgets) for (var i = 0, ws = line.widgets; i < ws.length; ++i) {
644
- var widget = ws[i], node = buildLineWidget(widget, wrap, dims);
645
- if (widget.above)
646
- wrap.insertBefore(node, cm.options.lineNumbers && line.height != 0 ? gutterWrap : lineElement);
647
- else
648
- wrap.appendChild(node);
649
- }
650
- if (ie_lt8) wrap.style.zIndex = 2;
651
- return wrap;
652
- }
653
-
654
- function buildLineWidget(widget, wrap, dims) {
655
- var node = elt("div", [widget.node], "CodeMirror-linewidget");
656
- node.widget = widget;
657
- if (widget.noHScroll) {
658
- (wrap.alignable || (wrap.alignable = [])).push(node);
659
- var width = dims.wrapperWidth;
660
- node.style.left = dims.fixedPos + "px";
661
- if (!widget.coverGutter) {
662
- width -= dims.gutterTotalWidth;
663
- node.style.paddingLeft = dims.gutterTotalWidth + "px";
664
- }
665
- node.style.width = width + "px";
666
- }
667
- if (widget.coverGutter) {
668
- node.style.zIndex = 5;
669
- node.style.position = "relative";
670
- if (!widget.noHScroll) node.style.marginLeft = -dims.gutterTotalWidth + "px";
671
- }
672
- return node;
673
- }
674
-
675
- // SELECTION / CURSOR
676
-
677
- function updateSelection(cm) {
678
- var display = cm.display;
679
- var collapsed = posEq(cm.view.sel.from, cm.view.sel.to);
680
- if (collapsed || cm.options.showCursorWhenSelecting)
681
- updateSelectionCursor(cm);
682
- else
683
- display.cursor.style.display = display.otherCursor.style.display = "none";
684
- if (!collapsed)
685
- updateSelectionRange(cm);
686
- else
687
- display.selectionDiv.style.display = "none";
688
-
689
- // Move the hidden textarea near the cursor to prevent scrolling artifacts
690
- var headPos = cursorCoords(cm, cm.view.sel.head, "div");
691
- var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect();
692
- display.inputDiv.style.top = Math.max(0, Math.min(display.wrapper.clientHeight - 10,
693
- headPos.top + lineOff.top - wrapOff.top)) + "px";
694
- display.inputDiv.style.left = Math.max(0, Math.min(display.wrapper.clientWidth - 10,
695
- headPos.left + lineOff.left - wrapOff.left)) + "px";
696
- }
697
-
698
- // No selection, plain cursor
699
- function updateSelectionCursor(cm) {
700
- var display = cm.display, pos = cursorCoords(cm, cm.view.sel.head, "div");
701
- display.cursor.style.left = pos.left + "px";
702
- display.cursor.style.top = pos.top + "px";
703
- display.cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px";
704
- display.cursor.style.display = "";
705
-
706
- if (pos.other) {
707
- display.otherCursor.style.display = "";
708
- display.otherCursor.style.left = pos.other.left + "px";
709
- display.otherCursor.style.top = pos.other.top + "px";
710
- display.otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px";
711
- } else { display.otherCursor.style.display = "none"; }
712
- }
713
-
714
- // Highlight selection
715
- function updateSelectionRange(cm) {
716
- var display = cm.display, doc = cm.view.doc, sel = cm.view.sel;
717
- var fragment = document.createDocumentFragment();
718
- var clientWidth = display.lineSpace.offsetWidth, pl = paddingLeft(cm.display);
719
-
720
- function add(left, top, width, bottom) {
721
- if (top < 0) top = 0;
722
- fragment.appendChild(elt("div", null, "CodeMirror-selected", "position: absolute; left: " + left +
723
- "px; top: " + top + "px; width: " + (width == null ? clientWidth - left : width) +
724
- "px; height: " + (bottom - top) + "px"));
725
- }
726
-
727
- function drawForLine(line, fromArg, toArg, retTop) {
728
- var lineObj = getLine(doc, line);
729
- var lineLen = lineObj.text.length, rVal = retTop ? Infinity : -Infinity;
730
- function coords(ch) {
731
- return charCoords(cm, {line: line, ch: ch}, "div", lineObj);
732
- }
733
-
734
- iterateBidiSections(getOrder(lineObj), fromArg || 0, toArg == null ? lineLen : toArg, function(from, to, dir) {
735
- var leftPos = coords(dir == "rtl" ? to - 1 : from);
736
- var rightPos = coords(dir == "rtl" ? from : to - 1);
737
- var left = leftPos.left, right = rightPos.right;
738
- if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part
739
- add(left, leftPos.top, null, leftPos.bottom);
740
- left = pl;
741
- if (leftPos.bottom < rightPos.top) add(left, leftPos.bottom, null, rightPos.top);
742
- }
743
- if (toArg == null && to == lineLen) right = clientWidth;
744
- if (fromArg == null && from == 0) left = pl;
745
- rVal = retTop ? Math.min(rightPos.top, rVal) : Math.max(rightPos.bottom, rVal);
746
- if (left < pl + 1) left = pl;
747
- add(left, rightPos.top, right - left, rightPos.bottom);
748
- });
749
- return rVal;
750
- }
751
-
752
- if (sel.from.line == sel.to.line) {
753
- drawForLine(sel.from.line, sel.from.ch, sel.to.ch);
754
- } else {
755
- var fromObj = getLine(doc, sel.from.line);
756
- var cur = fromObj, merged, path = [sel.from.line, sel.from.ch], singleLine;
757
- while (merged = collapsedSpanAtEnd(cur)) {
758
- var found = merged.find();
759
- path.push(found.from.ch, found.to.line, found.to.ch);
760
- if (found.to.line == sel.to.line) {
761
- path.push(sel.to.ch);
762
- singleLine = true;
763
- break;
764
- }
765
- cur = getLine(doc, found.to.line);
766
- }
767
-
768
- // This is a single, merged line
769
- if (singleLine) {
770
- for (var i = 0; i < path.length; i += 3)
771
- drawForLine(path[i], path[i+1], path[i+2]);
772
- } else {
773
- var middleTop, middleBot, toObj = getLine(doc, sel.to.line);
774
- if (sel.from.ch)
775
- // Draw the first line of selection.
776
- middleTop = drawForLine(sel.from.line, sel.from.ch, null, false);
777
- else
778
- // Simply include it in the middle block.
779
- middleTop = heightAtLine(cm, fromObj) - display.viewOffset;
780
-
781
- if (!sel.to.ch)
782
- middleBot = heightAtLine(cm, toObj) - display.viewOffset;
783
- else
784
- middleBot = drawForLine(sel.to.line, collapsedSpanAtStart(toObj) ? null : 0, sel.to.ch, true);
785
-
786
- if (middleTop < middleBot) add(pl, middleTop, null, middleBot);
787
- }
788
- }
789
-
790
- removeChildrenAndAdd(display.selectionDiv, fragment);
791
- display.selectionDiv.style.display = "";
792
- }
793
-
794
- // Cursor-blinking
795
- function restartBlink(cm) {
796
- var display = cm.display;
797
- clearInterval(display.blinker);
798
- var on = true;
799
- display.cursor.style.visibility = display.otherCursor.style.visibility = "";
800
- display.blinker = setInterval(function() {
801
- if (!display.cursor.offsetHeight) return;
802
- display.cursor.style.visibility = display.otherCursor.style.visibility = (on = !on) ? "" : "hidden";
803
- }, cm.options.cursorBlinkRate);
804
- }
805
-
806
- // HIGHLIGHT WORKER
807
-
808
- function startWorker(cm, time) {
809
- if (cm.view.mode.startState && cm.view.frontier < cm.display.showingTo)
810
- cm.view.highlight.set(time, bind(highlightWorker, cm));
811
- }
812
-
813
- function highlightWorker(cm) {
814
- var view = cm.view, doc = view.doc;
815
- if (view.frontier >= cm.display.showingTo) return;
816
- var end = +new Date + cm.options.workTime;
817
- var state = copyState(view.mode, getStateBefore(cm, view.frontier));
818
- var changed = [], prevChange;
819
- doc.iter(view.frontier, Math.min(doc.size, cm.display.showingTo + 500), function(line) {
820
- if (view.frontier >= cm.display.showingFrom) { // Visible
821
- var oldStyles = line.styles;
822
- line.styles = highlightLine(cm, line, state);
823
- var ischange = !oldStyles || oldStyles.length != line.styles.length;
824
- for (var i = 0; !ischange && i < oldStyles.length; ++i)
825
- ischange = oldStyles[i] != line.styles[i];
826
- if (ischange) {
827
- if (prevChange && prevChange.end == view.frontier) prevChange.end++;
828
- else changed.push(prevChange = {start: view.frontier, end: view.frontier + 1});
829
- }
830
- line.stateAfter = copyState(view.mode, state);
831
- } else {
832
- processLine(cm, line, state);
833
- line.stateAfter = view.frontier % 5 == 0 ? copyState(view.mode, state) : null;
834
- }
835
- ++view.frontier;
836
- if (+new Date > end) {
837
- startWorker(cm, cm.options.workDelay);
838
- return true;
839
- }
840
- });
841
- if (changed.length)
842
- operation(cm, function() {
843
- for (var i = 0; i < changed.length; ++i)
844
- regChange(this, changed[i].start, changed[i].end);
845
- })();
846
- }
847
-
848
- // Finds the line to start with when starting a parse. Tries to
849
- // find a line with a stateAfter, so that it can start with a
850
- // valid state. If that fails, it returns the line with the
851
- // smallest indentation, which tends to need the least context to
852
- // parse correctly.
853
- function findStartLine(cm, n) {
854
- var minindent, minline, doc = cm.view.doc;
855
- for (var search = n, lim = n - 100; search > lim; --search) {
856
- if (search == 0) return 0;
857
- var line = getLine(doc, search-1);
858
- if (line.stateAfter) return search;
859
- var indented = countColumn(line.text, null, cm.options.tabSize);
860
- if (minline == null || minindent > indented) {
861
- minline = search - 1;
862
- minindent = indented;
863
- }
864
- }
865
- return minline;
866
- }
867
-
868
- function getStateBefore(cm, n) {
869
- var view = cm.view;
870
- if (!view.mode.startState) return true;
871
- var pos = findStartLine(cm, n), state = pos && getLine(view.doc, pos-1).stateAfter;
872
- if (!state) state = startState(view.mode);
873
- else state = copyState(view.mode, state);
874
- view.doc.iter(pos, n, function(line) {
875
- processLine(cm, line, state);
876
- var save = pos == n - 1 || pos % 5 == 0 || pos >= view.showingFrom && pos < view.showingTo;
877
- line.stateAfter = save ? copyState(view.mode, state) : null;
878
- ++pos;
879
- });
880
- return state;
881
- }
882
-
883
- // POSITION MEASUREMENT
884
-
885
- function paddingTop(display) {return display.lineSpace.offsetTop;}
886
- function paddingLeft(display) {
887
- var e = removeChildrenAndAdd(display.measure, elt("pre")).appendChild(elt("span", "x"));
888
- return e.offsetLeft;
889
- }
890
-
891
- function measureChar(cm, line, ch, data) {
892
- var dir = -1;
893
- data = data || measureLine(cm, line);
894
-
895
- for (var pos = ch;; pos += dir) {
896
- var r = data[pos];
897
- if (r) break;
898
- if (dir < 0 && pos == 0) dir = 1;
899
- }
900
- return {left: pos < ch ? r.right : r.left,
901
- right: pos > ch ? r.left : r.right,
902
- top: r.top, bottom: r.bottom};
903
- }
904
-
905
- function measureLine(cm, line) {
906
- // First look in the cache
907
- var display = cm.display, cache = cm.display.measureLineCache;
908
- for (var i = 0; i < cache.length; ++i) {
909
- var memo = cache[i];
910
- if (memo.text == line.text && memo.markedSpans == line.markedSpans &&
911
- display.scroller.clientWidth == memo.width)
912
- return memo.measure;
913
- }
914
-
915
- var measure = measureLineInner(cm, line);
916
- // Store result in the cache
917
- var memo = {text: line.text, width: display.scroller.clientWidth,
918
- markedSpans: line.markedSpans, measure: measure};
919
- if (cache.length == 16) cache[++display.measureLineCachePos % 16] = memo;
920
- else cache.push(memo);
921
- return measure;
922
- }
923
-
924
- function measureLineInner(cm, line) {
925
- var display = cm.display, measure = emptyArray(line.text.length);
926
- var pre = lineContent(cm, line, measure);
927
-
928
- // IE does not cache element positions of inline elements between
929
- // calls to getBoundingClientRect. This makes the loop below,
930
- // which gathers the positions of all the characters on the line,
931
- // do an amount of layout work quadratic to the number of
932
- // characters. When line wrapping is off, we try to improve things
933
- // by first subdividing the line into a bunch of inline blocks, so
934
- // that IE can reuse most of the layout information from caches
935
- // for those blocks. This does interfere with line wrapping, so it
936
- // doesn't work when wrapping is on, but in that case the
937
- // situation is slightly better, since IE does cache line-wrapping
938
- // information and only recomputes per-line.
939
- if (ie && !ie_lt8 && !cm.options.lineWrapping && pre.childNodes.length > 100) {
940
- var fragment = document.createDocumentFragment();
941
- var chunk = 10, n = pre.childNodes.length;
942
- for (var i = 0, chunks = Math.ceil(n / chunk); i < chunks; ++i) {
943
- var wrap = elt("div", null, null, "display: inline-block");
944
- for (var j = 0; j < chunk && n; ++j) {
945
- wrap.appendChild(pre.firstChild);
946
- --n;
947
- }
948
- fragment.appendChild(wrap);
949
- }
950
- pre.appendChild(fragment);
951
- }
952
-
953
- removeChildrenAndAdd(display.measure, pre);
954
-
955
- var outer = display.lineDiv.getBoundingClientRect();
956
- var vranges = [], data = emptyArray(line.text.length), maxBot = pre.offsetHeight;
957
- for (var i = 0, cur; i < measure.length; ++i) if (cur = measure[i]) {
958
- var size = cur.getBoundingClientRect();
959
- var top = Math.max(0, size.top - outer.top), bot = Math.min(size.bottom - outer.top, maxBot);
960
- for (var j = 0; j < vranges.length; j += 2) {
961
- var rtop = vranges[j], rbot = vranges[j+1];
962
- if (rtop > bot || rbot < top) continue;
963
- if (rtop <= top && rbot >= bot ||
964
- top <= rtop && bot >= rbot ||
965
- Math.min(bot, rbot) - Math.max(top, rtop) >= (bot - top) >> 1) {
966
- vranges[j] = Math.min(top, rtop);
967
- vranges[j+1] = Math.max(bot, rbot);
968
- break;
969
- }
970
- }
971
- if (j == vranges.length) vranges.push(top, bot);
972
- data[i] = {left: size.left - outer.left, right: size.right - outer.left, top: j};
973
- }
974
- for (var i = 0, cur; i < data.length; ++i) if (cur = data[i]) {
975
- var vr = cur.top;
976
- cur.top = vranges[vr]; cur.bottom = vranges[vr+1];
977
- }
978
- return data;
979
- }
980
-
981
- function clearCaches(cm) {
982
- cm.display.measureLineCache.length = cm.display.measureLineCachePos = 0;
983
- cm.display.cachedCharWidth = cm.display.cachedTextHeight = null;
984
- cm.view.maxLineChanged = true;
985
- }
986
-
987
- // Context is one of "line", "div" (display.lineDiv), "local"/null (editor), or "page"
988
- function intoCoordSystem(cm, lineObj, rect, context) {
989
- if (lineObj.widgets) for (var i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) {
990
- var size = widgetHeight(lineObj.widgets[i]);
991
- rect.top += size; rect.bottom += size;
992
- }
993
- if (context == "line") return rect;
994
- if (!context) context = "local";
995
- var yOff = heightAtLine(cm, lineObj);
996
- if (context != "local") yOff -= cm.display.viewOffset;
997
- if (context == "page") {
998
- var lOff = cm.display.lineSpace.getBoundingClientRect();
999
- yOff += lOff.top + (window.pageYOffset || (document.documentElement || document.body).scrollTop);
1000
- var xOff = lOff.left + (window.pageXOffset || (document.documentElement || document.body).scrollLeft);
1001
- rect.left += xOff; rect.right += xOff;
1002
- }
1003
- rect.top += yOff; rect.bottom += yOff;
1004
- return rect;
1005
- }
1006
-
1007
- function charCoords(cm, pos, context, lineObj) {
1008
- if (!lineObj) lineObj = getLine(cm.view.doc, pos.line);
1009
- return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch), context);
1010
- }
1011
-
1012
- function cursorCoords(cm, pos, context, lineObj, measurement) {
1013
- lineObj = lineObj || getLine(cm.view.doc, pos.line);
1014
- if (!measurement) measurement = measureLine(cm, lineObj);
1015
- function get(ch, right) {
1016
- var m = measureChar(cm, lineObj, ch, measurement);
1017
- if (right) m.left = m.right; else m.right = m.left;
1018
- return intoCoordSystem(cm, lineObj, m, context);
1019
- }
1020
- var order = getOrder(lineObj), ch = pos.ch;
1021
- if (!order) return get(ch);
1022
- var main, other, linedir = order[0].level;
1023
- for (var i = 0; i < order.length; ++i) {
1024
- var part = order[i], rtl = part.level % 2, nb, here;
1025
- if (part.from < ch && part.to > ch) return get(ch, rtl);
1026
- var left = rtl ? part.to : part.from, right = rtl ? part.from : part.to;
1027
- if (left == ch) {
1028
- // Opera and IE return bogus offsets and widths for edges
1029
- // where the direction flips, but only for the side with the
1030
- // lower level. So we try to use the side with the higher
1031
- // level.
1032
- if (i && part.level < (nb = order[i-1]).level) here = get(nb.level % 2 ? nb.from : nb.to - 1, true);
1033
- else here = get(rtl && part.from != part.to ? ch - 1 : ch);
1034
- if (rtl == linedir) main = here; else other = here;
1035
- } else if (right == ch) {
1036
- var nb = i < order.length - 1 && order[i+1];
1037
- if (!rtl && nb && nb.from == nb.to) continue;
1038
- if (nb && part.level < nb.level) here = get(nb.level % 2 ? nb.to - 1 : nb.from);
1039
- else here = get(rtl ? ch : ch - 1, true);
1040
- if (rtl == linedir) main = here; else other = here;
1041
- }
1042
- }
1043
- if (linedir && !ch) other = get(order[0].to - 1);
1044
- if (!main) return other;
1045
- if (other) main.other = other;
1046
- return main;
1047
- }
1048
-
1049
- // Coords must be lineSpace-local
1050
- function coordsChar(cm, x, y) {
1051
- var doc = cm.view.doc;
1052
- y += cm.display.viewOffset;
1053
- if (y < 0) return {line: 0, ch: 0, outside: true};
1054
- var lineNo = lineAtHeight(doc, y);
1055
- if (lineNo >= doc.size) return {line: doc.size - 1, ch: getLine(doc, doc.size - 1).text.length};
1056
- if (x < 0) x = 0;
1057
-
1058
- for (;;) {
1059
- var lineObj = getLine(doc, lineNo);
1060
- var found = coordsCharInner(cm, lineObj, lineNo, x, y);
1061
- var merged = collapsedSpanAtEnd(lineObj);
1062
- var mergedPos = merged && merged.find();
1063
- if (merged && found.ch >= mergedPos.from.ch)
1064
- lineNo = mergedPos.to.line;
1065
- else
1066
- return found;
1067
- }
1068
- }
1069
-
1070
- function coordsCharInner(cm, lineObj, lineNo, x, y) {
1071
- var innerOff = y - heightAtLine(cm, lineObj);
1072
- var wrongLine = false, cWidth = cm.display.wrapper.clientWidth;
1073
- var measurement = measureLine(cm, lineObj);
1074
-
1075
- function getX(ch) {
1076
- var sp = cursorCoords(cm, {line: lineNo, ch: ch}, "line",
1077
- lineObj, measurement);
1078
- wrongLine = true;
1079
- if (innerOff > sp.bottom) return Math.max(0, sp.left - cWidth);
1080
- else if (innerOff < sp.top) return sp.left + cWidth;
1081
- else wrongLine = false;
1082
- return sp.left;
1083
- }
1084
-
1085
- var bidi = getOrder(lineObj), dist = lineObj.text.length;
1086
- var from = lineLeft(lineObj), to = lineRight(lineObj);
1087
- var fromX = paddingLeft(cm.display), toX = getX(to);
1088
-
1089
- if (x > toX) return {line: lineNo, ch: to, outside: wrongLine};
1090
- // Do a binary search between these bounds.
1091
- for (;;) {
1092
- if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) {
1093
- var after = x - fromX < toX - x, ch = after ? from : to;
1094
- while (isExtendingChar.test(lineObj.text.charAt(ch))) ++ch;
1095
- return {line: lineNo, ch: ch, after: after, outside: wrongLine};
1096
- }
1097
- var step = Math.ceil(dist / 2), middle = from + step;
1098
- if (bidi) {
1099
- middle = from;
1100
- for (var i = 0; i < step; ++i) middle = moveVisually(lineObj, middle, 1);
1101
- }
1102
- var middleX = getX(middle);
1103
- if (middleX > x) {to = middle; toX = middleX; if (wrongLine) toX += 1000; dist -= step;}
1104
- else {from = middle; fromX = middleX; dist = step;}
1105
- }
1106
- }
1107
-
1108
- var measureText;
1109
- function textHeight(display) {
1110
- if (display.cachedTextHeight != null) return display.cachedTextHeight;
1111
- if (measureText == null) {
1112
- measureText = elt("pre");
1113
- // Measure a bunch of lines, for browsers that compute
1114
- // fractional heights.
1115
- for (var i = 0; i < 49; ++i) {
1116
- measureText.appendChild(document.createTextNode("x"));
1117
- measureText.appendChild(elt("br"));
1118
- }
1119
- measureText.appendChild(document.createTextNode("x"));
1120
- }
1121
- removeChildrenAndAdd(display.measure, measureText);
1122
- var height = measureText.offsetHeight / 50;
1123
- if (height > 3) display.cachedTextHeight = height;
1124
- removeChildren(display.measure);
1125
- return height || 1;
1126
- }
1127
-
1128
- function charWidth(display) {
1129
- if (display.cachedCharWidth != null) return display.cachedCharWidth;
1130
- var anchor = elt("span", "x");
1131
- var pre = elt("pre", [anchor]);
1132
- removeChildrenAndAdd(display.measure, pre);
1133
- var width = anchor.offsetWidth;
1134
- if (width > 2) display.cachedCharWidth = width;
1135
- return width || 10;
1136
- }
1137
-
1138
- // OPERATIONS
1139
-
1140
- // Operations are used to wrap changes in such a way that each
1141
- // change won't have to update the cursor and display (which would
1142
- // be awkward, slow, and error-prone), but instead updates are
1143
- // batched and then all combined and executed at once.
1144
-
1145
- function startOperation(cm) {
1146
- if (cm.curOp) ++cm.curOp.depth;
1147
- else cm.curOp = {
1148
- // Nested operations delay update until the outermost one
1149
- // finishes.
1150
- depth: 1,
1151
- // An array of ranges of lines that have to be updated. See
1152
- // updateDisplay.
1153
- changes: [],
1154
- delayedCallbacks: [],
1155
- updateInput: null,
1156
- userSelChange: null,
1157
- textChanged: null,
1158
- selectionChanged: false,
1159
- updateMaxLine: false,
1160
- id: ++cm.nextOpId
1161
- };
1162
- }
1163
-
1164
- function endOperation(cm) {
1165
- var op = cm.curOp;
1166
- if (--op.depth) return;
1167
- cm.curOp = null;
1168
- var view = cm.view, display = cm.display;
1169
- if (op.updateMaxLine) computeMaxLength(view);
1170
- if (view.maxLineChanged && !cm.options.lineWrapping) {
1171
- var width = measureChar(cm, view.maxLine, view.maxLine.text.length).right;
1172
- display.sizer.style.minWidth = (width + 3 + scrollerCutOff) + "px";
1173
- view.maxLineChanged = false;
1174
- var maxScrollLeft = Math.max(0, display.sizer.offsetLeft + display.sizer.offsetWidth - display.scroller.clientWidth);
1175
- if (maxScrollLeft < view.scrollLeft)
1176
- setScrollLeft(cm, Math.min(display.scroller.scrollLeft, maxScrollLeft), true);
1177
- }
1178
- var newScrollPos, updated;
1179
- if (op.selectionChanged) {
1180
- var coords = cursorCoords(cm, view.sel.head);
1181
- newScrollPos = calculateScrollPos(cm, coords.left, coords.top, coords.left, coords.bottom);
1182
- }
1183
- if (op.changes.length || newScrollPos && newScrollPos.scrollTop != null)
1184
- updated = updateDisplay(cm, op.changes, newScrollPos && newScrollPos.scrollTop);
1185
- if (!updated && op.selectionChanged) updateSelection(cm);
1186
- if (newScrollPos) scrollCursorIntoView(cm);
1187
- if (op.selectionChanged) restartBlink(cm);
1188
-
1189
- if (view.focused && op.updateInput)
1190
- resetInput(cm, op.userSelChange);
1191
-
1192
- if (op.textChanged)
1193
- signal(cm, "change", cm, op.textChanged);
1194
- if (op.selectionChanged) signal(cm, "cursorActivity", cm);
1195
- for (var i = 0; i < op.delayedCallbacks.length; ++i) op.delayedCallbacks[i](cm);
1196
- }
1197
-
1198
- // Wraps a function in an operation. Returns the wrapped function.
1199
- function operation(cm1, f) {
1200
- return function() {
1201
- var cm = cm1 || this;
1202
- startOperation(cm);
1203
- try {var result = f.apply(cm, arguments);}
1204
- finally {endOperation(cm);}
1205
- return result;
1206
- };
1207
- }
1208
-
1209
- function regChange(cm, from, to, lendiff) {
1210
- cm.curOp.changes.push({from: from, to: to, diff: lendiff});
1211
- }
1212
-
1213
- // INPUT HANDLING
1214
-
1215
- function slowPoll(cm) {
1216
- if (cm.view.pollingFast) return;
1217
- cm.display.poll.set(cm.options.pollInterval, function() {
1218
- readInput(cm);
1219
- if (cm.view.focused) slowPoll(cm);
1220
- });
1221
- }
1222
-
1223
- function fastPoll(cm) {
1224
- var missed = false;
1225
- cm.display.pollingFast = true;
1226
- function p() {
1227
- var changed = readInput(cm);
1228
- if (!changed && !missed) {missed = true; cm.display.poll.set(60, p);}
1229
- else {cm.display.pollingFast = false; slowPoll(cm);}
1230
- }
1231
- cm.display.poll.set(20, p);
1232
- }
1233
-
1234
- // prevInput is a hack to work with IME. If we reset the textarea
1235
- // on every change, that breaks IME. So we look for changes
1236
- // compared to the previous content instead. (Modern browsers have
1237
- // events that indicate IME taking place, but these are not widely
1238
- // supported or compatible enough yet to rely on.)
1239
- function readInput(cm) {
1240
- var input = cm.display.input, prevInput = cm.display.prevInput, view = cm.view, sel = view.sel;
1241
- if (!view.focused || hasSelection(input) || isReadOnly(cm)) return false;
1242
- var text = input.value;
1243
- if (text == prevInput && posEq(sel.from, sel.to)) return false;
1244
- startOperation(cm);
1245
- view.sel.shift = false;
1246
- var same = 0, l = Math.min(prevInput.length, text.length);
1247
- while (same < l && prevInput[same] == text[same]) ++same;
1248
- var from = sel.from, to = sel.to;
1249
- if (same < prevInput.length)
1250
- from = {line: from.line, ch: from.ch - (prevInput.length - same)};
1251
- else if (view.overwrite && posEq(from, to) && !cm.display.pasteIncoming)
1252
- to = {line: to.line, ch: Math.min(getLine(cm.view.doc, to.line).text.length, to.ch + (text.length - same))};
1253
- var updateInput = cm.curOp.updateInput;
1254
- updateDoc(cm, from, to, splitLines(text.slice(same)), "end",
1255
- cm.display.pasteIncoming ? "paste" : "input", {from: from, to: to});
1256
- cm.curOp.updateInput = updateInput;
1257
- if (text.length > 1000) input.value = cm.display.prevInput = "";
1258
- else cm.display.prevInput = text;
1259
- endOperation(cm);
1260
- cm.display.pasteIncoming = false;
1261
- return true;
1262
- }
1263
-
1264
- function resetInput(cm, user) {
1265
- var view = cm.view, minimal, selected;
1266
- if (!posEq(view.sel.from, view.sel.to)) {
1267
- cm.display.prevInput = "";
1268
- minimal = hasCopyEvent &&
1269
- (view.sel.to.line - view.sel.from.line > 100 || (selected = cm.getSelection()).length > 1000);
1270
- if (minimal) cm.display.input.value = "-";
1271
- else cm.display.input.value = selected || cm.getSelection();
1272
- if (view.focused) selectInput(cm.display.input);
1273
- } else if (user) cm.display.prevInput = cm.display.input.value = "";
1274
- cm.display.inaccurateSelection = minimal;
1275
- }
1276
-
1277
- function focusInput(cm) {
1278
- if (cm.options.readOnly != "nocursor" && (ie || document.activeElement != cm.display.input))
1279
- cm.display.input.focus();
1280
- }
1281
-
1282
- function isReadOnly(cm) {
1283
- return cm.options.readOnly || cm.view.cantEdit;
1284
- }
1285
-
1286
- // EVENT HANDLERS
1287
-
1288
- function registerEventHandlers(cm) {
1289
- var d = cm.display;
1290
- on(d.scroller, "mousedown", operation(cm, onMouseDown));
1291
- on(d.scroller, "dblclick", operation(cm, e_preventDefault));
1292
- on(d.lineSpace, "selectstart", function(e) {
1293
- if (!eventInWidget(d, e)) e_preventDefault(e);
1294
- });
1295
- // Gecko browsers fire contextmenu *after* opening the menu, at
1296
- // which point we can't mess with it anymore. Context menu is
1297
- // handled in onMouseDown for Gecko.
1298
- if (!gecko) on(d.scroller, "contextmenu", function(e) {onContextMenu(cm, e);});
1299
-
1300
- on(d.scroller, "scroll", function() {
1301
- setScrollTop(cm, d.scroller.scrollTop);
1302
- setScrollLeft(cm, d.scroller.scrollLeft, true);
1303
- signal(cm, "scroll", cm);
1304
- });
1305
- on(d.scrollbarV, "scroll", function() {
1306
- setScrollTop(cm, d.scrollbarV.scrollTop);
1307
- });
1308
- on(d.scrollbarH, "scroll", function() {
1309
- setScrollLeft(cm, d.scrollbarH.scrollLeft);
1310
- });
1311
-
1312
- on(d.scroller, "mousewheel", function(e){onScrollWheel(cm, e);});
1313
- on(d.scroller, "DOMMouseScroll", function(e){onScrollWheel(cm, e);});
1314
-
1315
- function reFocus() { if (cm.view.focused) setTimeout(bind(focusInput, cm), 0); }
1316
- on(d.scrollbarH, "mousedown", reFocus);
1317
- on(d.scrollbarV, "mousedown", reFocus);
1318
- // Prevent wrapper from ever scrolling
1319
- on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; });
1320
-
1321
- if (!window.registered) window.registered = 0;
1322
- ++window.registered;
1323
- function onResize() {
1324
- // Might be a text scaling operation, clear size caches.
1325
- d.cachedCharWidth = d.cachedTextHeight = null;
1326
- clearCaches(cm);
1327
- updateDisplay(cm, true);
1328
- }
1329
- on(window, "resize", onResize);
1330
- // Above handler holds on to the editor and its data structures.
1331
- // Here we poll to unregister it when the editor is no longer in
1332
- // the document, so that it can be garbage-collected.
1333
- setTimeout(function unregister() {
1334
- for (var p = d.wrapper.parentNode; p && p != document.body; p = p.parentNode) {}
1335
- if (p) setTimeout(unregister, 5000);
1336
- else {--window.registered; off(window, "resize", onResize);}
1337
- }, 5000);
1338
-
1339
- on(d.input, "keyup", operation(cm, function(e) {
1340
- if (cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
1341
- if (e_prop(e, "keyCode") == 16) cm.view.sel.shift = false;
1342
- }));
1343
- on(d.input, "input", bind(fastPoll, cm));
1344
- on(d.input, "keydown", operation(cm, onKeyDown));
1345
- on(d.input, "keypress", operation(cm, onKeyPress));
1346
- on(d.input, "focus", bind(onFocus, cm));
1347
- on(d.input, "blur", bind(onBlur, cm));
1348
-
1349
- function drag_(e) {
1350
- if (cm.options.onDragEvent && cm.options.onDragEvent(cm, addStop(e))) return;
1351
- e_stop(e);
1352
- }
1353
- if (cm.options.dragDrop) {
1354
- on(d.scroller, "dragstart", function(e){onDragStart(cm, e);});
1355
- on(d.scroller, "dragenter", drag_);
1356
- on(d.scroller, "dragover", drag_);
1357
- on(d.scroller, "drop", operation(cm, onDrop));
1358
- }
1359
- on(d.scroller, "paste", function(e){
1360
- if (eventInWidget(d, e)) return;
1361
- focusInput(cm);
1362
- fastPoll(cm);
1363
- });
1364
- on(d.input, "paste", function() {
1365
- d.pasteIncoming = true;
1366
- fastPoll(cm);
1367
- });
1368
-
1369
- function prepareCopy() {
1370
- if (d.inaccurateSelection) {
1371
- d.prevInput = "";
1372
- d.inaccurateSelection = false;
1373
- d.input.value = cm.getSelection();
1374
- selectInput(d.input);
1375
- }
1376
- }
1377
- on(d.input, "cut", prepareCopy);
1378
- on(d.input, "copy", prepareCopy);
1379
-
1380
- // Needed to handle Tab key in KHTML
1381
- if (khtml) on(d.sizer, "mouseup", function() {
1382
- if (document.activeElement == d.input) d.input.blur();
1383
- focusInput(cm);
1384
- });
1385
- }
1386
-
1387
- function eventInWidget(display, e) {
1388
- for (var n = e_target(e); n != display.wrapper; n = n.parentNode) {
1389
- if (!n) return true;
1390
- if (/\bCodeMirror-(?:line)?widget\b/.test(n.className) ||
1391
- n.parentNode == display.sizer && n != display.mover) return true;
1392
- }
1393
- }
1394
-
1395
- function posFromMouse(cm, e, liberal) {
1396
- var display = cm.display;
1397
- if (!liberal) {
1398
- var target = e_target(e);
1399
- if (target == display.scrollbarH || target == display.scrollbarH.firstChild ||
1400
- target == display.scrollbarV || target == display.scrollbarV.firstChild ||
1401
- target == display.scrollbarFiller) return null;
1402
- }
1403
- var x, y, space = display.lineSpace.getBoundingClientRect();
1404
- // Fails unpredictably on IE[67] when mouse is dragged around quickly.
1405
- try { x = e.clientX; y = e.clientY; } catch (e) { return null; }
1406
- return coordsChar(cm, x - space.left, y - space.top);
1407
- }
1408
-
1409
- var lastClick, lastDoubleClick;
1410
- function onMouseDown(e) {
1411
- var cm = this, display = cm.display, view = cm.view, sel = view.sel, doc = view.doc;
1412
- sel.shift = e_prop(e, "shiftKey");
1413
-
1414
- if (eventInWidget(display, e)) {
1415
- if (!webkit) {
1416
- display.scroller.draggable = false;
1417
- setTimeout(function(){display.scroller.draggable = true;}, 100);
1418
- }
1419
- return;
1420
- }
1421
- if (clickInGutter(cm, e)) return;
1422
- var start = posFromMouse(cm, e);
1423
-
1424
- switch (e_button(e)) {
1425
- case 3:
1426
- if (gecko) onContextMenu.call(cm, cm, e);
1427
- return;
1428
- case 2:
1429
- if (start) extendSelection(cm, start);
1430
- setTimeout(bind(focusInput, cm), 20);
1431
- e_preventDefault(e);
1432
- return;
1433
- }
1434
- // For button 1, if it was clicked inside the editor
1435
- // (posFromMouse returning non-null), we have to adjust the
1436
- // selection.
1437
- if (!start) {if (e_target(e) == display.scroller) e_preventDefault(e); return;}
1438
-
1439
- if (!view.focused) onFocus(cm);
1440
-
1441
- var now = +new Date, type = "single";
1442
- if (lastDoubleClick && lastDoubleClick.time > now - 400 && posEq(lastDoubleClick.pos, start)) {
1443
- type = "triple";
1444
- e_preventDefault(e);
1445
- setTimeout(bind(focusInput, cm), 20);
1446
- selectLine(cm, start.line);
1447
- } else if (lastClick && lastClick.time > now - 400 && posEq(lastClick.pos, start)) {
1448
- type = "double";
1449
- lastDoubleClick = {time: now, pos: start};
1450
- e_preventDefault(e);
1451
- var word = findWordAt(getLine(doc, start.line).text, start);
1452
- extendSelection(cm, word.from, word.to);
1453
- } else { lastClick = {time: now, pos: start}; }
1454
-
1455
- var last = start;
1456
- if (cm.options.dragDrop && dragAndDrop && !isReadOnly(cm) && !posEq(sel.from, sel.to) &&
1457
- !posLess(start, sel.from) && !posLess(sel.to, start) && type == "single") {
1458
- var dragEnd = operation(cm, function(e2) {
1459
- if (webkit) display.scroller.draggable = false;
1460
- view.draggingText = false;
1461
- off(document, "mouseup", dragEnd);
1462
- off(display.scroller, "drop", dragEnd);
1463
- if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
1464
- e_preventDefault(e2);
1465
- extendSelection(cm, start);
1466
- focusInput(cm);
1467
- }
1468
- });
1469
- // Let the drag handler handle this.
1470
- if (webkit) display.scroller.draggable = true;
1471
- view.draggingText = dragEnd;
1472
- // IE's approach to draggable
1473
- if (display.scroller.dragDrop) display.scroller.dragDrop();
1474
- on(document, "mouseup", dragEnd);
1475
- on(display.scroller, "drop", dragEnd);
1476
- return;
1477
- }
1478
- e_preventDefault(e);
1479
- if (type == "single") extendSelection(cm, clipPos(doc, start));
1480
-
1481
- var startstart = sel.from, startend = sel.to;
1482
-
1483
- function doSelect(cur) {
1484
- if (type == "single") {
1485
- extendSelection(cm, clipPos(doc, start), cur);
1486
- return;
1487
- }
1488
-
1489
- startstart = clipPos(doc, startstart);
1490
- startend = clipPos(doc, startend);
1491
- if (type == "double") {
1492
- var word = findWordAt(getLine(doc, cur.line).text, cur);
1493
- if (posLess(cur, startstart)) extendSelection(cm, word.from, startend);
1494
- else extendSelection(cm, startstart, word.to);
1495
- } else if (type == "triple") {
1496
- if (posLess(cur, startstart)) extendSelection(cm, startend, clipPos(doc, {line: cur.line, ch: 0}));
1497
- else extendSelection(cm, startstart, clipPos(doc, {line: cur.line + 1, ch: 0}));
1498
- }
1499
- }
1500
-
1501
- var editorSize = display.wrapper.getBoundingClientRect();
1502
- // Used to ensure timeout re-tries don't fire when another extend
1503
- // happened in the meantime (clearTimeout isn't reliable -- at
1504
- // least on Chrome, the timeouts still happen even when cleared,
1505
- // if the clear happens after their scheduled firing time).
1506
- var counter = 0;
1507
-
1508
- function extend(e) {
1509
- var curCount = ++counter;
1510
- var cur = posFromMouse(cm, e, true);
1511
- if (!cur) return;
1512
- if (!posEq(cur, last)) {
1513
- if (!view.focused) onFocus(cm);
1514
- last = cur;
1515
- doSelect(cur);
1516
- var visible = visibleLines(display, doc);
1517
- if (cur.line >= visible.to || cur.line < visible.from)
1518
- setTimeout(operation(cm, function(){if (counter == curCount) extend(e);}), 150);
1519
- } else {
1520
- var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0;
1521
- if (outside) setTimeout(operation(cm, function() {
1522
- if (counter != curCount) return;
1523
- display.scroller.scrollTop += outside;
1524
- extend(e);
1525
- }), 50);
1526
- }
1527
- }
1528
-
1529
- function done(e) {
1530
- counter = Infinity;
1531
- var cur = posFromMouse(cm, e);
1532
- if (cur) doSelect(cur);
1533
- e_preventDefault(e);
1534
- focusInput(cm);
1535
- off(document, "mousemove", move);
1536
- off(document, "mouseup", up);
1537
- }
1538
-
1539
- var move = operation(cm, function(e) {
1540
- if (!ie && !e_button(e)) done(e);
1541
- else extend(e);
1542
- });
1543
- var up = operation(cm, done);
1544
- on(document, "mousemove", move);
1545
- on(document, "mouseup", up);
1546
- }
1547
-
1548
- function onDrop(e) {
1549
- var cm = this;
1550
- if (eventInWidget(cm.display, e) || (cm.options.onDragEvent && cm.options.onDragEvent(cm, addStop(e))))
1551
- return;
1552
- e_preventDefault(e);
1553
- var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files;
1554
- if (!pos || isReadOnly(cm)) return;
1555
- if (files && files.length && window.FileReader && window.File) {
1556
- var n = files.length, text = Array(n), read = 0;
1557
- var loadFile = function(file, i) {
1558
- var reader = new FileReader;
1559
- reader.onload = function() {
1560
- text[i] = reader.result;
1561
- if (++read == n) {
1562
- pos = clipPos(cm.view.doc, pos);
1563
- operation(cm, function() {
1564
- var end = replaceRange(cm, text.join(""), pos, pos, "paste");
1565
- setSelection(cm, pos, end);
1566
- })();
1567
- }
1568
- };
1569
- reader.readAsText(file);
1570
- };
1571
- for (var i = 0; i < n; ++i) loadFile(files[i], i);
1572
- } else {
1573
- // Don't do a replace if the drop happened inside of the selected text.
1574
- if (cm.view.draggingText && !(posLess(pos, cm.view.sel.from) || posLess(cm.view.sel.to, pos))) {
1575
- cm.view.draggingText(e);
1576
- // Ensure the editor is re-focused
1577
- setTimeout(bind(focusInput, cm), 20);
1578
- return;
1579
- }
1580
- try {
1581
- var text = e.dataTransfer.getData("Text");
1582
- if (text) {
1583
- var curFrom = cm.view.sel.from, curTo = cm.view.sel.to;
1584
- setSelection(cm, pos, pos);
1585
- if (cm.view.draggingText) replaceRange(cm, "", curFrom, curTo, "paste");
1586
- cm.replaceSelection(text, null, "paste");
1587
- focusInput(cm);
1588
- onFocus(cm);
1589
- }
1590
- }
1591
- catch(e){}
1592
- }
1593
- }
1594
-
1595
- function clickInGutter(cm, e) {
1596
- var display = cm.display;
1597
- try { var mX = e.clientX, mY = e.clientY; }
1598
- catch(e) { return false; }
1599
-
1600
- if (mX >= Math.floor(display.gutters.getBoundingClientRect().right)) return false;
1601
- e_preventDefault(e);
1602
- if (!hasHandler(cm, "gutterClick")) return true;
1603
-
1604
- var lineBox = display.lineDiv.getBoundingClientRect();
1605
- if (mY > lineBox.bottom) return true;
1606
- mY -= lineBox.top - display.viewOffset;
1607
-
1608
- for (var i = 0; i < cm.options.gutters.length; ++i) {
1609
- var g = display.gutters.childNodes[i];
1610
- if (g && g.getBoundingClientRect().right >= mX) {
1611
- var line = lineAtHeight(cm.view.doc, mY);
1612
- var gutter = cm.options.gutters[i];
1613
- signalLater(cm, cm, "gutterClick", cm, line, gutter, e);
1614
- break;
1615
- }
1616
- }
1617
- return true;
1618
- }
1619
-
1620
- function onDragStart(cm, e) {
1621
- if (eventInWidget(cm.display, e)) return;
1622
-
1623
- var txt = cm.getSelection();
1624
- e.dataTransfer.setData("Text", txt);
1625
-
1626
- // Use dummy image instead of default browsers image.
1627
- // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there.
1628
- if (e.dataTransfer.setDragImage && !safari) {
1629
- var img = elt("img", null, null, "position: fixed; left: 0; top: 0;");
1630
- if (opera) {
1631
- img.width = img.height = 1;
1632
- cm.display.wrapper.appendChild(img);
1633
- // Force a relayout, or Opera won't use our image for some obscure reason
1634
- img._top = img.offsetTop;
1635
- }
1636
- e.dataTransfer.setDragImage(img, 0, 0);
1637
- if (opera) img.parentNode.removeChild(img);
1638
- }
1639
- }
1640
-
1641
- function setScrollTop(cm, val) {
1642
- if (Math.abs(cm.view.scrollTop - val) < 2) return;
1643
- cm.view.scrollTop = val;
1644
- if (!gecko) updateDisplay(cm, [], val);
1645
- if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val;
1646
- if (cm.display.scrollbarV.scrollTop != val) cm.display.scrollbarV.scrollTop = val;
1647
- if (gecko) updateDisplay(cm, []);
1648
- }
1649
- function setScrollLeft(cm, val, isScroller) {
1650
- if (isScroller ? val == cm.view.scrollLeft : Math.abs(cm.view.scrollLeft - val) < 2) return;
1651
- val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth);
1652
- cm.view.scrollLeft = val;
1653
- alignHorizontally(cm);
1654
- if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val;
1655
- if (cm.display.scrollbarH.scrollLeft != val) cm.display.scrollbarH.scrollLeft = val;
1656
- }
1657
-
1658
- // Since the delta values reported on mouse wheel events are
1659
- // unstandardized between browsers and even browser versions, and
1660
- // generally horribly unpredictable, this code starts by measuring
1661
- // the scroll effect that the first few mouse wheel events have,
1662
- // and, from that, detects the way it can convert deltas to pixel
1663
- // offsets afterwards.
1664
- //
1665
- // The reason we want to know the amount a wheel event will scroll
1666
- // is that it gives us a chance to update the display before the
1667
- // actual scrolling happens, reducing flickering.
1668
-
1669
- var wheelSamples = 0, wheelPixelsPerUnit = null;
1670
- // Fill in a browser-detected starting value on browsers where we
1671
- // know one. These don't have to be accurate -- the result of them
1672
- // being wrong would just be a slight flicker on the first wheel
1673
- // scroll (if it is large enough).
1674
- if (ie) wheelPixelsPerUnit = -.53;
1675
- else if (gecko) wheelPixelsPerUnit = 15;
1676
- else if (chrome) wheelPixelsPerUnit = -.7;
1677
- else if (safari) wheelPixelsPerUnit = -1/3;
1678
-
1679
- function onScrollWheel(cm, e) {
1680
- var dx = e.wheelDeltaX, dy = e.wheelDeltaY;
1681
- if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) dx = e.detail;
1682
- if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) dy = e.detail;
1683
- else if (dy == null) dy = e.wheelDelta;
1684
-
1685
- // Webkit browsers on OS X abort momentum scrolls when the target
1686
- // of the scroll event is removed from the scrollable element.
1687
- // This hack (see related code in patchDisplay) makes sure the
1688
- // element is kept around.
1689
- if (dy && mac && webkit) {
1690
- for (var cur = e.target; cur != scroll; cur = cur.parentNode) {
1691
- if (cur.lineObj) {
1692
- cm.display.currentWheelTarget = cur;
1693
- break;
1694
- }
1695
- }
1696
- }
1697
-
1698
- var display = cm.display, scroll = display.scroller;
1699
- // On some browsers, horizontal scrolling will cause redraws to
1700
- // happen before the gutter has been realigned, causing it to
1701
- // wriggle around in a most unseemly way. When we have an
1702
- // estimated pixels/delta value, we just handle horizontal
1703
- // scrolling entirely here. It'll be slightly off from native, but
1704
- // better than glitching out.
1705
- if (dx && !gecko && !opera && wheelPixelsPerUnit != null) {
1706
- if (dy)
1707
- setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight)));
1708
- setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth)));
1709
- e_preventDefault(e);
1710
- display.wheelStartX = null; // Abort measurement, if in progress
1711
- return;
1712
- }
1713
-
1714
- if (dy && wheelPixelsPerUnit != null) {
1715
- var pixels = dy * wheelPixelsPerUnit;
1716
- var top = cm.view.scrollTop, bot = top + display.wrapper.clientHeight;
1717
- if (pixels < 0) top = Math.max(0, top + pixels - 50);
1718
- else bot = Math.min(cm.view.doc.height, bot + pixels + 50);
1719
- updateDisplay(cm, [], {top: top, bottom: bot});
1720
- }
1721
-
1722
- if (wheelSamples < 20) {
1723
- if (display.wheelStartX == null) {
1724
- display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop;
1725
- display.wheelDX = dx; display.wheelDY = dy;
1726
- setTimeout(function() {
1727
- if (display.wheelStartX == null) return;
1728
- var movedX = scroll.scrollLeft - display.wheelStartX;
1729
- var movedY = scroll.scrollTop - display.wheelStartY;
1730
- var sample = (movedY && display.wheelDY && movedY / display.wheelDY) ||
1731
- (movedX && display.wheelDX && movedX / display.wheelDX);
1732
- display.wheelStartX = display.wheelStartY = null;
1733
- if (!sample) return;
1734
- wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1);
1735
- ++wheelSamples;
1736
- }, 200);
1737
- } else {
1738
- display.wheelDX += dx; display.wheelDY += dy;
1739
- }
1740
- }
1741
- }
1742
-
1743
- function doHandleBinding(cm, bound, dropShift) {
1744
- if (typeof bound == "string") {
1745
- bound = commands[bound];
1746
- if (!bound) return false;
1747
- }
1748
- // Ensure previous input has been read, so that the handler sees a
1749
- // consistent view of the document
1750
- if (cm.display.pollingFast && readInput(cm)) cm.display.pollingFast = false;
1751
- var view = cm.view, prevShift = view.sel.shift;
1752
- try {
1753
- if (isReadOnly(cm)) view.suppressEdits = true;
1754
- if (dropShift) view.sel.shift = false;
1755
- bound(cm);
1756
- } catch(e) {
1757
- if (e != Pass) throw e;
1758
- return false;
1759
- } finally {
1760
- view.sel.shift = prevShift;
1761
- view.suppressEdits = false;
1762
- }
1763
- return true;
1764
- }
1765
-
1766
- function allKeyMaps(cm) {
1767
- var maps = cm.view.keyMaps.slice(0);
1768
- maps.push(cm.options.keyMap);
1769
- if (cm.options.extraKeys) maps.unshift(cm.options.extraKeys);
1770
- return maps;
1771
- }
1772
-
1773
- var maybeTransition;
1774
- function handleKeyBinding(cm, e) {
1775
- // Handle auto keymap transitions
1776
- var startMap = getKeyMap(cm.options.keyMap), next = startMap.auto;
1777
- clearTimeout(maybeTransition);
1778
- if (next && !isModifierKey(e)) maybeTransition = setTimeout(function() {
1779
- if (getKeyMap(cm.options.keyMap) == startMap)
1780
- cm.options.keyMap = (next.call ? next.call(null, cm) : next);
1781
- }, 50);
1782
-
1783
- var name = keyNames[e_prop(e, "keyCode")], handled = false;
1784
- if (name == null || e.altGraphKey) return false;
1785
- if (e_prop(e, "altKey")) name = "Alt-" + name;
1786
- if (e_prop(e, flipCtrlCmd ? "metaKey" : "ctrlKey")) name = "Ctrl-" + name;
1787
- if (e_prop(e, flipCtrlCmd ? "ctrlKey" : "metaKey")) name = "Cmd-" + name;
1788
-
1789
- var stopped = false;
1790
- function stop() { stopped = true; }
1791
- var keymaps = allKeyMaps(cm);
1792
-
1793
- if (e_prop(e, "shiftKey")) {
1794
- handled = lookupKey("Shift-" + name, keymaps,
1795
- function(b) {return doHandleBinding(cm, b, true);}, stop)
1796
- || lookupKey(name, keymaps, function(b) {
1797
- if (typeof b == "string" && /^go[A-Z]/.test(b)) return doHandleBinding(cm, b);
1798
- }, stop);
1799
- } else {
1800
- handled = lookupKey(name, keymaps,
1801
- function(b) { return doHandleBinding(cm, b); }, stop);
1802
- }
1803
- if (stopped) handled = false;
1804
- if (handled) {
1805
- e_preventDefault(e);
1806
- restartBlink(cm);
1807
- if (ie_lt9) { e.oldKeyCode = e.keyCode; e.keyCode = 0; }
1808
- }
1809
- return handled;
1810
- }
1811
-
1812
- function handleCharBinding(cm, e, ch) {
1813
- var handled = lookupKey("'" + ch + "'", allKeyMaps(cm),
1814
- function(b) { return doHandleBinding(cm, b, true); });
1815
- if (handled) {
1816
- e_preventDefault(e);
1817
- restartBlink(cm);
1818
- }
1819
- return handled;
1820
- }
1821
-
1822
- var lastStoppedKey = null;
1823
- function onKeyDown(e) {
1824
- var cm = this;
1825
- if (!cm.view.focused) onFocus(cm);
1826
- if (ie && e.keyCode == 27) { e.returnValue = false; }
1827
- if (cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
1828
- var code = e_prop(e, "keyCode");
1829
- // IE does strange things with escape.
1830
- cm.view.sel.shift = code == 16 || e_prop(e, "shiftKey");
1831
- // First give onKeyEvent option a chance to handle this.
1832
- var handled = handleKeyBinding(cm, e);
1833
- if (opera) {
1834
- lastStoppedKey = handled ? code : null;
1835
- // Opera has no cut event... we try to at least catch the key combo
1836
- if (!handled && code == 88 && !hasCopyEvent && e_prop(e, mac ? "metaKey" : "ctrlKey"))
1837
- cm.replaceSelection("");
1838
- }
1839
- }
1840
-
1841
- function onKeyPress(e) {
1842
- var cm = this;
1843
- if (cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
1844
- var keyCode = e_prop(e, "keyCode"), charCode = e_prop(e, "charCode");
1845
- if (opera && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;}
1846
- if (((opera && (!e.which || e.which < 10)) || khtml) && handleKeyBinding(cm, e)) return;
1847
- var ch = String.fromCharCode(charCode == null ? keyCode : charCode);
1848
- if (this.options.electricChars && this.view.mode.electricChars &&
1849
- this.options.smartIndent && !isReadOnly(this) &&
1850
- this.view.mode.electricChars.indexOf(ch) > -1)
1851
- setTimeout(operation(cm, function() {indentLine(cm, cm.view.sel.to.line, "smart");}), 75);
1852
- if (handleCharBinding(cm, e, ch)) return;
1853
- fastPoll(cm);
1854
- }
1855
-
1856
- function onFocus(cm) {
1857
- if (cm.options.readOnly == "nocursor") return;
1858
- if (!cm.view.focused) {
1859
- signal(cm, "focus", cm);
1860
- cm.view.focused = true;
1861
- if (cm.display.scroller.className.search(/\bCodeMirror-focused\b/) == -1)
1862
- cm.display.scroller.className += " CodeMirror-focused";
1863
- resetInput(cm, true);
1864
- }
1865
- slowPoll(cm);
1866
- restartBlink(cm);
1867
- }
1868
- function onBlur(cm) {
1869
- if (cm.view.focused) {
1870
- signal(cm, "blur", cm);
1871
- cm.view.focused = false;
1872
- cm.display.scroller.className = cm.display.scroller.className.replace(" CodeMirror-focused", "");
1873
- }
1874
- clearInterval(cm.display.blinker);
1875
- setTimeout(function() {if (!cm.view.focused) cm.view.sel.shift = false;}, 150);
1876
- }
1877
-
1878
- var detectingSelectAll;
1879
- function onContextMenu(cm, e) {
1880
- var display = cm.display;
1881
- if (eventInWidget(display, e)) return;
1882
-
1883
- var sel = cm.view.sel;
1884
- var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop;
1885
- if (!pos || opera) return; // Opera is difficult.
1886
- if (posEq(sel.from, sel.to) || posLess(pos, sel.from) || !posLess(pos, sel.to))
1887
- operation(cm, setSelection)(cm, pos, pos);
1888
-
1889
- var oldCSS = display.input.style.cssText;
1890
- display.inputDiv.style.position = "absolute";
1891
- display.input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) +
1892
- "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: white; outline: none;" +
1893
- "border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";
1894
- focusInput(cm);
1895
- resetInput(cm, true);
1896
- // Adds "Select all" to context menu in FF
1897
- if (posEq(sel.from, sel.to)) display.input.value = display.prevInput = " ";
1898
-
1899
- function rehide() {
1900
- display.inputDiv.style.position = "relative";
1901
- display.input.style.cssText = oldCSS;
1902
- if (ie_lt9) display.scrollbarV.scrollTop = display.scroller.scrollTop = scrollPos;
1903
- slowPoll(cm);
1904
-
1905
- // Try to detect the user choosing select-all
1906
- if (display.input.selectionStart != null) {
1907
- clearTimeout(detectingSelectAll);
1908
- var extval = display.input.value = " " + (posEq(sel.from, sel.to) ? "" : display.input.value), i = 0;
1909
- display.prevInput = " ";
1910
- display.input.selectionStart = 1; display.input.selectionEnd = extval.length;
1911
- detectingSelectAll = setTimeout(function poll(){
1912
- if (display.prevInput == " " && display.input.selectionStart == 0)
1913
- operation(cm, commands.selectAll)(cm);
1914
- else if (i++ < 10) detectingSelectAll = setTimeout(poll, 500);
1915
- else resetInput(cm);
1916
- }, 200);
1917
- }
1918
- }
1919
-
1920
- if (gecko) {
1921
- e_stop(e);
1922
- on(window, "mouseup", function mouseup() {
1923
- off(window, "mouseup", mouseup);
1924
- setTimeout(rehide, 20);
1925
- });
1926
- } else {
1927
- setTimeout(rehide, 50);
1928
- }
1929
- }
1930
-
1931
- // UPDATING
1932
-
1933
- // Replace the range from from to to by the strings in newText.
1934
- // Afterwards, set the selection to selFrom, selTo.
1935
- function updateDoc(cm, from, to, newText, selUpdate, origin) {
1936
- // Possibly split or suppress the update based on the presence
1937
- // of read-only spans in its range.
1938
- var split = sawReadOnlySpans &&
1939
- removeReadOnlyRanges(cm.view.doc, from, to);
1940
- if (split) {
1941
- for (var i = split.length - 1; i >= 1; --i)
1942
- updateDocInner(cm, split[i].from, split[i].to, [""], origin);
1943
- if (split.length)
1944
- return updateDocInner(cm, split[0].from, split[0].to, newText, selUpdate, origin);
1945
- } else {
1946
- return updateDocInner(cm, from, to, newText, selUpdate, origin);
1947
- }
1948
- }
1949
-
1950
- function updateDocInner(cm, from, to, newText, selUpdate, origin) {
1951
- if (cm.view.suppressEdits) return;
1952
-
1953
- var view = cm.view, doc = view.doc, old = [];
1954
- doc.iter(from.line, to.line + 1, function(line) {
1955
- old.push(newHL(line.text, line.markedSpans));
1956
- });
1957
- var startSelFrom = view.sel.from, startSelTo = view.sel.to;
1958
- var lines = updateMarkedSpans(hlSpans(old[0]), hlSpans(lst(old)), from.ch, to.ch, newText);
1959
- var retval = updateDocNoUndo(cm, from, to, lines, selUpdate, origin);
1960
- if (view.history) addChange(cm, from.line, newText.length, old, origin,
1961
- startSelFrom, startSelTo, view.sel.from, view.sel.to);
1962
- return retval;
1963
- }
1964
-
1965
- function unredoHelper(cm, type) {
1966
- var doc = cm.view.doc, hist = cm.view.history;
1967
- var set = (type == "undo" ? hist.done : hist.undone).pop();
1968
- if (!set) return;
1969
- var anti = {events: [], fromBefore: set.fromAfter, toBefore: set.toAfter,
1970
- fromAfter: set.fromBefore, toAfter: set.toBefore};
1971
- for (var i = set.events.length - 1; i >= 0; i -= 1) {
1972
- hist.dirtyCounter += type == "undo" ? -1 : 1;
1973
- var change = set.events[i];
1974
- var replaced = [], end = change.start + change.added;
1975
- doc.iter(change.start, end, function(line) { replaced.push(newHL(line.text, line.markedSpans)); });
1976
- anti.events.push({start: change.start, added: change.old.length, old: replaced});
1977
- var selPos = i ? null : {from: set.fromBefore, to: set.toBefore};
1978
- updateDocNoUndo(cm, {line: change.start, ch: 0}, {line: end - 1, ch: getLine(doc, end-1).text.length},
1979
- change.old, selPos, type);
1980
- }
1981
- (type == "undo" ? hist.undone : hist.done).push(anti);
1982
- }
1983
-
1984
- function updateDocNoUndo(cm, from, to, lines, selUpdate, origin) {
1985
- var view = cm.view, doc = view.doc, display = cm.display;
1986
- if (view.suppressEdits) return;
1987
-
1988
- var nlines = to.line - from.line, firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line);
1989
- var recomputeMaxLength = false, checkWidthStart = from.line;
1990
- if (!cm.options.lineWrapping) {
1991
- checkWidthStart = lineNo(visualLine(doc, firstLine));
1992
- doc.iter(checkWidthStart, to.line + 1, function(line) {
1993
- if (line == view.maxLine) {
1994
- recomputeMaxLength = true;
1995
- return true;
1996
- }
1997
- });
1998
- }
1999
-
2000
- var lastHL = lst(lines), th = textHeight(display);
2001
-
2002
- // First adjust the line structure
2003
- if (from.ch == 0 && to.ch == 0 && hlText(lastHL) == "") {
2004
- // This is a whole-line replace. Treated specially to make
2005
- // sure line objects move the way they are supposed to.
2006
- var added = [];
2007
- for (var i = 0, e = lines.length - 1; i < e; ++i)
2008
- added.push(makeLine(hlText(lines[i]), hlSpans(lines[i]), th));
2009
- updateLine(cm, lastLine, lastLine.text, hlSpans(lastHL));
2010
- if (nlines) doc.remove(from.line, nlines, cm);
2011
- if (added.length) doc.insert(from.line, added);
2012
- } else if (firstLine == lastLine) {
2013
- if (lines.length == 1) {
2014
- updateLine(cm, firstLine, firstLine.text.slice(0, from.ch) + hlText(lines[0]) +
2015
- firstLine.text.slice(to.ch), hlSpans(lines[0]));
2016
- } else {
2017
- for (var added = [], i = 1, e = lines.length - 1; i < e; ++i)
2018
- added.push(makeLine(hlText(lines[i]), hlSpans(lines[i]), th));
2019
- added.push(makeLine(hlText(lastHL) + firstLine.text.slice(to.ch), hlSpans(lastHL), th));
2020
- updateLine(cm, firstLine, firstLine.text.slice(0, from.ch) + hlText(lines[0]), hlSpans(lines[0]));
2021
- doc.insert(from.line + 1, added);
2022
- }
2023
- } else if (lines.length == 1) {
2024
- updateLine(cm, firstLine, firstLine.text.slice(0, from.ch) + hlText(lines[0]) +
2025
- lastLine.text.slice(to.ch), hlSpans(lines[0]));
2026
- doc.remove(from.line + 1, nlines, cm);
2027
- } else {
2028
- var added = [];
2029
- updateLine(cm, firstLine, firstLine.text.slice(0, from.ch) + hlText(lines[0]), hlSpans(lines[0]));
2030
- updateLine(cm, lastLine, hlText(lastHL) + lastLine.text.slice(to.ch), hlSpans(lastHL));
2031
- for (var i = 1, e = lines.length - 1; i < e; ++i)
2032
- added.push(makeLine(hlText(lines[i]), hlSpans(lines[i]), th));
2033
- if (nlines > 1) doc.remove(from.line + 1, nlines - 1, cm);
2034
- doc.insert(from.line + 1, added);
2035
- }
2036
-
2037
- if (cm.options.lineWrapping) {
2038
- var perLine = Math.max(5, display.scroller.clientWidth / charWidth(display) - 3);
2039
- doc.iter(from.line, from.line + lines.length, function(line) {
2040
- if (line.height == 0) return;
2041
- var guess = (Math.ceil(line.text.length / perLine) || 1) * th;
2042
- if (guess != line.height) updateLineHeight(line, guess);
2043
- });
2044
- } else {
2045
- doc.iter(checkWidthStart, from.line + lines.length, function(line) {
2046
- var len = lineLength(doc, line);
2047
- if (len > view.maxLineLength) {
2048
- view.maxLine = line;
2049
- view.maxLineLength = len;
2050
- view.maxLineChanged = true;
2051
- recomputeMaxLength = false;
2052
- }
2053
- });
2054
- if (recomputeMaxLength) cm.curOp.updateMaxLine = true;
2055
- }
2056
-
2057
- // Adjust frontier, schedule worker
2058
- view.frontier = Math.min(view.frontier, from.line);
2059
- startWorker(cm, 400);
2060
-
2061
- var lendiff = lines.length - nlines - 1;
2062
- // Remember that these lines changed, for updating the display
2063
- regChange(cm, from.line, to.line + 1, lendiff);
2064
- if (hasHandler(cm, "change")) {
2065
- // Normalize lines to contain only strings, since that's what
2066
- // the change event handler expects
2067
- for (var i = 0; i < lines.length; ++i)
2068
- if (typeof lines[i] != "string") lines[i] = lines[i].text;
2069
- var changeObj = {from: from, to: to, text: lines, origin: origin};
2070
- if (cm.curOp.textChanged) {
2071
- for (var cur = cm.curOp.textChanged; cur.next; cur = cur.next) {}
2072
- cur.next = changeObj;
2073
- } else cm.curOp.textChanged = changeObj;
2074
- }
2075
-
2076
- // Update the selection
2077
- var newSelFrom, newSelTo, end = {line: from.line + lines.length - 1,
2078
- ch: hlText(lastHL).length + (lines.length == 1 ? from.ch : 0)};
2079
- if (selUpdate && typeof selUpdate != "string") {
2080
- if (selUpdate.from) { newSelFrom = selUpdate.from; newSelTo = selUpdate.to; }
2081
- else newSelFrom = newSelTo = selUpdate;
2082
- } else if (selUpdate == "end") {
2083
- newSelFrom = newSelTo = end;
2084
- } else if (selUpdate == "start") {
2085
- newSelFrom = newSelTo = from;
2086
- } else if (selUpdate == "around") {
2087
- newSelFrom = from; newSelTo = end;
2088
- } else {
2089
- var adjustPos = function(pos) {
2090
- if (posLess(pos, from)) return pos;
2091
- if (!posLess(to, pos)) return end;
2092
- var line = pos.line + lendiff;
2093
- var ch = pos.ch;
2094
- if (pos.line == to.line)
2095
- ch += hlText(lastHL).length - (to.ch - (to.line == from.line ? from.ch : 0));
2096
- return {line: line, ch: ch};
2097
- };
2098
- newSelFrom = adjustPos(view.sel.from);
2099
- newSelTo = adjustPos(view.sel.to);
2100
- }
2101
- setSelection(cm, newSelFrom, newSelTo, null, true);
2102
- return end;
2103
- }
2104
-
2105
- function replaceRange(cm, code, from, to, origin) {
2106
- if (!to) to = from;
2107
- if (posLess(to, from)) { var tmp = to; to = from; from = tmp; }
2108
- return updateDoc(cm, from, to, splitLines(code), null, origin);
2109
- }
2110
-
2111
- // SELECTION
2112
-
2113
- function posEq(a, b) {return a.line == b.line && a.ch == b.ch;}
2114
- function posLess(a, b) {return a.line < b.line || (a.line == b.line && a.ch < b.ch);}
2115
- function copyPos(x) {return {line: x.line, ch: x.ch};}
2116
-
2117
- function clipLine(doc, n) {return Math.max(0, Math.min(n, doc.size-1));}
2118
- function clipPos(doc, pos) {
2119
- if (pos.line < 0) return {line: 0, ch: 0};
2120
- if (pos.line >= doc.size) return {line: doc.size-1, ch: getLine(doc, doc.size-1).text.length};
2121
- var ch = pos.ch, linelen = getLine(doc, pos.line).text.length;
2122
- if (ch == null || ch > linelen) return {line: pos.line, ch: linelen};
2123
- else if (ch < 0) return {line: pos.line, ch: 0};
2124
- else return pos;
2125
- }
2126
- function isLine(doc, l) {return l >= 0 && l < doc.size;}
2127
-
2128
- // If shift is held, this will move the selection anchor. Otherwise,
2129
- // it'll set the whole selection.
2130
- function extendSelection(cm, pos, other, bias) {
2131
- var sel = cm.view.sel;
2132
- if (sel.shift || sel.extend) {
2133
- var anchor = sel.anchor;
2134
- if (other) {
2135
- var posBefore = posLess(pos, anchor);
2136
- if (posBefore != posLess(other, anchor)) {
2137
- anchor = pos;
2138
- pos = other;
2139
- } else if (posBefore != posLess(pos, other)) {
2140
- pos = other;
2141
- }
2142
- }
2143
- setSelection(cm, anchor, pos, bias);
2144
- } else {
2145
- setSelection(cm, pos, other || pos, bias);
2146
- }
2147
- cm.curOp.userSelChange = true;
2148
- }
2149
-
2150
- // Update the selection. Last two args are only used by
2151
- // updateDoc, since they have to be expressed in the line
2152
- // numbers before the update.
2153
- function setSelection(cm, anchor, head, bias, checkAtomic) {
2154
- cm.view.goalColumn = null;
2155
- var sel = cm.view.sel;
2156
- // Skip over atomic spans.
2157
- if (checkAtomic || !posEq(anchor, sel.anchor))
2158
- anchor = skipAtomic(cm, anchor, bias, checkAtomic != "push");
2159
- if (checkAtomic || !posEq(head, sel.head))
2160
- head = skipAtomic(cm, head, bias, checkAtomic != "push");
2161
-
2162
- if (posEq(sel.anchor, anchor) && posEq(sel.head, head)) return;
2163
-
2164
- sel.anchor = anchor; sel.head = head;
2165
- var inv = posLess(head, anchor);
2166
- sel.from = inv ? head : anchor;
2167
- sel.to = inv ? anchor : head;
2168
-
2169
- cm.curOp.updateInput = true;
2170
- cm.curOp.selectionChanged = true;
2171
- }
2172
-
2173
- function reCheckSelection(cm) {
2174
- setSelection(cm, cm.view.sel.from, cm.view.sel.to, null, "push");
2175
- }
2176
-
2177
- function skipAtomic(cm, pos, bias, mayClear) {
2178
- var doc = cm.view.doc, flipped = false, curPos = pos;
2179
- var dir = bias || 1;
2180
- cm.view.cantEdit = false;
2181
- search: for (;;) {
2182
- var line = getLine(doc, curPos.line), toClear;
2183
- if (line.markedSpans) {
2184
- for (var i = 0; i < line.markedSpans.length; ++i) {
2185
- var sp = line.markedSpans[i], m = sp.marker;
2186
- if ((sp.from == null || (m.inclusiveLeft ? sp.from <= curPos.ch : sp.from < curPos.ch)) &&
2187
- (sp.to == null || (m.inclusiveRight ? sp.to >= curPos.ch : sp.to > curPos.ch))) {
2188
- if (mayClear && m.clearOnEnter) {
2189
- (toClear || (toClear = [])).push(m);
2190
- continue;
2191
- } else if (!m.atomic) continue;
2192
- var newPos = m.find()[dir < 0 ? "from" : "to"];
2193
- if (posEq(newPos, curPos)) {
2194
- newPos.ch += dir;
2195
- if (newPos.ch < 0) {
2196
- if (newPos.line) newPos = clipPos(doc, {line: newPos.line - 1});
2197
- else newPos = null;
2198
- } else if (newPos.ch > line.text.length) {
2199
- if (newPos.line < doc.size - 1) newPos = {line: newPos.line + 1, ch: 0};
2200
- else newPos = null;
2201
- }
2202
- if (!newPos) {
2203
- if (flipped) {
2204
- // Driven in a corner -- no valid cursor position found at all
2205
- // -- try again *with* clearing, if we didn't already
2206
- if (!mayClear) return skipAtomic(cm, pos, bias, true);
2207
- // Otherwise, turn off editing until further notice, and return the start of the doc
2208
- cm.view.cantEdit = true;
2209
- return {line: 0, ch: 0};
2210
- }
2211
- flipped = true; newPos = pos; dir = -dir;
2212
- }
2213
- }
2214
- curPos = newPos;
2215
- continue search;
2216
- }
2217
- }
2218
- if (toClear) for (var i = 0; i < toClear.length; ++i) toClear[i].clear();
2219
- }
2220
- return curPos;
2221
- }
2222
- }
2223
-
2224
- // SCROLLING
2225
-
2226
- function scrollCursorIntoView(cm) {
2227
- var view = cm.view;
2228
- var coords = scrollPosIntoView(cm, view.sel.head);
2229
- if (!view.focused) return;
2230
- var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null;
2231
- if (coords.top + box.top < 0) doScroll = true;
2232
- else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false;
2233
- if (doScroll != null && !phantom) {
2234
- var hidden = display.cursor.style.display == "none";
2235
- if (hidden) {
2236
- display.cursor.style.display = "";
2237
- display.cursor.style.left = coords.left + "px";
2238
- display.cursor.style.top = (coords.top - display.viewOffset) + "px";
2239
- }
2240
- display.cursor.scrollIntoView(doScroll);
2241
- if (hidden) display.cursor.style.display = "none";
2242
- }
2243
- }
2244
-
2245
- function scrollPosIntoView(cm, pos) {
2246
- for (;;) {
2247
- var changed = false, coords = cursorCoords(cm, pos);
2248
- var scrollPos = calculateScrollPos(cm, coords.left, coords.top, coords.left, coords.bottom);
2249
- var startTop = cm.view.scrollTop, startLeft = cm.view.scrollLeft;
2250
- if (scrollPos.scrollTop != null) {
2251
- setScrollTop(cm, scrollPos.scrollTop);
2252
- if (Math.abs(cm.view.scrollTop - startTop) > 1) changed = true;
2253
- }
2254
- if (scrollPos.scrollLeft != null) {
2255
- setScrollLeft(cm, scrollPos.scrollLeft);
2256
- if (Math.abs(cm.view.scrollLeft - startLeft) > 1) changed = true;
2257
- }
2258
- if (!changed) return coords;
2259
- }
2260
- }
2261
-
2262
- function scrollIntoView(cm, x1, y1, x2, y2) {
2263
- var scrollPos = calculateScrollPos(cm, x1, y1, x2, y2);
2264
- if (scrollPos.scrollTop != null) setScrollTop(cm, scrollPos.scrollTop);
2265
- if (scrollPos.scrollLeft != null) setScrollLeft(cm, scrollPos.scrollLeft);
2266
- }
2267
-
2268
- function calculateScrollPos(cm, x1, y1, x2, y2) {
2269
- var display = cm.display, pt = paddingTop(display);
2270
- y1 += pt; y2 += pt;
2271
- var screen = display.scroller.clientHeight - scrollerCutOff, screentop = display.scroller.scrollTop, result = {};
2272
- var docBottom = cm.view.doc.height + 2 * pt;
2273
- var atTop = y1 < pt + 10, atBottom = y2 + pt > docBottom - 10;
2274
- if (y1 < screentop) result.scrollTop = atTop ? 0 : Math.max(0, y1);
2275
- else if (y2 > screentop + screen) result.scrollTop = (atBottom ? docBottom : y2) - screen;
2276
-
2277
- var screenw = display.scroller.clientWidth - scrollerCutOff, screenleft = display.scroller.scrollLeft;
2278
- x1 += display.gutters.offsetWidth; x2 += display.gutters.offsetWidth;
2279
- var gutterw = display.gutters.offsetWidth;
2280
- var atLeft = x1 < gutterw + 10;
2281
- if (x1 < screenleft + gutterw || atLeft) {
2282
- if (atLeft) x1 = 0;
2283
- result.scrollLeft = Math.max(0, x1 - 10 - gutterw);
2284
- } else if (x2 > screenw + screenleft - 3) {
2285
- result.scrollLeft = x2 + 10 - screenw;
2286
- }
2287
- return result;
2288
- }
2289
-
2290
- // API UTILITIES
2291
-
2292
- function indentLine(cm, n, how, aggressive) {
2293
- var doc = cm.view.doc;
2294
- if (!how) how = "add";
2295
- if (how == "smart") {
2296
- if (!cm.view.mode.indent) how = "prev";
2297
- else var state = getStateBefore(cm, n);
2298
- }
2299
-
2300
- var tabSize = cm.options.tabSize;
2301
- var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize);
2302
- var curSpaceString = line.text.match(/^\s*/)[0], indentation;
2303
- if (how == "smart") {
2304
- indentation = cm.view.mode.indent(state, line.text.slice(curSpaceString.length), line.text);
2305
- if (indentation == Pass) {
2306
- if (!aggressive) return;
2307
- how = "prev";
2308
- }
2309
- }
2310
- if (how == "prev") {
2311
- if (n) indentation = countColumn(getLine(doc, n-1).text, null, tabSize);
2312
- else indentation = 0;
2313
- }
2314
- else if (how == "add") indentation = curSpace + cm.options.indentUnit;
2315
- else if (how == "subtract") indentation = curSpace - cm.options.indentUnit;
2316
- indentation = Math.max(0, indentation);
2317
-
2318
- var indentString = "", pos = 0;
2319
- if (cm.options.indentWithTabs)
2320
- for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";}
2321
- if (pos < indentation) indentString += spaceStr(indentation - pos);
2322
-
2323
- if (indentString != curSpaceString)
2324
- replaceRange(cm, indentString, {line: n, ch: 0}, {line: n, ch: curSpaceString.length}, "input");
2325
- line.stateAfter = null;
2326
- }
2327
-
2328
- function changeLine(cm, handle, op) {
2329
- var no = handle, line = handle, doc = cm.view.doc;
2330
- if (typeof handle == "number") line = getLine(doc, clipLine(doc, handle));
2331
- else no = lineNo(handle);
2332
- if (no == null) return null;
2333
- if (op(line, no)) regChange(cm, no, no + 1);
2334
- else return null;
2335
- return line;
2336
- }
2337
-
2338
- function findPosH(cm, dir, unit, visually) {
2339
- var doc = cm.view.doc, end = cm.view.sel.head, line = end.line, ch = end.ch;
2340
- var lineObj = getLine(doc, line);
2341
- function findNextLine() {
2342
- var l = line + dir;
2343
- if (l < 0 || l == doc.size) return false;
2344
- line = l;
2345
- return lineObj = getLine(doc, l);
2346
- }
2347
- function moveOnce(boundToLine) {
2348
- var next = (visually ? moveVisually : moveLogically)(lineObj, ch, dir, true);
2349
- if (next == null) {
2350
- if (!boundToLine && findNextLine()) {
2351
- if (visually) ch = (dir < 0 ? lineRight : lineLeft)(lineObj);
2352
- else ch = dir < 0 ? lineObj.text.length : 0;
2353
- } else return false;
2354
- } else ch = next;
2355
- return true;
2356
- }
2357
- if (unit == "char") moveOnce();
2358
- else if (unit == "column") moveOnce(true);
2359
- else if (unit == "word") {
2360
- var sawWord = false;
2361
- for (;;) {
2362
- if (dir < 0) if (!moveOnce()) break;
2363
- if (isWordChar(lineObj.text.charAt(ch))) sawWord = true;
2364
- else if (sawWord) {if (dir < 0) {dir = 1; moveOnce();} break;}
2365
- if (dir > 0) if (!moveOnce()) break;
2366
- }
2367
- }
2368
- return skipAtomic(cm, {line: line, ch: ch}, dir, true);
2369
- }
2370
-
2371
- function findWordAt(line, pos) {
2372
- var start = pos.ch, end = pos.ch;
2373
- if (line) {
2374
- if (pos.after === false || end == line.length) --start; else ++end;
2375
- var startChar = line.charAt(start);
2376
- var check = isWordChar(startChar) ? isWordChar :
2377
- /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);} :
2378
- function(ch) {return !/\s/.test(ch) && !isWordChar(ch);};
2379
- while (start > 0 && check(line.charAt(start - 1))) --start;
2380
- while (end < line.length && check(line.charAt(end))) ++end;
2381
- }
2382
- return {from: {line: pos.line, ch: start}, to: {line: pos.line, ch: end}};
2383
- }
2384
-
2385
- function selectLine(cm, line) {
2386
- extendSelection(cm, {line: line, ch: 0}, clipPos(cm.view.doc, {line: line + 1, ch: 0}));
2387
- }
2388
-
2389
- // PROTOTYPE
2390
-
2391
- // The publicly visible API. Note that operation(null, f) means
2392
- // 'wrap f in an operation, performed on its `this` parameter'
2393
-
2394
- CodeMirror.prototype = {
2395
- getValue: function(lineSep) {
2396
- var text = [], doc = this.view.doc;
2397
- doc.iter(0, doc.size, function(line) { text.push(line.text); });
2398
- return text.join(lineSep || "\n");
2399
- },
2400
-
2401
- setValue: operation(null, function(code) {
2402
- var doc = this.view.doc, top = {line: 0, ch: 0}, lastLen = getLine(doc, doc.size-1).text.length;
2403
- updateDocInner(this, top, {line: doc.size - 1, ch: lastLen}, splitLines(code), top, top, "setValue");
2404
- }),
2405
-
2406
- getSelection: function(lineSep) { return this.getRange(this.view.sel.from, this.view.sel.to, lineSep); },
2407
-
2408
- replaceSelection: operation(null, function(code, collapse, origin) {
2409
- var sel = this.view.sel;
2410
- updateDoc(this, sel.from, sel.to, splitLines(code), collapse || "around", origin);
2411
- }),
2412
-
2413
- focus: function(){window.focus(); focusInput(this); onFocus(this); fastPoll(this);},
2414
-
2415
- setOption: function(option, value) {
2416
- var options = this.options, old = options[option];
2417
- if (options[option] == value && option != "mode") return;
2418
- options[option] = value;
2419
- if (optionHandlers.hasOwnProperty(option))
2420
- operation(this, optionHandlers[option])(this, value, old);
2421
- },
2422
-
2423
- getOption: function(option) {return this.options[option];},
2424
-
2425
- getMode: function() {return this.view.mode;},
2426
-
2427
- addKeyMap: function(map) {
2428
- this.view.keyMaps.push(map);
2429
- },
2430
-
2431
- removeKeyMap: function(map) {
2432
- var maps = this.view.keyMaps;
2433
- for (var i = 0; i < maps.length; ++i)
2434
- if ((typeof map == "string" ? maps[i].name : maps[i]) == map) {
2435
- maps.splice(i, 1);
2436
- return true;
2437
- }
2438
- },
2439
-
2440
- addOverlay: operation(null, function(spec, options) {
2441
- var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec);
2442
- if (mode.startState) throw new Error("Overlays may not be stateful.");
2443
- this.view.overlays.push({mode: mode, modeSpec: spec, opaque: options && options.opaque});
2444
- this.view.modeGen++;
2445
- regChange(this, 0, this.view.doc.size);
2446
- }),
2447
- removeOverlay: operation(null, function(spec) {
2448
- var overlays = this.view.overlays;
2449
- for (var i = 0; i < overlays.length; ++i) {
2450
- if (overlays[i].modeSpec == spec) {
2451
- overlays.splice(i, 1);
2452
- this.view.modeGen++;
2453
- regChange(this, 0, this.view.doc.size);
2454
- return;
2455
- }
2456
- }
2457
- }),
2458
-
2459
- undo: operation(null, function() {unredoHelper(this, "undo");}),
2460
- redo: operation(null, function() {unredoHelper(this, "redo");}),
2461
-
2462
- indentLine: operation(null, function(n, dir, aggressive) {
2463
- if (typeof dir != "string") {
2464
- if (dir == null) dir = this.options.smartIndent ? "smart" : "prev";
2465
- else dir = dir ? "add" : "subtract";
2466
- }
2467
- if (isLine(this.view.doc, n)) indentLine(this, n, dir, aggressive);
2468
- }),
2469
-
2470
- indentSelection: operation(null, function(how) {
2471
- var sel = this.view.sel;
2472
- if (posEq(sel.from, sel.to)) return indentLine(this, sel.from.line, how);
2473
- var e = sel.to.line - (sel.to.ch ? 0 : 1);
2474
- for (var i = sel.from.line; i <= e; ++i) indentLine(this, i, how);
2475
- }),
2476
-
2477
- historySize: function() {
2478
- var hist = this.view.history;
2479
- return {undo: hist.done.length, redo: hist.undone.length};
2480
- },
2481
-
2482
- clearHistory: function() {this.view.history = makeHistory();},
2483
-
2484
- markClean: function() {
2485
- this.view.history.dirtyCounter = 0;
2486
- this.view.history.lastOp = this.view.history.lastOrigin = null;
2487
- },
2488
-
2489
- isClean: function () {return this.view.history.dirtyCounter == 0;},
2490
-
2491
- getHistory: function() {
2492
- var hist = this.view.history;
2493
- function cp(arr) {
2494
- for (var i = 0, nw = [], nwelt; i < arr.length; ++i) {
2495
- var set = arr[i];
2496
- nw.push({events: nwelt = [], fromBefore: set.fromBefore, toBefore: set.toBefore,
2497
- fromAfter: set.fromAfter, toAfter: set.toAfter});
2498
- for (var j = 0, elt = set.events; j < elt.length; ++j) {
2499
- var old = [], cur = elt[j];
2500
- nwelt.push({start: cur.start, added: cur.added, old: old});
2501
- for (var k = 0; k < cur.old.length; ++k) old.push(hlText(cur.old[k]));
2502
- }
2503
- }
2504
- return nw;
2505
- }
2506
- return {done: cp(hist.done), undone: cp(hist.undone)};
2507
- },
2508
-
2509
- setHistory: function(histData) {
2510
- var hist = this.view.history = makeHistory();
2511
- hist.done = histData.done;
2512
- hist.undone = histData.undone;
2513
- },
2514
-
2515
- // Fetch the parser token for a given character. Useful for hacks
2516
- // that want to inspect the mode state (say, for completion).
2517
- getTokenAt: function(pos) {
2518
- var doc = this.view.doc;
2519
- pos = clipPos(doc, pos);
2520
- var state = getStateBefore(this, pos.line), mode = this.view.mode;
2521
- var line = getLine(doc, pos.line);
2522
- var stream = new StringStream(line.text, this.options.tabSize);
2523
- while (stream.pos < pos.ch && !stream.eol()) {
2524
- stream.start = stream.pos;
2525
- var style = mode.token(stream, state);
2526
- }
2527
- return {start: stream.start,
2528
- end: stream.pos,
2529
- string: stream.current(),
2530
- className: style || null, // Deprecated, use 'type' instead
2531
- type: style || null,
2532
- state: state};
2533
- },
2534
-
2535
- getStateAfter: function(line) {
2536
- var doc = this.view.doc;
2537
- line = clipLine(doc, line == null ? doc.size - 1: line);
2538
- return getStateBefore(this, line + 1);
2539
- },
2540
-
2541
- cursorCoords: function(start, mode) {
2542
- var pos, sel = this.view.sel;
2543
- if (start == null) pos = sel.head;
2544
- else if (typeof start == "object") pos = clipPos(this.view.doc, start);
2545
- else pos = start ? sel.from : sel.to;
2546
- return cursorCoords(this, pos, mode || "page");
2547
- },
2548
-
2549
- charCoords: function(pos, mode) {
2550
- return charCoords(this, clipPos(this.view.doc, pos), mode || "page");
2551
- },
2552
-
2553
- coordsChar: function(coords) {
2554
- var off = this.display.lineSpace.getBoundingClientRect();
2555
- return coordsChar(this, coords.left - off.left, coords.top - off.top);
2556
- },
2557
-
2558
- defaultTextHeight: function() { return textHeight(this.display); },
2559
-
2560
- markText: operation(null, function(from, to, options) {
2561
- return markText(this, clipPos(this.view.doc, from), clipPos(this.view.doc, to),
2562
- options, "range");
2563
- }),
2564
-
2565
- setBookmark: operation(null, function(pos, widget) {
2566
- pos = clipPos(this.view.doc, pos);
2567
- return markText(this, pos, pos, widget ? {replacedWith: widget} : {}, "bookmark");
2568
- }),
2569
-
2570
- findMarksAt: function(pos) {
2571
- var doc = this.view.doc;
2572
- pos = clipPos(doc, pos);
2573
- var markers = [], spans = getLine(doc, pos.line).markedSpans;
2574
- if (spans) for (var i = 0; i < spans.length; ++i) {
2575
- var span = spans[i];
2576
- if ((span.from == null || span.from <= pos.ch) &&
2577
- (span.to == null || span.to >= pos.ch))
2578
- markers.push(span.marker);
2579
- }
2580
- return markers;
2581
- },
2582
-
2583
- setGutterMarker: operation(null, function(line, gutterID, value) {
2584
- return changeLine(this, line, function(line) {
2585
- var markers = line.gutterMarkers || (line.gutterMarkers = {});
2586
- markers[gutterID] = value;
2587
- if (!value && isEmpty(markers)) line.gutterMarkers = null;
2588
- return true;
2589
- });
2590
- }),
2591
-
2592
- clearGutter: operation(null, function(gutterID) {
2593
- var i = 0, cm = this, doc = cm.view.doc;
2594
- doc.iter(0, doc.size, function(line) {
2595
- if (line.gutterMarkers && line.gutterMarkers[gutterID]) {
2596
- line.gutterMarkers[gutterID] = null;
2597
- regChange(cm, i, i + 1);
2598
- if (isEmpty(line.gutterMarkers)) line.gutterMarkers = null;
2599
- }
2600
- ++i;
2601
- });
2602
- }),
2603
-
2604
- addLineClass: operation(null, function(handle, where, cls) {
2605
- return changeLine(this, handle, function(line) {
2606
- var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass";
2607
- if (!line[prop]) line[prop] = cls;
2608
- else if (new RegExp("\\b" + cls + "\\b").test(line[prop])) return false;
2609
- else line[prop] += " " + cls;
2610
- return true;
2611
- });
2612
- }),
2613
-
2614
- removeLineClass: operation(null, function(handle, where, cls) {
2615
- return changeLine(this, handle, function(line) {
2616
- var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass";
2617
- var cur = line[prop];
2618
- if (!cur) return false;
2619
- else if (cls == null) line[prop] = null;
2620
- else {
2621
- var upd = cur.replace(new RegExp("^" + cls + "\\b\\s*|\\s*\\b" + cls + "\\b"), "");
2622
- if (upd == cur) return false;
2623
- line[prop] = upd || null;
2624
- }
2625
- return true;
2626
- });
2627
- }),
2628
-
2629
- addLineWidget: operation(null, function(handle, node, options) {
2630
- return addLineWidget(this, handle, node, options);
2631
- }),
2632
-
2633
- removeLineWidget: function(widget) { widget.clear(); },
2634
-
2635
- lineInfo: function(line) {
2636
- if (typeof line == "number") {
2637
- if (!isLine(this.view.doc, line)) return null;
2638
- var n = line;
2639
- line = getLine(this.view.doc, line);
2640
- if (!line) return null;
2641
- } else {
2642
- var n = lineNo(line);
2643
- if (n == null) return null;
2644
- }
2645
- return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers,
2646
- textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass,
2647
- widgets: line.widgets};
2648
- },
2649
-
2650
- getViewport: function() { return {from: this.display.showingFrom, to: this.display.showingTo};},
2651
-
2652
- addWidget: function(pos, node, scroll, vert, horiz) {
2653
- var display = this.display;
2654
- pos = cursorCoords(this, clipPos(this.view.doc, pos));
2655
- var top = pos.top, left = pos.left;
2656
- node.style.position = "absolute";
2657
- display.sizer.appendChild(node);
2658
- if (vert == "over") top = pos.top;
2659
- else if (vert == "near") {
2660
- var vspace = Math.max(display.wrapper.clientHeight, this.view.doc.height),
2661
- hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth);
2662
- if (pos.bottom + node.offsetHeight > vspace && pos.top > node.offsetHeight)
2663
- top = pos.top - node.offsetHeight;
2664
- if (left + node.offsetWidth > hspace)
2665
- left = hspace - node.offsetWidth;
2666
- }
2667
- node.style.top = (top + paddingTop(display)) + "px";
2668
- node.style.left = node.style.right = "";
2669
- if (horiz == "right") {
2670
- left = display.sizer.clientWidth - node.offsetWidth;
2671
- node.style.right = "0px";
2672
- } else {
2673
- if (horiz == "left") left = 0;
2674
- else if (horiz == "middle") left = (display.sizer.clientWidth - node.offsetWidth) / 2;
2675
- node.style.left = left + "px";
2676
- }
2677
- if (scroll)
2678
- scrollIntoView(this, left, top, left + node.offsetWidth, top + node.offsetHeight);
2679
- },
2680
-
2681
- lineCount: function() {return this.view.doc.size;},
2682
-
2683
- clipPos: function(pos) {return clipPos(this.view.doc, pos);},
2684
-
2685
- getCursor: function(start) {
2686
- var sel = this.view.sel, pos;
2687
- if (start == null || start == "head") pos = sel.head;
2688
- else if (start == "anchor") pos = sel.anchor;
2689
- else if (start == "end" || start === false) pos = sel.to;
2690
- else pos = sel.from;
2691
- return copyPos(pos);
2692
- },
2693
-
2694
- somethingSelected: function() {return !posEq(this.view.sel.from, this.view.sel.to);},
2695
-
2696
- setCursor: operation(null, function(line, ch, extend) {
2697
- var pos = clipPos(this.view.doc, typeof line == "number" ? {line: line, ch: ch || 0} : line);
2698
- if (extend) extendSelection(this, pos);
2699
- else setSelection(this, pos, pos);
2700
- }),
2701
-
2702
- setSelection: operation(null, function(anchor, head) {
2703
- var doc = this.view.doc;
2704
- setSelection(this, clipPos(doc, anchor), clipPos(doc, head || anchor));
2705
- }),
2706
-
2707
- extendSelection: operation(null, function(from, to) {
2708
- var doc = this.view.doc;
2709
- extendSelection(this, clipPos(doc, from), to && clipPos(doc, to));
2710
- }),
2711
-
2712
- setExtending: function(val) {this.view.sel.extend = val;},
2713
-
2714
- getLine: function(line) {var l = this.getLineHandle(line); return l && l.text;},
2715
-
2716
- getLineHandle: function(line) {
2717
- var doc = this.view.doc;
2718
- if (isLine(doc, line)) return getLine(doc, line);
2719
- },
2720
-
2721
- getLineNumber: function(line) {return lineNo(line);},
2722
-
2723
- setLine: operation(null, function(line, text) {
2724
- if (isLine(this.view.doc, line))
2725
- replaceRange(this, text, {line: line, ch: 0}, {line: line, ch: getLine(this.view.doc, line).text.length});
2726
- }),
2727
-
2728
- removeLine: operation(null, function(line) {
2729
- if (isLine(this.view.doc, line))
2730
- replaceRange(this, "", {line: line, ch: 0}, clipPos(this.view.doc, {line: line+1, ch: 0}));
2731
- }),
2732
-
2733
- replaceRange: operation(null, function(code, from, to) {
2734
- var doc = this.view.doc;
2735
- from = clipPos(doc, from);
2736
- to = to ? clipPos(doc, to) : from;
2737
- return replaceRange(this, code, from, to);
2738
- }),
2739
-
2740
- getRange: function(from, to, lineSep) {
2741
- var doc = this.view.doc;
2742
- from = clipPos(doc, from); to = clipPos(doc, to);
2743
- var l1 = from.line, l2 = to.line;
2744
- if (l1 == l2) return getLine(doc, l1).text.slice(from.ch, to.ch);
2745
- var code = [getLine(doc, l1).text.slice(from.ch)];
2746
- doc.iter(l1 + 1, l2, function(line) { code.push(line.text); });
2747
- code.push(getLine(doc, l2).text.slice(0, to.ch));
2748
- return code.join(lineSep || "\n");
2749
- },
2750
-
2751
- triggerOnKeyDown: operation(null, onKeyDown),
2752
-
2753
- execCommand: function(cmd) {return commands[cmd](this);},
2754
-
2755
- // Stuff used by commands, probably not much use to outside code.
2756
- moveH: operation(null, function(dir, unit) {
2757
- var sel = this.view.sel, pos = dir < 0 ? sel.from : sel.to;
2758
- if (sel.shift || sel.extend || posEq(sel.from, sel.to))
2759
- pos = findPosH(this, dir, unit, this.options.rtlMoveVisually);
2760
- extendSelection(this, pos, pos, dir);
2761
- }),
2762
-
2763
- deleteH: operation(null, function(dir, unit) {
2764
- var sel = this.view.sel;
2765
- if (!posEq(sel.from, sel.to)) replaceRange(this, "", sel.from, sel.to, "delete");
2766
- else replaceRange(this, "", sel.from, findPosH(this, dir, unit, false), "delete");
2767
- this.curOp.userSelChange = true;
2768
- }),
2769
-
2770
- moveV: operation(null, function(dir, unit) {
2771
- var view = this.view, doc = view.doc, display = this.display;
2772
- var cur = view.sel.head, pos = cursorCoords(this, cur, "div");
2773
- var x = pos.left, y;
2774
- if (view.goalColumn != null) x = view.goalColumn;
2775
- if (unit == "page") {
2776
- var pageSize = Math.min(display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight);
2777
- y = pos.top + dir * pageSize;
2778
- } else if (unit == "line") {
2779
- y = dir > 0 ? pos.bottom + 3 : pos.top - 3;
2780
- }
2781
- do {
2782
- var target = coordsChar(this, x, y);
2783
- y += dir * 5;
2784
- } while (target.outside && (dir < 0 ? y > 0 : y < doc.height));
2785
-
2786
- if (unit == "page") display.scrollbarV.scrollTop += charCoords(this, target, "div").top - pos.top;
2787
- extendSelection(this, target, target, dir);
2788
- view.goalColumn = x;
2789
- }),
2790
-
2791
- toggleOverwrite: function() {
2792
- if (this.view.overwrite = !this.view.overwrite)
2793
- this.display.cursor.className += " CodeMirror-overwrite";
2794
- else
2795
- this.display.cursor.className = this.display.cursor.className.replace(" CodeMirror-overwrite", "");
2796
- },
2797
-
2798
- posFromIndex: function(off) {
2799
- var lineNo = 0, ch, doc = this.view.doc;
2800
- doc.iter(0, doc.size, function(line) {
2801
- var sz = line.text.length + 1;
2802
- if (sz > off) { ch = off; return true; }
2803
- off -= sz;
2804
- ++lineNo;
2805
- });
2806
- return clipPos(doc, {line: lineNo, ch: ch});
2807
- },
2808
- indexFromPos: function (coords) {
2809
- coords = clipPos(this.view.doc, coords);
2810
- var index = coords.ch;
2811
- this.view.doc.iter(0, coords.line, function (line) {
2812
- index += line.text.length + 1;
2813
- });
2814
- return index;
2815
- },
2816
-
2817
- scrollTo: function(x, y) {
2818
- if (x != null) this.display.scrollbarH.scrollLeft = this.display.scroller.scrollLeft = x;
2819
- if (y != null) this.display.scrollbarV.scrollTop = this.display.scroller.scrollTop = y;
2820
- updateDisplay(this, []);
2821
- },
2822
- getScrollInfo: function() {
2823
- var scroller = this.display.scroller, co = scrollerCutOff;
2824
- return {left: scroller.scrollLeft, top: scroller.scrollTop,
2825
- height: scroller.scrollHeight - co, width: scroller.scrollWidth - co,
2826
- clientHeight: scroller.clientHeight - co, clientWidth: scroller.clientWidth - co};
2827
- },
2828
-
2829
- scrollIntoView: function(pos) {
2830
- if (typeof pos == "number") pos = {line: pos, ch: 0};
2831
- if (!pos || pos.line != null) {
2832
- pos = pos ? clipPos(this.view.doc, pos) : this.view.sel.head;
2833
- scrollPosIntoView(this, pos);
2834
- } else {
2835
- scrollIntoView(this, pos.left, pos.top, pos.right, pos.bottom);
2836
- }
2837
- },
2838
-
2839
- setSize: function(width, height) {
2840
- function interpret(val) {
2841
- return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val;
2842
- }
2843
- if (width != null) this.display.wrapper.style.width = interpret(width);
2844
- if (height != null) this.display.wrapper.style.height = interpret(height);
2845
- this.refresh();
2846
- },
2847
-
2848
- on: function(type, f) {on(this, type, f);},
2849
- off: function(type, f) {off(this, type, f);},
2850
-
2851
- operation: function(f){return operation(this, f)();},
2852
-
2853
- refresh: function() {
2854
- clearCaches(this);
2855
- var sTop = this.view.scrollTop, sLeft = this.view.scrollLeft;
2856
- if (this.display.scroller.scrollHeight > sTop)
2857
- this.display.scrollbarV.scrollTop = this.display.scroller.scrollTop = sTop;
2858
- if (this.display.scroller.scrollWidth > sLeft)
2859
- this.display.scrollbarH.scrollLeft = this.display.scroller.scrollLeft = sLeft;
2860
- updateDisplay(this, true);
2861
- },
2862
-
2863
- getInputField: function(){return this.display.input;},
2864
- getWrapperElement: function(){return this.display.wrapper;},
2865
- getScrollerElement: function(){return this.display.scroller;},
2866
- getGutterElement: function(){return this.display.gutters;}
2867
- };
2868
-
2869
- // OPTION DEFAULTS
2870
-
2871
- var optionHandlers = CodeMirror.optionHandlers = {};
2872
-
2873
- // The default configuration options.
2874
- var defaults = CodeMirror.defaults = {};
2875
-
2876
- function option(name, deflt, handle, notOnInit) {
2877
- CodeMirror.defaults[name] = deflt;
2878
- if (handle) optionHandlers[name] =
2879
- notOnInit ? function(cm, val, old) {if (old != Init) handle(cm, val, old);} : handle;
2880
- }
2881
-
2882
- var Init = CodeMirror.Init = {toString: function(){return "CodeMirror.Init";}};
2883
-
2884
- // These two are, on init, called from the constructor because they
2885
- // have to be initialized before the editor can start at all.
2886
- option("value", "", function(cm, val) {cm.setValue(val);}, true);
2887
- option("mode", null, loadMode, true);
2888
-
2889
- option("indentUnit", 2, loadMode, true);
2890
- option("indentWithTabs", false);
2891
- option("smartIndent", true);
2892
- option("tabSize", 4, function(cm) {
2893
- loadMode(cm);
2894
- clearCaches(cm);
2895
- updateDisplay(cm, true);
2896
- }, true);
2897
- option("electricChars", true);
2898
- option("rtlMoveVisually", !windows);
2899
-
2900
- option("theme", "default", function(cm) {
2901
- themeChanged(cm);
2902
- guttersChanged(cm);
2903
- }, true);
2904
- option("keyMap", "default", keyMapChanged);
2905
- option("extraKeys", null);
2906
-
2907
- option("onKeyEvent", null);
2908
- option("onDragEvent", null);
2909
-
2910
- option("lineWrapping", false, wrappingChanged, true);
2911
- option("gutters", [], function(cm) {
2912
- setGuttersForLineNumbers(cm.options);
2913
- guttersChanged(cm);
2914
- }, true);
2915
- option("fixedGutter", true, function(cm, val) {
2916
- cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0";
2917
- cm.refresh();
2918
- }, true);
2919
- option("lineNumbers", false, function(cm) {
2920
- setGuttersForLineNumbers(cm.options);
2921
- guttersChanged(cm);
2922
- }, true);
2923
- option("firstLineNumber", 1, guttersChanged, true);
2924
- option("lineNumberFormatter", function(integer) {return integer;}, guttersChanged, true);
2925
- option("showCursorWhenSelecting", false, updateSelection, true);
2926
-
2927
- option("readOnly", false, function(cm, val) {
2928
- if (val == "nocursor") {onBlur(cm); cm.display.input.blur();}
2929
- else if (!val) resetInput(cm, true);
2930
- });
2931
- option("dragDrop", true);
2932
-
2933
- option("cursorBlinkRate", 530);
2934
- option("cursorHeight", 1);
2935
- option("workTime", 100);
2936
- option("workDelay", 100);
2937
- option("flattenSpans", true);
2938
- option("pollInterval", 100);
2939
- option("undoDepth", 40);
2940
- option("viewportMargin", 10, function(cm){cm.refresh();}, true);
2941
-
2942
- option("tabindex", null, function(cm, val) {
2943
- cm.display.input.tabIndex = val || "";
2944
- });
2945
- option("autofocus", null);
2946
-
2947
- // MODE DEFINITION AND QUERYING
2948
-
2949
- // Known modes, by name and by MIME
2950
- var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
2951
-
2952
- CodeMirror.defineMode = function(name, mode) {
2953
- if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name;
2954
- if (arguments.length > 2) {
2955
- mode.dependencies = [];
2956
- for (var i = 2; i < arguments.length; ++i) mode.dependencies.push(arguments[i]);
2957
- }
2958
- modes[name] = mode;
2959
- };
2960
-
2961
- CodeMirror.defineMIME = function(mime, spec) {
2962
- mimeModes[mime] = spec;
2963
- };
2964
-
2965
- CodeMirror.resolveMode = function(spec) {
2966
- if (typeof spec == "string" && mimeModes.hasOwnProperty(spec))
2967
- spec = mimeModes[spec];
2968
- else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec))
2969
- return CodeMirror.resolveMode("application/xml");
2970
- if (typeof spec == "string") return {name: spec};
2971
- else return spec || {name: "null"};
2972
- };
2973
-
2974
- CodeMirror.getMode = function(options, spec) {
2975
- spec = CodeMirror.resolveMode(spec);
2976
- var mfactory = modes[spec.name];
2977
- if (!mfactory) return CodeMirror.getMode(options, "text/plain");
2978
- var modeObj = mfactory(options, spec);
2979
- if (modeExtensions.hasOwnProperty(spec.name)) {
2980
- var exts = modeExtensions[spec.name];
2981
- for (var prop in exts) {
2982
- if (!exts.hasOwnProperty(prop)) continue;
2983
- if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop];
2984
- modeObj[prop] = exts[prop];
2985
- }
2986
- }
2987
- modeObj.name = spec.name;
2988
- return modeObj;
2989
- };
2990
-
2991
- CodeMirror.defineMode("null", function() {
2992
- return {token: function(stream) {stream.skipToEnd();}};
2993
- });
2994
- CodeMirror.defineMIME("text/plain", "null");
2995
-
2996
- var modeExtensions = CodeMirror.modeExtensions = {};
2997
- CodeMirror.extendMode = function(mode, properties) {
2998
- var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
2999
- for (var prop in properties) if (properties.hasOwnProperty(prop))
3000
- exts[prop] = properties[prop];
3001
- };
3002
-
3003
- // EXTENSIONS
3004
-
3005
- CodeMirror.defineExtension = function(name, func) {
3006
- CodeMirror.prototype[name] = func;
3007
- };
3008
-
3009
- CodeMirror.defineOption = option;
3010
-
3011
- var initHooks = [];
3012
- CodeMirror.defineInitHook = function(f) {initHooks.push(f);};
3013
-
3014
- // MODE STATE HANDLING
3015
-
3016
- // Utility functions for working with state. Exported because modes
3017
- // sometimes need to do this.
3018
- function copyState(mode, state) {
3019
- if (state === true) return state;
3020
- if (mode.copyState) return mode.copyState(state);
3021
- var nstate = {};
3022
- for (var n in state) {
3023
- var val = state[n];
3024
- if (val instanceof Array) val = val.concat([]);
3025
- nstate[n] = val;
3026
- }
3027
- return nstate;
3028
- }
3029
- CodeMirror.copyState = copyState;
3030
-
3031
- function startState(mode, a1, a2) {
3032
- return mode.startState ? mode.startState(a1, a2) : true;
3033
- }
3034
- CodeMirror.startState = startState;
3035
-
3036
- CodeMirror.innerMode = function(mode, state) {
3037
- while (mode.innerMode) {
3038
- var info = mode.innerMode(state);
3039
- state = info.state;
3040
- mode = info.mode;
3041
- }
3042
- return info || {mode: mode, state: state};
3043
- };
3044
-
3045
- // STANDARD COMMANDS
3046
-
3047
- var commands = CodeMirror.commands = {
3048
- selectAll: function(cm) {cm.setSelection({line: 0, ch: 0}, {line: cm.lineCount() - 1});},
3049
- killLine: function(cm) {
3050
- var from = cm.getCursor(true), to = cm.getCursor(false), sel = !posEq(from, to);
3051
- if (!sel && cm.getLine(from.line).length == from.ch)
3052
- cm.replaceRange("", from, {line: from.line + 1, ch: 0}, "delete");
3053
- else cm.replaceRange("", from, sel ? to : {line: from.line}, "delete");
3054
- },
3055
- deleteLine: function(cm) {
3056
- var l = cm.getCursor().line;
3057
- cm.replaceRange("", {line: l, ch: 0}, {line: l}, "delete");
3058
- },
3059
- undo: function(cm) {cm.undo();},
3060
- redo: function(cm) {cm.redo();},
3061
- goDocStart: function(cm) {cm.extendSelection({line: 0, ch: 0});},
3062
- goDocEnd: function(cm) {cm.extendSelection({line: cm.lineCount() - 1});},
3063
- goLineStart: function(cm) {
3064
- cm.extendSelection(lineStart(cm, cm.getCursor().line));
3065
- },
3066
- goLineStartSmart: function(cm) {
3067
- var cur = cm.getCursor(), start = lineStart(cm, cur.line);
3068
- var line = cm.getLineHandle(start.line);
3069
- var order = getOrder(line);
3070
- if (!order || order[0].level == 0) {
3071
- var firstNonWS = Math.max(0, line.text.search(/\S/));
3072
- var inWS = cur.line == start.line && cur.ch <= firstNonWS && cur.ch;
3073
- cm.extendSelection({line: start.line, ch: inWS ? 0 : firstNonWS});
3074
- } else cm.extendSelection(start);
3075
- },
3076
- goLineEnd: function(cm) {
3077
- cm.extendSelection(lineEnd(cm, cm.getCursor().line));
3078
- },
3079
- goLineUp: function(cm) {cm.moveV(-1, "line");},
3080
- goLineDown: function(cm) {cm.moveV(1, "line");},
3081
- goPageUp: function(cm) {cm.moveV(-1, "page");},
3082
- goPageDown: function(cm) {cm.moveV(1, "page");},
3083
- goCharLeft: function(cm) {cm.moveH(-1, "char");},
3084
- goCharRight: function(cm) {cm.moveH(1, "char");},
3085
- goColumnLeft: function(cm) {cm.moveH(-1, "column");},
3086
- goColumnRight: function(cm) {cm.moveH(1, "column");},
3087
- goWordLeft: function(cm) {cm.moveH(-1, "word");},
3088
- goWordRight: function(cm) {cm.moveH(1, "word");},
3089
- delCharBefore: function(cm) {cm.deleteH(-1, "char");},
3090
- delCharAfter: function(cm) {cm.deleteH(1, "char");},
3091
- delWordBefore: function(cm) {cm.deleteH(-1, "word");},
3092
- delWordAfter: function(cm) {cm.deleteH(1, "word");},
3093
- indentAuto: function(cm) {cm.indentSelection("smart");},
3094
- indentMore: function(cm) {cm.indentSelection("add");},
3095
- indentLess: function(cm) {cm.indentSelection("subtract");},
3096
- insertTab: function(cm) {cm.replaceSelection("\t", "end", "input");},
3097
- defaultTab: function(cm) {
3098
- if (cm.somethingSelected()) cm.indentSelection("add");
3099
- else cm.replaceSelection("\t", "end", "input");
3100
- },
3101
- transposeChars: function(cm) {
3102
- var cur = cm.getCursor(), line = cm.getLine(cur.line);
3103
- if (cur.ch > 0 && cur.ch < line.length - 1)
3104
- cm.replaceRange(line.charAt(cur.ch) + line.charAt(cur.ch - 1),
3105
- {line: cur.line, ch: cur.ch - 1}, {line: cur.line, ch: cur.ch + 1});
3106
- },
3107
- newlineAndIndent: function(cm) {
3108
- operation(cm, function() {
3109
- cm.replaceSelection("\n", "end", "input");
3110
- cm.indentLine(cm.getCursor().line, null, true);
3111
- })();
3112
- },
3113
- toggleOverwrite: function(cm) {cm.toggleOverwrite();}
3114
- };
3115
-
3116
- // STANDARD KEYMAPS
3117
-
3118
- var keyMap = CodeMirror.keyMap = {};
3119
- keyMap.basic = {
3120
- "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown",
3121
- "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown",
3122
- "Delete": "delCharAfter", "Backspace": "delCharBefore", "Tab": "defaultTab", "Shift-Tab": "indentAuto",
3123
- "Enter": "newlineAndIndent", "Insert": "toggleOverwrite"
3124
- };
3125
- // Note that the save and find-related commands aren't defined by
3126
- // default. Unknown commands are simply ignored.
3127
- keyMap.pcDefault = {
3128
- "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo",
3129
- "Ctrl-Home": "goDocStart", "Alt-Up": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Down": "goDocEnd",
3130
- "Ctrl-Left": "goWordLeft", "Ctrl-Right": "goWordRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd",
3131
- "Ctrl-Backspace": "delWordBefore", "Ctrl-Delete": "delWordAfter", "Ctrl-S": "save", "Ctrl-F": "find",
3132
- "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
3133
- "Ctrl-[": "indentLess", "Ctrl-]": "indentMore",
3134
- fallthrough: "basic"
3135
- };
3136
- keyMap.macDefault = {
3137
- "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo",
3138
- "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goWordLeft",
3139
- "Alt-Right": "goWordRight", "Cmd-Left": "goLineStart", "Cmd-Right": "goLineEnd", "Alt-Backspace": "delWordBefore",
3140
- "Ctrl-Alt-Backspace": "delWordAfter", "Alt-Delete": "delWordAfter", "Cmd-S": "save", "Cmd-F": "find",
3141
- "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
3142
- "Cmd-[": "indentLess", "Cmd-]": "indentMore",
3143
- fallthrough: ["basic", "emacsy"]
3144
- };
3145
- keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault;
3146
- keyMap.emacsy = {
3147
- "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
3148
- "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
3149
- "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore",
3150
- "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars"
3151
- };
3152
-
3153
- // KEYMAP DISPATCH
3154
-
3155
- function getKeyMap(val) {
3156
- if (typeof val == "string") return keyMap[val];
3157
- else return val;
3158
- }
3159
-
3160
- function lookupKey(name, maps, handle, stop) {
3161
- function lookup(map) {
3162
- map = getKeyMap(map);
3163
- var found = map[name];
3164
- if (found === false) {
3165
- if (stop) stop();
3166
- return true;
3167
- }
3168
- if (found != null && handle(found)) return true;
3169
- if (map.nofallthrough) {
3170
- if (stop) stop();
3171
- return true;
3172
- }
3173
- var fallthrough = map.fallthrough;
3174
- if (fallthrough == null) return false;
3175
- if (Object.prototype.toString.call(fallthrough) != "[object Array]")
3176
- return lookup(fallthrough);
3177
- for (var i = 0, e = fallthrough.length; i < e; ++i) {
3178
- if (lookup(fallthrough[i])) return true;
3179
- }
3180
- return false;
3181
- }
3182
-
3183
- for (var i = 0; i < maps.length; ++i)
3184
- if (lookup(maps[i])) return true;
3185
- }
3186
- function isModifierKey(event) {
3187
- var name = keyNames[e_prop(event, "keyCode")];
3188
- return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod";
3189
- }
3190
- CodeMirror.isModifierKey = isModifierKey;
3191
-
3192
- // FROMTEXTAREA
3193
-
3194
- CodeMirror.fromTextArea = function(textarea, options) {
3195
- if (!options) options = {};
3196
- options.value = textarea.value;
3197
- if (!options.tabindex && textarea.tabindex)
3198
- options.tabindex = textarea.tabindex;
3199
- // Set autofocus to true if this textarea is focused, or if it has
3200
- // autofocus and no other element is focused.
3201
- if (options.autofocus == null) {
3202
- var hasFocus = document.body;
3203
- // doc.activeElement occasionally throws on IE
3204
- try { hasFocus = document.activeElement; } catch(e) {}
3205
- options.autofocus = hasFocus == textarea ||
3206
- textarea.getAttribute("autofocus") != null && hasFocus == document.body;
3207
- }
3208
-
3209
- function save() {textarea.value = cm.getValue();}
3210
- if (textarea.form) {
3211
- // Deplorable hack to make the submit method do the right thing.
3212
- on(textarea.form, "submit", save);
3213
- var form = textarea.form, realSubmit = form.submit;
3214
- try {
3215
- form.submit = function wrappedSubmit() {
3216
- save();
3217
- form.submit = realSubmit;
3218
- form.submit();
3219
- form.submit = wrappedSubmit;
3220
- };
3221
- } catch(e) {}
3222
- }
3223
-
3224
- textarea.style.display = "none";
3225
- var cm = CodeMirror(function(node) {
3226
- textarea.parentNode.insertBefore(node, textarea.nextSibling);
3227
- }, options);
3228
- cm.save = save;
3229
- cm.getTextArea = function() { return textarea; };
3230
- cm.toTextArea = function() {
3231
- save();
3232
- textarea.parentNode.removeChild(cm.getWrapperElement());
3233
- textarea.style.display = "";
3234
- if (textarea.form) {
3235
- off(textarea.form, "submit", save);
3236
- if (typeof textarea.form.submit == "function")
3237
- textarea.form.submit = realSubmit;
3238
- }
3239
- };
3240
- return cm;
3241
- };
3242
-
3243
- // STRING STREAM
3244
-
3245
- // Fed to the mode parsers, provides helper functions to make
3246
- // parsers more succinct.
3247
-
3248
- // The character stream used by a mode's parser.
3249
- function StringStream(string, tabSize) {
3250
- this.pos = this.start = 0;
3251
- this.string = string;
3252
- this.tabSize = tabSize || 8;
3253
- }
3254
-
3255
- StringStream.prototype = {
3256
- eol: function() {return this.pos >= this.string.length;},
3257
- sol: function() {return this.pos == 0;},
3258
- peek: function() {return this.string.charAt(this.pos) || undefined;},
3259
- next: function() {
3260
- if (this.pos < this.string.length)
3261
- return this.string.charAt(this.pos++);
3262
- },
3263
- eat: function(match) {
3264
- var ch = this.string.charAt(this.pos);
3265
- if (typeof match == "string") var ok = ch == match;
3266
- else var ok = ch && (match.test ? match.test(ch) : match(ch));
3267
- if (ok) {++this.pos; return ch;}
3268
- },
3269
- eatWhile: function(match) {
3270
- var start = this.pos;
3271
- while (this.eat(match)){}
3272
- return this.pos > start;
3273
- },
3274
- eatSpace: function() {
3275
- var start = this.pos;
3276
- while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
3277
- return this.pos > start;
3278
- },
3279
- skipToEnd: function() {this.pos = this.string.length;},
3280
- skipTo: function(ch) {
3281
- var found = this.string.indexOf(ch, this.pos);
3282
- if (found > -1) {this.pos = found; return true;}
3283
- },
3284
- backUp: function(n) {this.pos -= n;},
3285
- column: function() {return countColumn(this.string, this.start, this.tabSize);},
3286
- indentation: function() {return countColumn(this.string, null, this.tabSize);},
3287
- match: function(pattern, consume, caseInsensitive) {
3288
- if (typeof pattern == "string") {
3289
- var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
3290
- if (cased(this.string).indexOf(cased(pattern), this.pos) == this.pos) {
3291
- if (consume !== false) this.pos += pattern.length;
3292
- return true;
3293
- }
3294
- } else {
3295
- var match = this.string.slice(this.pos).match(pattern);
3296
- if (match && match.index > 0) return null;
3297
- if (match && consume !== false) this.pos += match[0].length;
3298
- return match;
3299
- }
3300
- },
3301
- current: function(){return this.string.slice(this.start, this.pos);}
3302
- };
3303
- CodeMirror.StringStream = StringStream;
3304
-
3305
- // TEXTMARKERS
3306
-
3307
- function TextMarker(cm, type) {
3308
- this.lines = [];
3309
- this.type = type;
3310
- this.cm = cm;
3311
- }
3312
- CodeMirror.TextMarker = TextMarker;
3313
-
3314
- TextMarker.prototype.clear = function() {
3315
- if (this.explicitlyCleared) return;
3316
- startOperation(this.cm);
3317
- var view = this.cm.view, min = null, max = null;
3318
- for (var i = 0; i < this.lines.length; ++i) {
3319
- var line = this.lines[i];
3320
- var span = getMarkedSpanFor(line.markedSpans, this);
3321
- if (span.to != null) max = lineNo(line);
3322
- line.markedSpans = removeMarkedSpan(line.markedSpans, span);
3323
- if (span.from != null)
3324
- min = lineNo(line);
3325
- else if (this.collapsed && !lineIsHidden(line))
3326
- updateLineHeight(line, textHeight(this.cm.display));
3327
- }
3328
- if (this.collapsed && !this.cm.options.lineWrapping) for (var i = 0; i < this.lines.length; ++i) {
3329
- var visual = visualLine(view.doc, this.lines[i]), len = lineLength(view.doc, visual);
3330
- if (len > view.maxLineLength) {
3331
- view.maxLine = visual;
3332
- view.maxLineLength = len;
3333
- view.maxLineChanged = true;
3334
- }
3335
- }
3336
-
3337
- if (min != null) regChange(this.cm, min, max + 1);
3338
- this.lines.length = 0;
3339
- this.explicitlyCleared = true;
3340
- if (this.collapsed && this.cm.view.cantEdit) {
3341
- this.cm.view.cantEdit = false;
3342
- reCheckSelection(this.cm);
3343
- }
3344
- endOperation(this.cm);
3345
- signalLater(this.cm, this, "clear");
3346
- };
3347
-
3348
- TextMarker.prototype.find = function() {
3349
- var from, to;
3350
- for (var i = 0; i < this.lines.length; ++i) {
3351
- var line = this.lines[i];
3352
- var span = getMarkedSpanFor(line.markedSpans, this);
3353
- if (span.from != null || span.to != null) {
3354
- var found = lineNo(line);
3355
- if (span.from != null) from = {line: found, ch: span.from};
3356
- if (span.to != null) to = {line: found, ch: span.to};
3357
- }
3358
- }
3359
- if (this.type == "bookmark") return from;
3360
- return from && {from: from, to: to};
3361
- };
3362
-
3363
- TextMarker.prototype.getOptions = function(copyWidget) {
3364
- var repl = this.replacedWith;
3365
- return {className: this.className,
3366
- inclusiveLeft: this.inclusiveLeft, inclusiveRight: this.inclusiveRight,
3367
- atomic: this.atomic,
3368
- collapsed: this.collapsed,
3369
- clearOnEnter: this.clearOnEnter,
3370
- replacedWith: copyWidget ? repl && repl.cloneNode(true) : repl,
3371
- readOnly: this.readOnly,
3372
- startStyle: this.startStyle, endStyle: this.endStyle};
3373
- };
3374
-
3375
- function markText(cm, from, to, options, type) {
3376
- var doc = cm.view.doc;
3377
- var marker = new TextMarker(cm, type);
3378
- if (type == "range" && !posLess(from, to)) return marker;
3379
- if (options) for (var opt in options) if (options.hasOwnProperty(opt))
3380
- marker[opt] = options[opt];
3381
- if (marker.replacedWith) {
3382
- marker.collapsed = true;
3383
- marker.replacedWith = elt("span", [marker.replacedWith], "CodeMirror-widget");
3384
- }
3385
- if (marker.collapsed) sawCollapsedSpans = true;
3386
-
3387
- var curLine = from.line, size = 0, collapsedAtStart, collapsedAtEnd;
3388
- doc.iter(curLine, to.line + 1, function(line) {
3389
- if (marker.collapsed && !cm.options.lineWrapping && visualLine(doc, line) == cm.view.maxLine)
3390
- cm.curOp.updateMaxLine = true;
3391
- var span = {from: null, to: null, marker: marker};
3392
- size += line.text.length;
3393
- if (curLine == from.line) {span.from = from.ch; size -= from.ch;}
3394
- if (curLine == to.line) {span.to = to.ch; size -= line.text.length - to.ch;}
3395
- if (marker.collapsed) {
3396
- if (curLine == to.line) collapsedAtEnd = collapsedSpanAt(line, to.ch);
3397
- if (curLine == from.line) collapsedAtStart = collapsedSpanAt(line, from.ch);
3398
- else updateLineHeight(line, 0);
3399
- }
3400
- addMarkedSpan(line, span);
3401
- ++curLine;
3402
- });
3403
- if (marker.collapsed) doc.iter(from.line, to.line + 1, function(line) {
3404
- if (lineIsHidden(line)) updateLineHeight(line, 0);
3405
- });
3406
-
3407
- if (marker.readOnly) {
3408
- sawReadOnlySpans = true;
3409
- if (cm.view.history.done.length || cm.view.history.undone.length)
3410
- cm.clearHistory();
3411
- }
3412
- if (marker.collapsed) {
3413
- if (collapsedAtStart != collapsedAtEnd)
3414
- throw new Error("Inserting collapsed marker overlapping an existing one");
3415
- marker.size = size;
3416
- marker.atomic = true;
3417
- }
3418
- if (marker.className || marker.startStyle || marker.endStyle || marker.collapsed)
3419
- regChange(cm, from.line, to.line + 1);
3420
- if (marker.atomic) reCheckSelection(cm);
3421
- return marker;
3422
- }
3423
-
3424
- // TEXTMARKER SPANS
3425
-
3426
- function getMarkedSpanFor(spans, marker) {
3427
- if (spans) for (var i = 0; i < spans.length; ++i) {
3428
- var span = spans[i];
3429
- if (span.marker == marker) return span;
3430
- }
3431
- }
3432
- function removeMarkedSpan(spans, span) {
3433
- for (var r, i = 0; i < spans.length; ++i)
3434
- if (spans[i] != span) (r || (r = [])).push(spans[i]);
3435
- return r;
3436
- }
3437
- function addMarkedSpan(line, span) {
3438
- line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span];
3439
- span.marker.lines.push(line);
3440
- }
3441
-
3442
- function markedSpansBefore(old, startCh) {
3443
- if (old) for (var i = 0, nw; i < old.length; ++i) {
3444
- var span = old[i], marker = span.marker;
3445
- var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh);
3446
- if (startsBefore || marker.type == "bookmark" && span.from == startCh) {
3447
- var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh);
3448
- (nw || (nw = [])).push({from: span.from,
3449
- to: endsAfter ? null : span.to,
3450
- marker: marker});
3451
- }
3452
- }
3453
- return nw;
3454
- }
3455
-
3456
- function markedSpansAfter(old, startCh, endCh) {
3457
- if (old) for (var i = 0, nw; i < old.length; ++i) {
3458
- var span = old[i], marker = span.marker;
3459
- var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh);
3460
- if (endsAfter || marker.type == "bookmark" && span.from == endCh && span.from != startCh) {
3461
- var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh);
3462
- (nw || (nw = [])).push({from: startsBefore ? null : span.from - endCh,
3463
- to: span.to == null ? null : span.to - endCh,
3464
- marker: marker});
3465
- }
3466
- }
3467
- return nw;
3468
- }
3469
-
3470
- function updateMarkedSpans(oldFirst, oldLast, startCh, endCh, newText) {
3471
- if (!oldFirst && !oldLast) return newText;
3472
- // Get the spans that 'stick out' on both sides
3473
- var first = markedSpansBefore(oldFirst, startCh);
3474
- var last = markedSpansAfter(oldLast, startCh, endCh);
3475
-
3476
- // Next, merge those two ends
3477
- var sameLine = newText.length == 1, offset = lst(newText).length + (sameLine ? startCh : 0);
3478
- if (first) {
3479
- // Fix up .to properties of first
3480
- for (var i = 0; i < first.length; ++i) {
3481
- var span = first[i];
3482
- if (span.to == null) {
3483
- var found = getMarkedSpanFor(last, span.marker);
3484
- if (!found) span.to = startCh;
3485
- else if (sameLine) span.to = found.to == null ? null : found.to + offset;
3486
- }
3487
- }
3488
- }
3489
- if (last) {
3490
- // Fix up .from in last (or move them into first in case of sameLine)
3491
- for (var i = 0; i < last.length; ++i) {
3492
- var span = last[i];
3493
- if (span.to != null) span.to += offset;
3494
- if (span.from == null) {
3495
- var found = getMarkedSpanFor(first, span.marker);
3496
- if (!found) {
3497
- span.from = offset;
3498
- if (sameLine) (first || (first = [])).push(span);
3499
- }
3500
- } else {
3501
- span.from += offset;
3502
- if (sameLine) (first || (first = [])).push(span);
3503
- }
3504
- }
3505
- }
3506
-
3507
- var newMarkers = [newHL(newText[0], first)];
3508
- if (!sameLine) {
3509
- // Fill gap with whole-line-spans
3510
- var gap = newText.length - 2, gapMarkers;
3511
- if (gap > 0 && first)
3512
- for (var i = 0; i < first.length; ++i)
3513
- if (first[i].to == null)
3514
- (gapMarkers || (gapMarkers = [])).push({from: null, to: null, marker: first[i].marker});
3515
- for (var i = 0; i < gap; ++i)
3516
- newMarkers.push(newHL(newText[i+1], gapMarkers));
3517
- newMarkers.push(newHL(lst(newText), last));
3518
- }
3519
- return newMarkers;
3520
- }
3521
-
3522
- function removeReadOnlyRanges(doc, from, to) {
3523
- var markers = null;
3524
- doc.iter(from.line, to.line + 1, function(line) {
3525
- if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) {
3526
- var mark = line.markedSpans[i].marker;
3527
- if (mark.readOnly && (!markers || indexOf(markers, mark) == -1))
3528
- (markers || (markers = [])).push(mark);
3529
- }
3530
- });
3531
- if (!markers) return null;
3532
- var parts = [{from: from, to: to}];
3533
- for (var i = 0; i < markers.length; ++i) {
3534
- var m = markers[i].find();
3535
- for (var j = 0; j < parts.length; ++j) {
3536
- var p = parts[j];
3537
- if (!posLess(m.from, p.to) || posLess(m.to, p.from)) continue;
3538
- var newParts = [j, 1];
3539
- if (posLess(p.from, m.from)) newParts.push({from: p.from, to: m.from});
3540
- if (posLess(m.to, p.to)) newParts.push({from: m.to, to: p.to});
3541
- parts.splice.apply(parts, newParts);
3542
- j += newParts.length - 1;
3543
- }
3544
- }
3545
- return parts;
3546
- }
3547
-
3548
- function collapsedSpanAt(line, ch) {
3549
- var sps = sawCollapsedSpans && line.markedSpans, found;
3550
- if (sps) for (var sp, i = 0; i < sps.length; ++i) {
3551
- sp = sps[i];
3552
- if (!sp.marker.collapsed) continue;
3553
- if ((sp.from == null || sp.from < ch) &&
3554
- (sp.to == null || sp.to > ch) &&
3555
- (!found || found.width < sp.marker.width))
3556
- found = sp.marker;
3557
- }
3558
- return found;
3559
- }
3560
- function collapsedSpanAtStart(line) { return collapsedSpanAt(line, -1); }
3561
- function collapsedSpanAtEnd(line) { return collapsedSpanAt(line, line.text.length + 1); }
3562
-
3563
- function visualLine(doc, line) {
3564
- var merged;
3565
- while (merged = collapsedSpanAtStart(line))
3566
- line = getLine(doc, merged.find().from.line);
3567
- return line;
3568
- }
3569
-
3570
- function lineIsHidden(line) {
3571
- var sps = sawCollapsedSpans && line.markedSpans;
3572
- if (sps) for (var sp, i = 0; i < sps.length; ++i) {
3573
- sp = sps[i];
3574
- if (!sp.marker.collapsed) continue;
3575
- if (sp.from == null) return true;
3576
- if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(line, sp))
3577
- return true;
3578
- }
3579
- }
3580
- function lineIsHiddenInner(line, span) {
3581
- if (span.to == null) {
3582
- var end = span.marker.find().to, endLine = getLine(lineDoc(line), end.line);
3583
- return lineIsHiddenInner(endLine, getMarkedSpanFor(endLine.markedSpans, span.marker));
3584
- }
3585
- if (span.marker.inclusiveRight && span.to == line.text.length)
3586
- return true;
3587
- for (var sp, i = 0; i < line.markedSpans.length; ++i) {
3588
- sp = line.markedSpans[i];
3589
- if (sp.marker.collapsed && sp.from == span.to &&
3590
- (sp.marker.inclusiveLeft || span.marker.inclusiveRight) &&
3591
- lineIsHiddenInner(line, sp)) return true;
3592
- }
3593
- }
3594
-
3595
- // hl stands for history-line, a data structure that can be either a
3596
- // string (line without markers) or a {text, markedSpans} object.
3597
- function hlText(val) { return typeof val == "string" ? val : val.text; }
3598
- function hlSpans(val) {
3599
- if (typeof val == "string") return null;
3600
- var spans = val.markedSpans, out = null;
3601
- for (var i = 0; i < spans.length; ++i) {
3602
- if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i); }
3603
- else if (out) out.push(spans[i]);
3604
- }
3605
- return !out ? spans : out.length ? out : null;
3606
- }
3607
- function newHL(text, spans) { return spans ? {text: text, markedSpans: spans} : text; }
3608
-
3609
- function detachMarkedSpans(line) {
3610
- var spans = line.markedSpans;
3611
- if (!spans) return;
3612
- for (var i = 0; i < spans.length; ++i) {
3613
- var lines = spans[i].marker.lines;
3614
- var ix = indexOf(lines, line);
3615
- lines.splice(ix, 1);
3616
- }
3617
- line.markedSpans = null;
3618
- }
3619
-
3620
- function attachMarkedSpans(line, spans) {
3621
- if (!spans) return;
3622
- for (var i = 0; i < spans.length; ++i)
3623
- spans[i].marker.lines.push(line);
3624
- line.markedSpans = spans;
3625
- }
3626
-
3627
- // LINE WIDGETS
3628
-
3629
- var LineWidget = CodeMirror.LineWidget = function(cm, node, options) {
3630
- for (var opt in options) if (options.hasOwnProperty(opt))
3631
- this[opt] = options[opt];
3632
- this.cm = cm;
3633
- this.node = node;
3634
- };
3635
- function widgetOperation(f) {
3636
- return function() {
3637
- startOperation(this.cm);
3638
- try {var result = f.apply(this, arguments);}
3639
- finally {endOperation(this.cm);}
3640
- return result;
3641
- };
3642
- }
3643
- LineWidget.prototype.clear = widgetOperation(function() {
3644
- var ws = this.line.widgets, no = lineNo(this.line);
3645
- if (no == null || !ws) return;
3646
- for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1);
3647
- updateLineHeight(this.line, Math.max(0, this.line.height - widgetHeight(this)));
3648
- regChange(this.cm, no, no + 1);
3649
- });
3650
- LineWidget.prototype.changed = widgetOperation(function() {
3651
- var oldH = this.height;
3652
- this.height = null;
3653
- var diff = widgetHeight(this) - oldH;
3654
- if (!diff) return;
3655
- updateLineHeight(this.line, this.line.height + diff);
3656
- var no = lineNo(this.line);
3657
- regChange(this.cm, no, no + 1);
3658
- });
3659
-
3660
- function widgetHeight(widget) {
3661
- if (widget.height != null) return widget.height;
3662
- if (!widget.node.parentNode || widget.node.parentNode.nodeType != 1)
3663
- removeChildrenAndAdd(widget.cm.display.measure, elt("div", [widget.node], null, "position: relative"));
3664
- return widget.height = widget.node.offsetHeight;
3665
- }
3666
-
3667
- function addLineWidget(cm, handle, node, options) {
3668
- var widget = new LineWidget(cm, node, options);
3669
- if (widget.noHScroll) cm.display.alignWidgets = true;
3670
- changeLine(cm, handle, function(line) {
3671
- (line.widgets || (line.widgets = [])).push(widget);
3672
- widget.line = line;
3673
- if (!lineIsHidden(line) || widget.showIfHidden) {
3674
- var aboveVisible = heightAtLine(cm, line) < cm.display.scroller.scrollTop;
3675
- updateLineHeight(line, line.height + widgetHeight(widget));
3676
- if (aboveVisible)
3677
- setTimeout(function() {cm.display.scroller.scrollTop += widget.height;});
3678
- }
3679
- return true;
3680
- });
3681
- return widget;
3682
- }
3683
-
3684
- // LINE DATA STRUCTURE
3685
-
3686
- // Line objects. These hold state related to a line, including
3687
- // highlighting info (the styles array).
3688
- function makeLine(text, markedSpans, height) {
3689
- var line = {text: text, height: height};
3690
- attachMarkedSpans(line, markedSpans);
3691
- if (lineIsHidden(line)) line.height = 0;
3692
- return line;
3693
- }
3694
-
3695
- function updateLine(cm, line, text, markedSpans) {
3696
- line.text = text;
3697
- if (line.stateAfter) line.stateAfter = null;
3698
- if (line.styles) line.styles = null;
3699
- if (line.order != null) line.order = null;
3700
- detachMarkedSpans(line);
3701
- attachMarkedSpans(line, markedSpans);
3702
- if (lineIsHidden(line)) line.height = 0;
3703
- else if (!line.height) line.height = textHeight(cm.display);
3704
- signalLater(cm, line, "change");
3705
- }
3706
-
3707
- function cleanUpLine(line) {
3708
- line.parent = null;
3709
- detachMarkedSpans(line);
3710
- }
3711
-
3712
- // Run the given mode's parser over a line, update the styles
3713
- // array, which contains alternating fragments of text and CSS
3714
- // classes.
3715
- function runMode(cm, text, mode, state, f) {
3716
- var flattenSpans = cm.options.flattenSpans;
3717
- var curText = "", curStyle = null;
3718
- var stream = new StringStream(text, cm.options.tabSize);
3719
- if (text == "" && mode.blankLine) mode.blankLine(state);
3720
- while (!stream.eol()) {
3721
- var style = mode.token(stream, state);
3722
- if (stream.pos > 5000) {
3723
- flattenSpans = false;
3724
- // Webkit seems to refuse to render text nodes longer than 57444 characters
3725
- stream.pos = Math.min(text.length, stream.start + 50000);
3726
- style = null;
3727
- }
3728
- var substr = stream.current();
3729
- stream.start = stream.pos;
3730
- if (!flattenSpans || curStyle != style) {
3731
- if (curText) f(curText, curStyle);
3732
- curText = substr; curStyle = style;
3733
- } else curText = curText + substr;
3734
- }
3735
- if (curText) f(curText, curStyle);
3736
- }
3737
-
3738
- function highlightLine(cm, line, state) {
3739
- // A styles array always starts with a number identifying the
3740
- // mode/overlays that it is based on (for easy invalidation).
3741
- var st = [cm.view.modeGen];
3742
- // Compute the base array of styles
3743
- runMode(cm, line.text, cm.view.mode, state, function(txt, style) {st.push(txt, style);});
3744
-
3745
- // Run overlays, adjust style array.
3746
- for (var o = 0; o < cm.view.overlays.length; ++o) {
3747
- var overlay = cm.view.overlays[o], i = 1;
3748
- runMode(cm, line.text, overlay.mode, true, function(txt, style) {
3749
- var start = i, len = txt.length;
3750
- // Ensure there's a token end at the current position, and that i points at it
3751
- while (len) {
3752
- var cur = st[i], len_ = cur.length;
3753
- if (len_ <= len) {
3754
- len -= len_;
3755
- } else {
3756
- st.splice(i, 1, cur.slice(0, len), st[i+1], cur.slice(len));
3757
- len = 0;
3758
- }
3759
- i += 2;
3760
- }
3761
- if (!style) return;
3762
- if (overlay.opaque) {
3763
- st.splice(start, i - start, txt, style);
3764
- i = start + 2;
3765
- } else {
3766
- for (; start < i; start += 2) {
3767
- var cur = st[start+1];
3768
- st[start+1] = cur ? cur + " " + style : style;
3769
- }
3770
- }
3771
- });
3772
- }
3773
-
3774
- return st;
3775
- }
3776
-
3777
- function getLineStyles(cm, line) {
3778
- if (!line.styles || line.styles[0] != cm.view.modeGen)
3779
- line.styles = highlightLine(cm, line, line.stateAfter = getStateBefore(cm, lineNo(line)));
3780
- return line.styles;
3781
- }
3782
-
3783
- // Lightweight form of highlight -- proceed over this line and
3784
- // update state, but don't save a style array.
3785
- function processLine(cm, line, state) {
3786
- var mode = cm.view.mode;
3787
- var stream = new StringStream(line.text, cm.options.tabSize);
3788
- if (line.text == "" && mode.blankLine) mode.blankLine(state);
3789
- while (!stream.eol() && stream.pos <= 5000) {
3790
- mode.token(stream, state);
3791
- stream.start = stream.pos;
3792
- }
3793
- }
3794
-
3795
- var styleToClassCache = {};
3796
- function styleToClass(style) {
3797
- if (!style) return null;
3798
- return styleToClassCache[style] ||
3799
- (styleToClassCache[style] = "cm-" + style.replace(/ +/g, " cm-"));
3800
- }
3801
-
3802
- function lineContent(cm, realLine, measure) {
3803
- var merged, line = realLine, lineBefore, sawBefore, simple = true;
3804
- while (merged = collapsedSpanAtStart(line)) {
3805
- simple = false;
3806
- line = getLine(cm.view.doc, merged.find().from.line);
3807
- if (!lineBefore) lineBefore = line;
3808
- }
3809
-
3810
- var builder = {pre: elt("pre"), col: 0, pos: 0, display: !measure,
3811
- measure: null, addedOne: false, cm: cm};
3812
- if (line.textClass) builder.pre.className = line.textClass;
3813
-
3814
- do {
3815
- builder.measure = line == realLine && measure;
3816
- builder.pos = 0;
3817
- builder.addToken = builder.measure ? buildTokenMeasure : buildToken;
3818
- if (measure && sawBefore && line != realLine && !builder.addedOne) {
3819
- measure[0] = builder.pre.appendChild(zeroWidthElement(cm.display.measure));
3820
- builder.addedOne = true;
3821
- }
3822
- var next = insertLineContent(line, builder, getLineStyles(cm, line));
3823
- sawBefore = line == lineBefore;
3824
- if (next) {
3825
- line = getLine(cm.view.doc, next.to.line);
3826
- simple = false;
3827
- }
3828
- } while (next);
3829
-
3830
- if (measure && !builder.addedOne)
3831
- measure[0] = builder.pre.appendChild(simple ? elt("span", "\u00a0") : zeroWidthElement(cm.display.measure));
3832
- if (!builder.pre.firstChild && !lineIsHidden(realLine))
3833
- builder.pre.appendChild(document.createTextNode("\u00a0"));
3834
-
3835
- return builder.pre;
3836
- }
3837
-
3838
- var tokenSpecialChars = /[\t\u0000-\u0019\u200b\u2028\u2029\uFEFF]/g;
3839
- function buildToken(builder, text, style, startStyle, endStyle) {
3840
- if (!text) return;
3841
- if (!tokenSpecialChars.test(text)) {
3842
- builder.col += text.length;
3843
- var content = document.createTextNode(text);
3844
- } else {
3845
- var content = document.createDocumentFragment(), pos = 0;
3846
- while (true) {
3847
- tokenSpecialChars.lastIndex = pos;
3848
- var m = tokenSpecialChars.exec(text);
3849
- var skipped = m ? m.index - pos : text.length - pos;
3850
- if (skipped) {
3851
- content.appendChild(document.createTextNode(text.slice(pos, pos + skipped)));
3852
- builder.col += skipped;
3853
- }
3854
- if (!m) break;
3855
- pos += skipped + 1;
3856
- if (m[0] == "\t") {
3857
- var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize;
3858
- content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab"));
3859
- builder.col += tabWidth;
3860
- } else {
3861
- var token = elt("span", "\u2022", "cm-invalidchar");
3862
- token.title = "\\u" + m[0].charCodeAt(0).toString(16);
3863
- content.appendChild(token);
3864
- builder.col += 1;
3865
- }
3866
- }
3867
- }
3868
- if (style || startStyle || endStyle || builder.measure) {
3869
- var fullStyle = style || "";
3870
- if (startStyle) fullStyle += startStyle;
3871
- if (endStyle) fullStyle += endStyle;
3872
- return builder.pre.appendChild(elt("span", [content], fullStyle));
3873
- }
3874
- builder.pre.appendChild(content);
3875
- }
3876
-
3877
- function buildTokenMeasure(builder, text, style, startStyle, endStyle) {
3878
- for (var i = 0; i < text.length; ++i) {
3879
- if (i && i < text.length &&
3880
- builder.cm.options.lineWrapping &&
3881
- spanAffectsWrapping.test(text.slice(i - 1, i + 1)))
3882
- builder.pre.appendChild(elt("wbr"));
3883
- builder.measure[builder.pos++] =
3884
- buildToken(builder, text.charAt(i), style,
3885
- i == 0 && startStyle, i == text.length - 1 && endStyle);
3886
- }
3887
- if (text.length) builder.addedOne = true;
3888
- }
3889
-
3890
- function buildCollapsedSpan(builder, size, widget) {
3891
- if (widget) {
3892
- if (!builder.display) widget = widget.cloneNode(true);
3893
- builder.pre.appendChild(widget);
3894
- if (builder.measure && size) {
3895
- builder.measure[builder.pos] = widget;
3896
- builder.addedOne = true;
3897
- }
3898
- }
3899
- builder.pos += size;
3900
- }
3901
-
3902
- // Outputs a number of spans to make up a line, taking highlighting
3903
- // and marked text into account.
3904
- function insertLineContent(line, builder, styles) {
3905
- var spans = line.markedSpans;
3906
- if (!spans) {
3907
- for (var i = 1; i < styles.length; i+=2)
3908
- builder.addToken(builder, styles[i], styleToClass(styles[i+1]));
3909
- return;
3910
- }
3911
-
3912
- var allText = line.text, len = allText.length;
3913
- var pos = 0, i = 1, text = "", style;
3914
- var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, collapsed;
3915
- for (;;) {
3916
- if (nextChange == pos) { // Update current marker set
3917
- spanStyle = spanEndStyle = spanStartStyle = "";
3918
- collapsed = null; nextChange = Infinity;
3919
- var foundBookmark = null;
3920
- for (var j = 0; j < spans.length; ++j) {
3921
- var sp = spans[j], m = sp.marker;
3922
- if (sp.from <= pos && (sp.to == null || sp.to > pos)) {
3923
- if (sp.to != null && nextChange > sp.to) { nextChange = sp.to; spanEndStyle = ""; }
3924
- if (m.className) spanStyle += " " + m.className;
3925
- if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle;
3926
- if (m.endStyle && sp.to == nextChange) spanEndStyle += " " + m.endStyle;
3927
- if (m.collapsed && (!collapsed || collapsed.marker.width < m.width))
3928
- collapsed = sp;
3929
- } else if (sp.from > pos && nextChange > sp.from) {
3930
- nextChange = sp.from;
3931
- }
3932
- if (m.type == "bookmark" && sp.from == pos && m.replacedWith)
3933
- foundBookmark = m.replacedWith;
3934
- }
3935
- if (collapsed && (collapsed.from || 0) == pos) {
3936
- buildCollapsedSpan(builder, (collapsed.to == null ? len : collapsed.to) - pos,
3937
- collapsed.from != null && collapsed.marker.replacedWith);
3938
- if (collapsed.to == null) return collapsed.marker.find();
3939
- }
3940
- if (foundBookmark && !collapsed) buildCollapsedSpan(builder, 0, foundBookmark);
3941
- }
3942
- if (pos >= len) break;
3943
-
3944
- var upto = Math.min(len, nextChange);
3945
- while (true) {
3946
- if (text) {
3947
- var end = pos + text.length;
3948
- if (!collapsed) {
3949
- var tokenText = end > upto ? text.slice(0, upto - pos) : text;
3950
- builder.addToken(builder, tokenText, style + spanStyle,
3951
- spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "");
3952
- }
3953
- if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;}
3954
- pos = end;
3955
- spanStartStyle = "";
3956
- }
3957
- text = styles[i++]; style = styleToClass(styles[i++]);
3958
- }
3959
- }
3960
- }
3961
-
3962
- // DOCUMENT DATA STRUCTURE
3963
-
3964
- function LeafChunk(lines) {
3965
- this.lines = lines;
3966
- this.parent = null;
3967
- for (var i = 0, e = lines.length, height = 0; i < e; ++i) {
3968
- lines[i].parent = this;
3969
- height += lines[i].height;
3970
- }
3971
- this.height = height;
3972
- }
3973
-
3974
- LeafChunk.prototype = {
3975
- chunkSize: function() { return this.lines.length; },
3976
- remove: function(at, n, cm) {
3977
- for (var i = at, e = at + n; i < e; ++i) {
3978
- var line = this.lines[i];
3979
- this.height -= line.height;
3980
- cleanUpLine(line);
3981
- signalLater(cm, line, "delete");
3982
- }
3983
- this.lines.splice(at, n);
3984
- },
3985
- collapse: function(lines) {
3986
- lines.splice.apply(lines, [lines.length, 0].concat(this.lines));
3987
- },
3988
- insertHeight: function(at, lines, height) {
3989
- this.height += height;
3990
- this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at));
3991
- for (var i = 0, e = lines.length; i < e; ++i) lines[i].parent = this;
3992
- },
3993
- iterN: function(at, n, op) {
3994
- for (var e = at + n; at < e; ++at)
3995
- if (op(this.lines[at])) return true;
3996
- }
3997
- };
3998
-
3999
- function BranchChunk(children) {
4000
- this.children = children;
4001
- var size = 0, height = 0;
4002
- for (var i = 0, e = children.length; i < e; ++i) {
4003
- var ch = children[i];
4004
- size += ch.chunkSize(); height += ch.height;
4005
- ch.parent = this;
4006
- }
4007
- this.size = size;
4008
- this.height = height;
4009
- this.parent = null;
4010
- }
4011
-
4012
- BranchChunk.prototype = {
4013
- chunkSize: function() { return this.size; },
4014
- remove: function(at, n, callbacks) {
4015
- this.size -= n;
4016
- for (var i = 0; i < this.children.length; ++i) {
4017
- var child = this.children[i], sz = child.chunkSize();
4018
- if (at < sz) {
4019
- var rm = Math.min(n, sz - at), oldHeight = child.height;
4020
- child.remove(at, rm, callbacks);
4021
- this.height -= oldHeight - child.height;
4022
- if (sz == rm) { this.children.splice(i--, 1); child.parent = null; }
4023
- if ((n -= rm) == 0) break;
4024
- at = 0;
4025
- } else at -= sz;
4026
- }
4027
- if (this.size - n < 25) {
4028
- var lines = [];
4029
- this.collapse(lines);
4030
- this.children = [new LeafChunk(lines)];
4031
- this.children[0].parent = this;
4032
- }
4033
- },
4034
- collapse: function(lines) {
4035
- for (var i = 0, e = this.children.length; i < e; ++i) this.children[i].collapse(lines);
4036
- },
4037
- insert: function(at, lines) {
4038
- var height = 0;
4039
- for (var i = 0, e = lines.length; i < e; ++i) height += lines[i].height;
4040
- this.insertHeight(at, lines, height);
4041
- },
4042
- insertHeight: function(at, lines, height) {
4043
- this.size += lines.length;
4044
- this.height += height;
4045
- for (var i = 0, e = this.children.length; i < e; ++i) {
4046
- var child = this.children[i], sz = child.chunkSize();
4047
- if (at <= sz) {
4048
- child.insertHeight(at, lines, height);
4049
- if (child.lines && child.lines.length > 50) {
4050
- while (child.lines.length > 50) {
4051
- var spilled = child.lines.splice(child.lines.length - 25, 25);
4052
- var newleaf = new LeafChunk(spilled);
4053
- child.height -= newleaf.height;
4054
- this.children.splice(i + 1, 0, newleaf);
4055
- newleaf.parent = this;
4056
- }
4057
- this.maybeSpill();
4058
- }
4059
- break;
4060
- }
4061
- at -= sz;
4062
- }
4063
- },
4064
- maybeSpill: function() {
4065
- if (this.children.length <= 10) return;
4066
- var me = this;
4067
- do {
4068
- var spilled = me.children.splice(me.children.length - 5, 5);
4069
- var sibling = new BranchChunk(spilled);
4070
- if (!me.parent) { // Become the parent node
4071
- var copy = new BranchChunk(me.children);
4072
- copy.parent = me;
4073
- me.children = [copy, sibling];
4074
- me = copy;
4075
- } else {
4076
- me.size -= sibling.size;
4077
- me.height -= sibling.height;
4078
- var myIndex = indexOf(me.parent.children, me);
4079
- me.parent.children.splice(myIndex + 1, 0, sibling);
4080
- }
4081
- sibling.parent = me.parent;
4082
- } while (me.children.length > 10);
4083
- me.parent.maybeSpill();
4084
- },
4085
- iter: function(from, to, op) { this.iterN(from, to - from, op); },
4086
- iterN: function(at, n, op) {
4087
- for (var i = 0, e = this.children.length; i < e; ++i) {
4088
- var child = this.children[i], sz = child.chunkSize();
4089
- if (at < sz) {
4090
- var used = Math.min(n, sz - at);
4091
- if (child.iterN(at, used, op)) return true;
4092
- if ((n -= used) == 0) break;
4093
- at = 0;
4094
- } else at -= sz;
4095
- }
4096
- }
4097
- };
4098
-
4099
- // LINE UTILITIES
4100
-
4101
- function getLine(chunk, n) {
4102
- while (!chunk.lines) {
4103
- for (var i = 0;; ++i) {
4104
- var child = chunk.children[i], sz = child.chunkSize();
4105
- if (n < sz) { chunk = child; break; }
4106
- n -= sz;
4107
- }
4108
- }
4109
- return chunk.lines[n];
4110
- }
4111
-
4112
- function updateLineHeight(line, height) {
4113
- var diff = height - line.height;
4114
- for (var n = line; n; n = n.parent) n.height += diff;
4115
- }
4116
-
4117
- function lineNo(line) {
4118
- if (line.parent == null) return null;
4119
- var cur = line.parent, no = indexOf(cur.lines, line);
4120
- for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) {
4121
- for (var i = 0;; ++i) {
4122
- if (chunk.children[i] == cur) break;
4123
- no += chunk.children[i].chunkSize();
4124
- }
4125
- }
4126
- return no;
4127
- }
4128
-
4129
- function lineDoc(line) {
4130
- for (var d = line.parent; d.parent; d = d.parent) {}
4131
- return d;
4132
- }
4133
-
4134
- function lineAtHeight(chunk, h) {
4135
- var n = 0;
4136
- outer: do {
4137
- for (var i = 0, e = chunk.children.length; i < e; ++i) {
4138
- var child = chunk.children[i], ch = child.height;
4139
- if (h < ch) { chunk = child; continue outer; }
4140
- h -= ch;
4141
- n += child.chunkSize();
4142
- }
4143
- return n;
4144
- } while (!chunk.lines);
4145
- for (var i = 0, e = chunk.lines.length; i < e; ++i) {
4146
- var line = chunk.lines[i], lh = line.height;
4147
- if (h < lh) break;
4148
- h -= lh;
4149
- }
4150
- return n + i;
4151
- }
4152
-
4153
- function heightAtLine(cm, lineObj) {
4154
- lineObj = visualLine(cm.view.doc, lineObj);
4155
-
4156
- var h = 0, chunk = lineObj.parent;
4157
- for (var i = 0; i < chunk.lines.length; ++i) {
4158
- var line = chunk.lines[i];
4159
- if (line == lineObj) break;
4160
- else h += line.height;
4161
- }
4162
- for (var p = chunk.parent; p; chunk = p, p = chunk.parent) {
4163
- for (var i = 0; i < p.children.length; ++i) {
4164
- var cur = p.children[i];
4165
- if (cur == chunk) break;
4166
- else h += cur.height;
4167
- }
4168
- }
4169
- return h;
4170
- }
4171
-
4172
- function getOrder(line) {
4173
- var order = line.order;
4174
- if (order == null) order = line.order = bidiOrdering(line.text);
4175
- return order;
4176
- }
4177
-
4178
- // HISTORY
4179
-
4180
- function makeHistory() {
4181
- return {
4182
- // Arrays of history events. Doing something adds an event to
4183
- // done and clears undo. Undoing moves events from done to
4184
- // undone, redoing moves them in the other direction.
4185
- done: [], undone: [],
4186
- // Used to track when changes can be merged into a single undo
4187
- // event
4188
- lastTime: 0, lastOp: null, lastOrigin: null,
4189
- // Used by the isClean() method
4190
- dirtyCounter: 0
4191
- };
4192
- }
4193
-
4194
- function addChange(cm, start, added, old, origin, fromBefore, toBefore, fromAfter, toAfter) {
4195
- var history = cm.view.history;
4196
- history.undone.length = 0;
4197
- var time = +new Date, cur = lst(history.done);
4198
-
4199
- if (cur &&
4200
- (history.lastOp == cm.curOp.id ||
4201
- history.lastOrigin == origin && (origin == "input" || origin == "delete") &&
4202
- history.lastTime > time - 600)) {
4203
- // Merge this change into the last event
4204
- var last = lst(cur.events);
4205
- if (last.start > start + old.length || last.start + last.added < start) {
4206
- // Doesn't intersect with last sub-event, add new sub-event
4207
- cur.events.push({start: start, added: added, old: old});
4208
- } else {
4209
- // Patch up the last sub-event
4210
- var startBefore = Math.max(0, last.start - start),
4211
- endAfter = Math.max(0, (start + old.length) - (last.start + last.added));
4212
- for (var i = startBefore; i > 0; --i) last.old.unshift(old[i - 1]);
4213
- for (var i = endAfter; i > 0; --i) last.old.push(old[old.length - i]);
4214
- if (startBefore) last.start = start;
4215
- last.added += added - (old.length - startBefore - endAfter);
4216
- }
4217
- cur.fromAfter = fromAfter; cur.toAfter = toAfter;
4218
- } else {
4219
- // Can not be merged, start a new event.
4220
- cur = {events: [{start: start, added: added, old: old}],
4221
- fromBefore: fromBefore, toBefore: toBefore, fromAfter: fromAfter, toAfter: toAfter};
4222
- history.done.push(cur);
4223
- while (history.done.length > cm.options.undoDepth)
4224
- history.done.shift();
4225
- if (history.dirtyCounter < 0)
4226
- // The user has made a change after undoing past the last clean state.
4227
- // We can never get back to a clean state now until markClean() is called.
4228
- history.dirtyCounter = NaN;
4229
- else
4230
- history.dirtyCounter++;
4231
- }
4232
- history.lastTime = time;
4233
- history.lastOp = cm.curOp.id;
4234
- history.lastOrigin = origin;
4235
- }
4236
-
4237
- // EVENT OPERATORS
4238
-
4239
- function stopMethod() {e_stop(this);}
4240
- // Ensure an event has a stop method.
4241
- function addStop(event) {
4242
- if (!event.stop) event.stop = stopMethod;
4243
- return event;
4244
- }
4245
-
4246
- function e_preventDefault(e) {
4247
- if (e.preventDefault) e.preventDefault();
4248
- else e.returnValue = false;
4249
- }
4250
- function e_stopPropagation(e) {
4251
- if (e.stopPropagation) e.stopPropagation();
4252
- else e.cancelBubble = true;
4253
- }
4254
- function e_stop(e) {e_preventDefault(e); e_stopPropagation(e);}
4255
- CodeMirror.e_stop = e_stop;
4256
- CodeMirror.e_preventDefault = e_preventDefault;
4257
- CodeMirror.e_stopPropagation = e_stopPropagation;
4258
-
4259
- function e_target(e) {return e.target || e.srcElement;}
4260
- function e_button(e) {
4261
- var b = e.which;
4262
- if (b == null) {
4263
- if (e.button & 1) b = 1;
4264
- else if (e.button & 2) b = 3;
4265
- else if (e.button & 4) b = 2;
4266
- }
4267
- if (mac && e.ctrlKey && b == 1) b = 3;
4268
- return b;
4269
- }
4270
-
4271
- // Allow 3rd-party code to override event properties by adding an override
4272
- // object to an event object.
4273
- function e_prop(e, prop) {
4274
- var overridden = e.override && e.override.hasOwnProperty(prop);
4275
- return overridden ? e.override[prop] : e[prop];
4276
- }
4277
-
4278
- // EVENT HANDLING
4279
-
4280
- function on(emitter, type, f) {
4281
- if (emitter.addEventListener)
4282
- emitter.addEventListener(type, f, false);
4283
- else if (emitter.attachEvent)
4284
- emitter.attachEvent("on" + type, f);
4285
- else {
4286
- var map = emitter._handlers || (emitter._handlers = {});
4287
- var arr = map[type] || (map[type] = []);
4288
- arr.push(f);
4289
- }
4290
- }
4291
-
4292
- function off(emitter, type, f) {
4293
- if (emitter.removeEventListener)
4294
- emitter.removeEventListener(type, f, false);
4295
- else if (emitter.detachEvent)
4296
- emitter.detachEvent("on" + type, f);
4297
- else {
4298
- var arr = emitter._handlers && emitter._handlers[type];
4299
- if (!arr) return;
4300
- for (var i = 0; i < arr.length; ++i)
4301
- if (arr[i] == f) { arr.splice(i, 1); break; }
4302
- }
4303
- }
4304
-
4305
- function signal(emitter, type /*, values...*/) {
4306
- var arr = emitter._handlers && emitter._handlers[type];
4307
- if (!arr) return;
4308
- var args = Array.prototype.slice.call(arguments, 2);
4309
- for (var i = 0; i < arr.length; ++i) arr[i].apply(null, args);
4310
- }
4311
-
4312
- function signalLater(cm, emitter, type /*, values...*/) {
4313
- var arr = emitter._handlers && emitter._handlers[type];
4314
- if (!arr) return;
4315
- var args = Array.prototype.slice.call(arguments, 3), flist = cm.curOp && cm.curOp.delayedCallbacks;
4316
- function bnd(f) {return function(){f.apply(null, args);};};
4317
- for (var i = 0; i < arr.length; ++i)
4318
- if (flist) flist.push(bnd(arr[i]));
4319
- else arr[i].apply(null, args);
4320
- }
4321
-
4322
- function hasHandler(emitter, type) {
4323
- var arr = emitter._handlers && emitter._handlers[type];
4324
- return arr && arr.length > 0;
4325
- }
4326
-
4327
- CodeMirror.on = on; CodeMirror.off = off; CodeMirror.signal = signal;
4328
-
4329
- // MISC UTILITIES
4330
-
4331
- // Number of pixels added to scroller and sizer to hide scrollbar
4332
- var scrollerCutOff = 30;
4333
-
4334
- // Returned or thrown by various protocols to signal 'I'm not
4335
- // handling this'.
4336
- var Pass = CodeMirror.Pass = {toString: function(){return "CodeMirror.Pass";}};
4337
-
4338
- function Delayed() {this.id = null;}
4339
- Delayed.prototype = {set: function(ms, f) {clearTimeout(this.id); this.id = setTimeout(f, ms);}};
4340
-
4341
- // Counts the column offset in a string, taking tabs into account.
4342
- // Used mostly to find indentation.
4343
- function countColumn(string, end, tabSize) {
4344
- if (end == null) {
4345
- end = string.search(/[^\s\u00a0]/);
4346
- if (end == -1) end = string.length;
4347
- }
4348
- for (var i = 0, n = 0; i < end; ++i) {
4349
- if (string.charAt(i) == "\t") n += tabSize - (n % tabSize);
4350
- else ++n;
4351
- }
4352
- return n;
4353
- }
4354
- CodeMirror.countColumn = countColumn;
4355
-
4356
- var spaceStrs = [""];
4357
- function spaceStr(n) {
4358
- while (spaceStrs.length <= n)
4359
- spaceStrs.push(lst(spaceStrs) + " ");
4360
- return spaceStrs[n];
4361
- }
4362
-
4363
- function lst(arr) { return arr[arr.length-1]; }
4364
-
4365
- function selectInput(node) {
4366
- if (ios) { // Mobile Safari apparently has a bug where select() is broken.
4367
- node.selectionStart = 0;
4368
- node.selectionEnd = node.value.length;
4369
- } else node.select();
4370
- }
4371
-
4372
- function indexOf(collection, elt) {
4373
- if (collection.indexOf) return collection.indexOf(elt);
4374
- for (var i = 0, e = collection.length; i < e; ++i)
4375
- if (collection[i] == elt) return i;
4376
- return -1;
4377
- }
4378
-
4379
- function emptyArray(size) {
4380
- for (var a = [], i = 0; i < size; ++i) a.push(undefined);
4381
- return a;
4382
- }
4383
-
4384
- function bind(f) {
4385
- var args = Array.prototype.slice.call(arguments, 1);
4386
- return function(){return f.apply(null, args);};
4387
- }
4388
-
4389
- var nonASCIISingleCaseWordChar = /[\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc]/;
4390
- function isWordChar(ch) {
4391
- return /\w/.test(ch) || ch > "\x80" &&
4392
- (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch));
4393
- }
4394
-
4395
- function isEmpty(obj) {
4396
- var c = 0;
4397
- for (var n in obj) if (obj.hasOwnProperty(n) && obj[n]) ++c;
4398
- return !c;
4399
- }
4400
-
4401
- var isExtendingChar = /[\u0300-\u036F\u0483-\u0487\u0488-\u0489\u0591-\u05BD\u05BF\u05C1-\u05C2\u05C4-\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7-\u06E8\u06EA-\u06ED\uA66F\uA670-\uA672\uA674-\uA67D\uA69F]/;
4402
-
4403
- // DOM UTILITIES
4404
-
4405
- function elt(tag, content, className, style) {
4406
- var e = document.createElement(tag);
4407
- if (className) e.className = className;
4408
- if (style) e.style.cssText = style;
4409
- if (typeof content == "string") setTextContent(e, content);
4410
- else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]);
4411
- return e;
4412
- }
4413
-
4414
- function removeChildren(e) {
4415
- // IE will break all parent-child relations in subnodes when setting innerHTML
4416
- if (!ie) e.innerHTML = "";
4417
- else while (e.firstChild) e.removeChild(e.firstChild);
4418
- return e;
4419
- }
4420
-
4421
- function removeChildrenAndAdd(parent, e) {
4422
- return removeChildren(parent).appendChild(e);
4423
- }
4424
-
4425
- function setTextContent(e, str) {
4426
- if (ie_lt9) {
4427
- e.innerHTML = "";
4428
- e.appendChild(document.createTextNode(str));
4429
- } else e.textContent = str;
4430
- }
4431
-
4432
- // FEATURE DETECTION
4433
-
4434
- // Detect drag-and-drop
4435
- var dragAndDrop = function() {
4436
- // There is *some* kind of drag-and-drop support in IE6-8, but I
4437
- // couldn't get it to work yet.
4438
- if (ie_lt9) return false;
4439
- var div = elt('div');
4440
- return "draggable" in div || "dragDrop" in div;
4441
- }();
4442
-
4443
- // For a reason I have yet to figure out, some browsers disallow
4444
- // word wrapping between certain characters *only* if a new inline
4445
- // element is started between them. This makes it hard to reliably
4446
- // measure the position of things, since that requires inserting an
4447
- // extra span. This terribly fragile set of regexps matches the
4448
- // character combinations that suffer from this phenomenon on the
4449
- // various browsers.
4450
- var spanAffectsWrapping = /^$/; // Won't match any two-character string
4451
- if (gecko) spanAffectsWrapping = /$'/;
4452
- else if (safari) spanAffectsWrapping = /\-[^ \-?]|\?[^ !'\"\),.\-\/:;\?\]\}]/;
4453
- else if (chrome) spanAffectsWrapping = /\-[^ \-\.?]|\?[^ \-\.?\]\}:;!'\"\),\/]|[\.!\"#&%\)*+,:;=>\]|\}~][\(\{\[<]|\$'/;
4454
-
4455
- var knownScrollbarWidth;
4456
- function scrollbarWidth(measure) {
4457
- if (knownScrollbarWidth != null) return knownScrollbarWidth;
4458
- var test = elt("div", null, null, "width: 50px; height: 50px; overflow-x: scroll");
4459
- removeChildrenAndAdd(measure, test);
4460
- if (test.offsetWidth)
4461
- knownScrollbarWidth = test.offsetHeight - test.clientHeight;
4462
- return knownScrollbarWidth || 0;
4463
- }
4464
-
4465
- var zwspSupported;
4466
- function zeroWidthElement(measure) {
4467
- if (zwspSupported == null) {
4468
- var test = elt("span", "\u200b");
4469
- removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")]));
4470
- if (measure.firstChild.offsetHeight != 0)
4471
- zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !ie_lt8;
4472
- }
4473
- if (zwspSupported) return elt("span", "\u200b");
4474
- else return elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px");
4475
- }
4476
-
4477
- // See if "".split is the broken IE version, if so, provide an
4478
- // alternative way to split lines.
4479
- var splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) {
4480
- var pos = 0, result = [], l = string.length;
4481
- while (pos <= l) {
4482
- var nl = string.indexOf("\n", pos);
4483
- if (nl == -1) nl = string.length;
4484
- var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl);
4485
- var rt = line.indexOf("\r");
4486
- if (rt != -1) {
4487
- result.push(line.slice(0, rt));
4488
- pos += rt + 1;
4489
- } else {
4490
- result.push(line);
4491
- pos = nl + 1;
4492
- }
4493
- }
4494
- return result;
4495
- } : function(string){return string.split(/\r\n?|\n/);};
4496
- CodeMirror.splitLines = splitLines;
4497
-
4498
- var hasSelection = window.getSelection ? function(te) {
4499
- try { return te.selectionStart != te.selectionEnd; }
4500
- catch(e) { return false; }
4501
- } : function(te) {
4502
- try {var range = te.ownerDocument.selection.createRange();}
4503
- catch(e) {}
4504
- if (!range || range.parentElement() != te) return false;
4505
- return range.compareEndPoints("StartToEnd", range) != 0;
4506
- };
4507
-
4508
- var hasCopyEvent = (function() {
4509
- var e = elt("div");
4510
- if ("oncopy" in e) return true;
4511
- e.setAttribute("oncopy", "return;");
4512
- return typeof e.oncopy == 'function';
4513
- })();
4514
-
4515
- // KEY NAMING
4516
-
4517
- var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
4518
- 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
4519
- 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
4520
- 46: "Delete", 59: ";", 91: "Mod", 92: "Mod", 93: "Mod", 109: "-", 107: "=", 127: "Delete",
4521
- 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
4522
- 221: "]", 222: "'", 63276: "PageUp", 63277: "PageDown", 63275: "End", 63273: "Home",
4523
- 63234: "Left", 63232: "Up", 63235: "Right", 63233: "Down", 63302: "Insert", 63272: "Delete"};
4524
- CodeMirror.keyNames = keyNames;
4525
- (function() {
4526
- // Number keys
4527
- for (var i = 0; i < 10; i++) keyNames[i + 48] = String(i);
4528
- // Alphabetic keys
4529
- for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i);
4530
- // Function keys
4531
- for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i;
4532
- })();
4533
-
4534
- // BIDI HELPERS
4535
-
4536
- function iterateBidiSections(order, from, to, f) {
4537
- if (!order) return f(from, to, "ltr");
4538
- for (var i = 0; i < order.length; ++i) {
4539
- var part = order[i];
4540
- if (part.from < to && part.to > from || from == to && part.to == from)
4541
- f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr");
4542
- }
4543
- }
4544
-
4545
- function bidiLeft(part) { return part.level % 2 ? part.to : part.from; }
4546
- function bidiRight(part) { return part.level % 2 ? part.from : part.to; }
4547
-
4548
- function lineLeft(line) { var order = getOrder(line); return order ? bidiLeft(order[0]) : 0; }
4549
- function lineRight(line) {
4550
- var order = getOrder(line);
4551
- if (!order) return line.text.length;
4552
- return bidiRight(lst(order));
4553
- }
4554
-
4555
- function lineStart(cm, lineN) {
4556
- var line = getLine(cm.view.doc, lineN);
4557
- var visual = visualLine(cm.view.doc, line);
4558
- if (visual != line) lineN = lineNo(visual);
4559
- var order = getOrder(visual);
4560
- var ch = !order ? 0 : order[0].level % 2 ? lineRight(visual) : lineLeft(visual);
4561
- return {line: lineN, ch: ch};
4562
- }
4563
- function lineEnd(cm, lineNo) {
4564
- var merged, line;
4565
- while (merged = collapsedSpanAtEnd(line = getLine(cm.view.doc, lineNo)))
4566
- lineNo = merged.find().to.line;
4567
- var order = getOrder(line);
4568
- var ch = !order ? line.text.length : order[0].level % 2 ? lineLeft(line) : lineRight(line);
4569
- return {line: lineNo, ch: ch};
4570
- }
4571
-
4572
- // This is somewhat involved. It is needed in order to move
4573
- // 'visually' through bi-directional text -- i.e., pressing left
4574
- // should make the cursor go left, even when in RTL text. The
4575
- // tricky part is the 'jumps', where RTL and LTR text touch each
4576
- // other. This often requires the cursor offset to move more than
4577
- // one unit, in order to visually move one unit.
4578
- function moveVisually(line, start, dir, byUnit) {
4579
- var bidi = getOrder(line);
4580
- if (!bidi) return moveLogically(line, start, dir, byUnit);
4581
- var moveOneUnit = byUnit ? function(pos, dir) {
4582
- do pos += dir;
4583
- while (pos > 0 && isExtendingChar.test(line.text.charAt(pos)));
4584
- return pos;
4585
- } : function(pos, dir) { return pos + dir; };
4586
- var linedir = bidi[0].level;
4587
- for (var i = 0; i < bidi.length; ++i) {
4588
- var part = bidi[i], sticky = part.level % 2 == linedir;
4589
- if ((part.from < start && part.to > start) ||
4590
- (sticky && (part.from == start || part.to == start))) break;
4591
- }
4592
- var target = moveOneUnit(start, part.level % 2 ? -dir : dir);
4593
-
4594
- while (target != null) {
4595
- if (part.level % 2 == linedir) {
4596
- if (target < part.from || target > part.to) {
4597
- part = bidi[i += dir];
4598
- target = part && (dir > 0 == part.level % 2 ? moveOneUnit(part.to, -1) : moveOneUnit(part.from, 1));
4599
- } else break;
4600
- } else {
4601
- if (target == bidiLeft(part)) {
4602
- part = bidi[--i];
4603
- target = part && bidiRight(part);
4604
- } else if (target == bidiRight(part)) {
4605
- part = bidi[++i];
4606
- target = part && bidiLeft(part);
4607
- } else break;
4608
- }
4609
- }
4610
-
4611
- return target < 0 || target > line.text.length ? null : target;
4612
- }
4613
-
4614
- function moveLogically(line, start, dir, byUnit) {
4615
- var target = start + dir;
4616
- if (byUnit) while (target > 0 && isExtendingChar.test(line.text.charAt(target))) target += dir;
4617
- return target < 0 || target > line.text.length ? null : target;
4618
- }
4619
-
4620
- // Bidirectional ordering algorithm
4621
- // See http://unicode.org/reports/tr9/tr9-13.html for the algorithm
4622
- // that this (partially) implements.
4623
-
4624
- // One-char codes used for character types:
4625
- // L (L): Left-to-Right
4626
- // R (R): Right-to-Left
4627
- // r (AL): Right-to-Left Arabic
4628
- // 1 (EN): European Number
4629
- // + (ES): European Number Separator
4630
- // % (ET): European Number Terminator
4631
- // n (AN): Arabic Number
4632
- // , (CS): Common Number Separator
4633
- // m (NSM): Non-Spacing Mark
4634
- // b (BN): Boundary Neutral
4635
- // s (B): Paragraph Separator
4636
- // t (S): Segment Separator
4637
- // w (WS): Whitespace
4638
- // N (ON): Other Neutrals
4639
-
4640
- // Returns null if characters are ordered as they appear
4641
- // (left-to-right), or an array of sections ({from, to, level}
4642
- // objects) in the order in which they occur visually.
4643
- var bidiOrdering = (function() {
4644
- // Character types for codepoints 0 to 0xff
4645
- var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLL";
4646
- // Character types for codepoints 0x600 to 0x6ff
4647
- var arabicTypes = "rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmmrrrrrrrrrrrrrrrrrr";
4648
- function charType(code) {
4649
- if (code <= 0xff) return lowTypes.charAt(code);
4650
- else if (0x590 <= code && code <= 0x5f4) return "R";
4651
- else if (0x600 <= code && code <= 0x6ff) return arabicTypes.charAt(code - 0x600);
4652
- else if (0x700 <= code && code <= 0x8ac) return "r";
4653
- else return "L";
4654
- }
4655
-
4656
- var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;
4657
- var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/;
4658
- // Browsers seem to always treat the boundaries of block elements as being L.
4659
- var outerType = "L";
4660
-
4661
- return function charOrdering(str) {
4662
- if (!bidiRE.test(str)) return false;
4663
- var len = str.length, types = [];
4664
- for (var i = 0, type; i < len; ++i)
4665
- types.push(type = charType(str.charCodeAt(i)));
4666
-
4667
- // W1. Examine each non-spacing mark (NSM) in the level run, and
4668
- // change the type of the NSM to the type of the previous
4669
- // character. If the NSM is at the start of the level run, it will
4670
- // get the type of sor.
4671
- for (var i = 0, prev = outerType; i < len; ++i) {
4672
- var type = types[i];
4673
- if (type == "m") types[i] = prev;
4674
- else prev = type;
4675
- }
4676
-
4677
- // W2. Search backwards from each instance of a European number
4678
- // until the first strong type (R, L, AL, or sor) is found. If an
4679
- // AL is found, change the type of the European number to Arabic
4680
- // number.
4681
- // W3. Change all ALs to R.
4682
- for (var i = 0, cur = outerType; i < len; ++i) {
4683
- var type = types[i];
4684
- if (type == "1" && cur == "r") types[i] = "n";
4685
- else if (isStrong.test(type)) { cur = type; if (type == "r") types[i] = "R"; }
4686
- }
4687
-
4688
- // W4. A single European separator between two European numbers
4689
- // changes to a European number. A single common separator between
4690
- // two numbers of the same type changes to that type.
4691
- for (var i = 1, prev = types[0]; i < len - 1; ++i) {
4692
- var type = types[i];
4693
- if (type == "+" && prev == "1" && types[i+1] == "1") types[i] = "1";
4694
- else if (type == "," && prev == types[i+1] &&
4695
- (prev == "1" || prev == "n")) types[i] = prev;
4696
- prev = type;
4697
- }
4698
-
4699
- // W5. A sequence of European terminators adjacent to European
4700
- // numbers changes to all European numbers.
4701
- // W6. Otherwise, separators and terminators change to Other
4702
- // Neutral.
4703
- for (var i = 0; i < len; ++i) {
4704
- var type = types[i];
4705
- if (type == ",") types[i] = "N";
4706
- else if (type == "%") {
4707
- for (var end = i + 1; end < len && types[end] == "%"; ++end) {}
4708
- var replace = (i && types[i-1] == "!") || (end < len - 1 && types[end] == "1") ? "1" : "N";
4709
- for (var j = i; j < end; ++j) types[j] = replace;
4710
- i = end - 1;
4711
- }
4712
- }
4713
-
4714
- // W7. Search backwards from each instance of a European number
4715
- // until the first strong type (R, L, or sor) is found. If an L is
4716
- // found, then change the type of the European number to L.
4717
- for (var i = 0, cur = outerType; i < len; ++i) {
4718
- var type = types[i];
4719
- if (cur == "L" && type == "1") types[i] = "L";
4720
- else if (isStrong.test(type)) cur = type;
4721
- }
4722
-
4723
- // N1. A sequence of neutrals takes the direction of the
4724
- // surrounding strong text if the text on both sides has the same
4725
- // direction. European and Arabic numbers act as if they were R in
4726
- // terms of their influence on neutrals. Start-of-level-run (sor)
4727
- // and end-of-level-run (eor) are used at level run boundaries.
4728
- // N2. Any remaining neutrals take the embedding direction.
4729
- for (var i = 0; i < len; ++i) {
4730
- if (isNeutral.test(types[i])) {
4731
- for (var end = i + 1; end < len && isNeutral.test(types[end]); ++end) {}
4732
- var before = (i ? types[i-1] : outerType) == "L";
4733
- var after = (end < len - 1 ? types[end] : outerType) == "L";
4734
- var replace = before || after ? "L" : "R";
4735
- for (var j = i; j < end; ++j) types[j] = replace;
4736
- i = end - 1;
4737
- }
4738
- }
4739
-
4740
- // Here we depart from the documented algorithm, in order to avoid
4741
- // building up an actual levels array. Since there are only three
4742
- // levels (0, 1, 2) in an implementation that doesn't take
4743
- // explicit embedding into account, we can build up the order on
4744
- // the fly, without following the level-based algorithm.
4745
- var order = [], m;
4746
- for (var i = 0; i < len;) {
4747
- if (countsAsLeft.test(types[i])) {
4748
- var start = i;
4749
- for (++i; i < len && countsAsLeft.test(types[i]); ++i) {}
4750
- order.push({from: start, to: i, level: 0});
4751
- } else {
4752
- var pos = i, at = order.length;
4753
- for (++i; i < len && types[i] != "L"; ++i) {}
4754
- for (var j = pos; j < i;) {
4755
- if (countsAsNum.test(types[j])) {
4756
- if (pos < j) order.splice(at, 0, {from: pos, to: j, level: 1});
4757
- var nstart = j;
4758
- for (++j; j < i && countsAsNum.test(types[j]); ++j) {}
4759
- order.splice(at, 0, {from: nstart, to: j, level: 2});
4760
- pos = j;
4761
- } else ++j;
4762
- }
4763
- if (pos < i) order.splice(at, 0, {from: pos, to: i, level: 1});
4764
- }
4765
- }
4766
- if (order[0].level == 1 && (m = str.match(/^\s+/))) {
4767
- order[0].from = m[0].length;
4768
- order.unshift({from: 0, to: m[0].length, level: 0});
4769
- }
4770
- if (lst(order).level == 1 && (m = str.match(/\s+$/))) {
4771
- lst(order).to -= m[0].length;
4772
- order.push({from: len - m[0].length, to: len, level: 0});
4773
- }
4774
- if (order[0].level != lst(order).level)
4775
- order.push({from: len, to: len, level: order[0].level});
4776
-
4777
- return order;
4778
- };
4779
- })();
4780
-
4781
- // THE END
4782
-
4783
- CodeMirror.version = "3.02";
4784
-
4785
- return CodeMirror;
4786
- })();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/codemirror.min.css ADDED
@@ -0,0 +1 @@
 
1
+ .CodeMirror{font-family:monospace;height:300px}.CodeMirror-scroll{overflow:auto}.CodeMirror-lines{padding:4px 0}.CodeMirror pre{padding:0 4px}.CodeMirror-scrollbar-filler,.CodeMirror-gutter-filler{background-color:white}.CodeMirror-gutters{border-right:1px solid #ddd;background-color:#f7f7f7;white-space:nowrap}.CodeMirror-linenumber{padding:0 3px 0 5px;min-width:20px;text-align:right;color:#999}.CodeMirror div.CodeMirror-cursor{border-left:1px solid black;z-index:3}.CodeMirror div.CodeMirror-secondarycursor{border-left:1px solid silver}.CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor{width:auto;border:0;background:#7e7;z-index:1}.cm-tab{display:inline-block}.cm-s-default .cm-keyword{color:#708}.cm-s-default .cm-atom{color:#219}.cm-s-default .cm-number{color:#164}.cm-s-default .cm-def{color:#00f}.cm-s-default .cm-variable{color:black}.cm-s-default .cm-variable-2{color:#05a}.cm-s-default .cm-variable-3{color:#085}.cm-s-default .cm-property{color:black}.cm-s-default .cm-operator{color:black}.cm-s-default .cm-comment{color:#a50}.cm-s-default .cm-string{color:#a11}.cm-s-default .cm-string-2{color:#f50}.cm-s-default .cm-meta{color:#555}.cm-s-default .cm-error{color:red}.cm-s-default .cm-qualifier{color:#555}.cm-s-default .cm-builtin{color:#30a}.cm-s-default .cm-bracket{color:#997}.cm-s-default .cm-tag{color:#170}.cm-s-default .cm-attribute{color:#00c}.cm-s-default .cm-header{color:blue}.cm-s-default .cm-quote{color:#090}.cm-s-default .cm-hr{color:#999}.cm-s-default .cm-link{color:#00c}.cm-negative{color:#d44}.cm-positive{color:#292}.cm-header,.cm-strong{font-weight:bold}.cm-em{font-style:italic}.cm-link{text-decoration:underline}.cm-invalidchar{color:red}div.CodeMirror span.CodeMirror-matchingbracket{color:#0f0}div.CodeMirror span.CodeMirror-nonmatchingbracket{color:#f22}.CodeMirror-activeline-background{background:#e8f2ff}.CodeMirror{line-height:1;position:relative;overflow:hidden;background:white;color:black}.CodeMirror-scroll{margin-bottom:-30px;margin-right:-30px;padding-bottom:30px;padding-right:30px;height:100%;outline:0;position:relative;-moz-box-sizing:content-box;box-sizing:content-box}.CodeMirror-sizer{position:relative}.CodeMirror-vscrollbar,.CodeMirror-hscrollbar,.CodeMirror-scrollbar-filler,.CodeMirror-gutter-filler{position:absolute;z-index:6;display:none}.CodeMirror-vscrollbar{right:0;top:0;overflow-x:hidden;overflow-y:scroll}.CodeMirror-hscrollbar{bottom:0;left:0;overflow-y:hidden;overflow-x:scroll}.CodeMirror-scrollbar-filler{right:0;bottom:0}.CodeMirror-gutter-filler{left:0;bottom:0}.CodeMirror-gutters{position:absolute;left:0;top:0;padding-bottom:30px;z-index:3}.CodeMirror-gutter{white-space:normal;height:100%;-moz-box-sizing:content-box;box-sizing:content-box;padding-bottom:30px;margin-bottom:-32px;display:inline-block;*zoom:1;*display:inline}.CodeMirror-gutter-elt{position:absolute;cursor:default;z-index:4}.CodeMirror-lines{cursor:text}.CodeMirror pre{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;border-width:0;background:transparent;font-family:inherit;font-size:inherit;margin:0;white-space:pre;word-wrap:normal;line-height:inherit;color:inherit;z-index:2;position:relative;overflow:visible}.CodeMirror-wrap pre{word-wrap:break-word;white-space:pre-wrap;word-break:normal}.CodeMirror-code pre{border-right:30px solid transparent;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}.CodeMirror-wrap .CodeMirror-code pre{border-right:0;width:auto}.CodeMirror-linebackground{position:absolute;left:0;right:0;top:0;bottom:0;z-index:0}.CodeMirror-linewidget{position:relative;z-index:2;overflow:auto}.CodeMirror-wrap .CodeMirror-scroll{overflow-x:hidden}.CodeMirror-measure{position:absolute;width:100%;height:0;overflow:hidden;visibility:hidden}.CodeMirror-measure pre{position:static}.CodeMirror div.CodeMirror-cursor{position:absolute;visibility:hidden;border-right:0;width:0}.CodeMirror-focused div.CodeMirror-cursor{visibility:visible}.CodeMirror-selected{background:#d9d9d9}.CodeMirror-focused .CodeMirror-selected{background:#d7d4f0}.cm-searching{background:#ffa;background:rgba(255,255,0,.4)}.CodeMirror span{*vertical-align:text-bottom}@media print{.CodeMirror div.CodeMirror-cursor{visibility:hidden}}
lib/css.js DELETED
@@ -1,465 +0,0 @@
1
- CodeMirror.defineMode("css", function(config) {
2
- var indentUnit = config.indentUnit, type;
3
-
4
- var atMediaTypes = keySet([
5
- "all", "aural", "braille", "handheld", "print", "projection", "screen",
6
- "tty", "tv", "embossed"
7
- ]);
8
-
9
- var atMediaFeatures = keySet([
10
- "width", "min-width", "max-width", "height", "min-height", "max-height",
11
- "device-width", "min-device-width", "max-device-width", "device-height",
12
- "min-device-height", "max-device-height", "aspect-ratio",
13
- "min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio",
14
- "min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color",
15
- "max-color", "color-index", "min-color-index", "max-color-index",
16
- "monochrome", "min-monochrome", "max-monochrome", "resolution",
17
- "min-resolution", "max-resolution", "scan", "grid"
18
- ]);
19
-
20
- var propertyKeywords = keySet([
21
- "align-content", "align-items", "align-self", "alignment-adjust",
22
- "alignment-baseline", "anchor-point", "animation", "animation-delay",
23
- "animation-direction", "animation-duration", "animation-iteration-count",
24
- "animation-name", "animation-play-state", "animation-timing-function",
25
- "appearance", "azimuth", "backface-visibility", "background",
26
- "background-attachment", "background-clip", "background-color",
27
- "background-image", "background-origin", "background-position",
28
- "background-repeat", "background-size", "baseline-shift", "binding",
29
- "bleed", "bookmark-label", "bookmark-level", "bookmark-state",
30
- "bookmark-target", "border", "border-bottom", "border-bottom-color",
31
- "border-bottom-left-radius", "border-bottom-right-radius",
32
- "border-bottom-style", "border-bottom-width", "border-collapse",
33
- "border-color", "border-image", "border-image-outset",
34
- "border-image-repeat", "border-image-slice", "border-image-source",
35
- "border-image-width", "border-left", "border-left-color",
36
- "border-left-style", "border-left-width", "border-radius", "border-right",
37
- "border-right-color", "border-right-style", "border-right-width",
38
- "border-spacing", "border-style", "border-top", "border-top-color",
39
- "border-top-left-radius", "border-top-right-radius", "border-top-style",
40
- "border-top-width", "border-width", "bottom", "box-decoration-break",
41
- "box-shadow", "box-sizing", "break-after", "break-before", "break-inside",
42
- "caption-side", "clear", "clip", "color", "color-profile", "column-count",
43
- "column-fill", "column-gap", "column-rule", "column-rule-color",
44
- "column-rule-style", "column-rule-width", "column-span", "column-width",
45
- "columns", "content", "counter-increment", "counter-reset", "crop", "cue",
46
- "cue-after", "cue-before", "cursor", "direction", "display",
47
- "dominant-baseline", "drop-initial-after-adjust",
48
- "drop-initial-after-align", "drop-initial-before-adjust",
49
- "drop-initial-before-align", "drop-initial-size", "drop-initial-value",
50
- "elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis",
51
- "flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap",
52
- "float", "float-offset", "font", "font-feature-settings", "font-family",
53
- "font-kerning", "font-language-override", "font-size", "font-size-adjust",
54
- "font-stretch", "font-style", "font-synthesis", "font-variant",
55
- "font-variant-alternates", "font-variant-caps", "font-variant-east-asian",
56
- "font-variant-ligatures", "font-variant-numeric", "font-variant-position",
57
- "font-weight", "grid-cell", "grid-column", "grid-column-align",
58
- "grid-column-sizing", "grid-column-span", "grid-columns", "grid-flow",
59
- "grid-row", "grid-row-align", "grid-row-sizing", "grid-row-span",
60
- "grid-rows", "grid-template", "hanging-punctuation", "height", "hyphens",
61
- "icon", "image-orientation", "image-rendering", "image-resolution",
62
- "inline-box-align", "justify-content", "left", "letter-spacing",
63
- "line-break", "line-height", "line-stacking", "line-stacking-ruby",
64
- "line-stacking-shift", "line-stacking-strategy", "list-style",
65
- "list-style-image", "list-style-position", "list-style-type", "margin",
66
- "margin-bottom", "margin-left", "margin-right", "margin-top",
67
- "marker-offset", "marks", "marquee-direction", "marquee-loop",
68
- "marquee-play-count", "marquee-speed", "marquee-style", "max-height",
69
- "max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index",
70
- "nav-left", "nav-right", "nav-up", "opacity", "order", "orphans", "outline",
71
- "outline-color", "outline-offset", "outline-style", "outline-width",
72
- "overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y",
73
- "padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
74
- "page", "page-break-after", "page-break-before", "page-break-inside",
75
- "page-policy", "pause", "pause-after", "pause-before", "perspective",
76
- "perspective-origin", "pitch", "pitch-range", "play-during", "position",
77
- "presentation-level", "punctuation-trim", "quotes", "rendering-intent",
78
- "resize", "rest", "rest-after", "rest-before", "richness", "right",
79
- "rotation", "rotation-point", "ruby-align", "ruby-overhang",
80
- "ruby-position", "ruby-span", "size", "speak", "speak-as", "speak-header",
81
- "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
82
- "tab-size", "table-layout", "target", "target-name", "target-new",
83
- "target-position", "text-align", "text-align-last", "text-decoration",
84
- "text-decoration-color", "text-decoration-line", "text-decoration-skip",
85
- "text-decoration-style", "text-emphasis", "text-emphasis-color",
86
- "text-emphasis-position", "text-emphasis-style", "text-height",
87
- "text-indent", "text-justify", "text-outline", "text-shadow",
88
- "text-space-collapse", "text-transform", "text-underline-position",
89
- "text-wrap", "top", "transform", "transform-origin", "transform-style",
90
- "transition", "transition-delay", "transition-duration",
91
- "transition-property", "transition-timing-function", "unicode-bidi",
92
- "vertical-align", "visibility", "voice-balance", "voice-duration",
93
- "voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
94
- "voice-volume", "volume", "white-space", "widows", "width", "word-break",
95
- "word-spacing", "word-wrap", "z-index"
96
- ]);
97
-
98
- var colorKeywords = keySet([
99
- "black", "silver", "gray", "white", "maroon", "red", "purple", "fuchsia",
100
- "green", "lime", "olive", "yellow", "navy", "blue", "teal", "aqua"
101
- ]);
102
-
103
- var valueKeywords = keySet([
104
- "above", "absolute", "activeborder", "activecaption", "afar",
105
- "after-white-space", "ahead", "alias", "all", "all-scroll", "alternate",
106
- "always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
107
- "arabic-indic", "armenian", "asterisks", "auto", "avoid", "background",
108
- "backwards", "baseline", "below", "bidi-override", "binary", "bengali",
109
- "blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
110
- "both", "bottom", "break-all", "break-word", "button", "button-bevel",
111
- "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "cambodian",
112
- "capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
113
- "cell", "center", "checkbox", "circle", "cjk-earthly-branch",
114
- "cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
115
- "col-resize", "collapse", "compact", "condensed", "contain", "content",
116
- "content-box", "context-menu", "continuous", "copy", "cover", "crop",
117
- "cross", "crosshair", "currentcolor", "cursive", "dashed", "decimal",
118
- "decimal-leading-zero", "default", "default-button", "destination-atop",
119
- "destination-in", "destination-out", "destination-over", "devanagari",
120
- "disc", "discard", "document", "dot-dash", "dot-dot-dash", "dotted",
121
- "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
122
- "element", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
123
- "ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
124
- "ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er",
125
- "ethiopic-halehame-aa-et", "ethiopic-halehame-am-et",
126
- "ethiopic-halehame-gez", "ethiopic-halehame-om-et",
127
- "ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
128
- "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et",
129
- "ethiopic-halehame-tig", "ew-resize", "expanded", "extra-condensed",
130
- "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "footnotes",
131
- "forwards", "from", "geometricPrecision", "georgian", "graytext", "groove",
132
- "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hebrew",
133
- "help", "hidden", "hide", "higher", "highlight", "highlighttext",
134
- "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "icon", "ignore",
135
- "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
136
- "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
137
- "inline-block", "inline-table", "inset", "inside", "intrinsic", "invert",
138
- "italic", "justify", "kannada", "katakana", "katakana-iroha", "khmer",
139
- "landscape", "lao", "large", "larger", "left", "level", "lighter",
140
- "line-through", "linear", "lines", "list-item", "listbox", "listitem",
141
- "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
142
- "lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
143
- "lower-roman", "lowercase", "ltr", "malayalam", "match",
144
- "media-controls-background", "media-current-time-display",
145
- "media-fullscreen-button", "media-mute-button", "media-play-button",
146
- "media-return-to-realtime-button", "media-rewind-button",
147
- "media-seek-back-button", "media-seek-forward-button", "media-slider",
148
- "media-sliderthumb", "media-time-remaining-display", "media-volume-slider",
149
- "media-volume-slider-container", "media-volume-sliderthumb", "medium",
150
- "menu", "menulist", "menulist-button", "menulist-text",
151
- "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic",
152
- "mix", "mongolian", "monospace", "move", "multiple", "myanmar", "n-resize",
153
- "narrower", "navy", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
154
- "no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
155
- "ns-resize", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote",
156
- "optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
157
- "outside", "overlay", "overline", "padding", "padding-box", "painted",
158
- "paused", "persian", "plus-darker", "plus-lighter", "pointer", "portrait",
159
- "pre", "pre-line", "pre-wrap", "preserve-3d", "progress", "push-button",
160
- "radio", "read-only", "read-write", "read-write-plaintext-only", "relative",
161
- "repeat", "repeat-x", "repeat-y", "reset", "reverse", "rgb", "rgba",
162
- "ridge", "right", "round", "row-resize", "rtl", "run-in", "running",
163
- "s-resize", "sans-serif", "scroll", "scrollbar", "se-resize", "searchfield",
164
- "searchfield-cancel-button", "searchfield-decoration",
165
- "searchfield-results-button", "searchfield-results-decoration",
166
- "semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama",
167
- "single", "skip-white-space", "slide", "slider-horizontal",
168
- "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
169
- "small", "small-caps", "small-caption", "smaller", "solid", "somali",
170
- "source-atop", "source-in", "source-out", "source-over", "space", "square",
171
- "square-button", "start", "static", "status-bar", "stretch", "stroke",
172
- "sub", "subpixel-antialiased", "super", "sw-resize", "table",
173
- "table-caption", "table-cell", "table-column", "table-column-group",
174
- "table-footer-group", "table-header-group", "table-row", "table-row-group",
175
- "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai",
176
- "thick", "thin", "threeddarkshadow", "threedface", "threedhighlight",
177
- "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er",
178
- "tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top",
179
- "transparent", "ultra-condensed", "ultra-expanded", "underline", "up",
180
- "upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
181
- "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
182
- "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
183
- "visibleStroke", "visual", "w-resize", "wait", "wave", "white", "wider",
184
- "window", "windowframe", "windowtext", "x-large", "x-small", "xor",
185
- "xx-large", "xx-small", "yellow"
186
- ]);
187
-
188
- function keySet(array) { var keys = {}; for (var i = 0; i < array.length; ++i) keys[array[i]] = true; return keys; }
189
- function ret(style, tp) {type = tp; return style;}
190
-
191
- function tokenBase(stream, state) {
192
- var ch = stream.next();
193
- if (ch == "@") {stream.eatWhile(/[\w\\\-]/); return ret("def", stream.current());}
194
- else if (ch == "/" && stream.eat("*")) {
195
- state.tokenize = tokenCComment;
196
- return tokenCComment(stream, state);
197
- }
198
- else if (ch == "<" && stream.eat("!")) {
199
- state.tokenize = tokenSGMLComment;
200
- return tokenSGMLComment(stream, state);
201
- }
202
- else if (ch == "=") ret(null, "compare");
203
- else if ((ch == "~" || ch == "|") && stream.eat("=")) return ret(null, "compare");
204
- else if (ch == "\"" || ch == "'") {
205
- state.tokenize = tokenString(ch);
206
- return state.tokenize(stream, state);
207
- }
208
- else if (ch == "#") {
209
- stream.eatWhile(/[\w\\\-]/);
210
- return ret("atom", "hash");
211
- }
212
- else if (ch == "!") {
213
- stream.match(/^\s*\w*/);
214
- return ret("keyword", "important");
215
- }
216
- else if (/\d/.test(ch)) {
217
- stream.eatWhile(/[\w.%]/);
218
- return ret("number", "unit");
219
- }
220
- else if (ch === "-") {
221
- if (/\d/.test(stream.peek())) {
222
- stream.eatWhile(/[\w.%]/);
223
- return ret("number", "unit");
224
- } else if (stream.match(/^[^-]+-/)) {
225
- return ret("meta", "meta");
226
- }
227
- }
228
- else if (/[,+>*\/]/.test(ch)) {
229
- return ret(null, "select-op");
230
- }
231
- else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
232
- return ret("qualifier", "qualifier");
233
- }
234
- else if (ch == ":") {
235
- return ret("operator", ch);
236
- }
237
- else if (/[;{}\[\]\(\)]/.test(ch)) {
238
- return ret(null, ch);
239
- }
240
- else if (ch == "u" && stream.match("rl(")) {
241
- stream.backUp(1);
242
- state.tokenize = tokenParenthesized;
243
- return ret("property", "variable");
244
- }
245
- else {
246
- stream.eatWhile(/[\w\\\-]/);
247
- return ret("property", "variable");
248
- }
249
- }
250
-
251
- function tokenCComment(stream, state) {
252
- var maybeEnd = false, ch;
253
- while ((ch = stream.next()) != null) {
254
- if (maybeEnd && ch == "/") {
255
- state.tokenize = tokenBase;
256
- break;
257
- }
258
- maybeEnd = (ch == "*");
259
- }
260
- return ret("comment", "comment");
261
- }
262
-
263
- function tokenSGMLComment(stream, state) {
264
- var dashes = 0, ch;
265
- while ((ch = stream.next()) != null) {
266
- if (dashes >= 2 && ch == ">") {
267
- state.tokenize = tokenBase;
268
- break;
269
- }
270
- dashes = (ch == "-") ? dashes + 1 : 0;
271
- }
272
- return ret("comment", "comment");
273
- }
274
-
275
- function tokenString(quote, nonInclusive) {
276
- return function(stream, state) {
277
- var escaped = false, ch;
278
- while ((ch = stream.next()) != null) {
279
- if (ch == quote && !escaped)
280
- break;
281
- escaped = !escaped && ch == "\\";
282
- }
283
- if (!escaped) {
284
- if (nonInclusive) stream.backUp(1);
285
- state.tokenize = tokenBase;
286
- }
287
- return ret("string", "string");
288
- };
289
- }
290
-
291
- function tokenParenthesized(stream, state) {
292
- stream.next(); // Must be '('
293
- if (!stream.match(/\s*[\"\']/, false))
294
- state.tokenize = tokenString(")", true);
295
- else
296
- state.tokenize = tokenBase;
297
- return ret(null, "(");
298
- }
299
-
300
- return {
301
- startState: function(base) {
302
- return {tokenize: tokenBase,
303
- baseIndent: base || 0,
304
- stack: []};
305
- },
306
-
307
- token: function(stream, state) {
308
-
309
- // Use these terms when applicable (see http://www.xanthir.com/blog/b4E50)
310
- //
311
- // rule** or **ruleset:
312
- // A selector + braces combo, or an at-rule.
313
- //
314
- // declaration block:
315
- // A sequence of declarations.
316
- //
317
- // declaration:
318
- // A property + colon + value combo.
319
- //
320
- // property value:
321
- // The entire value of a property.
322
- //
323
- // component value:
324
- // A single piece of a property value. Like the 5px in
325
- // text-shadow: 0 0 5px blue;. Can also refer to things that are
326
- // multiple terms, like the 1-4 terms that make up the background-size
327
- // portion of the background shorthand.
328
- //
329
- // term:
330
- // The basic unit of author-facing CSS, like a single number (5),
331
- // dimension (5px), string ("foo"), or function. Officially defined
332
- // by the CSS 2.1 grammar (look for the 'term' production)
333
- //
334
- //
335
- // simple selector:
336
- // A single atomic selector, like a type selector, an attr selector, a
337
- // class selector, etc.
338
- //
339
- // compound selector:
340
- // One or more simple selectors without a combinator. div.example is
341
- // compound, div > .example is not.
342
- //
343
- // complex selector:
344
- // One or more compound selectors chained with combinators.
345
- //
346
- // combinator:
347
- // The parts of selectors that express relationships. There are four
348
- // currently - the space (descendant combinator), the greater-than
349
- // bracket (child combinator), the plus sign (next sibling combinator),
350
- // and the tilda (following sibling combinator).
351
- //
352
- // sequence of selectors:
353
- // One or more of the named type of selector chained with commas.
354
-
355
- if (state.tokenize == tokenBase && stream.eatSpace()) return null;
356
- var style = state.tokenize(stream, state);
357
-
358
- // Changing style returned based on context
359
- var context = state.stack[state.stack.length-1];
360
- if (style == "property") {
361
- if (context == "propertyValue"){
362
- if (valueKeywords[stream.current()]) {
363
- style = "string-2";
364
- } else if (colorKeywords[stream.current()]) {
365
- style = "keyword";
366
- } else {
367
- style = "variable-2";
368
- }
369
- } else if (context == "rule") {
370
- if (!propertyKeywords[stream.current()]) {
371
- style += " error";
372
- }
373
- } else if (!context || context == "@media{") {
374
- style = "tag";
375
- } else if (context == "@media") {
376
- if (atMediaTypes[stream.current()]) {
377
- style = "attribute"; // Known attribute
378
- } else if (/^(only|not)$/i.test(stream.current())) {
379
- style = "keyword";
380
- } else if (stream.current().toLowerCase() == "and") {
381
- style = "error"; // "and" is only allowed in @mediaType
382
- } else if (atMediaFeatures[stream.current()]) {
383
- style = "error"; // Known property, should be in @mediaType(
384
- } else {
385
- // Unknown, expecting keyword or attribute, assuming attribute
386
- style = "attribute error";
387
- }
388
- } else if (context == "@mediaType") {
389
- if (atMediaTypes[stream.current()]) {
390
- style = "attribute";
391
- } else if (stream.current().toLowerCase() == "and") {
392
- style = "operator";
393
- } else if (/^(only|not)$/i.test(stream.current())) {
394
- style = "error"; // Only allowed in @media
395
- } else if (atMediaFeatures[stream.current()]) {
396
- style = "error"; // Known property, should be in parentheses
397
- } else {
398
- // Unknown attribute or property, but expecting property (preceded
399
- // by "and"). Should be in parentheses
400
- style = "error";
401
- }
402
- } else if (context == "@mediaType(") {
403
- if (propertyKeywords[stream.current()]) {
404
- // do nothing, remains "property"
405
- } else if (atMediaTypes[stream.current()]) {
406
- style = "error"; // Known property, should be in parentheses
407
- } else if (stream.current().toLowerCase() == "and") {
408
- style = "operator";
409
- } else if (/^(only|not)$/i.test(stream.current())) {
410
- style = "error"; // Only allowed in @media
411
- } else {
412
- style += " error";
413
- }
414
- } else {
415
- style = "error";
416
- }
417
- } else if (style == "atom") {
418
- if(!context || context == "@media{") {
419
- style = "builtin";
420
- } else if (context == "propertyValue") {
421
- if (!/^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/.test(stream.current())) {
422
- style += " error";
423
- }
424
- } else {
425
- style = "error";
426
- }
427
- } else if (context == "@media" && type == "{") {
428
- style = "error";
429
- }
430
-
431
- // Push/pop context stack
432
- if (type == "{") {
433
- if (context == "@media" || context == "@mediaType") {
434
- state.stack.pop();
435
- state.stack[state.stack.length-1] = "@media{";
436
- }
437
- else state.stack.push("rule");
438
- }
439
- else if (type == "}") {
440
- state.stack.pop();
441
- if (context == "propertyValue") state.stack.pop();
442
- }
443
- else if (type == "@media") state.stack.push("@media");
444
- else if (context == "@media" && /\b(keyword|attribute)\b/.test(style))
445
- state.stack.push("@mediaType");
446
- else if (context == "@mediaType" && stream.current() == ",") state.stack.pop();
447
- else if (context == "@mediaType" && type == "(") state.stack.push("@mediaType(");
448
- else if (context == "@mediaType(" && type == ")") state.stack.pop();
449
- else if (context == "rule" && type == ":") state.stack.push("propertyValue");
450
- else if (context == "propertyValue" && type == ";") state.stack.pop();
451
- return style;
452
- },
453
-
454
- indent: function(state, textAfter) {
455
- var n = state.stack.length;
456
- if (/^\}/.test(textAfter))
457
- n -= state.stack[state.stack.length-1] == "propertyValue" ? 2 : 1;
458
- return state.baseIndent + n * indentUnit;
459
- },
460
-
461
- electricChars: "}"
462
- };
463
- });
464
-
465
- CodeMirror.defineMIME("text/css", "css");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/htmlmixed.js DELETED
@@ -1,84 +0,0 @@
1
- CodeMirror.defineMode("htmlmixed", function(config) {
2
- var htmlMode = CodeMirror.getMode(config, {name: "xml", htmlMode: true});
3
- var jsMode = CodeMirror.getMode(config, "javascript");
4
- var cssMode = CodeMirror.getMode(config, "css");
5
-
6
- function html(stream, state) {
7
- var style = htmlMode.token(stream, state.htmlState);
8
- if (/(?:^|\s)tag(?:\s|$)/.test(style) && stream.current() == ">" && state.htmlState.context) {
9
- if (/^script$/i.test(state.htmlState.context.tagName)) {
10
- state.token = javascript;
11
- state.localState = jsMode.startState(htmlMode.indent(state.htmlState, ""));
12
- }
13
- else if (/^style$/i.test(state.htmlState.context.tagName)) {
14
- state.token = css;
15
- state.localState = cssMode.startState(htmlMode.indent(state.htmlState, ""));
16
- }
17
- }
18
- return style;
19
- }
20
- function maybeBackup(stream, pat, style) {
21
- var cur = stream.current();
22
- var close = cur.search(pat), m;
23
- if (close > -1) stream.backUp(cur.length - close);
24
- else if (m = cur.match(/<\/?$/)) {
25
- stream.backUp(cur.length);
26
- if (!stream.match(pat, false)) stream.match(cur[0]);
27
- }
28
- return style;
29
- }
30
- function javascript(stream, state) {
31
- if (stream.match(/^<\/\s*script\s*>/i, false)) {
32
- state.token = html;
33
- state.localState = null;
34
- return html(stream, state);
35
- }
36
- return maybeBackup(stream, /<\/\s*script\s*>/,
37
- jsMode.token(stream, state.localState));
38
- }
39
- function css(stream, state) {
40
- if (stream.match(/^<\/\s*style\s*>/i, false)) {
41
- state.token = html;
42
- state.localState = null;
43
- return html(stream, state);
44
- }
45
- return maybeBackup(stream, /<\/\s*style\s*>/,
46
- cssMode.token(stream, state.localState));
47
- }
48
-
49
- return {
50
- startState: function() {
51
- var state = htmlMode.startState();
52
- return {token: html, localState: null, mode: "html", htmlState: state};
53
- },
54
-
55
- copyState: function(state) {
56
- if (state.localState)
57
- var local = CodeMirror.copyState(state.token == css ? cssMode : jsMode, state.localState);
58
- return {token: state.token, localState: local, mode: state.mode,
59
- htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
60
- },
61
-
62
- token: function(stream, state) {
63
- return state.token(stream, state);
64
- },
65
-
66
- indent: function(state, textAfter) {
67
- if (state.token == html || /^\s*<\//.test(textAfter))
68
- return htmlMode.indent(state.htmlState, textAfter);
69
- else if (state.token == javascript)
70
- return jsMode.indent(state.localState, textAfter);
71
- else
72
- return cssMode.indent(state.localState, textAfter);
73
- },
74
-
75
- electricChars: "/{}:",
76
-
77
- innerMode: function(state) {
78
- var mode = state.token == html ? htmlMode : state.token == javascript ? jsMode : cssMode;
79
- return {state: state.localState || state.htmlState, mode: mode};
80
- }
81
- };
82
- }, "xml", "javascript", "css");
83
-
84
- CodeMirror.defineMIME("text/html", "htmlmixed");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/javascript.js DELETED
@@ -1,422 +0,0 @@
1
- // TODO actually recognize syntax of TypeScript constructs
2
-
3
- CodeMirror.defineMode("javascript", function(config, parserConfig) {
4
- var indentUnit = config.indentUnit;
5
- var jsonMode = parserConfig.json;
6
- var isTS = parserConfig.typescript;
7
-
8
- // Tokenizer
9
-
10
- var keywords = function(){
11
- function kw(type) {return {type: type, style: "keyword"};}
12
- var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
13
- var operator = kw("operator"), atom = {type: "atom", style: "atom"};
14
-
15
- var jsKeywords = {
16
- "if": A, "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
17
- "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C,
18
- "var": kw("var"), "const": kw("var"), "let": kw("var"),
19
- "function": kw("function"), "catch": kw("catch"),
20
- "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
21
- "in": operator, "typeof": operator, "instanceof": operator,
22
- "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom
23
- };
24
-
25
- // Extend the 'normal' keywords with the TypeScript language extensions
26
- if (isTS) {
27
- var type = {type: "variable", style: "variable-3"};
28
- var tsKeywords = {
29
- // object-like things
30
- "interface": kw("interface"),
31
- "class": kw("class"),
32
- "extends": kw("extends"),
33
- "constructor": kw("constructor"),
34
-
35
- // scope modifiers
36
- "public": kw("public"),
37
- "private": kw("private"),
38
- "protected": kw("protected"),
39
- "static": kw("static"),
40
-
41
- "super": kw("super"),
42
-
43
- // types
44
- "string": type, "number": type, "bool": type, "any": type
45
- };
46
-
47
- for (var attr in tsKeywords) {
48
- jsKeywords[attr] = tsKeywords[attr];
49
- }
50
- }
51
-
52
- return jsKeywords;
53
- }();
54
-
55
- var isOperatorChar = /[+\-*&%=<>!?|]/;
56
-
57
- function chain(stream, state, f) {
58
- state.tokenize = f;
59
- return f(stream, state);
60
- }
61
-
62
- function nextUntilUnescaped(stream, end) {
63
- var escaped = false, next;
64
- while ((next = stream.next()) != null) {
65
- if (next == end && !escaped)
66
- return false;
67
- escaped = !escaped && next == "\\";
68
- }
69
- return escaped;
70
- }
71
-
72
- // Used as scratch variables to communicate multiple values without
73
- // consing up tons of objects.
74
- var type, content;
75
- function ret(tp, style, cont) {
76
- type = tp; content = cont;
77
- return style;
78
- }
79
-
80
- function jsTokenBase(stream, state) {
81
- var ch = stream.next();
82
- if (ch == '"' || ch == "'")
83
- return chain(stream, state, jsTokenString(ch));
84
- else if (/[\[\]{}\(\),;\:\.]/.test(ch))
85
- return ret(ch);
86
- else if (ch == "0" && stream.eat(/x/i)) {
87
- stream.eatWhile(/[\da-f]/i);
88
- return ret("number", "number");
89
- }
90
- else if (/\d/.test(ch) || ch == "-" && stream.eat(/\d/)) {
91
- stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
92
- return ret("number", "number");
93
- }
94
- else if (ch == "/") {
95
- if (stream.eat("*")) {
96
- return chain(stream, state, jsTokenComment);
97
- }
98
- else if (stream.eat("/")) {
99
- stream.skipToEnd();
100
- return ret("comment", "comment");
101
- }
102
- else if (state.lastType == "operator" || state.lastType == "keyword c" ||
103
- /^[\[{}\(,;:]$/.test(state.lastType)) {
104
- nextUntilUnescaped(stream, "/");
105
- stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla
106
- return ret("regexp", "string-2");
107
- }
108
- else {
109
- stream.eatWhile(isOperatorChar);
110
- return ret("operator", null, stream.current());
111
- }
112
- }
113
- else if (ch == "#") {
114
- stream.skipToEnd();
115
- return ret("error", "error");
116
- }
117
- else if (isOperatorChar.test(ch)) {
118
- stream.eatWhile(isOperatorChar);
119
- return ret("operator", null, stream.current());
120
- }
121
- else {
122
- stream.eatWhile(/[\w\$_]/);
123
- var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
124
- return (known && state.lastType != ".") ? ret(known.type, known.style, word) :
125
- ret("variable", "variable", word);
126
- }
127
- }
128
-
129
- function jsTokenString(quote) {
130
- return function(stream, state) {
131
- if (!nextUntilUnescaped(stream, quote))
132
- state.tokenize = jsTokenBase;
133
- return ret("string", "string");
134
- };
135
- }
136
-
137
- function jsTokenComment(stream, state) {
138
- var maybeEnd = false, ch;
139
- while (ch = stream.next()) {
140
- if (ch == "/" && maybeEnd) {
141
- state.tokenize = jsTokenBase;
142
- break;
143
- }
144
- maybeEnd = (ch == "*");
145
- }
146
- return ret("comment", "comment");
147
- }
148
-
149
- // Parser
150
-
151
- var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true};
152
-
153
- function JSLexical(indented, column, type, align, prev, info) {
154
- this.indented = indented;
155
- this.column = column;
156
- this.type = type;
157
- this.prev = prev;
158
- this.info = info;
159
- if (align != null) this.align = align;
160
- }
161
-
162
- function inScope(state, varname) {
163
- for (var v = state.localVars; v; v = v.next)
164
- if (v.name == varname) return true;
165
- }
166
-
167
- function parseJS(state, style, type, content, stream) {
168
- var cc = state.cc;
169
- // Communicate our context to the combinators.
170
- // (Less wasteful than consing up a hundred closures on every call.)
171
- cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
172
-
173
- if (!state.lexical.hasOwnProperty("align"))
174
- state.lexical.align = true;
175
-
176
- while(true) {
177
- var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
178
- if (combinator(type, content)) {
179
- while(cc.length && cc[cc.length - 1].lex)
180
- cc.pop()();
181
- if (cx.marked) return cx.marked;
182
- if (type == "variable" && inScope(state, content)) return "variable-2";
183
- return style;
184
- }
185
- }
186
- }
187
-
188
- // Combinator utils
189
-
190
- var cx = {state: null, column: null, marked: null, cc: null};
191
- function pass() {
192
- for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
193
- }
194
- function cont() {
195
- pass.apply(null, arguments);
196
- return true;
197
- }
198
- function register(varname) {
199
- function inList(list) {
200
- for (var v = list; v; v = v.next)
201
- if (v.name == varname) return true;
202
- return false;
203
- }
204
- var state = cx.state;
205
- if (state.context) {
206
- cx.marked = "def";
207
- if (inList(state.localVars)) return;
208
- state.localVars = {name: varname, next: state.localVars};
209
- } else {
210
- if (inList(state.globalVars)) return;
211
- state.globalVars = {name: varname, next: state.globalVars};
212
- }
213
- }
214
-
215
- // Combinators
216
-
217
- var defaultVars = {name: "this", next: {name: "arguments"}};
218
- function pushcontext() {
219
- cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
220
- cx.state.localVars = defaultVars;
221
- }
222
- function popcontext() {
223
- cx.state.localVars = cx.state.context.vars;
224
- cx.state.context = cx.state.context.prev;
225
- }
226
- function pushlex(type, info) {
227
- var result = function() {
228
- var state = cx.state;
229
- state.lexical = new JSLexical(state.indented, cx.stream.column(), type, null, state.lexical, info);
230
- };
231
- result.lex = true;
232
- return result;
233
- }
234
- function poplex() {
235
- var state = cx.state;
236
- if (state.lexical.prev) {
237
- if (state.lexical.type == ")")
238
- state.indented = state.lexical.indented;
239
- state.lexical = state.lexical.prev;
240
- }
241
- }
242
- poplex.lex = true;
243
-
244
- function expect(wanted) {
245
- return function expecting(type) {
246
- if (type == wanted) return cont();
247
- else if (wanted == ";") return pass();
248
- else return cont(arguments.callee);
249
- };
250
- }
251
-
252
- function statement(type) {
253
- if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex);
254
- if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
255
- if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
256
- if (type == "{") return cont(pushlex("}"), block, poplex);
257
- if (type == ";") return cont();
258
- if (type == "function") return cont(functiondef);
259
- if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"),
260
- poplex, statement, poplex);
261
- if (type == "variable") return cont(pushlex("stat"), maybelabel);
262
- if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
263
- block, poplex, poplex);
264
- if (type == "case") return cont(expression, expect(":"));
265
- if (type == "default") return cont(expect(":"));
266
- if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
267
- statement, poplex, popcontext);
268
- return pass(pushlex("stat"), expression, expect(";"), poplex);
269
- }
270
- function expression(type) {
271
- if (atomicTypes.hasOwnProperty(type)) return cont(maybeoperator);
272
- if (type == "function") return cont(functiondef);
273
- if (type == "keyword c") return cont(maybeexpression);
274
- if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeoperator);
275
- if (type == "operator") return cont(expression);
276
- if (type == "[") return cont(pushlex("]"), commasep(expression, "]"), poplex, maybeoperator);
277
- if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeoperator);
278
- return cont();
279
- }
280
- function maybeexpression(type) {
281
- if (type.match(/[;\}\)\],]/)) return pass();
282
- return pass(expression);
283
- }
284
-
285
- function maybeoperator(type, value) {
286
- if (type == "operator" && /\+\+|--/.test(value)) return cont(maybeoperator);
287
- if (type == "operator" && value == "?") return cont(expression, expect(":"), expression);
288
- if (type == ";") return;
289
- if (type == "(") return cont(pushlex(")"), commasep(expression, ")"), poplex, maybeoperator);
290
- if (type == ".") return cont(property, maybeoperator);
291
- if (type == "[") return cont(pushlex("]"), expression, expect("]"), poplex, maybeoperator);
292
- }
293
- function maybelabel(type) {
294
- if (type == ":") return cont(poplex, statement);
295
- return pass(maybeoperator, expect(";"), poplex);
296
- }
297
- function property(type) {
298
- if (type == "variable") {cx.marked = "property"; return cont();}
299
- }
300
- function objprop(type) {
301
- if (type == "variable") cx.marked = "property";
302
- if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expression);
303
- }
304
- function commasep(what, end) {
305
- function proceed(type) {
306
- if (type == ",") return cont(what, proceed);
307
- if (type == end) return cont();
308
- return cont(expect(end));
309
- }
310
- return function commaSeparated(type) {
311
- if (type == end) return cont();
312
- else return pass(what, proceed);
313
- };
314
- }
315
- function block(type) {
316
- if (type == "}") return cont();
317
- return pass(statement, block);
318
- }
319
- function maybetype(type) {
320
- if (type == ":") return cont(typedef);
321
- return pass();
322
- }
323
- function typedef(type) {
324
- if (type == "variable"){cx.marked = "variable-3"; return cont();}
325
- return pass();
326
- }
327
- function vardef1(type, value) {
328
- if (type == "variable") {
329
- register(value);
330
- return isTS ? cont(maybetype, vardef2) : cont(vardef2);
331
- }
332
- return pass();
333
- }
334
- function vardef2(type, value) {
335
- if (value == "=") return cont(expression, vardef2);
336
- if (type == ",") return cont(vardef1);
337
- }
338
- function forspec1(type) {
339
- if (type == "var") return cont(vardef1, expect(";"), forspec2);
340
- if (type == ";") return cont(forspec2);
341
- if (type == "variable") return cont(formaybein);
342
- return cont(forspec2);
343
- }
344
- function formaybein(_type, value) {
345
- if (value == "in") return cont(expression);
346
- return cont(maybeoperator, forspec2);
347
- }
348
- function forspec2(type, value) {
349
- if (type == ";") return cont(forspec3);
350
- if (value == "in") return cont(expression);
351
- return cont(expression, expect(";"), forspec3);
352
- }
353
- function forspec3(type) {
354
- if (type != ")") cont(expression);
355
- }
356
- function functiondef(type, value) {
357
- if (type == "variable") {register(value); return cont(functiondef);}
358
- if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, statement, popcontext);
359
- }
360
- function funarg(type, value) {
361
- if (type == "variable") {register(value); return isTS ? cont(maybetype) : cont();}
362
- }
363
-
364
- // Interface
365
-
366
- return {
367
- startState: function(basecolumn) {
368
- return {
369
- tokenize: jsTokenBase,
370
- lastType: null,
371
- cc: [],
372
- lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
373
- localVars: parserConfig.localVars,
374
- globalVars: parserConfig.globalVars,
375
- context: parserConfig.localVars && {vars: parserConfig.localVars},
376
- indented: 0
377
- };
378
- },
379
-
380
- token: function(stream, state) {
381
- if (stream.sol()) {
382
- if (!state.lexical.hasOwnProperty("align"))
383
- state.lexical.align = false;
384
- state.indented = stream.indentation();
385
- }
386
- if (stream.eatSpace()) return null;
387
- var style = state.tokenize(stream, state);
388
- if (type == "comment") return style;
389
- state.lastType = type;
390
- return parseJS(state, style, type, content, stream);
391
- },
392
-
393
- indent: function(state, textAfter) {
394
- if (state.tokenize == jsTokenComment) return CodeMirror.Pass;
395
- if (state.tokenize != jsTokenBase) return 0;
396
- var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
397
- if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
398
- var type = lexical.type, closing = firstChar == type;
399
- if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? 4 : 0);
400
- else if (type == "form" && firstChar == "{") return lexical.indented;
401
- else if (type == "form") return lexical.indented + indentUnit;
402
- else if (type == "stat")
403
- return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? indentUnit : 0);
404
- else if (lexical.info == "switch" && !closing)
405
- return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
406
- else if (lexical.align) return lexical.column + (closing ? 0 : 1);
407
- else return lexical.indented + (closing ? 0 : indentUnit);
408
- },
409
-
410
- electricChars: ":{}",
411
-
412
- jsonMode: jsonMode
413
- };
414
- });
415
-
416
- CodeMirror.defineMIME("text/javascript", "javascript");
417
- CodeMirror.defineMIME("text/ecmascript", "javascript");
418
- CodeMirror.defineMIME("application/javascript", "javascript");
419
- CodeMirror.defineMIME("application/ecmascript", "javascript");
420
- CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
421
- CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
422
- CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/util/active-line.js DELETED
@@ -1,39 +0,0 @@
1
- // Because sometimes you need to style the cursor's line.
2
- //
3
- // Adds an option 'styleActiveLine' which, when enabled, gives the
4
- // active line's wrapping <div> the CSS class "CodeMirror-activeline",
5
- // and gives its background <div> the class "CodeMirror-activeline-background".
6
-
7
- (function() {
8
- "use strict";
9
- var WRAP_CLASS = "CodeMirror-activeline";
10
- var BACK_CLASS = "CodeMirror-activeline-background";
11
-
12
- CodeMirror.defineOption("styleActiveLine", false, function(cm, val, old) {
13
- var prev = old && old != CodeMirror.Init;
14
- if (val && !prev) {
15
- updateActiveLine(cm);
16
- cm.on("cursorActivity", updateActiveLine);
17
- } else if (!val && prev) {
18
- cm.off("cursorActivity", updateActiveLine);
19
- clearActiveLine(cm);
20
- delete cm._activeLine;
21
- }
22
- });
23
-
24
- function clearActiveLine(cm) {
25
- if ("_activeLine" in cm) {
26
- cm.removeLineClass(cm._activeLine, "wrap", WRAP_CLASS);
27
- cm.removeLineClass(cm._activeLine, "background", BACK_CLASS);
28
- }
29
- }
30
-
31
- function updateActiveLine(cm) {
32
- var line = cm.getLineHandle(cm.getCursor().line);
33
- if (cm._activeLine == line) return;
34
- clearActiveLine(cm);
35
- cm.addLineClass(line, "wrap", WRAP_CLASS);
36
- cm.addLineClass(line, "background", BACK_CLASS);
37
- cm._activeLine = line;
38
- }
39
- })();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/util/formatting.js DELETED
@@ -1,114 +0,0 @@
1
- (function() {
2
-
3
- CodeMirror.extendMode("css", {
4
- commentStart: "/*",
5
- commentEnd: "*/",
6
- newlineAfterToken: function(_type, content) {
7
- return /^[;{}]$/.test(content);
8
- }
9
- });
10
-
11
- CodeMirror.extendMode("javascript", {
12
- commentStart: "/*",
13
- commentEnd: "*/",
14
- // FIXME semicolons inside of for
15
- newlineAfterToken: function(_type, content, textAfter, state) {
16
- if (this.jsonMode) {
17
- return /^[\[,{]$/.test(content) || /^}/.test(textAfter);
18
- } else {
19
- if (content == ";" && state.lexical && state.lexical.type == ")") return false;
20
- return /^[;{}]$/.test(content) && !/^;/.test(textAfter);
21
- }
22
- }
23
- });
24
-
25
- var inlineElements = /^(a|abbr|acronym|area|base|bdo|big|br|button|caption|cite|code|col|colgroup|dd|del|dfn|em|frame|hr|iframe|img|input|ins|kbd|label|legend|link|map|object|optgroup|option|param|q|samp|script|select|small|span|strong|sub|sup|textarea|tt|var)$/;
26
-
27
- CodeMirror.extendMode("xml", {
28
- commentStart: "<!--",
29
- commentEnd: "-->",
30
- newlineAfterToken: function(type, content, textAfter, state) {
31
- var inline = false;
32
- if (this.configuration == "html")
33
- inline = state.context ? inlineElements.test(state.context.tagName) : false;
34
- return !inline && ((type == "tag" && />$/.test(content) && state.context) ||
35
- /^</.test(textAfter));
36
- }
37
- });
38
-
39
- // Comment/uncomment the specified range
40
- CodeMirror.defineExtension("commentRange", function (isComment, from, to) {
41
- var cm = this, curMode = CodeMirror.innerMode(cm.getMode(), cm.getTokenAt(from).state).mode;
42
- cm.operation(function() {
43
- if (isComment) { // Comment range
44
- cm.replaceRange(curMode.commentEnd, to);
45
- cm.replaceRange(curMode.commentStart, from);
46
- if (from.line == to.line && from.ch == to.ch) // An empty comment inserted - put cursor inside
47
- cm.setCursor(from.line, from.ch + curMode.commentStart.length);
48
- } else { // Uncomment range
49
- var selText = cm.getRange(from, to);
50
- var startIndex = selText.indexOf(curMode.commentStart);
51
- var endIndex = selText.lastIndexOf(curMode.commentEnd);
52
- if (startIndex > -1 && endIndex > -1 && endIndex > startIndex) {
53
- // Take string till comment start
54
- selText = selText.substr(0, startIndex)
55
- // From comment start till comment end
56
- + selText.substring(startIndex + curMode.commentStart.length, endIndex)
57
- // From comment end till string end
58
- + selText.substr(endIndex + curMode.commentEnd.length);
59
- }
60
- cm.replaceRange(selText, from, to);
61
- }
62
- });
63
- });
64
-
65
- // Applies automatic mode-aware indentation to the specified range
66
- CodeMirror.defineExtension("autoIndentRange", function (from, to) {
67
- var cmInstance = this;
68
- this.operation(function () {
69
- for (var i = from.line; i <= to.line; i++) {
70
- cmInstance.indentLine(i, "smart");
71
- }
72
- });
73
- });
74
-
75
- // Applies automatic formatting to the specified range
76
- CodeMirror.defineExtension("autoFormatRange", function (from, to) {
77
- var cm = this;
78
- var outer = cm.getMode(), text = cm.getRange(from, to).split("\n");
79
- var state = CodeMirror.copyState(outer, cm.getTokenAt(from).state);
80
- var tabSize = cm.getOption("tabSize");
81
-
82
- var out = "", lines = 0, atSol = from.ch == 0;
83
- function newline() {
84
- out += "\n";
85
- atSol = true;
86
- ++lines;
87
- }
88
-
89
- for (var i = 0; i < text.length; ++i) {
90
- var stream = new CodeMirror.StringStream(text[i], tabSize);
91
- while (!stream.eol()) {
92
- var inner = CodeMirror.innerMode(outer, state);
93
- var style = outer.token(stream, state), cur = stream.current();
94
- stream.start = stream.pos;
95
- if (!atSol || /\S/.test(cur)) {
96
- out += cur;
97
- atSol = false;
98
- }
99
- if (!atSol && inner.mode.newlineAfterToken &&
100
- inner.mode.newlineAfterToken(style, cur, stream.string.slice(stream.pos) || text[i+1] || "", inner.state))
101
- newline();
102
- }
103
- if (!stream.pos && outer.blankLine) outer.blankLine(state);
104
- if (!atSol && i < text.length - 1) newline();
105
- }
106
-
107
- cm.operation(function () {
108
- cm.replaceRange(out, from, to);
109
- for (var cur = from.line + 1, end = from.line + lines; cur <= end; ++cur)
110
- cm.indentLine(cur, "smart");
111
- cm.setSelection(from, cm.getCursor(false));
112
- });
113
- });
114
- })();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/xml.js DELETED
@@ -1,324 +0,0 @@
1
- CodeMirror.defineMode("xml", function(config, parserConfig) {
2
- var indentUnit = config.indentUnit;
3
- var Kludges = parserConfig.htmlMode ? {
4
- autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
5
- 'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
6
- 'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
7
- 'track': true, 'wbr': true},
8
- implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
9
- 'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
10
- 'th': true, 'tr': true},
11
- contextGrabbers: {
12
- 'dd': {'dd': true, 'dt': true},
13
- 'dt': {'dd': true, 'dt': true},
14
- 'li': {'li': true},
15
- 'option': {'option': true, 'optgroup': true},
16
- 'optgroup': {'optgroup': true},
17
- 'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
18
- 'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
19
- 'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
20
- 'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
21
- 'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
22
- 'rp': {'rp': true, 'rt': true},
23
- 'rt': {'rp': true, 'rt': true},
24
- 'tbody': {'tbody': true, 'tfoot': true},
25
- 'td': {'td': true, 'th': true},
26
- 'tfoot': {'tbody': true},
27
- 'th': {'td': true, 'th': true},
28
- 'thead': {'tbody': true, 'tfoot': true},
29
- 'tr': {'tr': true}
30
- },
31
- doNotIndent: {"pre": true},
32
- allowUnquoted: true,
33
- allowMissing: true
34
- } : {
35
- autoSelfClosers: {},
36
- implicitlyClosed: {},
37
- contextGrabbers: {},
38
- doNotIndent: {},
39
- allowUnquoted: false,
40
- allowMissing: false
41
- };
42
- var alignCDATA = parserConfig.alignCDATA;
43
-
44
- // Return variables for tokenizers
45
- var tagName, type;
46
-
47
- function inText(stream, state) {
48
- function chain(parser) {
49
- state.tokenize = parser;
50
- return parser(stream, state);
51
- }
52
-
53
- var ch = stream.next();
54
- if (ch == "<") {
55
- if (stream.eat("!")) {
56
- if (stream.eat("[")) {
57
- if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
58
- else return null;
59
- }
60
- else if (stream.match("--")) return chain(inBlock("comment", "-->"));
61
- else if (stream.match("DOCTYPE", true, true)) {
62
- stream.eatWhile(/[\w\._\-]/);
63
- return chain(doctype(1));
64
- }
65
- else return null;
66
- }
67
- else if (stream.eat("?")) {
68
- stream.eatWhile(/[\w\._\-]/);
69
- state.tokenize = inBlock("meta", "?>");
70
- return "meta";
71
- }
72
- else {
73
- var isClose = stream.eat("/");
74
- tagName = "";
75
- var c;
76
- while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c;
77
- if (!tagName) return "error";
78
- type = isClose ? "closeTag" : "openTag";
79
- state.tokenize = inTag;
80
- return "tag";
81
- }
82
- }
83
- else if (ch == "&") {
84
- var ok;
85
- if (stream.eat("#")) {
86
- if (stream.eat("x")) {
87
- ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";");
88
- } else {
89
- ok = stream.eatWhile(/[\d]/) && stream.eat(";");
90
- }
91
- } else {
92
- ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";");
93
- }
94
- return ok ? "atom" : "error";
95
- }
96
- else {
97
- stream.eatWhile(/[^&<]/);
98
- return null;
99
- }
100
- }
101
-
102
- function inTag(stream, state) {
103
- var ch = stream.next();
104
- if (ch == ">" || (ch == "/" && stream.eat(">"))) {
105
- state.tokenize = inText;
106
- type = ch == ">" ? "endTag" : "selfcloseTag";
107
- return "tag";
108
- }
109
- else if (ch == "=") {
110
- type = "equals";
111
- return null;
112
- }
113
- else if (/[\'\"]/.test(ch)) {
114
- state.tokenize = inAttribute(ch);
115
- return state.tokenize(stream, state);
116
- }
117
- else {
118
- stream.eatWhile(/[^\s\u00a0=<>\"\']/);
119
- return "word";
120
- }
121
- }
122
-
123
- function inAttribute(quote) {
124
- return function(stream, state) {
125
- while (!stream.eol()) {
126
- if (stream.next() == quote) {
127
- state.tokenize = inTag;
128
- break;
129
- }
130
- }
131
- return "string";
132
- };
133
- }
134
-
135
- function inBlock(style, terminator) {
136
- return function(stream, state) {
137
- while (!stream.eol()) {
138
- if (stream.match(terminator)) {
139
- state.tokenize = inText;
140
- break;
141
- }
142
- stream.next();
143
- }
144
- return style;
145
- };
146
- }
147
- function doctype(depth) {
148
- return function(stream, state) {
149
- var ch;
150
- while ((ch = stream.next()) != null) {
151
- if (ch == "<") {
152
- state.tokenize = doctype(depth + 1);
153
- return state.tokenize(stream, state);
154
- } else if (ch == ">") {
155
- if (depth == 1) {
156
- state.tokenize = inText;
157
- break;
158
- } else {
159
- state.tokenize = doctype(depth - 1);
160
- return state.tokenize(stream, state);
161
- }
162
- }
163
- }
164
- return "meta";
165
- };
166
- }
167
-
168
- var curState, setStyle;
169
- function pass() {
170
- for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i]);
171
- }
172
- function cont() {
173
- pass.apply(null, arguments);
174
- return true;
175
- }
176
-
177
- function pushContext(tagName, startOfLine) {
178
- var noIndent = Kludges.doNotIndent.hasOwnProperty(tagName) || (curState.context && curState.context.noIndent);
179
- curState.context = {
180
- prev: curState.context,
181
- tagName: tagName,
182
- indent: curState.indented,
183
- startOfLine: startOfLine,
184
- noIndent: noIndent
185
- };
186
- }
187
- function popContext() {
188
- if (curState.context) curState.context = curState.context.prev;
189
- }
190
-
191
- function element(type) {
192
- if (type == "openTag") {
193
- curState.tagName = tagName;
194
- return cont(attributes, endtag(curState.startOfLine));
195
- } else if (type == "closeTag") {
196
- var err = false;
197
- if (curState.context) {
198
- if (curState.context.tagName != tagName) {
199
- if (Kludges.implicitlyClosed.hasOwnProperty(curState.context.tagName.toLowerCase())) {
200
- popContext();
201
- }
202
- err = !curState.context || curState.context.tagName != tagName;
203
- }
204
- } else {
205
- err = true;
206
- }
207
- if (err) setStyle = "error";
208
- return cont(endclosetag(err));
209
- }
210
- return cont();
211
- }
212
- function endtag(startOfLine) {
213
- return function(type) {
214
- var tagName = curState.tagName;
215
- curState.tagName = null;
216
- if (type == "selfcloseTag" ||
217
- (type == "endTag" && Kludges.autoSelfClosers.hasOwnProperty(tagName.toLowerCase()))) {
218
- maybePopContext(tagName.toLowerCase());
219
- return cont();
220
- }
221
- if (type == "endTag") {
222
- maybePopContext(tagName.toLowerCase());
223
- pushContext(tagName, startOfLine);
224
- return cont();
225
- }
226
- return cont();
227
- };
228
- }
229
- function endclosetag(err) {
230
- return function(type) {
231
- if (err) setStyle = "error";
232
- if (type == "endTag") { popContext(); return cont(); }
233
- setStyle = "error";
234
- return cont(arguments.callee);
235
- };
236
- }
237
- function maybePopContext(nextTagName) {
238
- var parentTagName;
239
- while (true) {
240
- if (!curState.context) {
241
- return;
242
- }
243
- parentTagName = curState.context.tagName.toLowerCase();
244
- if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) ||
245
- !Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
246
- return;
247
- }
248
- popContext();
249
- }
250
- }
251
-
252
- function attributes(type) {
253
- if (type == "word") {setStyle = "attribute"; return cont(attribute, attributes);}
254
- if (type == "endTag" || type == "selfcloseTag") return pass();
255
- setStyle = "error";
256
- return cont(attributes);
257
- }
258
- function attribute(type) {
259
- if (type == "equals") return cont(attvalue, attributes);
260
- if (!Kludges.allowMissing) setStyle = "error";
261
- else if (type == "word") setStyle = "attribute";
262
- return (type == "endTag" || type == "selfcloseTag") ? pass() : cont();
263
- }
264
- function attvalue(type) {
265
- if (type == "string") return cont(attvaluemaybe);
266
- if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return cont();}
267
- setStyle = "error";
268
- return (type == "endTag" || type == "selfCloseTag") ? pass() : cont();
269
- }
270
- function attvaluemaybe(type) {
271
- if (type == "string") return cont(attvaluemaybe);
272
- else return pass();
273
- }
274
-
275
- return {
276
- startState: function() {
277
- return {tokenize: inText, cc: [], indented: 0, startOfLine: true, tagName: null, context: null};
278
- },
279
-
280
- token: function(stream, state) {
281
- if (stream.sol()) {
282
- state.startOfLine = true;
283
- state.indented = stream.indentation();
284
- }
285
- if (stream.eatSpace()) return null;
286
-
287
- setStyle = type = tagName = null;
288
- var style = state.tokenize(stream, state);
289
- state.type = type;
290
- if ((style || type) && style != "comment") {
291
- curState = state;
292
- while (true) {
293
- var comb = state.cc.pop() || element;
294
- if (comb(type || style)) break;
295
- }
296
- }
297
- state.startOfLine = false;
298
- return setStyle || style;
299
- },
300
-
301
- indent: function(state, textAfter, fullLine) {
302
- var context = state.context;
303
- if ((state.tokenize != inTag && state.tokenize != inText) ||
304
- context && context.noIndent)
305
- return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
306
- if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
307
- if (context && /^<\//.test(textAfter))
308
- context = context.prev;
309
- while (context && !context.startOfLine)
310
- context = context.prev;
311
- if (context) return context.indent + indentUnit;
312
- else return 0;
313
- },
314
-
315
- electricChars: "/",
316
-
317
- configuration: parserConfig.htmlMode ? "html" : "xml"
318
- };
319
- });
320
-
321
- CodeMirror.defineMIME("text/xml", "xml");
322
- CodeMirror.defineMIME("application/xml", "xml");
323
- if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
324
- CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
readme.txt CHANGED
@@ -3,10 +3,10 @@ Contributors: nixdns
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=TM7JTJY6HDTAQ
4
  Tags: html editor, syntax highlighter, plugin editor, syntax, highlighting, syntax hilighting
5
  Requires at least: 3.3
6
- Tested up to: 3.5.1
7
- Stable tag: 1.3.0
8
 
9
- Add syntax highlighting to the HTML editor.
10
 
11
  == Description ==
12
 
@@ -19,6 +19,11 @@ Add syntax highlighting to the HTML editor.
19
 
20
  == Changelog ==
21
 
 
 
 
 
 
22
  = 1.3.0 =
23
  * CodeMirror library updated to the version 3.02
24
  * Added quick-tags toolbar buttons
@@ -39,6 +44,9 @@ Bug fix (thanks to collinprice):
39
  = 1.0 =
40
  Initial release.
41
 
 
 
 
42
  == Screenshots ==
43
  1. Syntax highlighting in the Post/Page HTML editor.
44
  2. Syntax highlighting in the Post/Page HTML editor - full screen mode.
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=TM7JTJY6HDTAQ
4
  Tags: html editor, syntax highlighter, plugin editor, syntax, highlighting, syntax hilighting
5
  Requires at least: 3.3
6
+ Tested up to: 3.6.1
7
+ Stable tag: 1.3.2
8
 
9
+ Add syntax highlighting to the Post/Page HTML editor.
10
 
11
  == Description ==
12
 
19
 
20
  == Changelog ==
21
 
22
+ = 1.3.2 =
23
+ * Updated CodeMirror library
24
+ * Increased loading performance
25
+ * Match brackets
26
+
27
  = 1.3.0 =
28
  * CodeMirror library updated to the version 3.02
29
  * Added quick-tags toolbar buttons
44
  = 1.0 =
45
  Initial release.
46
 
47
+
48
+
49
+
50
  == Screenshots ==
51
  1. Syntax highlighting in the Post/Page HTML editor.
52
  2. Syntax highlighting in the Post/Page HTML editor - full screen mode.