1
window.CodeMirror=(function(){function r(a9,a5){var ct={},bG=r.defaults;for(var aX in bG){if(bG.hasOwnProperty(aX)){ct[aX]=(a5&&a5.hasOwnProperty(aX)?a5:bG)[aX]}}var bJ=ak("textarea",null,null,"position: absolute; padding: 0; width: 1px; height: 1em");bJ.setAttribute("wrap","off");bJ.setAttribute("autocorrect","off");bJ.setAttribute("autocapitalize","off");var cp=ak("div",[bJ],null,"overflow: hidden; position: relative; width: 3px; height: 0px;");var cR=ak("div",null,"CodeMirror-scrollbar-inner");var a8=ak("div",[cR],"CodeMirror-scrollbar");var aO=ak("div"),bD=ak("div",null,null,"position: relative; z-index: -1");var bA=ak("pre","\u00a0","CodeMirror-cursor"),bu=ak("pre","\u00a0","CodeMirror-cursor","visibility: hidden");var aT=ak("div",null,null,"position: absolute; width: 100%; height: 0px; overflow: hidden; visibility: hidden;");var bU=ak("div",[aT,bA,bu,bD,aO],null,"position: relative; z-index: 0");var bl=ak("div",null,"CodeMirror-gutter-text"),a3=ak("div",[bl],"CodeMirror-gutter");var cM=ak("div",[a3,ak("div",[bU],"CodeMirror-lines")],null,"position: relative");var cC=ak("div",[cM],null,"position: relative");var bH=ak("div",[cC],"CodeMirror-scroll");bH.setAttribute("tabIndex","-1");var a1=ak("div",[cp,a8,bH],"CodeMirror"+(ct.lineWrapping?" CodeMirror-wrap":""));if(a9.appendChild){a9.appendChild(a1)}else{a9(a1)}c8();c1();if(i){bJ.style.width="0px"}if(!m){bH.draggable=true}bU.style.outline="none";if(ct.tabindex!=null){bJ.tabIndex=ct.tabindex}if(ct.autofocus){b1()}if(!ct.gutter&&!ct.lineNumbers){a3.style.display="none"}if(ah){cp.style.height="1px",cp.style.position="absolute"}if(W){a8.style.zIndex=-2;a8.style.visibility="hidden"}else{if(L){a8.style.minWidth="18px"}}var cA=new j(),aU=new j(),dl;var cH,c4=new al([new Q([new J("")])]),df=0,cO;cm();var dt={from:{line:0,ch:0},to:{line:0,ch:0},inverted:false};var cN,bO,bn,bW=0,bz,cT=false,cY=false,cf=false;var cV,cz,aZ,dj,bc,bf,c5;var bB=0,dm=0,cc=0,cd=0;var cw;var b6=db(0),c9=false,bN=true;var bS=false;var c0=null;aP(function(){bj(ct.value||"");cV=false})();var bx=new F();aE(bH,"mousedown",aP(cP));aE(bH,"dblclick",aP(co));aE(bU,"selectstart",f);if(!x){aE(bH,"contextmenu",bp)}aE(bH,"scroll",cE);aE(a8,"scroll",b2);aE(a8,"mousedown",function(){if(cO){setTimeout(b1,0)}});var cD=aE(window,"resize",function(){if(a1.parentNode){cJ(true)}else{cD()}},true);aE(bJ,"keyup",aP(cQ));aE(bJ,"input",bd);aE(bJ,"keydown",aP(cI));aE(bJ,"keypress",aP(bK));aE(bJ,"focus",dr);aE(bJ,"blur",a2);function b5(dv){if(ct.onDragEvent&&ct.onDragEvent(cF,R(dv))){return}ae(dv)}if(ct.dragDrop){aE(bH,"dragstart",a4);aE(bH,"dragenter",b5);aE(bH,"dragover",b5);aE(bH,"drop",aP(aK))}aE(bH,"paste",function(){b1();bd()});aE(bJ,"paste",function(){cf=true;bd()});aE(bJ,"cut",aP(function(){if(!ct.readOnly){bR("")}}));if(ah){aE(cC,"mouseup",function(){if(document.activeElement==bJ){bJ.blur()}b1()})}var c2;try{c2=(document.activeElement==bJ)}catch(cB){}if(c2||ct.autofocus){setTimeout(dr,20)}else{a2()}function bQ(dv){return dv>=0&&dv<c4.size}var cF=a1.CodeMirror={getValue:cu,setValue:aP(bj),getSelection:cv,replaceSelection:aP(bR),focus:function(){window.focus();b1();dr();bd()},setOption:function(dw,dx){var dv=ct[dw];ct[dw]=dx;if(dw=="mode"||dw=="indentUnit"){cm()}else{if(dw=="readOnly"&&dx=="nocursor"){a2();bJ.blur()}else{if(dw=="readOnly"&&!dx){c7(true)}else{if(dw=="theme"){c8()}else{if(dw=="lineWrapping"&&dv!=dx){aP(dc)()}else{if(dw=="tabSize"){cJ(true)}else{if(dw=="keyMap"){c1()}else{if(dw=="tabindex"){bJ.tabIndex=dx}else{if(dw=="showCursorWhenSelecting"){ds()}}}}}}}}}if(dw=="lineNumbers"||dw=="gutter"||dw=="firstLineNumber"||dw=="theme"||dw=="lineNumberFormatter"){bC();cJ(true)}},getOption:function(dv){return ct[dv]},getMode:function(){return cH},undo:aP(dq),redo:aP(de),indentLine:aP(function(dw,dv){if(typeof dv!="string"){if(dv==null){dv=ct.smartIndent?"smart":"prev"}else{dv=dv?"add":"subtract"}}if(bQ(dw)){b0(dw,dv)}}),indentSelection:aP(c6),historySize:function(){return{undo:bx.done.length,redo:bx.undone.length}},clearHistory:function(){bx=new F()},setHistory:function(dv){bx=new F();bx.done=dv.done;bx.undone=dv.undone},getHistory:function(){function dv(dB){for(var dA=0,dC=[],dD;dA<dB.length;++dA){dC.push(dD=[]);for(var dz=0,dy=dB[dA];dz<dy.length;++dz){var dw=[],dE=dy[dz];dD.push({start:dE.start,added:dE.added,old:dw});for(var dx=0;dx<dE.old.length;++dx){dw.push(au(dE.old[dx]))}}}return dC}return{done:dv(bx.done),undone:dv(bx.undone)}},matchBrackets:aP(function(){cK(true)}),getTokenAt:aP(function(dv){dv=bg(dv);return db(dv.line).getTokenAt(cH,cZ(dv.line),ct.tabSize,dv.ch)}),getStateAfter:function(dv){dv=cr(dv==null?c4.size-1:dv);return cZ(dv+1)},cursorCoords:function(dw,dv){if(dw==null){dw=dt.inverted}return this.charCoords(dw?dt.from:dt.to,dv)},charCoords:function(dw,dv){dw=bg(dw);if(dv=="local"){return dn(dw,false)}if(dv=="div"){return dn(dw,true)}return aM(dw)},coordsChar:function(dv){var dw=B(bU);return b9(dv.x-dw.left,dv.y-dw.top)},defaultTextHeight:function(){return ch()},markText:aP(b7),setBookmark:bh,findMarksAt:bL,setMarker:aP(cn),clearMarker:aP(aS),setLineClass:aP(bI),hideLine:aP(function(dv){return dg(dv,true)}),showLine:aP(function(dv){return dg(dv,false)}),onDeleteLine:function(dv,dw){if(typeof dv=="number"){if(!bQ(dv)){return null}dv=db(dv)}(dv.handlers||(dv.handlers=[])).push(dw);return dv},lineInfo:bi,getViewport:function(){return{from:dm,to:cc}},addWidget:function(dz,dx,dB,dy,dD){dz=dn(bg(dz));var dA=dz.yBot,dw=dz.x;dx.style.position="absolute";cC.appendChild(dx);if(dy=="over"){dA=dz.y}else{if(dy=="near"){var dv=Math.max(bH.offsetHeight,c4.height*ch()),dC=Math.max(cC.clientWidth,bU.clientWidth)-bt();if(dz.yBot+dx.offsetHeight>dv&&dz.y>dx.offsetHeight){dA=dz.y-dx.offsetHeight}if(dw+dx.offsetWidth>dC){dw=dC-dx.offsetWidth}}}dx.style.top=(dA+cX())+"px";dx.style.left=dx.style.right="";if(dD=="right"){dw=cC.clientWidth-dx.offsetWidth;dx.style.right="0px"}else{if(dD=="left"){dw=0}else{if(dD=="middle"){dw=(cC.clientWidth-dx.offsetWidth)/2}}dx.style.left=(dw+bt())+"px"}if(dB){aY(dw,dA,dw+dx.offsetWidth,dA+dx.offsetHeight)}},lineCount:function(){return c4.size},clipPos:bg,getCursor:function(dv){if(dv==null||dv=="head"){dv=dt.inverted}if(dv=="anchor"){dv=!dt.inverted}if(dv=="end"){dv=false}return aa(dv?dt.from:dt.to)},somethingSelected:function(){return !T(dt.from,dt.to)},setCursor:aP(function(dv,dx,dw){if(dx==null&&typeof dv.line=="number"){bv(dv.line,dv.ch,dw)}else{bv(dv,dx,dw)}}),setSelection:aP(function(dx,dw,dv){(dv?bZ:bX)(bg(dx),bg(dw||dx))}),getLine:function(dv){if(bQ(dv)){return db(dv).text}},getLineHandle:function(dv){if(bQ(dv)){return db(dv)}},setLine:aP(function(dv,dw){if(bQ(dv)){ci(dw,{line:dv,ch:0},{line:dv,ch:db(dv).text.length})}}),removeLine:aP(function(dv){if(bQ(dv)){ci("",{line:dv,ch:0},bg({line:dv+1,ch:0}))}}),replaceRange:aP(ci),getRange:function(dx,dw,dv){return dk(bg(dx),bg(dw),dv)},triggerOnKeyDown:aP(cI),execCommand:function(dv){return t[dv](cF)},moveH:aP(da),deleteH:aP(cS),moveV:aP(c3),toggleOverwrite:function(){if(cT){cT=false;bA.className=bA.className.replace(" CodeMirror-overwrite","")}else{cT=true;bA.className+=" CodeMirror-overwrite"}},posFromIndex:function(dw){var dx=0,dv;c4.iter(0,c4.size,function(dy){var dz=dy.text.length+1;if(dz>dw){dv=dw;return true}dw-=dz;++dx});return bg({line:dx,ch:dv})},indexFromPos:function(dw){if(dw.line<0||dw.ch<0){return 0}var dv=dw.ch;c4.iter(0,dw.line,function(dx){dv+=dx.text.length+1});return dv},scrollTo:function(dv,dw){if(dv!=null){bH.scrollLeft=dv}if(dw!=null){a8.scrollTop=bH.scrollTop=dw}cJ([])},getScrollInfo:function(){return{x:bH.scrollLeft,y:a8.scrollTop,height:a8.scrollHeight,width:bH.scrollWidth}},scrollIntoView:function(dw){var dv=dn(dw?bg(dw):dt.inverted?dt.from:dt.to);aY(dv.x,dv.y,dv.x,dv.yBot)},setSize:function(dx,dv){function dw(dy){dy=String(dy);return/^\d+$/.test(dy)?dy+"px":dy}if(dx!=null){a1.style.width=dw(dx)}if(dv!=null){bH.style.height=dw(dv)}cF.refresh()},operation:function(dv){return aP(dv)()},compoundChange:function(dv){return cg(dv)},refresh:function(){cJ(true,null,bW);if(a8.scrollHeight>bW){a8.scrollTop=bW}},getInputField:function(){return bJ},getWrapperElement:function(){return a1},getScrollerElement:function(){return bH},getGutterElement:function(){return a3}};function db(dv){return M(c4,dv)}function br(dw,dv){bf=true;var dx=dv-dw.height;for(var dy=dw;dy;dy=dy.parent){dy.height+=dx}}function ce(dv,dw){if(!dv.styles){dv.highlight(cH,dv.stateAfter=cZ(X(dv)),ct.tabSize)}return dv.getContent(ct.tabSize,dw,ct.lineWrapping)}function bj(dv){var dw={line:0,ch:0};bb(dw,{line:c4.size-1,ch:db(c4.size-1).text.length},h(dv),dw,dw);cV=true}function cu(dw){var dv=[];c4.iter(0,c4.size,function(dx){dv.push(dx.text)});return dv.join(dw||"\n")}function b2(dv){if(Math.abs(a8.scrollTop-bW)>1){bW=bH.scrollTop=a8.scrollTop;cJ([])}}function cE(dv){if(ct.fixedGutter&&a3.style.left!=bH.scrollLeft+"px"){a3.style.left=bH.scrollLeft+"px"}if(Math.abs(bH.scrollTop-bW)>1){bW=bH.scrollTop;if(a8.scrollTop!=bW){a8.scrollTop=bW}cJ([])}if(ct.onScroll){ct.onScroll(cF)}}function cP(dH){bs(ad(dH,"shiftKey"));for(var dB=ar(dH);dB!=a1;dB=dB.parentNode){if(dB.parentNode==cC&&dB!=cM){return}}for(var dB=ar(dH);dB!=a1;dB=dB.parentNode){if(dB.parentNode==bl){if(ct.onGutterClick){ct.onGutterClick(cF,u(bl.childNodes,dB)+dm,dH)}return f(dH)}}var dw=bq(dH);switch(E(dH)){case 3:if(x){bp(dH)}return;case 2:if(dw){bv(dw.line,dw.ch,true)}setTimeout(b1,20);f(dH);return}if(!dw){if(ar(dH)==bH){f(dH)}return}if(!cO){dr()}var dx=+new Date,dK="single";if(bn&&bn.time>dx-400&&T(bn.pos,dw)){dK="triple";f(dH);setTimeout(b1,20);a6(dw.line)}else{if(bO&&bO.time>dx-400&&T(bO.pos,dw)){dK="double";bn={time:dx,pos:dw};f(dH);var dv=bT(dw);bZ(dv.from,dv.to)}else{bO={time:dx,pos:dw}}}function dC(dM){if(m){bH.draggable=false}bz=false;dG();dA();if(Math.abs(dH.clientX-dM.clientX)+Math.abs(dH.clientY-dM.clientY)<10){f(dM);bv(dw.line,dw.ch,true);b1()}}var dL=dw,dz;if(ct.dragDrop&&ac&&!ct.readOnly&&!T(dt.from,dt.to)&&!D(dw,dt.from)&&!D(dt.to,dw)&&dK=="single"){if(m){bH.draggable=true}var dG=aE(document,"mouseup",aP(dC),true);var dA=aE(bH,"drop",aP(dC),true);bz=true;if(bH.dragDrop){bH.dragDrop()}return}f(dH);if(dK=="single"){bv(dw.line,dw.ch,true)}var dJ=dt.from,dy=dt.to;function dE(dN){if(dK=="single"){bZ(bg(dw),dN);return}dJ=bg(dJ);dy=bg(dy);if(dK=="double"){var dM=bT(dN);if(D(dN,dJ)){bZ(dM.from,dy)}else{bZ(dJ,dM.to)}}else{if(dK=="triple"){if(D(dN,dJ)){bZ(dy,bg({line:dN.line,ch:0}))}else{bZ(dJ,bg({line:dN.line+1,ch:0}))}}}}function dI(dM){var dO=bq(dM,true);if(dO&&!T(dO,dL)){if(!cO){dr()}dL=dO;dE(dO);cV=false;var dN=b3();if(dO.line>=dN.to||dO.line<dN.from){dz=setTimeout(aP(function(){dI(dM)}),150)}}}function dF(dM){clearTimeout(dz);var dN=bq(dM);if(dN){dE(dN)}f(dM);b1();cV=true;dD();dG()}var dD=aE(document,"mousemove",aP(function(dM){clearTimeout(dz);f(dM);if(!U&&!E(dM)){dF(dM)}else{dI(dM)}}),true);var dG=aE(document,"mouseup",aP(dF),true)}function co(dv){for(var dw=ar(dv);dw!=a1;dw=dw.parentNode){if(dw.parentNode==bl){return f(dv)}}f(dv)}function aK(dz){if(ct.onDragEvent&&ct.onDragEvent(cF,R(dz))){return}f(dz);var dC=bq(dz,true),dw=dz.dataTransfer.files;if(!dC||ct.readOnly){return}if(dw&&dw.length&&window.FileReader&&window.File){var dB=dw.length,dA=Array(dB),dx=0;var dy=function(dF,dE){var dD=new FileReader;dD.onload=function(){dA[dE]=dD.result;if(++dx==dB){dC=bg(dC);aP(function(){var dG=ci(dA.join(""),dC,dC);bZ(dC,dG)})()}};dD.readAsText(dF)};for(var dv=0;dv<dB;++dv){dy(dw[dv],dv)}}else{if(bz&&!(D(dC,dt.from)||D(dt.to,dC))){return}try{var dA=dz.dataTransfer.getData("Text");if(dA){cg(function(){var dE=dt.from,dD=dt.to;bZ(dC,dC);if(bz){ci("",dE,dD)}bR(dA);b1()})}}catch(dz){}}}function a4(dw){var dv=cv();dw.dataTransfer.setData("Text",dv);if(dw.dataTransfer.setDragImage){dw.dataTransfer.setDragImage(ak("img"),0,0)}}function bF(dx,dv){if(typeof dx=="string"){dx=t[dx];if(!dx){return false}}var dw=cN;try{if(ct.readOnly){cY=true}if(dv){cN=null}dx(cF)}catch(dy){if(dy!=aq){throw dy}return false}finally{cN=dw;cY=false}return true}var b4;function dh(dB){var dv=at(ct.keyMap),dy=dv.auto;clearTimeout(b4);if(dy&&!aj(dB)){b4=setTimeout(function(){if(at(ct.keyMap)==dv){ct.keyMap=(dy.call?dy.call(null,cF):dy)}},50)}var dw=w[ad(dB,"keyCode")],dA=false;if(dw==null||dB.altGraphKey){return false}if(ad(dB,"altKey")){dw="Alt-"+dw}if(ad(dB,d?"metaKey":"ctrlKey")){dw="Ctrl-"+dw}if(ad(dB,d?"ctrlKey":"metaKey")){dw="Cmd-"+dw}var dz=false;function dx(){dz=true}if(ad(dB,"shiftKey")){dA=av("Shift-"+dw,ct.extraKeys,ct.keyMap,function(dC){return bF(dC,true)},dx)||av(dw,ct.extraKeys,ct.keyMap,function(dC){if(typeof dC=="string"&&/^go[A-Z]/.test(dC)){return bF(dC)}},dx)}else{dA=av(dw,ct.extraKeys,ct.keyMap,bF,dx)}if(dz){dA=false}if(dA){f(dB);di();if(I){dB.oldKeyCode=dB.keyCode;dB.keyCode=0}}return dA}function cq(dx,dv){var dw=av("'"+dv+"'",ct.extraKeys,ct.keyMap,function(dy){return bF(dy,true)});if(dw){f(dx);di()}return dw}var dd=null;function cI(dx){if(!cO){dr()}if(U&&dx.keyCode==27){dx.returnValue=false}if(bS){if(cb()){bS=false}}if(ct.onKeyEvent&&ct.onKeyEvent(cF,R(dx))){return}var dv=ad(dx,"keyCode");bs(dv==16||ad(dx,"shiftKey"));var dw=dh(dx);if(ax){dd=dw?dv:null;if(!dw&&dv==88&&ad(dx,K?"metaKey":"ctrlKey")){bR("")}}}function bK(dy){if(bS){cb()}if(ct.onKeyEvent&&ct.onKeyEvent(cF,R(dy))){return}var dx=ad(dy,"keyCode"),dv=ad(dy,"charCode");if(ax&&dx==dd){dd=null;f(dy);return}if(((ax&&(!dy.which||dy.which<10))||ah)&&dh(dy)){return}var dw=String.fromCharCode(dv==null?dx:dv);if(ct.electricChars&&cH.electricChars&&ct.smartIndent&&!ct.readOnly){if(cH.electricChars.indexOf(dw)>-1){setTimeout(aP(function(){b0(dt.to.line,"smart")}),75)}}if(cq(dy,dw)){return}bd()}function cQ(dv){if(ct.onKeyEvent&&ct.onKeyEvent(cF,R(dv))){return}if(ad(dv,"keyCode")==16){cN=null}}function dr(){if(ct.readOnly=="nocursor"){return}if(!cO){if(ct.onFocus){ct.onFocus(cF)}cO=true;if(bH.className.search(/\bCodeMirror-focused\b/)==-1){bH.className+=" CodeMirror-focused"}}aJ();di()}function a2(){if(cO){if(ct.onBlur){ct.onBlur(cF)}cO=false;if(cw){aP(function(){if(cw){cw();cw=null}})()}bH.className=bH.className.replace(" CodeMirror-focused","")}clearInterval(dl);setTimeout(function(){if(!cO){cN=null}},150)}function bb(dB,dA,dz,dw,dv){if(cY){return}var dy=[];c4.iter(dB.line,dA.line+1,function(dC){dy.push(k(dC.text,dC.markedSpans))});if(bx){bx.addChange(dB.line,dz.length,dy);while(bx.done.length>ct.undoDepth){bx.done.shift()}}var dx=Y(e(dy[0]),e(P(dy)),dB.ch,dA.ch,dz);aQ(dB,dA,dx,dw,dv)}function cG(dA,dB){if(!dA.length){return}var dC=dA.pop(),dw=[];for(var dx=dC.length-1;dx>=0;dx-=1){var dz=dC[dx];var dD=[],dv=dz.start+dz.added;c4.iter(dz.start,dv,function(dE){dD.push(k(dE.text,dE.markedSpans))});dw.push({start:dz.start,added:dz.old.length,old:dD});var dy={line:dz.start+dz.old.length-1,ch:C(au(P(dD)),au(P(dz.old)))};aQ({line:dz.start,ch:0},{line:dv-1,ch:db(dv-1).text.length},dz.old,dy,dy)}cV=true;dB.push(dw)}function dq(){cG(bx.done,bx.undone)}function de(){cG(bx.undone,bx.done)}function aQ(dK,dz,dw,dv,dO){if(cY){return}var dN=false,dy=b6.text.length;if(!ct.lineWrapping){c4.iter(dK.line,dz.line+1,function(dP){if(!dP.hidden&&dP.text.length==dy){dN=true;return true}})}if(dK.line!=dz.line||dw.length>1){bf=true}var dI=dz.line-dK.line,dH=db(dK.line),dx=db(dz.line);var dE=P(dw);if(dK.ch==0&&dz.ch==0&&au(dE)==""){var dF=[],dG=null;for(var dL=0,dM=dw.length-1;dL<dM;++dL){dF.push(new J(au(dw[dL]),e(dw[dL])))}dx.update(dx.text,e(dE));if(dI){c4.remove(dK.line,dI,c5)}if(dF.length){c4.insert(dK.line,dF)}}else{if(dH==dx){if(dw.length==1){dH.update(dH.text.slice(0,dK.ch)+au(dw[0])+dH.text.slice(dz.ch),e(dw[0]))}else{for(var dF=[],dL=1,dM=dw.length-1;dL<dM;++dL){dF.push(new J(au(dw[dL]),e(dw[dL])))}dF.push(new J(au(dE)+dH.text.slice(dz.ch),e(dE)));dH.update(dH.text.slice(0,dK.ch)+au(dw[0]),e(dw[0]));c4.insert(dK.line+1,dF)}}else{if(dw.length==1){dH.update(dH.text.slice(0,dK.ch)+au(dw[0])+dx.text.slice(dz.ch),e(dw[0]));c4.remove(dK.line+1,dI,c5)}else{var dF=[];dH.update(dH.text.slice(0,dK.ch)+au(dw[0]),e(dw[0]));dx.update(au(dE)+dx.text.slice(dz.ch),e(dE));for(var dL=1,dM=dw.length-1;dL<dM;++dL){dF.push(new J(au(dw[dL]),e(dw[dL])))}if(dI>1){c4.remove(dK.line+1,dI-1,c5)}c4.insert(dK.line+1,dF)}}}if(ct.lineWrapping){var dB=Math.max(5,bH.clientWidth/bE()-3);c4.iter(dK.line,dK.line+dw.length,function(dP){if(dP.hidden){return}var dQ=Math.ceil(dP.text.length/dB)||1;if(dQ!=dP.height){br(dP,dQ)}})}else{c4.iter(dK.line,dK.line+dw.length,function(dQ){var dP=dQ.text;if(!dQ.hidden&&dP.length>dy){b6=dQ;dy=dP.length;bN=true;dN=false}});if(dN){c9=true}}df=Math.min(df,dK.line);b8(400);var dD=dw.length-dI-1;aZ.push({from:dK.line,to:dz.line+1,diff:dD});if(ct.onChange){for(var dL=0;dL<dw.length;++dL){if(typeof dw[dL]!="string"){dw[dL]=dw[dL].text}}var dC={from:dK,to:dz,text:dw};if(dj){for(var dA=dj;dA.next;dA=dA.next){}dA.next=dC}else{dj=dC}}function dJ(dP){return dP<=Math.min(dz.line,dz.line+dD)?dP:dP+dD}bX(bg(dv),bg(dO),dJ(dt.from.line),dJ(dt.to.line))}function aN(){var dv=c4.height*ch()+2*cX();return dv*0.99>bH.offsetHeight?dv:false}function aR(dw){var dv=aN();a8.style.display=dv?"block":"none";if(dv){cR.style.height=cC.style.minHeight=dv+"px";a8.style.height=bH.clientHeight+"px";if(dw!=null){a8.scrollTop=bH.scrollTop=dw;if(m){setTimeout(function(){if(a8.scrollTop!=dw){return}a8.scrollTop=dw+(dw?-1:1);a8.scrollTop=dw},0)}}}else{cC.style.minHeight=""}cM.style.top=bB*ch()+"px"}function bY(){b6=db(0);bN=true;var dv=b6.text.length;c4.iter(1,c4.size,function(dx){var dw=dx.text;if(!dx.hidden&&dw.length>dv){dv=dw.length;b6=dx}});c9=false}function ci(dw,dz,dy){dz=bg(dz);if(!dy){dy=dz}else{dy=bg(dy)}dw=h(dw);function dx(dC){if(D(dC,dz)){return dC}if(!D(dy,dC)){return dv}var dA=dC.line+dw.length-(dy.line-dz.line)-1;var dB=dC.ch;if(dC.line==dy.line){dB+=P(dw).length-(dy.ch-(dy.line==dz.line?dz.ch:0))}return{line:dA,ch:dB}}var dv;a0(dw,dz,dy,function(dA){dv=dA;return{from:dx(dt.from),to:dx(dt.to)}});return dv}function bR(dv,dw){a0(h(dv),dt.from,dt.to,function(dx){if(dw=="end"){return{from:dx,to:dx}}else{if(dw=="start"){return{from:dt.from,to:dt.from}}else{return{from:dt.from,to:dx}}}})}function a0(dy,dA,dz,dv){var dx=dy.length==1?dy[0].length+dA.ch:P(dy).length;var dw=dv({line:dA.line+dy.length-1,ch:dx});bb(dA,dz,dy,dw.from,dw.to)}function dk(dA,dz,dy){var dw=dA.line,dv=dz.line;if(dw==dv){return db(dw).text.slice(dA.ch,dz.ch)}var dx=[db(dw).text.slice(dA.ch)];c4.iter(dw+1,dv,function(dB){dx.push(dB.text)});dx.push(db(dv).text.slice(0,dz.ch));return dx.join(dy||"\n")}function cv(dv){return dk(dt.from,dt.to,dv)}function aJ(){if(bS){return}cA.set(ct.pollInterval,function(){cb();if(cO){aJ()}})}function bd(){var dv=false;bS=true;function dw(){var dx=cb();if(!dx&&!dv){dv=true;cA.set(60,dw)}else{bS=false;aJ()}}cA.set(20,dw)}var by="";function cb(){if(!cO||b(bJ)||ct.readOnly){return false}var dw=bJ.value;if(dw==by){return false}if(!cW){ba()}cN=null;var dx=0,dv=Math.min(by.length,dw.length);while(dx<dv&&by[dx]==dw[dx]){++dx}if(dx<by.length){dt.from={line:dt.from.line,ch:dt.from.ch-(by.length-dx)}}else{if(cT&&T(dt.from,dt.to)&&!cf){dt.to={line:dt.to.line,ch:Math.min(db(dt.to.line).text.length,dt.to.ch+(dw.length-dx))}}}bR(dw.slice(dx),"end");if(dw.length>1000){bJ.value=by=""}else{by=dw}if(!cW){aW()}cf=false;return true}function c7(dv){if(!T(dt.from,dt.to)){by="";bJ.value=cv();if(cO){aF(bJ)}}else{if(dv){by=bJ.value=""}}}function b1(){if(ct.readOnly!="nocursor"&&(I||document.activeElement!=bJ)){bJ.focus()}}function cL(){var dy=cj();aY(dy.x,dy.y,dy.x,dy.yBot);if(!cO){return}var dw=cC.getBoundingClientRect(),dv=null;if(dy.y+dw.top<0){dv=true}else{if(dy.y+dw.top+ch()>(window.innerHeight||document.documentElement.clientHeight)){dv=false}}if(dv!=null){var dx=bA.style.display=="none";if(dx){bA.style.display="";bA.style.left=dy.x+"px";bA.style.top=(dy.y-bB)+"px"}bA.scrollIntoView(dv);if(dx){bA.style.display="none"}}}function cj(){var dw=dn(dt.inverted?dt.from:dt.to);var dv=ct.lineWrapping?Math.min(dw.x,bU.offsetWidth):dw.x;return{x:dv,y:dw.y,yBot:dw.yBot}}function aY(dw,dy,dv,dx){var dz=bm(dw,dy,dv,dx);if(dz.scrollLeft!=null){bH.scrollLeft=dz.scrollLeft}if(dz.scrollTop!=null){a8.scrollTop=bH.scrollTop=dz.scrollTop}}function bm(dy,dF,dw,dE){var dB=bt(),dK=cX();dF+=dK;dE+=dK;dy+=dB;dw+=dB;var dH=bH.clientHeight,dz=a8.scrollTop,dJ={};var dx=aN()||Infinity;var dv=dF<dK+10,dD=dE+dK>dx-10;if(dF<dz){dJ.scrollTop=dv?0:Math.max(0,dF)}else{if(dE>dz+dH){dJ.scrollTop=(dD?dx:dE)-dH}}var dG=bH.clientWidth,dI=bH.scrollLeft;var dC=ct.fixedGutter?a3.clientWidth:0;var dA=dy<dC+dB+10;if(dy<dI+dC||dA){if(dA){dy=0}dJ.scrollLeft=Math.max(0,dy-10-dC)}else{if(dw>dG+dI-3){dJ.scrollLeft=dw+10-dG}}return dJ}function b3(dz){var dv=ch(),dy=(dz!=null?dz:a8.scrollTop)-cX();var dx=Math.max(0,Math.floor(dy/dv));var dw=Math.ceil((dy+bH.clientHeight)/dv);return{from:af(c4,dx),to:af(c4,dw)}}function cJ(dE,dA,dy){if(!bH.clientWidth){dm=cc=bB=0;return}var dz=b3(dy);if(dE!==true&&dE.length==0&&dz.from>dm&&dz.to<cc){aR(dy);return}var dF=Math.max(dz.from-100,0),dG=Math.min(c4.size,dz.to+100);if(dm<dF&&dF-dm<20){dF=dm}if(cc>dG&&cc-dG<20){dG=Math.min(c4.size,cc)}var dI=dE===true?[]:cs([{from:dm,to:cc,domStart:0}],dE);var dD=0;for(var dB=0;dB<dI.length;++dB){var dC=dI[dB];if(dC.from<dF){dC.domStart+=(dF-dC.from);dC.from=dF}if(dC.to>dG){dC.to=dG}if(dC.from>=dC.to){dI.splice(dB--,1)}else{dD+=dC.to-dC.from}}if(dD==dG-dF&&dF==dm&&dG==cc){aR(dy);return}dI.sort(function(dK,dJ){return dK.domStart-dJ.domStart});var dx=ch(),dv=a3.style.display;aO.style.display="none";be(dF,dG,dI);aO.style.display=a3.style.display="";var dw=dF!=dm||dG!=cc||cd!=bH.clientHeight+dx;if(dw){cd=bH.clientHeight+dx}if(dF!=dm||dG!=cc&&ct.onViewportChange){setTimeout(function(){if(ct.onViewportChange){ct.onViewportChange(cF,dF,dG)}})}dm=dF;cc=dG;bB=a(c4,dF);b8(100);if(aO.childNodes.length!=cc-dm){throw new Error("BAD PATCH! "+JSON.stringify(dI)+" size="+(cc-dm)+" nodes="+aO.childNodes.length)}function dH(){var dK=aO.firstChild,dJ=false;c4.iter(dm,cc,function(dM){if(!dK){return}if(!dM.hidden){var dL=Math.round(dK.offsetHeight/dx)||1;if(dM.height!=dL){br(dM,dL);bf=dJ=true}}dK=dK.nextSibling});return dJ}if(ct.lineWrapping){dH()}a3.style.display=dv;if(dw||bf){a7()&&ct.lineWrapping&&dH()&&a7()}aR(dy);ds();if(!dA&&ct.onUpdate){ct.onUpdate(cF)}return true}function cs(dE,dC){for(var dz=0,dx=dC.length||0;dz<dx;++dz){var dB=dC[dz],dv=[],dD=dB.diff||0;for(var dy=0,dw=dE.length;dy<dw;++dy){var dA=dE[dy];if(dB.to<=dA.from&&dB.diff){dv.push({from:dA.from+dD,to:dA.to+dD,domStart:dA.domStart})}else{if(dB.to<=dA.from||dB.from>=dA.to){dv.push(dA)}else{if(dB.from>dA.from){dv.push({from:dA.from,to:dB.from,domStart:dA.domStart})}if(dB.to<dA.to){dv.push({from:dB.to+dD,to:dA.to+dD,domStart:dA.domStart+(dB.to-dA.from)})}}}}dE=dv}return dE}function be(dD,dE,dG){function dv(dI){var dH=dI.nextSibling;dI.parentNode.removeChild(dI);return dH}if(!dG.length){aH(aO)}else{var dz=0,dx=aO.firstChild,dw;for(var dA=0;dA<dG.length;++dA){var dF=dG[dA];while(dF.domStart>dz){dx=dv(dx);dz++}for(var dy=0,dC=dF.to-dF.from;dy<dC;++dy){dx=dx.nextSibling;dz++}}while(dx){dx=dv(dx)}}var dB=dG.shift(),dx=aO.firstChild,dy=dD;c4.iter(dD,dE,function(dH){if(dB&&dB.to==dy){dB=dG.shift()}if(!dB||dB.from>dy){if(dH.hidden){var dI=ak("pre")}else{var dI=ce(dH);if(dH.className){dI.className=dH.className}if(dH.bgClassName){var dJ=ak("pre","\u00a0",dH.bgClassName,"position: absolute; left: 0; right: 0; top: 0; bottom: 0; z-index: -2");dI=ak("div",[dJ,dI],null,"position: relative")}}aO.insertBefore(dI,dx)}else{dx=dx.nextSibling}++dy})}function a7(){if(!ct.gutter&&!ct.lineNumbers){return}var dw=cM.offsetHeight,dE=bH.clientHeight;a3.style.height=(dw-dE<2?dE:dw)+"px";var dC=document.createDocumentFragment(),dA=dm,dD;c4.iter(dm,Math.max(cc,dm+1),function(dG){if(dG.hidden){dC.appendChild(ak("pre"))}else{var dF=dG.gutterMarker;var dJ=ct.lineNumbers?ct.lineNumberFormatter(dA+ct.firstLineNumber):null;if(dF&&dF.text){dJ=dF.text.replace("%N%",dJ!=null?dJ:"")}else{if(dJ==null){dJ="\u00a0"}}var dI=dC.appendChild(ak("pre",null,dF&&dF.style));dI.innerHTML=dJ;for(var dH=1;dH<dG.height;++dH){dI.appendChild(ak("br"));dI.appendChild(document.createTextNode("\u00a0"))}if(!dF){dD=dA}}++dA});a3.style.display="none";s(bl,dC);if(dD!=null&&ct.lineNumbers){var dy=bl.childNodes[dD-dm];var dz=String(c4.size).length,dv=aB(dy.firstChild),dx="";while(dv.length+dx.length<dz){dx+="\u00a0"}if(dx){dy.insertBefore(document.createTextNode(dx),dy.firstChild)}}a3.style.display="";var dB=Math.abs((parseInt(bU.style.marginLeft)||0)-a3.offsetWidth)>2;bU.style.marginLeft=a3.offsetWidth+"px";bf=false;return dB}function ds(){var dy=T(dt.from,dt.to);var dJ=dn(dt.from,true);var dE=dy?dJ:dn(dt.to,true);var dC=dt.inverted?dJ:dE,dw=ch();var dv=B(a1),dx=B(aO);cp.style.top=Math.max(0,Math.min(bH.offsetHeight,dC.y+dx.top-dv.top))+"px";cp.style.left=Math.max(0,Math.min(bH.offsetWidth,dC.x+dx.left-dv.left))+"px";if(dy||ct.showCursorWhenSelecting){bA.style.top=dC.y+"px";bA.style.left=(ct.lineWrapping?Math.min(dC.x,bU.offsetWidth):dC.x)+"px";bA.style.display=""}else{bA.style.display="none"}if(!dy){var dH=dJ.y==dE.y,dB=document.createDocumentFragment();var dF=bU.clientWidth||bU.offsetWidth;var dA=bU.clientHeight||bU.offsetHeight;var dI=function(dO,dN,dM,dK){var dL=n?"width: "+(!dM?dF:dF-dM-dO)+"px":"right: "+(dM-1)+"px";dB.appendChild(ak("div",null,"CodeMirror-selected","position: absolute; left: "+dO+"px; top: "+dN+"px; "+dL+"; height: "+dK+"px"))};if(dt.from.ch&&dJ.y>=0){var dG=dH?dF-dE.x:0;dI(dJ.x,dJ.y,dG,dw)}var dz=Math.max(0,dJ.y+(dt.from.ch?dw:0));var dD=Math.min(dE.y,dA)-dz;if(dD>0.2*dw){dI(0,dz,0,dD)}if((!dH||!dt.from.ch)&&dE.y<dA-0.5*dw){dI(0,dE.y,dF-dE.x,dw)}s(bD,dB);bD.style.display=""}else{bD.style.display="none"}}function bs(dv){if(dv){cN=cN||(dt.inverted?dt.to:dt.from)}else{cN=null}}function bZ(dx,dw){var dv=cN&&bg(cN);if(dv){if(D(dv,dx)){dx=dv}else{if(D(dw,dv)){dw=dv}}}bX(dx,dw);cz=true}function bX(dC,dB,dv,dA){c0=null;if(dv==null){dv=dt.from.line;dA=dt.to.line}if(T(dt.from,dC)&&T(dt.to,dB)){return}if(D(dB,dC)){var dy=dB;dB=dC;dC=dy}if(dC.line!=dv){var dz=ck(dC,dv,dt.from.ch);if(!dz){dg(dC.line,false)}else{dC=dz}}if(dB.line!=dA){dB=ck(dB,dA,dt.to.ch)}if(T(dC,dB)){dt.inverted=false}else{if(T(dC,dt.to)){dt.inverted=false}else{if(T(dB,dt.from)){dt.inverted=true}}}if(ct.autoClearEmptyLines&&T(dt.from,dt.to)){var dx=dt.inverted?dC:dB;if(dx.line!=dt.from.line&&dt.from.line<c4.size){var dw=db(dt.from.line);if(/^\s+$/.test(dw.text)){setTimeout(aP(function(){if(dw.parent&&/^\s+$/.test(dw.text)){var dD=X(dw);ci("",{line:dD,ch:0},{line:dD,ch:dw.text.length})}},10))}}}dt.from=dC;dt.to=dB;bc=true}function ck(dA,dw,dx){function dz(dD){var dF=dA.line+dD,dC=dD==1?c4.size:-1;while(dF!=dC){var dB=db(dF);if(!dB.hidden){var dE=dA.ch;if(dy||dE>dx||dE>dB.text.length){dE=dB.text.length}return{line:dF,ch:dE}}dF+=dD}}var dv=db(dA.line);var dy=dA.ch==dv.text.length&&dA.ch!=dx;if(!dv.hidden){return dA}if(dA.line>=dw){return dz(1)||dz(-1)}else{return dz(-1)||dz(1)}}function bv(dv,dx,dw){var dy=bg({line:dv,ch:dx||0});(dw?bZ:bX)(dy,dy)}function cr(dv){return Math.max(0,Math.min(dv,c4.size-1))}function bg(dx){if(dx.line<0){return{line:0,ch:0}}if(dx.line>=c4.size){return{line:c4.size-1,ch:db(c4.size-1).text.length}}var dv=dx.ch,dw=db(dx.line).text.length;if(dv==null||dv>dw){return{line:dx.line,ch:dw}}else{if(dv<0){return{line:dx.line,ch:0}}else{return dx}}}function cU(dy,dC){var dz=dt.inverted?dt.from:dt.to,dD=dz.line,dv=dz.ch;var dB=db(dD);function dw(){for(var dE=dD+dy,dG=dy<0?-1:c4.size;dE!=dG;dE+=dy){var dF=db(dE);if(!dF.hidden){dD=dE;dB=dF;return true}}}function dA(dE){if(dv==(dy<0?0:dB.text.length)){if(!dE&&dw()){dv=dy<0?dB.text.length:0}else{return false}}else{dv+=dy}return true}if(dC=="char"){dA()}else{if(dC=="column"){dA(true)}else{if(dC=="word"){var dx=false;for(;;){if(dy<0){if(!dA()){break}}if(N(dB.text.charAt(dv))){dx=true}else{if(dx){if(dy<0){dy=1;dA()}break}}if(dy>0){if(!dA()){break}}}}}}return{line:dD,ch:dv}}function da(dv,dw){var dx=dv<0?dt.from:dt.to;if(cN||T(dt.from,dt.to)){dx=cU(dv,dw)}bv(dx.line,dx.ch,true)}function cS(dv,dw){if(!T(dt.from,dt.to)){ci("",dt.from,dt.to)}else{if(dv<0){ci("",cU(dv,dw),dt.to)}else{ci("",dt.from,cU(dv,dw))}}cz=true}function c3(dw,dy){var dA=0,dB=dn(dt.inverted?dt.from:dt.to,true);if(c0!=null){dB.x=c0}if(dy=="page"){var dv=Math.min(bH.clientHeight,window.innerHeight||document.documentElement.clientHeight);var dz=b9(dB.x,dB.y+dv*dw)}else{if(dy=="line"){var dx=ch();var dz=b9(dB.x,dB.y+0.5*dx+dw*dx)}}if(dy=="page"){a8.scrollTop+=dn(dz,true).y-dB.y}bv(dz.line,dz.ch,true);c0=dB.x}function bT(dA){var dy=db(dA.line).text;var dz=dA.ch,dx=dA.ch;if(dy){if(dA.after===false||dx==dy.length){--dz}else{++dx}var dw=dy.charAt(dz);var dv=N(dw)?N:/\s/.test(dw)?function(dB){return/\s/.test(dB)}:function(dB){return !/\s/.test(dB)&&N(dB)};while(dz>0&&dv(dy.charAt(dz-1))){--dz}while(dx<dy.length&&dv(dy.charAt(dx))){++dx}}return{from:{line:dA.line,ch:dz},to:{line:dA.line,ch:dx}}}function a6(dv){bZ({line:dv,ch:0},bg({line:dv+1,ch:0}))}function c6(dx){if(T(dt.from,dt.to)){return b0(dt.from.line,dx)}var dw=dt.to.line-(dt.to.ch?0:1);for(var dv=dt.from.line;dv<=dw;++dv){b0(dv,dx)}}function b0(dx,dE){if(!dE){dE="add"}if(dE=="smart"){if(!cH.indent){dE="prev"}else{var dv=cZ(dx)}}var dF=db(dx),dz=dF.indentation(ct.tabSize),dw=dF.text.match(/^\s*/)[0],dB;if(dE=="smart"){dB=cH.indent(dv,dF.text.slice(dw.length),dF.text);if(dB==aq){dE="prev"}}if(dE=="prev"){if(dx){dB=db(dx-1).indentation(ct.tabSize)}else{dB=0}}else{if(dE=="add"){dB=dz+ct.indentUnit}else{if(dE=="subtract"){dB=dz-ct.indentUnit}}}dB=Math.max(0,dB);var dD=dB-dz;var dC="",dA=0;if(ct.indentWithTabs){for(var dy=Math.floor(dB/ct.tabSize);dy;--dy){dA+=ct.tabSize;dC+="\t"}}if(dA<dB){dC+=az(dB-dA)}if(dC!=dw){ci(dC,{line:dx,ch:0},{line:dx,ch:dw.length})}dF.stateAfter=null}function cm(){cH=r.getMode(ct,ct.mode);c4.iter(0,c4.size,function(dv){dv.stateAfter=null});df=0;b8(100)}function bC(){var dv=ct.gutter||ct.lineNumbers;a3.style.display=dv?"":"none";if(dv){bf=true}else{aO.parentNode.style.marginLeft=0}}function dc(dx,dw){if(ct.lineWrapping){a1.className+=" CodeMirror-wrap";var dv=bH.clientWidth/bE()-3;c4.iter(0,c4.size,function(dy){if(dy.hidden){return}var dz=Math.ceil(dy.text.length/dv)||1;if(dz!=1){br(dy,dz)}});bU.style.minWidth=bu.style.left=""}else{a1.className=a1.className.replace(" CodeMirror-wrap","");bY();c4.iter(0,c4.size,function(dy){if(dy.height!=1&&!dy.hidden){br(dy,1)}})}aZ.push({from:0,to:c4.size})}function c8(){bH.className=bH.className.replace(/\s*cm-s-\S+/g,"")+ct.theme.replace(/(^|\s)\s*/g," cm-s-")}function c1(){var dv=g[ct.keyMap].style;a1.className=a1.className.replace(/\s*cm-keymap-\S+/g,"")+(dv?" cm-keymap-"+dv:"")}function du(dw,dv){this.lines=[];this.type=dw;if(dv){this.style=dv}}du.prototype.clear=aP(function(){var dy,dv;for(var dx=0;dx<this.lines.length;++dx){var dw=this.lines[dx];var dz=aI(dw.markedSpans,this);if(dz.from!=null){dy=X(dw)}if(dz.to!=null){dv=X(dw)}dw.markedSpans=aD(dw.markedSpans,dz)}if(dy!=null){aZ.push({from:dy,to:dv+1})}this.lines.length=0;this.explicitlyCleared=true});du.prototype.find=function(){var dA,dz;for(var dw=0;dw<this.lines.length;++dw){var dv=this.lines[dw];var dx=aI(dv.markedSpans,this);if(dx.from!=null||dx.to!=null){var dy=X(dv);if(dx.from!=null){dA={line:dy,ch:dx.from}}if(dx.to!=null){dz={line:dy,ch:dx.to}}}}if(this.type=="bookmark"){return dA}return dA&&{from:dA,to:dz}};function b7(dB,dA,dz,dx){dB=bg(dB);dA=bg(dA);var dw=new du("range",dz);if(dx){for(var dy in dx){if(dx.hasOwnProperty(dy)){dw[dy]=dx[dy]}}}var dv=dB.line;c4.iter(dv,dA.line+1,function(dC){var dD={from:dv==dB.line?dB.ch:null,to:dv==dA.line?dA.ch:null,marker:dw};dC.markedSpans=(dC.markedSpans||[]).concat([dD]);dw.lines.push(dC);++dv});aZ.push({from:dB.line,to:dA.line+1});return dw}function bh(dy){dy=bg(dy);var dw=new du("bookmark"),dv=db(dy.line);bx.addChange(dy.line,1,[k(dv.text,dv.markedSpans)],true);var dx={from:dy.ch,to:dy.ch,marker:dw};dv.markedSpans=(dv.markedSpans||[]).concat([dx]);dw.lines.push(dv);return dw}function bL(dz){dz=bg(dz);var dy=[],dw=db(dz.line).markedSpans;if(dw){for(var dv=0;dv<dw.length;++dv){var dx=dw[dv];if((dx.from==null||dx.from<=dz.ch)&&(dx.to==null||dx.to>=dz.ch)){dy.push(dx.marker)}}}return dy}function cn(dv,dx,dw){if(typeof dv=="number"){dv=db(cr(dv))}dv.gutterMarker={text:dx,style:dw};bf=true;return dv}function aS(dv){if(typeof dv=="number"){dv=db(cr(dv))}dv.gutterMarker=null;bf=true}function bk(dw,dy){var dx=dw,dv=dw;if(typeof dw=="number"){dv=db(cr(dw))}else{dx=X(dw)}if(dx==null){return null}if(dy(dv,dx)){aZ.push({from:dx,to:dx+1})}else{return null}return dv}function bI(dw,dv,dx){return bk(dw,function(dy){if(dy.className!=dv||dy.bgClassName!=dx){dy.className=dv;dy.bgClassName=dx;return true}})}function dg(dw,dv){return bk(dw,function(dx,dA){if(dx.hidden!=dv){dx.hidden=dv;if(!ct.lineWrapping){if(dv&&dx.text.length==b6.text.length){c9=true}else{if(!dv&&dx.text.length>b6.text.length){b6=dx;c9=false}}}br(dx,dv?0:1);var dz=dt.from.line,dy=dt.to.line;if(dv&&(dz==dA||dy==dA)){var dC=dz==dA?ck({line:dz,ch:0},dz,0):dt.from;var dB=dy==dA?ck({line:dy,ch:0},dy,0):dt.to;if(!dB){return}bX(dC,dB)}return(bf=true)}})}function bi(dw){if(typeof dw=="number"){if(!bQ(dw)){return null}var dx=dw;dw=db(dw);if(!dw){return null}}else{var dx=X(dw);if(dx==null){return null}}var dv=dw.gutterMarker;return{line:dx,handle:dw,text:dw.text,markerText:dv&&dv.text,markerClass:dv&&dv.style,lineClass:dw.className,bgClass:dw.bgClassName}}function cx(dv,dy){if(dy==0){return{top:0,left:0}}var dB=ce(dv,dy);s(aT,dB);var dx=dB.anchor;var dA=dx.offsetTop,dz=dx.offsetLeft;if(U&&dA==0&&dz==0){var dw=ak("span","x");dx.parentNode.insertBefore(dw,dx.nextSibling);dA=dw.offsetTop}return{top:dA,left:dz}}function dn(dA,dy){var dv,dw=ch(),dz=dw*(a(c4,dA.line)-(dy?bB:0));if(dA.ch==0){dv=0}else{var dx=cx(db(dA.line),dA.ch);dv=dx.left;if(ct.lineWrapping){dz+=Math.max(0,dx.top)}}return{x:dv,y:dz,yBot:dz+dw}}function b9(dG,dF){var dD=ch(),dA=bE(),dM=bB+Math.floor(dF/dD);if(dM<0){return{line:0,ch:0}}var dH=af(c4,dM);if(dH>=c4.size){return{line:c4.size-1,ch:db(c4.size-1).text.length}}var dw=db(dH),dJ=dw.text;var dO=ct.lineWrapping,dE=dO?dM-a(c4,dH):0;if(dG<=0&&dE==0){return{line:dH,ch:0}}var dB=false;function dN(dQ){var dR=cx(dw,dQ);if(dO){var dS=Math.round(dR.top/dD);dB=dS!=dE;return Math.max(0,dR.left+(dS-dE)*bH.clientWidth)}return dR.left}var dL=0,dK=0,dx=dJ.length,dv;var dI=Math.min(dx,Math.ceil((dG+dE*bH.clientWidth*0.9)/dA));for(;;){var dC=dN(dI);if(dC<=dG&&dI<dx){dI=Math.min(dx,Math.ceil(dI*1.2))}else{dv=dC;dx=dI;break}}if(dG>dv){return{line:dH,ch:dx}}dI=Math.floor(dx*0.8);dC=dN(dI);if(dC<dG){dL=dI;dK=dC}for(;;){if(dx-dL<=1){var dz=dG-dK<dv-dG;return{line:dH,ch:dz?dL:dx,after:dz}}var dP=Math.ceil((dL+dx)/2),dy=dN(dP);if(dy>dG){dx=dP;dv=dy;if(dB){dv+=1000}}else{dL=dP;dK=dy}}}function aM(dx){var dv=dn(dx,true),dw=B(bU);return{x:dw.left+dv.x,y:dw.top+dv.y,yBot:dw.top+dv.yBot}}var bo,aV,aL;function ch(){if(aL==null){aL=ak("pre");for(var dw=0;dw<49;++dw){aL.appendChild(document.createTextNode("x"));aL.appendChild(ak("br"))}aL.appendChild(document.createTextNode("x"))}var dv=aO.clientHeight;if(dv==aV){return bo}aV=dv;s(aT,aL.cloneNode(true));bo=aT.firstChild.offsetHeight/50||1;aH(aT);return bo}var dp,bV=0;function bE(){if(bH.clientWidth==bV){return dp}bV=bH.clientWidth;var dv=ak("span","x");var dw=ak("pre",[dv]);s(aT,dw);return(dp=dv.offsetWidth||10)}function cX(){return bU.offsetTop}function bt(){return bU.offsetLeft}function bq(dz,dy){var dx=B(bH,true),dv,dA;try{dv=dz.clientX;dA=dz.clientY}catch(dz){return null}if(!dy&&(dv-dx.left>bH.clientWidth||dA-dx.top>bH.clientHeight)){return null}var dw=B(bU,true);return b9(dv-dw.left,dA-dw.top)}var bP;function bp(dw){var dA=bq(dw),dz=a8.scrollTop;if(!dA||ax){return}if(T(dt.from,dt.to)||D(dA,dt.from)||!D(dA,dt.to)){aP(bv)(dA.line,dA.ch)}var dy=bJ.style.cssText;cp.style.position="absolute";bJ.style.cssText="position: fixed; width: 30px; height: 30px; top: "+(dw.clientY-5)+"px; left: "+(dw.clientX-5)+"px; z-index: 1000; background: white; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";b1();c7(true);if(T(dt.from,dt.to)){bJ.value=by=" "}function dv(){cp.style.position="relative";bJ.style.cssText=dy;if(I){a8.scrollTop=dz}aJ();if(bJ.selectionStart!=null){clearTimeout(bP);var dC=bJ.value=" "+(T(dt.from,dt.to)?"":bJ.value),dB=0;by=" ";bJ.selectionStart=1;bJ.selectionEnd=dC.length;bP=setTimeout(function dD(){if(by==" "&&bJ.selectionStart==0){aP(t.selectAll)(cF)}else{if(dB++<10){bP=setTimeout(dD,500)}else{c7()}}},200)}}if(x){ae(dw);var dx=aE(window,"mouseup",function(){dx();setTimeout(dv,20)},true)}else{setTimeout(dv,50)}}function di(){clearInterval(dl);var dv=true;bA.style.visibility="";dl=setInterval(function(){bA.style.visibility=(dv=!dv)?"":"hidden"},ct.cursorBlinkRate)}var bM={"(":")>",")":"(<","[":"]>","]":"[<","{":"}>","}":"{<"};function cK(dB){var dv=dt.inverted?dt.from:dt.to,dD=db(dv.line),dw=dv.ch-1;var dA=(dw>=0&&bM[dD.text.charAt(dw)])||bM[dD.text.charAt(++dw)];if(!dA){return}var dE=dA.charAt(0),dC=dA.charAt(1)==">",dO=dC?1:-1,dJ=dD.styles;for(var dP=dw+1,dL=0,dN=dJ.length;dL<dN;dL+=2){if((dP-=dJ[dL].length)<=0){var dM=dJ[dL+1];break}}var dy=[dD.text.charAt(dw)],dI=/[(){}[\]]/;function dG(d1,dW,dX){if(!d1.text){return}var d0=d1.styles,dV=dC?0:d1.text.length-1,dY;for(var dS=dC?0:d0.length-2,dU=dC?d0.length:-2;dS!=dU;dS+=2*dO){var dZ=d0[dS];if(d0[dS+1]!=dM){dV+=dO*dZ.length;continue}for(var dR=dC?0:dZ.length-1,dQ=dC?dZ.length:-1;dR!=dQ;dR+=dO,dV+=dO){if(dV>=dW&&dV<dX&&dI.test(dY=dZ.charAt(dR))){var dT=bM[dY];if(dT.charAt(1)==">"==dC){dy.push(dY)}else{if(dy.pop()!=dT.charAt(0)){return{pos:dV,match:false}}else{if(!dy.length){return{pos:dV,match:true}}}}}}}}for(var dL=dv.line,dN=dC?Math.min(dL+100,c4.size):Math.max(-1,dL-100);dL!=dN;dL+=dO){var dD=db(dL),dz=dL==dv.line;var dF=dG(dD,dz&&dC?dw+1:0,dz&&!dC?dw:dD.text.length);if(dF){break}}if(!dF){dF={pos:null,match:false}}var dM=dF.match?"CodeMirror-matchingbracket":"CodeMirror-nonmatchingbracket";var dK=b7({line:dv.line,ch:dw},{line:dv.line,ch:dw+1},dM),dx=dF.pos!=null&&b7({line:dL,ch:dF.pos},{line:dL,ch:dF.pos+1},dM);var dH=aP(function(){dK.clear();dx&&dx.clear()});if(dB){setTimeout(dH,800)}else{cw=dH}}function bw(dB){var dA,dx;for(var dw=dB,dy=dB-40;dw>dy;--dw){if(dw==0){return 0}var dv=db(dw-1);if(dv.stateAfter){return dw}var dz=dv.indentation(ct.tabSize);if(dx==null||dA>dz){dx=dw-1;dA=dz}}return dx}function cZ(dx){var dw=bw(dx),dv=dw&&db(dw-1).stateAfter;if(!dv){dv=v(cH)}else{dv=o(cH,dv)}c4.iter(dw,dx,function(dy){dy.process(cH,dv,ct.tabSize);dy.stateAfter=(dw==dx-1||dw%5==0)?o(cH,dv):null});return dv}function cl(){if(df>=cc){return}var dv=+new Date+ct.workTime,dx=o(cH,cZ(df));var dw=df;c4.iter(df,cc,function(dy){if(df>=dm){dy.highlight(cH,dx,ct.tabSize);dy.stateAfter=o(cH,dx)}else{dy.process(cH,dx,ct.tabSize);dy.stateAfter=df%5==0?o(cH,dx):null}++df;if(+new Date>dv){b8(ct.workDelay);return true}});if(cc>dw&&df>=dm){aP(function(){aZ.push({from:dw,to:df})})()}}function b8(dv){if(df<cc){aU.set(dv,cl)}}function ba(){cV=cz=dj=null;aZ=[];bc=false;c5=[]}function aW(){if(c9){bY()}if(bN&&!ct.lineWrapping){var dv=bu.offsetWidth,dB=cx(b6,b6.text.length).left;if(!L){bu.style.left=dB+"px";bU.style.minWidth=(dB+dv)+"px"}bN=false}var dz,dw;if(bc){var dA=cj();dz=bm(dA.x,dA.y,dA.x,dA.yBot)}if(aZ.length||dz&&dz.scrollTop!=null){dw=cJ(aZ,true,dz&&dz.scrollTop)}if(!dw){if(bc){ds()}if(bf){a7()}}if(dz){cL()}if(bc){di()}if(cO&&(cV===true||(cV!==false&&bc))){c7(cz)}if(bc&&ct.matchBrackets){setTimeout(aP(function(){if(cw){cw();cw=null}if(T(dt.from,dt.to)){cK(false)}}),20)}var dC=bc,dx=c5;if(dj&&ct.onChange&&cF){ct.onChange(cF,dj)}if(dC&&ct.onCursorActivity){ct.onCursorActivity(cF)}for(var dy=0;dy<dx.length;++dy){dx[dy](cF)}if(dw&&ct.onUpdate){ct.onUpdate(cF)}}var cW=0;function aP(dv){return function(){if(!cW++){ba()}try{var dw=dv.apply(this,arguments)}finally{if(!--cW){aW()}}return dw}}function cg(dv){bx.startCompound();try{return dv()}finally{bx.endCompound()}}for(var ca in c){if(c.propertyIsEnumerable(ca)&&!cF.propertyIsEnumerable(ca)){cF[ca]=c[ca]}}for(var cy=0;cy<ay.length;++cy){ay[cy](cF)}return cF}r.defaults={value:"",mode:null,theme:"default",indentUnit:2,indentWithTabs:false,smartIndent:true,tabSize:4,keyMap:"default",extraKeys:null,electricChars:true,autoClearEmptyLines:false,onKeyEvent:null,onDragEvent:null,lineWrapping:false,lineNumbers:false,gutter:false,fixedGutter:false,firstLineNumber:1,showCursorWhenSelecting:false,readOnly:false,dragDrop:true,onChange:null,onCursorActivity:null,onViewportChange:null,onGutterClick:null,onUpdate:null,onFocus:null,onBlur:null,onScroll:null,matchBrackets:false,cursorBlinkRate:530,workTime:100,workDelay:200,pollInterval:100,undoDepth:40,tabindex:null,autofocus:null,lineNumberFormatter:function(aJ){return aJ}};var i=/AppleWebKit/.test(navigator.userAgent)&&/Mobile\/\w+/.test(navigator.userAgent);var K=i||/Mac/.test(navigator.platform);var ag=/Win/.test(navigator.platform);var A=r.modes={},am=r.mimeModes={};r.defineMode=function(aJ,aL){if(!r.defaults.mode&&aJ!="null"){r.defaults.mode=aJ}if(arguments.length>2){aL.dependencies=[];for(var aK=2;aK<arguments.length;++aK){aL.dependencies.push(arguments[aK])}}A[aJ]=aL};r.defineMIME=function(aK,aJ){am[aK]=aJ};r.resolveMode=function(aJ){if(typeof aJ=="string"&&am.hasOwnProperty(aJ)){aJ=am[aJ]}else{if(typeof aJ=="string"&&/^[\w\-]+\/[\w\-]+\+xml$/.test(aJ)){return r.resolveMode("application/xml")}}if(typeof aJ=="string"){return{name:aJ}}else{return aJ||{name:"null"}}};r.getMode=function(aK,aJ){var aJ=r.resolveMode(aJ);var aM=A[aJ.name];if(!aM){return r.getMode(aK,"text/plain")}var aN=aM(aK,aJ);if(ab.hasOwnProperty(aJ.name)){var aL=ab[aJ.name];for(var aO in aL){if(!aL.hasOwnProperty(aO)){continue}if(aN.hasOwnProperty(aO)){aN["_"+aO]=aN[aO]}aN[aO]=aL[aO]}}aN.name=aJ.name;return aN};r.listModes=function(){var aK=[];for(var aJ in A){if(A.propertyIsEnumerable(aJ)){aK.push(aJ)}}return aK};r.listMIMEs=function(){var aK=[];for(var aJ in am){if(am.propertyIsEnumerable(aJ)){aK.push({mime:aJ,mode:am[aJ]})}}return aK};var c=r.extensions={};r.defineExtension=function(aJ,aK){c[aJ]=aK};var ay=[];r.defineInitHook=function(aJ){ay.push(aJ)};var ab=r.modeExtensions={};r.extendMode=function(aL,aK){var aJ=ab.hasOwnProperty(aL)?ab[aL]:(ab[aL]={});for(var aM in aK){if(aK.hasOwnProperty(aM)){aJ[aM]=aK[aM]}}};var t=r.commands={selectAll:function(aJ){aJ.setSelection({line:0,ch:0},{line:aJ.lineCount()-1})},killLine:function(aJ){var aM=aJ.getCursor(true),aL=aJ.getCursor(false),aK=!T(aM,aL);if(!aK&&aJ.getLine(aM.line).length==aM.ch){aJ.replaceRange("",aM,{line:aM.line+1,ch:0})}else{aJ.replaceRange("",aM,aK?aL:{line:aM.line})}},deleteLine:function(aJ){var aK=aJ.getCursor().line;aJ.replaceRange("",{line:aK,ch:0},{line:aK})},undo:function(aJ){aJ.undo()},redo:function(aJ){aJ.redo()},goDocStart:function(aJ){aJ.setCursor(0,0,true)},goDocEnd:function(aJ){aJ.setSelection({line:aJ.lineCount()-1},null,true)},goLineStart:function(aJ){aJ.setCursor(aJ.getCursor().line,0,true)},goLineStartSmart:function(aJ){var aM=aJ.getCursor();var aL=aJ.getLine(aM.line),aK=Math.max(0,aL.search(/\S/));aJ.setCursor(aM.line,aM.ch<=aK&&aM.ch?0:aK,true)},goLineEnd:function(aJ){aJ.setSelection({line:aJ.getCursor().line},null,true)},goLineUp:function(aJ){aJ.moveV(-1,"line")},goLineDown:function(aJ){aJ.moveV(1,"line")},goPageUp:function(aJ){aJ.moveV(-1,"page")},goPageDown:function(aJ){aJ.moveV(1,"page")},goCharLeft:function(aJ){aJ.moveH(-1,"char")},goCharRight:function(aJ){aJ.moveH(1,"char")},goColumnLeft:function(aJ){aJ.moveH(-1,"column")},goColumnRight:function(aJ){aJ.moveH(1,"column")},goWordLeft:function(aJ){aJ.moveH(-1,"word")},goWordRight:function(aJ){aJ.moveH(1,"word")},delCharLeft:function(aJ){aJ.deleteH(-1,"char")},delCharRight:function(aJ){aJ.deleteH(1,"char")},delWordLeft:function(aJ){aJ.deleteH(-1,"word")},delWordRight:function(aJ){aJ.deleteH(1,"word")},indentAuto:function(aJ){aJ.indentSelection("smart")},indentMore:function(aJ){aJ.indentSelection("add")},indentLess:function(aJ){aJ.indentSelection("subtract")},insertTab:function(aJ){aJ.replaceSelection("\t","end")},defaultTab:function(aJ){if(aJ.somethingSelected()){aJ.indentSelection("add")}else{aJ.replaceSelection("\t","end")}},transposeChars:function(aJ){var aL=aJ.getCursor(),aK=aJ.getLine(aL.line);if(aL.ch>0&&aL.ch<aK.length-1){aJ.replaceRange(aK.charAt(aL.ch)+aK.charAt(aL.ch-1),{line:aL.line,ch:aL.ch-1},{line:aL.line,ch:aL.ch+1})}},newlineAndIndent:function(aJ){aJ.replaceSelection("\n","end");aJ.indentLine(aJ.getCursor().line)},toggleOverwrite:function(aJ){aJ.toggleOverwrite()}};var g=r.keyMap={};g.basic={Left:"goCharLeft",Right:"goCharRight",Up:"goLineUp",Down:"goLineDown",End:"goLineEnd",Home:"goLineStartSmart",PageUp:"goPageUp",PageDown:"goPageDown",Delete:"delCharRight",Backspace:"delCharLeft",Tab:"defaultTab","Shift-Tab":"indentAuto",Enter:"newlineAndIndent",Insert:"toggleOverwrite"};g.pcDefault={"Ctrl-A":"selectAll","Ctrl-D":"deleteLine","Ctrl-Z":"undo","Shift-Ctrl-Z":"redo","Ctrl-Y":"redo","Ctrl-Home":"goDocStart","Alt-Up":"goDocStart","Ctrl-End":"goDocEnd","Ctrl-Down":"goDocEnd","Ctrl-Left":"goWordLeft","Ctrl-Right":"goWordRight","Alt-Left":"goLineStart","Alt-Right":"goLineEnd","Ctrl-Backspace":"delWordLeft","Ctrl-Delete":"delWordRight","Ctrl-S":"save","Ctrl-F":"find","Ctrl-G":"findNext","Shift-Ctrl-G":"findPrev","Shift-Ctrl-F":"replace","Shift-Ctrl-R":"replaceAll","Ctrl-[":"indentLess","Ctrl-]":"indentMore",fallthrough:"basic"};g.macDefault={"Cmd-A":"selectAll","Cmd-D":"deleteLine","Cmd-Z":"undo","Shift-Cmd-Z":"redo","Cmd-Y":"redo","Cmd-Up":"goDocStart","Cmd-End":"goDocEnd","Cmd-Down":"goDocEnd","Alt-Left":"goWordLeft","Alt-Right":"goWordRight","Cmd-Left":"goLineStart","Cmd-Right":"goLineEnd","Alt-Backspace":"delWordLeft","Ctrl-Alt-Backspace":"delWordRight","Alt-Delete":"delWordRight","Cmd-S":"save","Cmd-F":"find","Cmd-G":"findNext","Shift-Cmd-G":"findPrev","Cmd-Alt-F":"replace","Shift-Cmd-Alt-F":"replaceAll","Cmd-[":"indentLess","Cmd-]":"indentMore",fallthrough:["basic","emacsy"]};g["default"]=K?g.macDefault:g.pcDefault;g.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":"delCharRight","Ctrl-H":"delCharLeft","Alt-D":"delWordRight","Alt-Backspace":"delWordLeft","Ctrl-K":"killLine","Ctrl-T":"transposeChars"};function at(aJ){if(typeof aJ=="string"){return g[aJ]}else{return aJ}}function av(aK,aJ,aO,aM,aL){function aN(aT){aT=at(aT);var aR=aT[aK];if(aR===false){if(aL){aL()}return true}if(aR!=null&&aM(aR)){return true}if(aT.nofallthrough){if(aL){aL()}return true}var aQ=aT.fallthrough;if(aQ==null){return false}if(Object.prototype.toString.call(aQ)!="[object Array]"){return aN(aQ)}for(var aP=0,aS=aQ.length;aP<aS;++aP){if(aN(aQ[aP])){return true}}return false}if(aJ&&aN(aJ)){return true}return aN(aO)}function aj(aK){var aJ=w[ad(aK,"keyCode")];return aJ=="Ctrl"||aJ=="Alt"||aJ=="Shift"||aJ=="Mod"}r.isModifierKey=aj;r.fromTextArea=function(aQ,aS){if(!aS){aS={}}aS.value=aQ.value;if(!aS.tabindex&&aQ.tabindex){aS.tabindex=aQ.tabindex}if(aS.autofocus==null){var aJ=document.body;try{aJ=document.activeElement}catch(aM){}aS.autofocus=aJ==aQ||aQ.getAttribute("autofocus")!=null&&aJ==document.body}function aO(){aQ.value=aR.getValue()}if(aQ.form){var aL=aE(aQ.form,"submit",aO,true);var aK=aQ.form,aP=aK.submit;aQ.form.submit=function aN(){aO();aK.submit=aP;aK.submit();aK.submit=aN}}aQ.style.display="none";var aR=r(function(aT){aQ.parentNode.insertBefore(aT,aQ.nextSibling)},aS);aR.save=aO;aR.getTextArea=function(){return aQ};aR.toTextArea=function(){aO();aQ.parentNode.removeChild(aR.getWrapperElement());aQ.style.display="";if(aQ.form){aL();if(typeof aQ.form.submit=="function"){aQ.form.submit=aP}}};return aR};var x=/gecko\/\d/i.test(navigator.userAgent);var U=/MSIE \d/.test(navigator.userAgent);var L=/MSIE [1-7]\b/.test(navigator.userAgent);var I=/MSIE [1-8]\b/.test(navigator.userAgent);var n=U&&document.documentMode==5;var m=/WebKit\//.test(navigator.userAgent);var l=m&&/Qt\/\d+\.\d+/.test(navigator.userAgent);var p=/Chrome\//.test(navigator.userAgent);var ax=/Opera\//.test(navigator.userAgent);var G=/Apple Computer/.test(navigator.vendor);var ah=/KHTML\//.test(navigator.userAgent);var W=/Mac OS X 10\D([7-9]|\d\d)\D/.test(navigator.userAgent);var aG=ax&&navigator.userAgent.match(/Version\/(\d*\.\d*)/);if(aG){aG=Number(aG[1])}var d=K&&(l||ax&&(aG==null||aG<12.11));function o(aM,aJ){if(aJ===true){return aJ}if(aM.copyState){return aM.copyState(aJ)}var aL={};for(var aN in aJ){var aK=aJ[aN];if(aK instanceof Array){aK=aK.concat([])}aL[aN]=aK}return aL}r.copyState=o;function v(aL,aK,aJ){return aL.startState?aL.startState(aK,aJ):true}r.startState=v;r.innerMode=function(aL,aJ){while(aL.innerMode){var aK=aL.innerMode(aJ);aJ=aK.state;aL=aK.mode}return aK||{mode:aL,state:aJ}};function ai(aJ,aK){this.pos=this.start=0;this.string=aJ;this.tabSize=aK||8}ai.prototype={eol:function(){return this.pos>=this.string.length},sol:function(){return this.pos==0},peek:function(){return this.string.charAt(this.pos)||undefined},next:function(){if(this.pos<this.string.length){return this.string.charAt(this.pos++)}},eat:function(aJ){var aL=this.string.charAt(this.pos);if(typeof aJ=="string"){var aK=aL==aJ}else{var aK=aL&&(aJ.test?aJ.test(aL):aJ(aL))}if(aK){++this.pos;return aL}},eatWhile:function(aJ){var aK=this.pos;while(this.eat(aJ)){}return this.pos>aK},eatSpace:function(){var aJ=this.pos;while(/[\s\u00a0]/.test(this.string.charAt(this.pos))){++this.pos}return this.pos>aJ},skipToEnd:function(){this.pos=this.string.length},skipTo:function(aJ){var aK=this.string.indexOf(aJ,this.pos);if(aK>-1){this.pos=aK;return true}},backUp:function(aJ){this.pos-=aJ},column:function(){return ap(this.string,this.start,this.tabSize)},indentation:function(){return ap(this.string,null,this.tabSize)},match:function(aM,aK,aJ){if(typeof aM=="string"){var aN=function(aO){return aJ?aO.toLowerCase():aO};if(aN(this.string).indexOf(aN(aM),this.pos)==this.pos){if(aK!==false){this.pos+=aM.length}return true}}else{var aL=this.string.slice(this.pos).match(aM);if(aL&&aL.index>0){return null}if(aL&&aK!==false){this.pos+=aL[0].length}return aL}},current:function(){return this.string.slice(this.start,this.pos)}};r.StringStream=ai;function Z(aL,aK,aJ){this.from=aL;this.to=aK;this.marker=aJ}function aI(aL,aJ){if(aL){for(var aK=0;aK<aL.length;++aK){var aM=aL[aK];if(aM.marker==aJ){return aM}}}}function aD(aK,aL){var aM;for(var aJ=0;aJ<aK.length;++aJ){if(aK[aJ]!=aL){(aM||(aM=[])).push(aK[aJ])}}return aM}function V(aK,aL,aN){if(aK){for(var aO=0,aQ;aO<aK.length;++aO){var aR=aK[aO],aP=aR.marker;var aJ=aR.from==null||(aP.inclusiveLeft?aR.from<=aL:aR.from<aL);if(aJ||aP.type=="bookmark"&&aR.from==aL&&aR.from!=aN){var aM=aR.to==null||(aP.inclusiveRight?aR.to>=aL:aR.to>aL);(aQ||(aQ=[])).push({from:aR.from,to:aM?null:aR.to,marker:aP})}}}return aQ}function aw(aL,aO){if(aL){for(var aN=0,aK;aN<aL.length;++aN){var aP=aL[aN],aJ=aP.marker;var aQ=aP.to==null||(aJ.inclusiveRight?aP.to>=aO:aP.to>aO);if(aQ||aJ.type=="bookmark"&&aP.from==aO){var aM=aP.from==null||(aJ.inclusiveLeft?aP.from<=aO:aP.from<aO);(aK||(aK=[])).push({from:aM?null:aP.from-aO,to:aP.to==null?null:aP.to-aO,marker:aJ})}}}return aK}function Y(aR,aW,aK,aN,aQ){if(!aR&&!aW){return aQ}var aP=V(aR,aK);var aU=aw(aW,aN);var aV=aQ.length==1,aL=P(aQ).length+(aV?aK:0);if(aP){for(var aM=0;aM<aP.length;++aM){var aT=aP[aM];if(aT.to==null){var aX=aI(aU,aT.marker);if(!aX){aT.to=aK}else{if(aV){aT.to=aX.to==null?null:aX.to+aL}}}}}if(aU){for(var aM=0;aM<aU.length;++aM){var aT=aU[aM];if(aT.to!=null){aT.to+=aL}if(aT.from==null){var aX=aI(aP,aT.marker);if(!aX){aT.from=aL;if(aV){(aP||(aP=[])).push(aT)}}}else{aT.from+=aL;if(aV){(aP||(aP=[])).push(aT)}}}}var aO=[k(aQ[0],aP)];if(!aV){var aS=aQ.length-2,aJ;if(aS>0&&aP){for(var aM=0;aM<aP.length;++aM){if(aP[aM].to==null){(aJ||(aJ=[])).push({from:null,to:null,marker:aP[aM].marker})}}}for(var aM=0;aM<aS;++aM){aO.push(k(aQ[aM+1],aJ))}aO.push(k(P(aQ),aU))}return aO}function au(aJ){return typeof aJ=="string"?aJ:aJ.text}function e(aM){if(typeof aM=="string"){return null}var aL=aM.markedSpans,aJ=null;for(var aK=0;aK<aL.length;++aK){if(aL[aK].marker.explicitlyCleared){if(!aJ){aJ=aL.slice(0,aK)}}else{if(aJ){aJ.push(aL[aK])}}}return !aJ?aL:aJ.length?aJ:null}function k(aK,aJ){return aJ?{text:aK,markedSpans:aJ}:aK}function aA(aL){var aN=aL.markedSpans;if(!aN){return}for(var aM=0;aM<aN.length;++aM){var aK=aN[aM].marker.lines;var aJ=u(aK,aL);aK.splice(aJ,1)}aL.markedSpans=null}function aC(aK,aM){if(!aM){return}for(var aL=0;aL<aM.length;++aL){var aJ=aM[aL].marker.lines.push(aK)}aK.markedSpans=aM}var ao=" ";if(x||(U&&!L)){ao="\u200b"}else{if(ax){ao=""}}function J(aK,aJ){this.text=aK;this.height=1;aC(this,aJ)}J.prototype={update:function(aK,aJ){this.text=aK;this.stateAfter=this.styles=null;aA(this);aC(this,aJ)},highlight:function(aP,aM,aN){var aO=new ai(this.text,aN),aJ=this.styles||(this.styles=[]);var aQ=aJ.length=0;if(this.text==""&&aP.blankLine){aP.blankLine(aM)}while(!aO.eol()){var aK=aP.token(aO,aM),aL=aO.current();aO.start=aO.pos;if(aQ&&aJ[aQ-1]==aK){aJ[aQ-2]+=aL}else{if(aL){aJ[aQ++]=aL;aJ[aQ++]=aK}}if(aO.pos>5000){aJ[aQ++]=this.text.slice(aO.pos);aJ[aQ++]=null;break}}},process:function(aM,aJ,aK){var aL=new ai(this.text,aK);if(this.text==""&&aM.blankLine){aM.blankLine(aJ)}while(!aL.eol()&&aL.pos<=5000){aM.token(aL,aJ);aL.start=aL.pos}},getTokenAt:function(aP,aM,aN,aL){var aJ=this.text,aO=new ai(aJ,aN);while(aO.pos<aL&&!aO.eol()){aO.start=aO.pos;var aK=aP.token(aO,aM)}return{start:aO.start,end:aO.pos,string:aO.current(),className:aK||null,state:aM}},indentation:function(aJ){return ap(this.text,null,aJ)},getContent:function(aY,aJ,aU){var aP=true,aN=0,a5=/[\t\u0000-\u0019\u200b\u2028\u2029\uFEFF]/g;var aX=ak("pre");function a6(bk,bp,bh){if(!bp){return}if(aP&&U&&bp.charAt(0)==" "){bp="\u00a0"+bp.slice(1)}aP=false;if(!a5.test(bp)){aN+=bp.length;var bl=document.createTextNode(bp)}else{var bl=document.createDocumentFragment(),bn=0;while(true){a5.lastIndex=bn;var bi=a5.exec(bp);var bm=bi?bi.index-bn:bp.length-bn;if(bm){bl.appendChild(document.createTextNode(bp.slice(bn,bn+bm)));aN+=bm}if(!bi){break}bn+=bm+1;if(bi[0]=="\t"){var bo=aY-aN%aY;bl.appendChild(ak("span",az(bo),"cm-tab"));aN+=bo}else{var bj=ak("span","\u2022","cm-invalidchar");bj.title="\\u"+bi[0].charCodeAt(0).toString(16);bl.appendChild(bj);aN+=1}}}if(bh){bk.appendChild(ak("span",[bl],bh))}else{bk.appendChild(bl)}}var a9=a6;if(aJ!=null){var a3=0,aQ=aX.anchor=ak("span");a9=function(bj,bm,bk){var bi=bm.length;if(aJ>=a3&&aJ<a3+bi){var bl=aJ-a3;if(bl){a6(bj,bm.slice(0,bl),bk);if(aU){var bh=bm.slice(bl-1,bl+1);if(H.test(bh)){bj.appendChild(ak("wbr"))}else{if(!L&&/\w\w/.test(bh)){bj.appendChild(document.createTextNode("\u200d"))}}}}bj.appendChild(aQ);a6(aQ,ax?bm.slice(bl,bl+1):bm.slice(bl),bk);if(ax){a6(bj,bm.slice(bl+1),bk)}aJ--;a3+=bi}else{a3+=bi;a6(bj,bm,bk);if(a3==aJ&&a3==bd){y(aQ,ao);bj.appendChild(aQ)}else{if(a3>aJ+10&&/\s/.test(bm)){a9=function(){}}}}}}var a2=this.styles,aR=this.text,aZ=this.markedSpans;var bd=aR.length;function aM(bh){if(!bh){return null}return"cm-"+bh.replace(/ +/g," cm-")}if(!aR&&aJ==null){a9(aX," ")}else{if(!aZ||!aZ.length){for(var ba=0,aT=0;aT<bd;ba+=2){var a1=a2[ba],bc=a2[ba+1],a4=a1.length;if(aT+a4>bd){a1=a1.slice(0,bd-aT)}aT+=a4;a9(aX,a1,aM(bc))}}else{aZ.sort(function(bi,bh){return bi.from-bh.from});var aO=0,ba=0,aW="",bc,bg=0;var bf=aZ[0].from||0,a8=[],be=0;var bb=function(){var bh;while(be<aZ.length&&((bh=aZ[be]).from==aO||bh.from==null)){if(bh.marker.type=="range"){a8.push(bh)}++be}bf=be<aZ.length?aZ[be].from:Infinity;for(var bi=0;bi<a8.length;++bi){var bj=a8[bi].to;if(bj==null){bj=Infinity}if(bj==aO){a8.splice(bi--,1)}else{bf=Math.min(bj,bf)}}};var a0=0;while(aO<bd){if(bf==aO){bb()}var aV=Math.min(bd,bf);while(true){if(aW){var aL=aO+aW.length;var aK=bc;for(var a7=0;a7<a8.length;++a7){var aS=a8[a7];aK=(aK?aK+" ":"")+aS.marker.style;if(aS.marker.endStyle&&aS.to===Math.min(aL,aV)){aK+=" "+aS.marker.endStyle}if(aS.marker.startStyle&&aS.from===aO){aK+=" "+aS.marker.startStyle}}a9(aX,aL>aV?aW.slice(0,aV-aO):aW,aK);if(aL>=aV){aW=aW.slice(aV-aO);aO=aV;break}aO=aL}aW=a2[ba++];bc=aM(a2[ba++])}}}}return aX},cleanUp:function(){this.parent=null;aA(this)}};function Q(aK){this.lines=aK;this.parent=null;for(var aL=0,aM=aK.length,aJ=0;aL<aM;++aL){aK[aL].parent=this;aJ+=aK[aL].height}this.height=aJ}Q.prototype={chunkSize:function(){return this.lines.length},remove:function(aJ,aP,aN){for(var aM=aJ,aO=aJ+aP;aM<aO;++aM){var aK=this.lines[aM];this.height-=aK.height;aK.cleanUp();if(aK.handlers){for(var aL=0;aL<aK.handlers.length;++aL){aN.push(aK.handlers[aL])}}}this.lines.splice(aJ,aP)},collapse:function(aJ){aJ.splice.apply(aJ,[aJ.length,0].concat(this.lines))},insertHeight:function(aK,aL,aJ){this.height+=aJ;this.lines=this.lines.slice(0,aK).concat(aL).concat(this.lines.slice(aK));for(var aM=0,aN=aL.length;aM<aN;++aM){aL[aM].parent=this}},iterN:function(aJ,aM,aL){for(var aK=aJ+aM;aJ<aK;++aJ){if(aL(this.lines[aJ])){return true}}}};function al(aM){this.children=aM;var aL=0,aJ=0;for(var aK=0,aO=aM.length;aK<aO;++aK){var aN=aM[aK];aL+=aN.chunkSize();aJ+=aN.height;aN.parent=this}this.size=aL;this.height=aJ;this.parent=null}al.prototype={chunkSize:function(){return this.size},remove:function(aL,aK,aO){this.size-=aK;for(var aM=0;aM<this.children.length;++aM){var aJ=this.children[aM],aP=aJ.chunkSize();if(aL<aP){var aN=Math.min(aK,aP-aL),aQ=aJ.height;aJ.remove(aL,aN,aO);this.height-=aQ-aJ.height;if(aP==aN){this.children.splice(aM--,1);aJ.parent=null}if((aK-=aN)==0){break}aL=0}else{aL-=aP}}if(this.size-aK<25){var aR=[];this.collapse(aR);this.children=[new Q(aR)];this.children[0].parent=this}},collapse:function(aJ){for(var aK=0,aL=this.children.length;aK<aL;++aK){this.children[aK].collapse(aJ)}},insert:function(aK,aL){var aJ=0;for(var aM=0,aN=aL.length;aM<aN;++aM){aJ+=aL[aM].height}this.insertHeight(aK,aL,aJ)},insertHeight:function(aK,aR,aQ){this.size+=aR.length;this.height+=aQ;for(var aL=0,aN=this.children.length;aL<aN;++aL){var aJ=this.children[aL],aO=aJ.chunkSize();if(aK<=aO){aJ.insertHeight(aK,aR,aQ);if(aJ.lines&&aJ.lines.length>50){while(aJ.lines.length>50){var aM=aJ.lines.splice(aJ.lines.length-25,25);var aP=new Q(aM);aJ.height-=aP.height;this.children.splice(aL+1,0,aP);aP.parent=this}this.maybeSpill()}break}aK-=aO}},maybeSpill:function(){if(this.children.length<=10){return}var aM=this;do{var aK=aM.children.splice(aM.children.length-5,5);var aL=new al(aK);if(!aM.parent){var aN=new al(aM.children);aN.parent=aM;aM.children=[aN,aL];aM=aN}else{aM.size-=aL.size;aM.height-=aL.height;var aJ=u(aM.parent.children,aM);aM.parent.children.splice(aJ+1,0,aL)}aL.parent=aM.parent}while(aM.children.length>10);aM.parent.maybeSpill()},iter:function(aL,aK,aJ){this.iterN(aL,aK-aL,aJ)},iterN:function(aJ,aQ,aP){for(var aK=0,aN=this.children.length;aK<aN;++aK){var aO=this.children[aK],aM=aO.chunkSize();if(aJ<aM){var aL=Math.min(aQ,aM-aJ);if(aO.iterN(aJ,aL,aP)){return true}if((aQ-=aL)==0){break}aJ=0}else{aJ-=aM}}}};function M(aJ,aN){while(!aJ.lines){for(var aK=0;;++aK){var aM=aJ.children[aK],aL=aM.chunkSize();if(aN<aL){aJ=aM;break}aN-=aL}}return aJ.lines[aN]}function X(aJ){if(aJ.parent==null){return null}var aN=aJ.parent,aM=u(aN.lines,aJ);for(var aK=aN.parent;aK;aN=aK,aK=aK.parent){for(var aL=0;;++aL){if(aK.children[aL]==aN){break}aM+=aK.children[aL].chunkSize()}}return aM}function af(aP,aN){var aL=0;outer:do{for(var aM=0,aO=aP.children.length;aM<aO;++aM){var aK=aP.children[aM],aJ=aK.height;if(aN<aJ){aP=aK;continue outer}aN-=aJ;aL+=aK.chunkSize()}return aL}while(!aP.lines);for(var aM=0,aO=aP.lines.length;aM<aO;++aM){var aR=aP.lines[aM],aQ=aR.height;if(aN<aQ){break}aN-=aQ}return aL+aM}function a(aJ,aP){var aL=0;outer:do{for(var aK=0,aN=aJ.children.length;aK<aN;++aK){var aO=aJ.children[aK],aM=aO.chunkSize();if(aP<aM){aJ=aO;continue outer}aP-=aM;aL+=aO.height}return aL}while(!aJ.lines);for(var aK=0;aK<aP;++aK){aL+=aJ.lines[aK].height}return aL}function F(){this.time=0;this.done=[];this.undone=[];this.compound=0;this.closed=false}F.prototype={addChange:function(aJ,aO,aK){this.undone.length=0;var aL=+new Date,aQ=P(this.done),aR=aQ&&P(aQ);var aN=aL-this.time;if(aQ&&!this.closed&&this.compound){aQ.push({start:aJ,added:aO,old:aK})}else{if(aN>400||!aR||this.closed||aR.start>aJ+aK.length||aR.start+aR.added<aJ){this.done.push([{start:aJ,added:aO,old:aK}]);this.closed=false}else{var aP=Math.max(0,aR.start-aJ),aS=Math.max(0,(aJ+aK.length)-(aR.start+aR.added));for(var aM=aP;aM>0;--aM){aR.old.unshift(aK[aM-1])}for(var aM=aS;aM>0;--aM){aR.old.push(aK[aK.length-aM])}if(aP){aR.start=aJ}aR.added+=aO-(aK.length-aP-aS)}}this.time=aL},startCompound:function(){if(!this.compound++){this.closed=true}},endCompound:function(){if(!--this.compound){this.closed=true}}};function z(){ae(this)}function R(aJ){if(!aJ.stop){aJ.stop=z}return aJ}function f(aJ){if(aJ.preventDefault){aJ.preventDefault()}else{aJ.returnValue=false}}function q(aJ){if(aJ.stopPropagation){aJ.stopPropagation()}else{aJ.cancelBubble=true}}function ae(aJ){f(aJ);q(aJ)}r.e_stop=ae;r.e_preventDefault=f;r.e_stopPropagation=q;function ar(aJ){return aJ.target||aJ.srcElement}function E(aK){var aJ=aK.which;if(aJ==null){if(aK.button&1){aJ=1}else{if(aK.button&2){aJ=3}else{if(aK.button&4){aJ=2}}}}if(K&&aK.ctrlKey&&aJ==1){aJ=3}return aJ}function ad(aK,aL){var aJ=aK.override&&aK.override.hasOwnProperty(aL);return aJ?aK.override[aL]:aK[aL]}function aE(aM,aL,aK,aJ){if(typeof aM.addEventListener=="function"){aM.addEventListener(aL,aK,false);if(aJ){return function(){aM.removeEventListener(aL,aK,false)}}}else{var aN=function(aO){aK(aO||window.event)};aM.attachEvent("on"+aL,aN);if(aJ){return function(){aM.detachEvent("on"+aL,aN)}}}}r.connect=aE;function j(){this.id=null}j.prototype={set:function(aJ,aK){clearTimeout(this.id);this.id=setTimeout(aK,aJ)}};var aq=r.Pass={toString:function(){return"CodeMirror.Pass"}};var ac=function(){if(I){return false}var aJ=ak("div");return"draggable" in aJ||"dragDrop" in aJ}();var S=function(){var aJ=ak("textarea");aJ.value="foo\nbar";if(aJ.value.indexOf("\r")>-1){return"\r\n"}return"\n"}();var H=/^$/;if(x){H=/$'/}else{if(G){H=/\-[^ \-?]|\?[^ !'\"\),.\-\/:;\?\]\}]/}else{if(p){H=/\-[^ \-\.?]|\?[^ \-\.?\]\}:;!'\"\),\/]|[\.!\"#&%\)*+,:;=>\]|\}~][\(\{\[<]|\$'/}}}function ap(aK,aJ,aM){if(aJ==null){aJ=aK.search(/[^\s\u00a0]/);if(aJ==-1){aJ=aK.length}}for(var aL=0,aN=0;aL<aJ;++aL){if(aK.charAt(aL)=="\t"){aN+=aM-(aN%aM)}else{++aN}}return aN}function B(aM,aJ){try{var aL=aM.getBoundingClientRect();aL={top:aL.top,left:aL.left}}catch(aN){aL={top:0,left:0}}if(!aJ){if(window.pageYOffset==null){var aK=document.documentElement||document.body.parentNode;if(aK.scrollTop==null){aK=document.body}aL.top+=aK.scrollTop;aL.left+=aK.scrollLeft}else{aL.top+=window.pageYOffset;aL.left+=window.pageXOffset}}return aL}function aB(aJ){return aJ.textContent||aJ.innerText||aJ.nodeValue||""}var an=[""];function az(aJ){while(an.length<=aJ){an.push(P(an)+" ")}return an[aJ]}function P(aJ){return aJ[aJ.length-1]}function aF(aJ){if(i){aJ.selectionStart=0;aJ.selectionEnd=aJ.value.length}else{aJ.select()}}function T(aK,aJ){return aK.line==aJ.line&&aK.ch==aJ.ch}function D(aK,aJ){return aK.line<aJ.line||(aK.line==aJ.line&&aK.ch<aJ.ch)}function aa(aJ){return{line:aJ.line,ch:aJ.ch}}function ak(aJ,aN,aM,aL){var aO=document.createElement(aJ);if(aM){aO.className=aM}if(aL){aO.style.cssText=aL}if(typeof aN=="string"){y(aO,aN)}else{if(aN){for(var aK=0;aK<aN.length;++aK){aO.appendChild(aN[aK])}}}return aO}function aH(aJ){aJ.innerHTML="";return aJ}function s(aJ,aK){aH(aJ).appendChild(aK)}function y(aJ,aK){if(I){aJ.innerHTML="";aJ.appendChild(document.createTextNode(aK))}else{aJ.textContent=aK}}function C(aM,aL){if(!aL){return 0}if(!aM){return aL.length}for(var aK=aM.length,aJ=aL.length;aK>=0&&aJ>=0;--aK,--aJ){if(aM.charAt(aK)!=aL.charAt(aJ)){break}}return aJ+1}function u(aM,aJ){if(aM.indexOf){return aM.indexOf(aJ)}for(var aK=0,aL=aM.length;aK<aL;++aK){if(aM[aK]==aJ){return aK}}return -1}var O=/[\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc]/;function N(aJ){return/\w/.test(aJ)||aJ>"\x80"&&(aJ.toUpperCase()!=aJ.toLowerCase()||O.test(aJ))}var h="\n\nb".split(/\n/).length!=3?function(aO){var aP=0,aJ=[],aN=aO.length;while(aP<=aN){var aM=aO.indexOf("\n",aP);if(aM==-1){aM=aO.length}var aL=aO.slice(aP,aO.charAt(aM-1)=="\r"?aM-1:aM);var aK=aL.indexOf("\r");if(aK!=-1){aJ.push(aL.slice(0,aK));aP+=aK+1}else{aJ.push(aL);aP=aM+1}}return aJ}:function(aJ){return aJ.split(/\r\n?|\n/)};r.splitLines=h;var b=window.getSelection?function(aK){try{return aK.selectionStart!=aK.selectionEnd}catch(aJ){return false}}:function(aL){try{var aJ=aL.ownerDocument.selection.createRange()}catch(aK){}if(!aJ||aJ.parentElement()!=aL){return false}return aJ.compareEndPoints("StartToEnd",aJ)!=0};r.defineMode("null",function(){return{token:function(aJ){aJ.skipToEnd()}}});r.defineMIME("text/plain","null");var w={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"};r.keyNames=w;(function(){for(var aJ=0;aJ<10;aJ++){w[aJ+48]=String(aJ)}for(var aJ=65;aJ<=90;aJ++){w[aJ]=String.fromCharCode(aJ)}for(var aJ=1;aJ<=12;aJ++){w[aJ+111]=w[aJ+63235]="F"+aJ}})();r.version="2.38";return r})();
b'\\ No newline at end of file'
1
// CodeMirror version 2.38
3
// All functions that need access to the editor's state live inside
4
// the CodeMirror function. Below that, at the bottom of the file,
5
// some utilities are defined.
7
// CodeMirror is the only global var we claim
8
window.CodeMirror = (function() {
10
// This is the function that produces an editor instance. Its
11
// closure is used to store the editor state.
12
function CodeMirror(place, givenOptions) {
13
// Determine effective options based on given values and defaults.
14
var options = {}, defaults = CodeMirror.defaults;
15
for (var opt in defaults)
16
if (defaults.hasOwnProperty(opt))
17
options[opt] = (givenOptions && givenOptions.hasOwnProperty(opt) ? givenOptions : defaults)[opt];
19
var input = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em");
20
input.setAttribute("wrap", "off"); input.setAttribute("autocorrect", "off"); input.setAttribute("autocapitalize", "off");
21
// Wraps and hides input textarea
22
var inputDiv = elt("div", [input], null, "overflow: hidden; position: relative; width: 3px; height: 0px;");
23
// The empty scrollbar content, used solely for managing the scrollbar thumb.
24
var scrollbarInner = elt("div", null, "CodeMirror-scrollbar-inner");
25
// The vertical scrollbar. Horizontal scrolling is handled by the scroller itself.
26
var scrollbar = elt("div", [scrollbarInner], "CodeMirror-scrollbar");
27
// DIVs containing the selection and the actual code
28
var lineDiv = elt("div"), selectionDiv = elt("div", null, null, "position: relative; z-index: -1");
29
// Blinky cursor, and element used to ensure cursor fits at the end of a line
30
var cursor = elt("pre", "\u00a0", "CodeMirror-cursor"), widthForcer = elt("pre", "\u00a0", "CodeMirror-cursor", "visibility: hidden");
31
// Used to measure text size
32
var measure = elt("div", null, null, "position: absolute; width: 100%; height: 0px; overflow: hidden; visibility: hidden;");
33
var lineSpace = elt("div", [measure, cursor, widthForcer, selectionDiv, lineDiv], null, "position: relative; z-index: 0");
34
var gutterText = elt("div", null, "CodeMirror-gutter-text"), gutter = elt("div", [gutterText], "CodeMirror-gutter");
35
// Moved around its parent to cover visible view
36
var mover = elt("div", [gutter, elt("div", [lineSpace], "CodeMirror-lines")], null, "position: relative");
37
// Set to the height of the text, causes scrolling
38
var sizer = elt("div", [mover], null, "position: relative");
40
var scroller = elt("div", [sizer], "CodeMirror-scroll");
41
scroller.setAttribute("tabIndex", "-1");
42
// The element in which the editor lives.
43
var wrapper = elt("div", [inputDiv, scrollbar, scroller], "CodeMirror" + (options.lineWrapping ? " CodeMirror-wrap" : ""));
44
if (place.appendChild) place.appendChild(wrapper); else place(wrapper);
46
themeChanged(); keyMapChanged();
47
// Needed to hide big blue blinking cursor on Mobile Safari
48
if (ios) input.style.width = "0px";
49
if (!webkit) scroller.draggable = true;
50
lineSpace.style.outline = "none";
51
if (options.tabindex != null) input.tabIndex = options.tabindex;
52
if (options.autofocus) focusInput();
53
if (!options.gutter && !options.lineNumbers) gutter.style.display = "none";
54
// Needed to handle Tab key in KHTML
55
if (khtml) inputDiv.style.height = "1px", inputDiv.style.position = "absolute";
57
// Check for OS X >= 10.7. This has transparent scrollbars, so the
58
// overlaying of one scrollbar with another won't work. This is a
59
// temporary hack to simply turn off the overlay scrollbar. See
61
if (mac_geLion) { scrollbar.style.zIndex = -2; scrollbar.style.visibility = "hidden"; }
62
// Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
63
else if (ie_lt8) scrollbar.style.minWidth = "18px";
65
// Delayed object wrap timeouts, making sure only one is active. blinker holds an interval.
66
var poll = new Delayed(), highlight = new Delayed(), blinker;
68
// mode holds a mode API object. doc is the tree of Line objects,
69
// frontier is the point up to which the content has been parsed,
70
// and history the undo history (instance of History constructor).
71
var mode, doc = new BranchChunk([new LeafChunk([new Line("")])]), frontier = 0, focused;
73
// The selection. These are always maintained to point at valid
74
// positions. Inverted is used to remember that the user is
75
// selecting bottom-to-top.
76
var sel = {from: {line: 0, ch: 0}, to: {line: 0, ch: 0}, inverted: false};
77
// Selection-related flags. shiftSelecting obviously tracks
78
// whether the user is holding shift.
79
var shiftSelecting, lastClick, lastDoubleClick, lastScrollTop = 0, draggingText,
80
overwrite = false, suppressEdits = false, pasteIncoming = false;
81
// Variables used by startOperation/endOperation to track what
82
// happened during the operation.
83
var updateInput, userSelChange, changes, textChanged, selectionChanged,
84
gutterDirty, callbacks;
85
// Current visible range (may be bigger than the view window).
86
var displayOffset = 0, showingFrom = 0, showingTo = 0, lastSizeC = 0;
87
// bracketHighlighted is used to remember that a bracket has been
89
var bracketHighlighted;
90
// Tracks the maximum line length so that the horizontal scrollbar
91
// can be kept static when scrolling.
92
var maxLine = getLine(0), updateMaxLine = false, maxLineChanged = true;
93
var pollingFast = false; // Ensures slowPoll doesn't cancel fastPoll
94
var goalColumn = null;
96
// Initialize the content.
97
operation(function(){setValue(options.value || ""); updateInput = false;})();
98
var history = new History();
100
// Register our event handlers.
101
connect(scroller, "mousedown", operation(onMouseDown));
102
connect(scroller, "dblclick", operation(onDoubleClick));
103
connect(lineSpace, "selectstart", e_preventDefault);
104
// Gecko browsers fire contextmenu *after* opening the menu, at
105
// which point we can't mess with it anymore. Context menu is
106
// handled in onMouseDown for Gecko.
107
if (!gecko) connect(scroller, "contextmenu", onContextMenu);
108
connect(scroller, "scroll", onScrollMain);
109
connect(scrollbar, "scroll", onScrollBar);
110
connect(scrollbar, "mousedown", function() {if (focused) setTimeout(focusInput, 0);});
111
var resizeHandler = connect(window, "resize", function() {
112
if (wrapper.parentNode) updateDisplay(true);
113
else resizeHandler();
115
connect(input, "keyup", operation(onKeyUp));
116
connect(input, "input", fastPoll);
117
connect(input, "keydown", operation(onKeyDown));
118
connect(input, "keypress", operation(onKeyPress));
119
connect(input, "focus", onFocus);
120
connect(input, "blur", onBlur);
123
if (options.onDragEvent && options.onDragEvent(instance, addStop(e))) return;
126
if (options.dragDrop) {
127
connect(scroller, "dragstart", onDragStart);
128
connect(scroller, "dragenter", drag_);
129
connect(scroller, "dragover", drag_);
130
connect(scroller, "drop", operation(onDrop));
132
connect(scroller, "paste", function(){focusInput(); fastPoll();});
133
connect(input, "paste", function(){pasteIncoming = true; fastPoll();});
134
connect(input, "cut", operation(function(){
135
if (!options.readOnly) replaceSelection("");
138
// Needed to handle Tab key in KHTML
139
if (khtml) connect(sizer, "mouseup", function() {
140
if (document.activeElement == input) input.blur();
144
// IE throws unspecified error in certain cases, when
145
// trying to access activeElement before onload
146
var hasFocus; try { hasFocus = (document.activeElement == input); } catch(e) { }
147
if (hasFocus || options.autofocus) setTimeout(onFocus, 20);
150
function isLine(l) {return l >= 0 && l < doc.size;}
151
// The instance object that we'll return. Mostly calls out to
152
// local functions in the CodeMirror function. Some do some extra
153
// range checking and/or clipping. operation is used to wrap the
154
// call so that changes it makes are tracked, and the display is
155
// updated afterwards.
156
var instance = wrapper.CodeMirror = {
158
setValue: operation(setValue),
159
getSelection: getSelection,
160
replaceSelection: operation(replaceSelection),
161
focus: function(){window.focus(); focusInput(); onFocus(); fastPoll();},
162
setOption: function(option, value) {
163
var oldVal = options[option];
164
options[option] = value;
165
if (option == "mode" || option == "indentUnit") loadMode();
166
else if (option == "readOnly" && value == "nocursor") {onBlur(); input.blur();}
167
else if (option == "readOnly" && !value) {resetInput(true);}
168
else if (option == "theme") themeChanged();
169
else if (option == "lineWrapping" && oldVal != value) operation(wrappingChanged)();
170
else if (option == "tabSize") updateDisplay(true);
171
else if (option == "keyMap") keyMapChanged();
172
else if (option == "tabindex") input.tabIndex = value;
173
else if (option == "showCursorWhenSelecting") updateSelection();
174
if (option == "lineNumbers" || option == "gutter" || option == "firstLineNumber" ||
175
option == "theme" || option == "lineNumberFormatter") {
180
getOption: function(option) {return options[option];},
181
getMode: function() {return mode;},
182
undo: operation(undo),
183
redo: operation(redo),
184
indentLine: operation(function(n, dir) {
185
if (typeof dir != "string") {
186
if (dir == null) dir = options.smartIndent ? "smart" : "prev";
187
else dir = dir ? "add" : "subtract";
189
if (isLine(n)) indentLine(n, dir);
191
indentSelection: operation(indentSelected),
192
historySize: function() {return {undo: history.done.length, redo: history.undone.length};},
193
clearHistory: function() {history = new History();},
194
setHistory: function(histData) {
195
history = new History();
196
history.done = histData.done;
197
history.undone = histData.undone;
199
getHistory: function() {
201
for (var i = 0, nw = [], nwelt; i < arr.length; ++i) {
203
for (var j = 0, elt = arr[i]; j < elt.length; ++j) {
204
var old = [], cur = elt[j];
205
nwelt.push({start: cur.start, added: cur.added, old: old});
206
for (var k = 0; k < cur.old.length; ++k) old.push(hlText(cur.old[k]));
211
return {done: cp(history.done), undone: cp(history.undone)};
213
matchBrackets: operation(function(){matchBrackets(true);}),
214
getTokenAt: operation(function(pos) {
216
return getLine(pos.line).getTokenAt(mode, getStateBefore(pos.line), options.tabSize, pos.ch);
218
getStateAfter: function(line) {
219
line = clipLine(line == null ? doc.size - 1: line);
220
return getStateBefore(line + 1);
222
cursorCoords: function(start, mode) {
223
if (start == null) start = sel.inverted;
224
return this.charCoords(start ? sel.from : sel.to, mode);
226
charCoords: function(pos, mode) {
228
if (mode == "local") return localCoords(pos, false);
229
if (mode == "div") return localCoords(pos, true);
230
return pageCoords(pos);
232
coordsChar: function(coords) {
233
var off = eltOffset(lineSpace);
234
return coordsChar(coords.x - off.left, coords.y - off.top);
236
defaultTextHeight: function() { return textHeight(); },
237
markText: operation(markText),
238
setBookmark: setBookmark,
239
findMarksAt: findMarksAt,
240
setMarker: operation(addGutterMarker),
241
clearMarker: operation(removeGutterMarker),
242
setLineClass: operation(setLineClass),
243
hideLine: operation(function(h) {return setLineHidden(h, true);}),
244
showLine: operation(function(h) {return setLineHidden(h, false);}),
245
onDeleteLine: function(line, f) {
246
if (typeof line == "number") {
247
if (!isLine(line)) return null;
248
line = getLine(line);
250
(line.handlers || (line.handlers = [])).push(f);
254
getViewport: function() { return {from: showingFrom, to: showingTo};},
255
addWidget: function(pos, node, scroll, vert, horiz) {
256
pos = localCoords(clipPos(pos));
257
var top = pos.yBot, left = pos.x;
258
node.style.position = "absolute";
259
sizer.appendChild(node);
260
if (vert == "over") top = pos.y;
261
else if (vert == "near") {
262
var vspace = Math.max(scroller.offsetHeight, doc.height * textHeight()),
263
hspace = Math.max(sizer.clientWidth, lineSpace.clientWidth) - paddingLeft();
264
if (pos.yBot + node.offsetHeight > vspace && pos.y > node.offsetHeight)
265
top = pos.y - node.offsetHeight;
266
if (left + node.offsetWidth > hspace)
267
left = hspace - node.offsetWidth;
269
node.style.top = (top + paddingTop()) + "px";
270
node.style.left = node.style.right = "";
271
if (horiz == "right") {
272
left = sizer.clientWidth - node.offsetWidth;
273
node.style.right = "0px";
275
if (horiz == "left") left = 0;
276
else if (horiz == "middle") left = (sizer.clientWidth - node.offsetWidth) / 2;
277
node.style.left = (left + paddingLeft()) + "px";
280
scrollIntoView(left, top, left + node.offsetWidth, top + node.offsetHeight);
283
lineCount: function() {return doc.size;},
285
getCursor: function(start) {
286
if (start == null || start == "head") start = sel.inverted;
287
if (start == "anchor") start = !sel.inverted;
288
if (start == "end") start = false;
289
return copyPos(start ? sel.from : sel.to);
291
somethingSelected: function() {return !posEq(sel.from, sel.to);},
292
setCursor: operation(function(line, ch, user) {
293
if (ch == null && typeof line.line == "number") setCursor(line.line, line.ch, user);
294
else setCursor(line, ch, user);
296
setSelection: operation(function(from, to, user) {
297
(user ? setSelectionUser : setSelection)(clipPos(from), clipPos(to || from));
299
getLine: function(line) {if (isLine(line)) return getLine(line).text;},
300
getLineHandle: function(line) {if (isLine(line)) return getLine(line);},
301
setLine: operation(function(line, text) {
302
if (isLine(line)) replaceRange(text, {line: line, ch: 0}, {line: line, ch: getLine(line).text.length});
304
removeLine: operation(function(line) {
305
if (isLine(line)) replaceRange("", {line: line, ch: 0}, clipPos({line: line+1, ch: 0}));
307
replaceRange: operation(replaceRange),
308
getRange: function(from, to, lineSep) {return getRange(clipPos(from), clipPos(to), lineSep);},
310
triggerOnKeyDown: operation(onKeyDown),
311
execCommand: function(cmd) {return commands[cmd](instance);},
312
// Stuff used by commands, probably not much use to outside code.
313
moveH: operation(moveH),
314
deleteH: operation(deleteH),
315
moveV: operation(moveV),
316
toggleOverwrite: function() {
319
cursor.className = cursor.className.replace(" CodeMirror-overwrite", "");
322
cursor.className += " CodeMirror-overwrite";
326
posFromIndex: function(off) {
328
doc.iter(0, doc.size, function(line) {
329
var sz = line.text.length + 1;
330
if (sz > off) { ch = off; return true; }
334
return clipPos({line: lineNo, ch: ch});
336
indexFromPos: function (coords) {
337
if (coords.line < 0 || coords.ch < 0) return 0;
338
var index = coords.ch;
339
doc.iter(0, coords.line, function (line) {
340
index += line.text.length + 1;
344
scrollTo: function(x, y) {
345
if (x != null) scroller.scrollLeft = x;
346
if (y != null) scrollbar.scrollTop = scroller.scrollTop = y;
349
getScrollInfo: function() {
350
return {x: scroller.scrollLeft, y: scrollbar.scrollTop,
351
height: scrollbar.scrollHeight, width: scroller.scrollWidth};
353
scrollIntoView: function(pos) {
354
var coords = localCoords(pos ? clipPos(pos) : sel.inverted ? sel.from : sel.to);
355
scrollIntoView(coords.x, coords.y, coords.x, coords.yBot);
358
setSize: function(width, height) {
359
function interpret(val) {
361
return /^\d+$/.test(val) ? val + "px" : val;
363
if (width != null) wrapper.style.width = interpret(width);
364
if (height != null) scroller.style.height = interpret(height);
368
operation: function(f){return operation(f)();},
369
compoundChange: function(f){return compoundChange(f);},
371
updateDisplay(true, null, lastScrollTop);
372
if (scrollbar.scrollHeight > lastScrollTop)
373
scrollbar.scrollTop = lastScrollTop;
375
getInputField: function(){return input;},
376
getWrapperElement: function(){return wrapper;},
377
getScrollerElement: function(){return scroller;},
378
getGutterElement: function(){return gutter;}
381
function getLine(n) { return getLineAt(doc, n); }
382
function updateLineHeight(line, height) {
384
var diff = height - line.height;
385
for (var n = line; n; n = n.parent) n.height += diff;
388
function lineContent(line, wrapAt) {
390
line.highlight(mode, line.stateAfter = getStateBefore(lineNo(line)), options.tabSize);
391
return line.getContent(options.tabSize, wrapAt, options.lineWrapping);
394
function setValue(code) {
395
var top = {line: 0, ch: 0};
396
updateLines(top, {line: doc.size - 1, ch: getLine(doc.size-1).text.length},
397
splitLines(code), top, top);
400
function getValue(lineSep) {
402
doc.iter(0, doc.size, function(line) { text.push(line.text); });
403
return text.join(lineSep || "\n");
406
function onScrollBar(e) {
407
if (Math.abs(scrollbar.scrollTop - lastScrollTop) > 1) {
408
lastScrollTop = scroller.scrollTop = scrollbar.scrollTop;
413
function onScrollMain(e) {
414
if (options.fixedGutter && gutter.style.left != scroller.scrollLeft + "px")
415
gutter.style.left = scroller.scrollLeft + "px";
416
if (Math.abs(scroller.scrollTop - lastScrollTop) > 1) {
417
lastScrollTop = scroller.scrollTop;
418
if (scrollbar.scrollTop != lastScrollTop)
419
scrollbar.scrollTop = lastScrollTop;
422
if (options.onScroll) options.onScroll(instance);
425
function onMouseDown(e) {
426
setShift(e_prop(e, "shiftKey"));
427
// Check whether this is a click in a widget
428
for (var n = e_target(e); n != wrapper; n = n.parentNode)
429
if (n.parentNode == sizer && n != mover) return;
431
// See if this is a click in the gutter
432
for (var n = e_target(e); n != wrapper; n = n.parentNode)
433
if (n.parentNode == gutterText) {
434
if (options.onGutterClick)
435
options.onGutterClick(instance, indexOf(gutterText.childNodes, n) + showingFrom, e);
436
return e_preventDefault(e);
439
var start = posFromMouse(e);
441
switch (e_button(e)) {
443
if (gecko) onContextMenu(e);
446
if (start) setCursor(start.line, start.ch, true);
447
setTimeout(focusInput, 20);
451
// For button 1, if it was clicked inside the editor
452
// (posFromMouse returning non-null), we have to adjust the
454
if (!start) {if (e_target(e) == scroller) e_preventDefault(e); return;}
456
if (!focused) onFocus();
458
var now = +new Date, type = "single";
459
if (lastDoubleClick && lastDoubleClick.time > now - 400 && posEq(lastDoubleClick.pos, start)) {
462
setTimeout(focusInput, 20);
463
selectLine(start.line);
464
} else if (lastClick && lastClick.time > now - 400 && posEq(lastClick.pos, start)) {
466
lastDoubleClick = {time: now, pos: start};
468
var word = findWordAt(start);
469
setSelectionUser(word.from, word.to);
470
} else { lastClick = {time: now, pos: start}; }
472
function dragEnd(e2) {
473
if (webkit) scroller.draggable = false;
474
draggingText = false;
476
if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
477
e_preventDefault(e2);
478
setCursor(start.line, start.ch, true);
482
var last = start, going;
483
if (options.dragDrop && dragAndDrop && !options.readOnly && !posEq(sel.from, sel.to) &&
484
!posLess(start, sel.from) && !posLess(sel.to, start) && type == "single") {
485
// Let the drag handler handle this.
486
if (webkit) scroller.draggable = true;
487
var up = connect(document, "mouseup", operation(dragEnd), true);
488
var drop = connect(scroller, "drop", operation(dragEnd), true);
490
// IE's approach to draggable
491
if (scroller.dragDrop) scroller.dragDrop();
495
if (type == "single") setCursor(start.line, start.ch, true);
497
var startstart = sel.from, startend = sel.to;
499
function doSelect(cur) {
500
if (type == "single") {
501
setSelectionUser(clipPos(start), cur);
504
startstart = clipPos(startstart);
505
startend = clipPos(startend);
506
if (type == "double") {
507
var word = findWordAt(cur);
508
if (posLess(cur, startstart)) setSelectionUser(word.from, startend);
509
else setSelectionUser(startstart, word.to);
510
} else if (type == "triple") {
511
if (posLess(cur, startstart)) setSelectionUser(startend, clipPos({line: cur.line, ch: 0}));
512
else setSelectionUser(startstart, clipPos({line: cur.line + 1, ch: 0}));
517
var cur = posFromMouse(e, true);
518
if (cur && !posEq(cur, last)) {
519
if (!focused) onFocus();
523
var visible = visibleLines();
524
if (cur.line >= visible.to || cur.line < visible.from)
525
going = setTimeout(operation(function(){extend(e);}), 150);
531
var cur = posFromMouse(e);
532
if (cur) doSelect(cur);
538
var move = connect(document, "mousemove", operation(function(e) {
541
if (!ie && !e_button(e)) done(e);
544
var up = connect(document, "mouseup", operation(done), true);
546
function onDoubleClick(e) {
547
for (var n = e_target(e); n != wrapper; n = n.parentNode)
548
if (n.parentNode == gutterText) return e_preventDefault(e);
552
if (options.onDragEvent && options.onDragEvent(instance, addStop(e))) return;
554
var pos = posFromMouse(e, true), files = e.dataTransfer.files;
555
if (!pos || options.readOnly) return;
556
if (files && files.length && window.FileReader && window.File) {
557
var n = files.length, text = Array(n), read = 0;
558
var loadFile = function(file, i) {
559
var reader = new FileReader;
560
reader.onload = function() {
561
text[i] = reader.result;
564
operation(function() {
565
var end = replaceRange(text.join(""), pos, pos);
566
setSelectionUser(pos, end);
570
reader.readAsText(file);
572
for (var i = 0; i < n; ++i) loadFile(files[i], i);
574
// Don't do a replace if the drop happened inside of the selected text.
575
if (draggingText && !(posLess(pos, sel.from) || posLess(sel.to, pos))) return;
577
var text = e.dataTransfer.getData("Text");
579
compoundChange(function() {
580
var curFrom = sel.from, curTo = sel.to;
581
setSelectionUser(pos, pos);
582
if (draggingText) replaceRange("", curFrom, curTo);
583
replaceSelection(text);
591
function onDragStart(e) {
592
var txt = getSelection();
593
e.dataTransfer.setData("Text", txt);
595
// Use dummy image instead of default browsers image.
596
if (e.dataTransfer.setDragImage)
597
e.dataTransfer.setDragImage(elt('img'), 0, 0);
600
function doHandleBinding(bound, dropShift) {
601
if (typeof bound == "string") {
602
bound = commands[bound];
603
if (!bound) return false;
605
var prevShift = shiftSelecting;
607
if (options.readOnly) suppressEdits = true;
608
if (dropShift) shiftSelecting = null;
611
if (e != Pass) throw e;
614
shiftSelecting = prevShift;
615
suppressEdits = false;
620
function handleKeyBinding(e) {
621
// Handle auto keymap transitions
622
var startMap = getKeyMap(options.keyMap), next = startMap.auto;
623
clearTimeout(maybeTransition);
624
if (next && !isModifierKey(e)) maybeTransition = setTimeout(function() {
625
if (getKeyMap(options.keyMap) == startMap) {
626
options.keyMap = (next.call ? next.call(null, instance) : next);
630
var name = keyNames[e_prop(e, "keyCode")], handled = false;
631
if (name == null || e.altGraphKey) return false;
632
if (e_prop(e, "altKey")) name = "Alt-" + name;
633
if (e_prop(e, flipCtrlCmd ? "metaKey" : "ctrlKey")) name = "Ctrl-" + name;
634
if (e_prop(e, flipCtrlCmd ? "ctrlKey" : "metaKey")) name = "Cmd-" + name;
637
function stop() { stopped = true; }
639
if (e_prop(e, "shiftKey")) {
640
handled = lookupKey("Shift-" + name, options.extraKeys, options.keyMap,
641
function(b) {return doHandleBinding(b, true);}, stop)
642
|| lookupKey(name, options.extraKeys, options.keyMap, function(b) {
643
if (typeof b == "string" && /^go[A-Z]/.test(b)) return doHandleBinding(b);
646
handled = lookupKey(name, options.extraKeys, options.keyMap, doHandleBinding, stop);
648
if (stopped) handled = false;
652
if (ie_lt9) { e.oldKeyCode = e.keyCode; e.keyCode = 0; }
656
function handleCharBinding(e, ch) {
657
var handled = lookupKey("'" + ch + "'", options.extraKeys,
658
options.keyMap, function(b) { return doHandleBinding(b, true); });
666
var lastStoppedKey = null;
667
function onKeyDown(e) {
668
if (!focused) onFocus();
669
if (ie && e.keyCode == 27) { e.returnValue = false; }
670
if (pollingFast) { if (readInput()) pollingFast = false; }
671
if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return;
672
var code = e_prop(e, "keyCode");
673
// IE does strange things with escape.
674
setShift(code == 16 || e_prop(e, "shiftKey"));
675
// First give onKeyEvent option a chance to handle this.
676
var handled = handleKeyBinding(e);
678
lastStoppedKey = handled ? code : null;
679
// Opera has no cut event... we try to at least catch the key combo
680
if (!handled && code == 88 && e_prop(e, mac ? "metaKey" : "ctrlKey"))
681
replaceSelection("");
684
function onKeyPress(e) {
685
if (pollingFast) readInput();
686
if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return;
687
var keyCode = e_prop(e, "keyCode"), charCode = e_prop(e, "charCode");
688
if (opera && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;}
689
if (((opera && (!e.which || e.which < 10)) || khtml) && handleKeyBinding(e)) return;
690
var ch = String.fromCharCode(charCode == null ? keyCode : charCode);
691
if (options.electricChars && mode.electricChars && options.smartIndent && !options.readOnly) {
692
if (mode.electricChars.indexOf(ch) > -1)
693
setTimeout(operation(function() {indentLine(sel.to.line, "smart");}), 75);
695
if (handleCharBinding(e, ch)) return;
698
function onKeyUp(e) {
699
if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return;
700
if (e_prop(e, "keyCode") == 16) shiftSelecting = null;
704
if (options.readOnly == "nocursor") return;
706
if (options.onFocus) options.onFocus(instance);
708
if (scroller.className.search(/\bCodeMirror-focused\b/) == -1)
709
scroller.className += " CodeMirror-focused";
716
if (options.onBlur) options.onBlur(instance);
718
if (bracketHighlighted)
719
operation(function(){
720
if (bracketHighlighted) { bracketHighlighted(); bracketHighlighted = null; }
722
scroller.className = scroller.className.replace(" CodeMirror-focused", "");
724
clearInterval(blinker);
725
setTimeout(function() {if (!focused) shiftSelecting = null;}, 150);
728
// Replace the range from from to to by the strings in newText.
729
// Afterwards, set the selection to selFrom, selTo.
730
function updateLines(from, to, newText, selFrom, selTo) {
731
if (suppressEdits) return;
733
doc.iter(from.line, to.line + 1, function(line) {
734
old.push(newHL(line.text, line.markedSpans));
737
history.addChange(from.line, newText.length, old);
738
while (history.done.length > options.undoDepth) history.done.shift();
740
var lines = updateMarkedSpans(hlSpans(old[0]), hlSpans(lst(old)), from.ch, to.ch, newText);
741
updateLinesNoUndo(from, to, lines, selFrom, selTo);
743
function unredoHelper(from, to) {
744
if (!from.length) return;
745
var set = from.pop(), out = [];
746
for (var i = set.length - 1; i >= 0; i -= 1) {
748
var replaced = [], end = change.start + change.added;
749
doc.iter(change.start, end, function(line) { replaced.push(newHL(line.text, line.markedSpans)); });
750
out.push({start: change.start, added: change.old.length, old: replaced});
751
var pos = {line: change.start + change.old.length - 1,
752
ch: editEnd(hlText(lst(replaced)), hlText(lst(change.old)))};
753
updateLinesNoUndo({line: change.start, ch: 0}, {line: end - 1, ch: getLine(end-1).text.length},
754
change.old, pos, pos);
759
function undo() {unredoHelper(history.done, history.undone);}
760
function redo() {unredoHelper(history.undone, history.done);}
762
function updateLinesNoUndo(from, to, lines, selFrom, selTo) {
763
if (suppressEdits) return;
764
var recomputeMaxLength = false, maxLineLength = maxLine.text.length;
765
if (!options.lineWrapping)
766
doc.iter(from.line, to.line + 1, function(line) {
767
if (!line.hidden && line.text.length == maxLineLength) {recomputeMaxLength = true; return true;}
769
if (from.line != to.line || lines.length > 1) gutterDirty = true;
771
var nlines = to.line - from.line, firstLine = getLine(from.line), lastLine = getLine(to.line);
772
var lastHL = lst(lines);
774
// First adjust the line structure
775
if (from.ch == 0 && to.ch == 0 && hlText(lastHL) == "") {
776
// This is a whole-line replace. Treated specially to make
777
// sure line objects move the way they are supposed to.
778
var added = [], prevLine = null;
779
for (var i = 0, e = lines.length - 1; i < e; ++i)
780
added.push(new Line(hlText(lines[i]), hlSpans(lines[i])));
781
lastLine.update(lastLine.text, hlSpans(lastHL));
782
if (nlines) doc.remove(from.line, nlines, callbacks);
783
if (added.length) doc.insert(from.line, added);
784
} else if (firstLine == lastLine) {
785
if (lines.length == 1) {
786
firstLine.update(firstLine.text.slice(0, from.ch) + hlText(lines[0]) + firstLine.text.slice(to.ch), hlSpans(lines[0]));
788
for (var added = [], i = 1, e = lines.length - 1; i < e; ++i)
789
added.push(new Line(hlText(lines[i]), hlSpans(lines[i])));
790
added.push(new Line(hlText(lastHL) + firstLine.text.slice(to.ch), hlSpans(lastHL)));
791
firstLine.update(firstLine.text.slice(0, from.ch) + hlText(lines[0]), hlSpans(lines[0]));
792
doc.insert(from.line + 1, added);
794
} else if (lines.length == 1) {
795
firstLine.update(firstLine.text.slice(0, from.ch) + hlText(lines[0]) + lastLine.text.slice(to.ch), hlSpans(lines[0]));
796
doc.remove(from.line + 1, nlines, callbacks);
799
firstLine.update(firstLine.text.slice(0, from.ch) + hlText(lines[0]), hlSpans(lines[0]));
800
lastLine.update(hlText(lastHL) + lastLine.text.slice(to.ch), hlSpans(lastHL));
801
for (var i = 1, e = lines.length - 1; i < e; ++i)
802
added.push(new Line(hlText(lines[i]), hlSpans(lines[i])));
803
if (nlines > 1) doc.remove(from.line + 1, nlines - 1, callbacks);
804
doc.insert(from.line + 1, added);
806
if (options.lineWrapping) {
807
var perLine = Math.max(5, scroller.clientWidth / charWidth() - 3);
808
doc.iter(from.line, from.line + lines.length, function(line) {
809
if (line.hidden) return;
810
var guess = Math.ceil(line.text.length / perLine) || 1;
811
if (guess != line.height) updateLineHeight(line, guess);
814
doc.iter(from.line, from.line + lines.length, function(line) {
816
if (!line.hidden && l.length > maxLineLength) {
817
maxLine = line; maxLineLength = l.length; maxLineChanged = true;
818
recomputeMaxLength = false;
821
if (recomputeMaxLength) updateMaxLine = true;
824
// Adjust frontier, schedule worker
825
frontier = Math.min(frontier, from.line);
828
var lendiff = lines.length - nlines - 1;
829
// Remember that these lines changed, for updating the display
830
changes.push({from: from.line, to: to.line + 1, diff: lendiff});
831
if (options.onChange) {
832
// Normalize lines to contain only strings, since that's what
833
// the change event handler expects
834
for (var i = 0; i < lines.length; ++i)
835
if (typeof lines[i] != "string") lines[i] = lines[i].text;
836
var changeObj = {from: from, to: to, text: lines};
838
for (var cur = textChanged; cur.next; cur = cur.next) {}
839
cur.next = changeObj;
840
} else textChanged = changeObj;
843
// Update the selection
844
function updateLine(n) {return n <= Math.min(to.line, to.line + lendiff) ? n : n + lendiff;}
845
setSelection(clipPos(selFrom), clipPos(selTo),
846
updateLine(sel.from.line), updateLine(sel.to.line));
849
function needsScrollbar() {
850
var realHeight = doc.height * textHeight() + 2 * paddingTop();
851
return realHeight * .99 > scroller.offsetHeight ? realHeight : false;
854
function updateVerticalScroll(scrollTop) {
855
var scrollHeight = needsScrollbar();
856
scrollbar.style.display = scrollHeight ? "block" : "none";
858
scrollbarInner.style.height = sizer.style.minHeight = scrollHeight + "px";
859
scrollbar.style.height = scroller.clientHeight + "px";
860
if (scrollTop != null) {
861
scrollbar.scrollTop = scroller.scrollTop = scrollTop;
862
// 'Nudge' the scrollbar to work around a Webkit bug where,
863
// in some situations, we'd end up with a scrollbar that
864
// reported its scrollTop (and looked) as expected, but
865
// *behaved* as if it was still in a previous state (i.e.
866
// couldn't scroll up, even though it appeared to be at the
868
if (webkit) setTimeout(function() {
869
if (scrollbar.scrollTop != scrollTop) return;
870
scrollbar.scrollTop = scrollTop + (scrollTop ? -1 : 1);
871
scrollbar.scrollTop = scrollTop;
875
sizer.style.minHeight = "";
877
// Position the mover div to align with the current virtual scroll position
878
mover.style.top = displayOffset * textHeight() + "px";
881
function computeMaxLength() {
882
maxLine = getLine(0); maxLineChanged = true;
883
var maxLineLength = maxLine.text.length;
884
doc.iter(1, doc.size, function(line) {
886
if (!line.hidden && l.length > maxLineLength) {
887
maxLineLength = l.length; maxLine = line;
890
updateMaxLine = false;
893
function replaceRange(code, from, to) {
894
from = clipPos(from);
895
if (!to) to = from; else to = clipPos(to);
896
code = splitLines(code);
897
function adjustPos(pos) {
898
if (posLess(pos, from)) return pos;
899
if (!posLess(to, pos)) return end;
900
var line = pos.line + code.length - (to.line - from.line) - 1;
902
if (pos.line == to.line)
903
ch += lst(code).length - (to.ch - (to.line == from.line ? from.ch : 0));
904
return {line: line, ch: ch};
907
replaceRange1(code, from, to, function(end1) {
909
return {from: adjustPos(sel.from), to: adjustPos(sel.to)};
913
function replaceSelection(code, collapse) {
914
replaceRange1(splitLines(code), sel.from, sel.to, function(end) {
915
if (collapse == "end") return {from: end, to: end};
916
else if (collapse == "start") return {from: sel.from, to: sel.from};
917
else return {from: sel.from, to: end};
920
function replaceRange1(code, from, to, computeSel) {
921
var endch = code.length == 1 ? code[0].length + from.ch : lst(code).length;
922
var newSel = computeSel({line: from.line + code.length - 1, ch: endch});
923
updateLines(from, to, code, newSel.from, newSel.to);
926
function getRange(from, to, lineSep) {
927
var l1 = from.line, l2 = to.line;
928
if (l1 == l2) return getLine(l1).text.slice(from.ch, to.ch);
929
var code = [getLine(l1).text.slice(from.ch)];
930
doc.iter(l1 + 1, l2, function(line) { code.push(line.text); });
931
code.push(getLine(l2).text.slice(0, to.ch));
932
return code.join(lineSep || "\n");
934
function getSelection(lineSep) {
935
return getRange(sel.from, sel.to, lineSep);
938
function slowPoll() {
939
if (pollingFast) return;
940
poll.set(options.pollInterval, function() {
942
if (focused) slowPoll();
945
function fastPoll() {
949
var changed = readInput();
950
if (!changed && !missed) {missed = true; poll.set(60, p);}
951
else {pollingFast = false; slowPoll();}
956
// Previnput is a hack to work with IME. If we reset the textarea
957
// on every change, that breaks IME. So we look for changes
958
// compared to the previous content instead. (Modern browsers have
959
// events that indicate IME taking place, but these are not widely
960
// supported or compatible enough yet to rely on.)
962
function readInput() {
963
if (!focused || hasSelection(input) || options.readOnly) return false;
964
var text = input.value;
965
if (text == prevInput) return false;
966
if (!nestedOperation) startOperation();
967
shiftSelecting = null;
968
var same = 0, l = Math.min(prevInput.length, text.length);
969
while (same < l && prevInput[same] == text[same]) ++same;
970
if (same < prevInput.length)
971
sel.from = {line: sel.from.line, ch: sel.from.ch - (prevInput.length - same)};
972
else if (overwrite && posEq(sel.from, sel.to) && !pasteIncoming)
973
sel.to = {line: sel.to.line, ch: Math.min(getLine(sel.to.line).text.length, sel.to.ch + (text.length - same))};
974
replaceSelection(text.slice(same), "end");
975
if (text.length > 1000) { input.value = prevInput = ""; }
976
else prevInput = text;
977
if (!nestedOperation) endOperation();
978
pasteIncoming = false;
981
function resetInput(user) {
982
if (!posEq(sel.from, sel.to)) {
984
input.value = getSelection();
985
if (focused) selectInput(input);
986
} else if (user) prevInput = input.value = "";
989
function focusInput() {
990
if (options.readOnly != "nocursor" && (ie_lt9 || document.activeElement != input))
994
function scrollCursorIntoView() {
995
var coords = calculateCursorCoords();
996
scrollIntoView(coords.x, coords.y, coords.x, coords.yBot);
997
if (!focused) return;
998
var box = sizer.getBoundingClientRect(), doScroll = null;
999
if (coords.y + box.top < 0) doScroll = true;
1000
else if (coords.y + box.top + textHeight() > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false;
1001
if (doScroll != null) {
1002
var hidden = cursor.style.display == "none";
1004
cursor.style.display = "";
1005
cursor.style.left = coords.x + "px";
1006
cursor.style.top = (coords.y - displayOffset) + "px";
1008
cursor.scrollIntoView(doScroll);
1009
if (hidden) cursor.style.display = "none";
1012
function calculateCursorCoords() {
1013
var cursor = localCoords(sel.inverted ? sel.from : sel.to);
1014
var x = options.lineWrapping ? Math.min(cursor.x, lineSpace.offsetWidth) : cursor.x;
1015
return {x: x, y: cursor.y, yBot: cursor.yBot};
1017
function scrollIntoView(x1, y1, x2, y2) {
1018
var scrollPos = calculateScrollPos(x1, y1, x2, y2);
1019
if (scrollPos.scrollLeft != null) {scroller.scrollLeft = scrollPos.scrollLeft;}
1020
if (scrollPos.scrollTop != null) {scrollbar.scrollTop = scroller.scrollTop = scrollPos.scrollTop;}
1022
function calculateScrollPos(x1, y1, x2, y2) {
1023
var pl = paddingLeft(), pt = paddingTop();
1024
y1 += pt; y2 += pt; x1 += pl; x2 += pl;
1025
var screen = scroller.clientHeight, screentop = scrollbar.scrollTop, result = {};
1026
var docBottom = needsScrollbar() || Infinity;
1027
var atTop = y1 < pt + 10, atBottom = y2 + pt > docBottom - 10;
1028
if (y1 < screentop) result.scrollTop = atTop ? 0 : Math.max(0, y1);
1029
else if (y2 > screentop + screen) result.scrollTop = (atBottom ? docBottom : y2) - screen;
1031
var screenw = scroller.clientWidth, screenleft = scroller.scrollLeft;
1032
var gutterw = options.fixedGutter ? gutter.clientWidth : 0;
1033
var atLeft = x1 < gutterw + pl + 10;
1034
if (x1 < screenleft + gutterw || atLeft) {
1036
result.scrollLeft = Math.max(0, x1 - 10 - gutterw);
1037
} else if (x2 > screenw + screenleft - 3) {
1038
result.scrollLeft = x2 + 10 - screenw;
1043
function visibleLines(scrollTop) {
1044
var lh = textHeight(), top = (scrollTop != null ? scrollTop : scrollbar.scrollTop) - paddingTop();
1045
var fromHeight = Math.max(0, Math.floor(top / lh));
1046
var toHeight = Math.ceil((top + scroller.clientHeight) / lh);
1047
return {from: lineAtHeight(doc, fromHeight),
1048
to: lineAtHeight(doc, toHeight)};
1050
// Uses a set of changes plus the current scroll position to
1051
// determine which DOM updates have to be made, and makes the
1053
function updateDisplay(changes, suppressCallback, scrollTop) {
1054
if (!scroller.clientWidth) {
1055
showingFrom = showingTo = displayOffset = 0;
1058
// Compute the new visible window
1059
// If scrollTop is specified, use that to determine which lines
1060
// to render instead of the current scrollbar position.
1061
var visible = visibleLines(scrollTop);
1062
// Bail out if the visible area is already rendered and nothing changed.
1063
if (changes !== true && changes.length == 0 && visible.from > showingFrom && visible.to < showingTo) {
1064
updateVerticalScroll(scrollTop);
1067
var from = Math.max(visible.from - 100, 0), to = Math.min(doc.size, visible.to + 100);
1068
if (showingFrom < from && from - showingFrom < 20) from = showingFrom;
1069
if (showingTo > to && showingTo - to < 20) to = Math.min(doc.size, showingTo);
1071
// Create a range of theoretically intact lines, and punch holes
1072
// in that using the change info.
1073
var intact = changes === true ? [] :
1074
computeIntact([{from: showingFrom, to: showingTo, domStart: 0}], changes);
1075
// Clip off the parts that won't be visible
1076
var intactLines = 0;
1077
for (var i = 0; i < intact.length; ++i) {
1078
var range = intact[i];
1079
if (range.from < from) {range.domStart += (from - range.from); range.from = from;}
1080
if (range.to > to) range.to = to;
1081
if (range.from >= range.to) intact.splice(i--, 1);
1082
else intactLines += range.to - range.from;
1084
if (intactLines == to - from && from == showingFrom && to == showingTo) {
1085
updateVerticalScroll(scrollTop);
1088
intact.sort(function(a, b) {return a.domStart - b.domStart;});
1090
var th = textHeight(), gutterDisplay = gutter.style.display;
1091
lineDiv.style.display = "none";
1092
patchDisplay(from, to, intact);
1093
lineDiv.style.display = gutter.style.display = "";
1095
var different = from != showingFrom || to != showingTo || lastSizeC != scroller.clientHeight + th;
1096
// This is just a bogus formula that detects when the editor is
1097
// resized or the font size changes.
1098
if (different) lastSizeC = scroller.clientHeight + th;
1099
if (from != showingFrom || to != showingTo && options.onViewportChange)
1100
setTimeout(function(){
1101
if (options.onViewportChange) options.onViewportChange(instance, from, to);
1103
showingFrom = from; showingTo = to;
1104
displayOffset = heightAtLine(doc, from);
1107
// Since this is all rather error prone, it is honoured with the
1108
// only assertion in the whole file.
1109
if (lineDiv.childNodes.length != showingTo - showingFrom)
1110
throw new Error("BAD PATCH! " + JSON.stringify(intact) + " size=" + (showingTo - showingFrom) +
1111
" nodes=" + lineDiv.childNodes.length);
1113
function checkHeights() {
1114
var curNode = lineDiv.firstChild, heightChanged = false;
1115
doc.iter(showingFrom, showingTo, function(line) {
1116
// Work around bizarro IE7 bug where, sometimes, our curNode
1117
// is magically replaced with a new node in the DOM, leaving
1118
// us with a reference to an orphan (nextSibling-less) node.
1119
if (!curNode) return;
1121
var height = Math.round(curNode.offsetHeight / th) || 1;
1122
if (line.height != height) {
1123
updateLineHeight(line, height);
1124
gutterDirty = heightChanged = true;
1127
curNode = curNode.nextSibling;
1129
return heightChanged;
1132
if (options.lineWrapping) checkHeights();
1134
gutter.style.display = gutterDisplay;
1135
if (different || gutterDirty) {
1136
// If the gutter grew in size, re-check heights. If those changed, re-draw gutter.
1137
updateGutter() && options.lineWrapping && checkHeights() && updateGutter();
1139
updateVerticalScroll(scrollTop);
1141
if (!suppressCallback && options.onUpdate) options.onUpdate(instance);
1145
function computeIntact(intact, changes) {
1146
for (var i = 0, l = changes.length || 0; i < l; ++i) {
1147
var change = changes[i], intact2 = [], diff = change.diff || 0;
1148
for (var j = 0, l2 = intact.length; j < l2; ++j) {
1149
var range = intact[j];
1150
if (change.to <= range.from && change.diff)
1151
intact2.push({from: range.from + diff, to: range.to + diff,
1152
domStart: range.domStart});
1153
else if (change.to <= range.from || change.from >= range.to)
1154
intact2.push(range);
1156
if (change.from > range.from)
1157
intact2.push({from: range.from, to: change.from, domStart: range.domStart});
1158
if (change.to < range.to)
1159
intact2.push({from: change.to + diff, to: range.to + diff,
1160
domStart: range.domStart + (change.to - range.from)});
1168
function patchDisplay(from, to, intact) {
1169
function killNode(node) {
1170
var tmp = node.nextSibling;
1171
node.parentNode.removeChild(node);
1174
// The first pass removes the DOM nodes that aren't intact.
1175
if (!intact.length) removeChildren(lineDiv);
1177
var domPos = 0, curNode = lineDiv.firstChild, n;
1178
for (var i = 0; i < intact.length; ++i) {
1179
var cur = intact[i];
1180
while (cur.domStart > domPos) {curNode = killNode(curNode); domPos++;}
1181
for (var j = 0, e = cur.to - cur.from; j < e; ++j) {curNode = curNode.nextSibling; domPos++;}
1183
while (curNode) curNode = killNode(curNode);
1185
// This pass fills in the lines that actually changed.
1186
var nextIntact = intact.shift(), curNode = lineDiv.firstChild, j = from;
1187
doc.iter(from, to, function(line) {
1188
if (nextIntact && nextIntact.to == j) nextIntact = intact.shift();
1189
if (!nextIntact || nextIntact.from > j) {
1190
if (line.hidden) var lineElement = elt("pre");
1192
var lineElement = lineContent(line);
1193
if (line.className) lineElement.className = line.className;
1194
// Kludge to make sure the styled element lies behind the selection (by z-index)
1195
if (line.bgClassName) {
1196
var pre = elt("pre", "\u00a0", line.bgClassName, "position: absolute; left: 0; right: 0; top: 0; bottom: 0; z-index: -2");
1197
lineElement = elt("div", [pre, lineElement], null, "position: relative");
1200
lineDiv.insertBefore(lineElement, curNode);
1202
curNode = curNode.nextSibling;
1208
function updateGutter() {
1209
if (!options.gutter && !options.lineNumbers) return;
1210
var hText = mover.offsetHeight, hEditor = scroller.clientHeight;
1211
gutter.style.height = (hText - hEditor < 2 ? hEditor : hText) + "px";
1212
var fragment = document.createDocumentFragment(), i = showingFrom, normalNode;
1213
doc.iter(showingFrom, Math.max(showingTo, showingFrom + 1), function(line) {
1215
fragment.appendChild(elt("pre"));
1217
var marker = line.gutterMarker;
1218
var text = options.lineNumbers ? options.lineNumberFormatter(i + options.firstLineNumber) : null;
1219
if (marker && marker.text)
1220
text = marker.text.replace("%N%", text != null ? text : "");
1221
else if (text == null)
1223
var markerElement = fragment.appendChild(elt("pre", null, marker && marker.style));
1224
markerElement.innerHTML = text;
1225
for (var j = 1; j < line.height; ++j) {
1226
markerElement.appendChild(elt("br"));
1227
markerElement.appendChild(document.createTextNode("\u00a0"));
1229
if (!marker) normalNode = i;
1233
gutter.style.display = "none";
1234
removeChildrenAndAdd(gutterText, fragment);
1235
// Make sure scrolling doesn't cause number gutter size to pop
1236
if (normalNode != null && options.lineNumbers) {
1237
var node = gutterText.childNodes[normalNode - showingFrom];
1238
var minwidth = String(doc.size).length, val = eltText(node.firstChild), pad = "";
1239
while (val.length + pad.length < minwidth) pad += "\u00a0";
1240
if (pad) node.insertBefore(document.createTextNode(pad), node.firstChild);
1242
gutter.style.display = "";
1243
var resized = Math.abs((parseInt(lineSpace.style.marginLeft) || 0) - gutter.offsetWidth) > 2;
1244
lineSpace.style.marginLeft = gutter.offsetWidth + "px";
1245
gutterDirty = false;
1248
function updateSelection() {
1249
var collapsed = posEq(sel.from, sel.to);
1250
var fromPos = localCoords(sel.from, true);
1251
var toPos = collapsed ? fromPos : localCoords(sel.to, true);
1252
var headPos = sel.inverted ? fromPos : toPos, th = textHeight();
1253
var wrapOff = eltOffset(wrapper), lineOff = eltOffset(lineDiv);
1254
inputDiv.style.top = Math.max(0, Math.min(scroller.offsetHeight, headPos.y + lineOff.top - wrapOff.top)) + "px";
1255
inputDiv.style.left = Math.max(0, Math.min(scroller.offsetWidth, headPos.x + lineOff.left - wrapOff.left)) + "px";
1256
if (collapsed || options.showCursorWhenSelecting) {
1257
cursor.style.top = headPos.y + "px";
1258
cursor.style.left = (options.lineWrapping ? Math.min(headPos.x, lineSpace.offsetWidth) : headPos.x) + "px";
1259
cursor.style.display = "";
1261
cursor.style.display = "none";
1264
var sameLine = fromPos.y == toPos.y, fragment = document.createDocumentFragment();
1265
var clientWidth = lineSpace.clientWidth || lineSpace.offsetWidth;
1266
var clientHeight = lineSpace.clientHeight || lineSpace.offsetHeight;
1267
var add = function(left, top, right, height) {
1268
var rstyle = quirksMode ? "width: " + (!right ? clientWidth : clientWidth - right - left) + "px"
1269
: "right: " + (right - 1) + "px";
1270
fragment.appendChild(elt("div", null, "CodeMirror-selected", "position: absolute; left: " + left +
1271
"px; top: " + top + "px; " + rstyle + "; height: " + height + "px"));
1273
if (sel.from.ch && fromPos.y >= 0) {
1274
var right = sameLine ? clientWidth - toPos.x : 0;
1275
add(fromPos.x, fromPos.y, right, th);
1277
var middleStart = Math.max(0, fromPos.y + (sel.from.ch ? th : 0));
1278
var middleHeight = Math.min(toPos.y, clientHeight) - middleStart;
1279
if (middleHeight > 0.2 * th)
1280
add(0, middleStart, 0, middleHeight);
1281
if ((!sameLine || !sel.from.ch) && toPos.y < clientHeight - .5 * th)
1282
add(0, toPos.y, clientWidth - toPos.x, th);
1283
removeChildrenAndAdd(selectionDiv, fragment);
1284
selectionDiv.style.display = "";
1286
selectionDiv.style.display = "none";
1290
function setShift(val) {
1291
if (val) shiftSelecting = shiftSelecting || (sel.inverted ? sel.to : sel.from);
1292
else shiftSelecting = null;
1294
function setSelectionUser(from, to) {
1295
var sh = shiftSelecting && clipPos(shiftSelecting);
1297
if (posLess(sh, from)) from = sh;
1298
else if (posLess(to, sh)) to = sh;
1300
setSelection(from, to);
1301
userSelChange = true;
1303
// Update the selection. Last two args are only used by
1304
// updateLines, since they have to be expressed in the line
1305
// numbers before the update.
1306
function setSelection(from, to, oldFrom, oldTo) {
1308
if (oldFrom == null) {oldFrom = sel.from.line; oldTo = sel.to.line;}
1309
if (posEq(sel.from, from) && posEq(sel.to, to)) return;
1310
if (posLess(to, from)) {var tmp = to; to = from; from = tmp;}
1312
// Skip over hidden lines.
1313
if (from.line != oldFrom) {
1314
var from1 = skipHidden(from, oldFrom, sel.from.ch);
1315
// If there is no non-hidden line left, force visibility on current line
1316
if (!from1) setLineHidden(from.line, false);
1319
if (to.line != oldTo) to = skipHidden(to, oldTo, sel.to.ch);
1321
if (posEq(from, to)) sel.inverted = false;
1322
else if (posEq(from, sel.to)) sel.inverted = false;
1323
else if (posEq(to, sel.from)) sel.inverted = true;
1325
if (options.autoClearEmptyLines && posEq(sel.from, sel.to)) {
1326
var head = sel.inverted ? from : to;
1327
if (head.line != sel.from.line && sel.from.line < doc.size) {
1328
var oldLine = getLine(sel.from.line);
1329
if (/^\s+$/.test(oldLine.text))
1330
setTimeout(operation(function() {
1331
if (oldLine.parent && /^\s+$/.test(oldLine.text)) {
1332
var no = lineNo(oldLine);
1333
replaceRange("", {line: no, ch: 0}, {line: no, ch: oldLine.text.length});
1339
sel.from = from; sel.to = to;
1340
selectionChanged = true;
1342
function skipHidden(pos, oldLine, oldCh) {
1343
function getNonHidden(dir) {
1344
var lNo = pos.line + dir, end = dir == 1 ? doc.size : -1;
1345
while (lNo != end) {
1346
var line = getLine(lNo);
1349
if (toEnd || ch > oldCh || ch > line.text.length) ch = line.text.length;
1350
return {line: lNo, ch: ch};
1355
var line = getLine(pos.line);
1356
var toEnd = pos.ch == line.text.length && pos.ch != oldCh;
1357
if (!line.hidden) return pos;
1358
if (pos.line >= oldLine) return getNonHidden(1) || getNonHidden(-1);
1359
else return getNonHidden(-1) || getNonHidden(1);
1361
function setCursor(line, ch, user) {
1362
var pos = clipPos({line: line, ch: ch || 0});
1363
(user ? setSelectionUser : setSelection)(pos, pos);
1366
function clipLine(n) {return Math.max(0, Math.min(n, doc.size-1));}
1367
function clipPos(pos) {
1368
if (pos.line < 0) return {line: 0, ch: 0};
1369
if (pos.line >= doc.size) return {line: doc.size-1, ch: getLine(doc.size-1).text.length};
1370
var ch = pos.ch, linelen = getLine(pos.line).text.length;
1371
if (ch == null || ch > linelen) return {line: pos.line, ch: linelen};
1372
else if (ch < 0) return {line: pos.line, ch: 0};
1376
function findPosH(dir, unit) {
1377
var end = sel.inverted ? sel.from : sel.to, line = end.line, ch = end.ch;
1378
var lineObj = getLine(line);
1379
function findNextLine() {
1380
for (var l = line + dir, e = dir < 0 ? -1 : doc.size; l != e; l += dir) {
1381
var lo = getLine(l);
1382
if (!lo.hidden) { line = l; lineObj = lo; return true; }
1385
function moveOnce(boundToLine) {
1386
if (ch == (dir < 0 ? 0 : lineObj.text.length)) {
1387
if (!boundToLine && findNextLine()) ch = dir < 0 ? lineObj.text.length : 0;
1392
if (unit == "char") moveOnce();
1393
else if (unit == "column") moveOnce(true);
1394
else if (unit == "word") {
1395
var sawWord = false;
1397
if (dir < 0) if (!moveOnce()) break;
1398
if (isWordChar(lineObj.text.charAt(ch))) sawWord = true;
1399
else if (sawWord) {if (dir < 0) {dir = 1; moveOnce();} break;}
1400
if (dir > 0) if (!moveOnce()) break;
1403
return {line: line, ch: ch};
1405
function moveH(dir, unit) {
1406
var pos = dir < 0 ? sel.from : sel.to;
1407
if (shiftSelecting || posEq(sel.from, sel.to)) pos = findPosH(dir, unit);
1408
setCursor(pos.line, pos.ch, true);
1410
function deleteH(dir, unit) {
1411
if (!posEq(sel.from, sel.to)) replaceRange("", sel.from, sel.to);
1412
else if (dir < 0) replaceRange("", findPosH(dir, unit), sel.to);
1413
else replaceRange("", sel.from, findPosH(dir, unit));
1414
userSelChange = true;
1416
function moveV(dir, unit) {
1417
var dist = 0, pos = localCoords(sel.inverted ? sel.from : sel.to, true);
1418
if (goalColumn != null) pos.x = goalColumn;
1419
if (unit == "page") {
1420
var screen = Math.min(scroller.clientHeight, window.innerHeight || document.documentElement.clientHeight);
1421
var target = coordsChar(pos.x, pos.y + screen * dir);
1422
} else if (unit == "line") {
1423
var th = textHeight();
1424
var target = coordsChar(pos.x, pos.y + .5 * th + dir * th);
1426
if (unit == "page") scrollbar.scrollTop += localCoords(target, true).y - pos.y;
1427
setCursor(target.line, target.ch, true);
1431
function findWordAt(pos) {
1432
var line = getLine(pos.line).text;
1433
var start = pos.ch, end = pos.ch;
1435
if (pos.after === false || end == line.length) --start; else ++end;
1436
var startChar = line.charAt(start);
1437
var check = isWordChar(startChar) ? isWordChar :
1438
/\s/.test(startChar) ? function(ch) {return /\s/.test(ch);} :
1439
function(ch) {return !/\s/.test(ch) && isWordChar(ch);};
1440
while (start > 0 && check(line.charAt(start - 1))) --start;
1441
while (end < line.length && check(line.charAt(end))) ++end;
1443
return {from: {line: pos.line, ch: start}, to: {line: pos.line, ch: end}};
1445
function selectLine(line) {
1446
setSelectionUser({line: line, ch: 0}, clipPos({line: line + 1, ch: 0}));
1448
function indentSelected(mode) {
1449
if (posEq(sel.from, sel.to)) return indentLine(sel.from.line, mode);
1450
var e = sel.to.line - (sel.to.ch ? 0 : 1);
1451
for (var i = sel.from.line; i <= e; ++i) indentLine(i, mode);
1454
function indentLine(n, how) {
1455
if (!how) how = "add";
1456
if (how == "smart") {
1457
if (!mode.indent) how = "prev";
1458
else var state = getStateBefore(n);
1461
var line = getLine(n), curSpace = line.indentation(options.tabSize),
1462
curSpaceString = line.text.match(/^\s*/)[0], indentation;
1463
if (how == "smart") {
1464
indentation = mode.indent(state, line.text.slice(curSpaceString.length), line.text);
1465
if (indentation == Pass) how = "prev";
1467
if (how == "prev") {
1468
if (n) indentation = getLine(n-1).indentation(options.tabSize);
1469
else indentation = 0;
1471
else if (how == "add") indentation = curSpace + options.indentUnit;
1472
else if (how == "subtract") indentation = curSpace - options.indentUnit;
1473
indentation = Math.max(0, indentation);
1474
var diff = indentation - curSpace;
1476
var indentString = "", pos = 0;
1477
if (options.indentWithTabs)
1478
for (var i = Math.floor(indentation / options.tabSize); i; --i) {pos += options.tabSize; indentString += "\t";}
1479
if (pos < indentation) indentString += spaceStr(indentation - pos);
1481
if (indentString != curSpaceString)
1482
replaceRange(indentString, {line: n, ch: 0}, {line: n, ch: curSpaceString.length});
1483
line.stateAfter = null;
1486
function loadMode() {
1487
mode = CodeMirror.getMode(options, options.mode);
1488
doc.iter(0, doc.size, function(line) { line.stateAfter = null; });
1492
function gutterChanged() {
1493
var visible = options.gutter || options.lineNumbers;
1494
gutter.style.display = visible ? "" : "none";
1495
if (visible) gutterDirty = true;
1496
else lineDiv.parentNode.style.marginLeft = 0;
1498
function wrappingChanged(from, to) {
1499
if (options.lineWrapping) {
1500
wrapper.className += " CodeMirror-wrap";
1501
var perLine = scroller.clientWidth / charWidth() - 3;
1502
doc.iter(0, doc.size, function(line) {
1503
if (line.hidden) return;
1504
var guess = Math.ceil(line.text.length / perLine) || 1;
1505
if (guess != 1) updateLineHeight(line, guess);
1507
lineSpace.style.minWidth = widthForcer.style.left = "";
1509
wrapper.className = wrapper.className.replace(" CodeMirror-wrap", "");
1511
doc.iter(0, doc.size, function(line) {
1512
if (line.height != 1 && !line.hidden) updateLineHeight(line, 1);
1515
changes.push({from: 0, to: doc.size});
1517
function themeChanged() {
1518
scroller.className = scroller.className.replace(/\s*cm-s-\S+/g, "") +
1519
options.theme.replace(/(^|\s)\s*/g, " cm-s-");
1521
function keyMapChanged() {
1522
var style = keyMap[options.keyMap].style;
1523
wrapper.className = wrapper.className.replace(/\s*cm-keymap-\S+/g, "") +
1524
(style ? " cm-keymap-" + style : "");
1527
function TextMarker(type, style) { this.lines = []; this.type = type; if (style) this.style = style; }
1528
TextMarker.prototype.clear = operation(function() {
1530
for (var i = 0; i < this.lines.length; ++i) {
1531
var line = this.lines[i];
1532
var span = getMarkedSpanFor(line.markedSpans, this);
1533
if (span.from != null) min = lineNo(line);
1534
if (span.to != null) max = lineNo(line);
1535
line.markedSpans = removeMarkedSpan(line.markedSpans, span);
1537
if (min != null) changes.push({from: min, to: max + 1});
1538
this.lines.length = 0;
1539
this.explicitlyCleared = true;
1541
TextMarker.prototype.find = function() {
1543
for (var i = 0; i < this.lines.length; ++i) {
1544
var line = this.lines[i];
1545
var span = getMarkedSpanFor(line.markedSpans, this);
1546
if (span.from != null || span.to != null) {
1547
var found = lineNo(line);
1548
if (span.from != null) from = {line: found, ch: span.from};
1549
if (span.to != null) to = {line: found, ch: span.to};
1552
if (this.type == "bookmark") return from;
1553
return from && {from: from, to: to};
1556
function markText(from, to, className, options) {
1557
from = clipPos(from); to = clipPos(to);
1558
var marker = new TextMarker("range", className);
1559
if (options) for (var opt in options) if (options.hasOwnProperty(opt))
1560
marker[opt] = options[opt];
1561
var curLine = from.line;
1562
doc.iter(curLine, to.line + 1, function(line) {
1563
var span = {from: curLine == from.line ? from.ch : null,
1564
to: curLine == to.line ? to.ch : null,
1566
line.markedSpans = (line.markedSpans || []).concat([span]);
1567
marker.lines.push(line);
1570
changes.push({from: from.line, to: to.line + 1});
1574
function setBookmark(pos) {
1576
var marker = new TextMarker("bookmark"), line = getLine(pos.line);
1577
history.addChange(pos.line, 1, [newHL(line.text, line.markedSpans)], true);
1578
var span = {from: pos.ch, to: pos.ch, marker: marker};
1579
line.markedSpans = (line.markedSpans || []).concat([span]);
1580
marker.lines.push(line);
1584
function findMarksAt(pos) {
1586
var markers = [], spans = getLine(pos.line).markedSpans;
1587
if (spans) for (var i = 0; i < spans.length; ++i) {
1588
var span = spans[i];
1589
if ((span.from == null || span.from <= pos.ch) &&
1590
(span.to == null || span.to >= pos.ch))
1591
markers.push(span.marker);
1596
function addGutterMarker(line, text, className) {
1597
if (typeof line == "number") line = getLine(clipLine(line));
1598
line.gutterMarker = {text: text, style: className};
1602
function removeGutterMarker(line) {
1603
if (typeof line == "number") line = getLine(clipLine(line));
1604
line.gutterMarker = null;
1608
function changeLine(handle, op) {
1609
var no = handle, line = handle;
1610
if (typeof handle == "number") line = getLine(clipLine(handle));
1611
else no = lineNo(handle);
1612
if (no == null) return null;
1613
if (op(line, no)) changes.push({from: no, to: no + 1});
1617
function setLineClass(handle, className, bgClassName) {
1618
return changeLine(handle, function(line) {
1619
if (line.className != className || line.bgClassName != bgClassName) {
1620
line.className = className;
1621
line.bgClassName = bgClassName;
1626
function setLineHidden(handle, hidden) {
1627
return changeLine(handle, function(line, no) {
1628
if (line.hidden != hidden) {
1629
line.hidden = hidden;
1630
if (!options.lineWrapping) {
1631
if (hidden && line.text.length == maxLine.text.length) {
1632
updateMaxLine = true;
1633
} else if (!hidden && line.text.length > maxLine.text.length) {
1634
maxLine = line; updateMaxLine = false;
1637
updateLineHeight(line, hidden ? 0 : 1);
1638
var fline = sel.from.line, tline = sel.to.line;
1639
if (hidden && (fline == no || tline == no)) {
1640
var from = fline == no ? skipHidden({line: fline, ch: 0}, fline, 0) : sel.from;
1641
var to = tline == no ? skipHidden({line: tline, ch: 0}, tline, 0) : sel.to;
1642
// Can't hide the last visible line, we'd have no place to put the cursor
1644
setSelection(from, to);
1646
return (gutterDirty = true);
1651
function lineInfo(line) {
1652
if (typeof line == "number") {
1653
if (!isLine(line)) return null;
1655
line = getLine(line);
1656
if (!line) return null;
1658
var n = lineNo(line);
1659
if (n == null) return null;
1661
var marker = line.gutterMarker;
1662
return {line: n, handle: line, text: line.text, markerText: marker && marker.text,
1663
markerClass: marker && marker.style, lineClass: line.className, bgClass: line.bgClassName};
1666
function measureLine(line, ch) {
1667
if (ch == 0) return {top: 0, left: 0};
1668
var pre = lineContent(line, ch);
1669
removeChildrenAndAdd(measure, pre);
1670
var anchor = pre.anchor;
1671
var top = anchor.offsetTop, left = anchor.offsetLeft;
1672
// Older IEs report zero offsets for spans directly after a wrap
1673
if (ie && top == 0 && left == 0) {
1674
var backup = elt("span", "x");
1675
anchor.parentNode.insertBefore(backup, anchor.nextSibling);
1676
top = backup.offsetTop;
1678
return {top: top, left: left};
1680
function localCoords(pos, inLineWrap) {
1681
var x, lh = textHeight(), y = lh * (heightAtLine(doc, pos.line) - (inLineWrap ? displayOffset : 0));
1682
if (pos.ch == 0) x = 0;
1684
var sp = measureLine(getLine(pos.line), pos.ch);
1686
if (options.lineWrapping) y += Math.max(0, sp.top);
1688
return {x: x, y: y, yBot: y + lh};
1690
// Coords must be lineSpace-local
1691
function coordsChar(x, y) {
1692
var th = textHeight(), cw = charWidth(), heightPos = displayOffset + Math.floor(y / th);
1693
if (heightPos < 0) return {line: 0, ch: 0};
1694
var lineNo = lineAtHeight(doc, heightPos);
1695
if (lineNo >= doc.size) return {line: doc.size - 1, ch: getLine(doc.size - 1).text.length};
1696
var lineObj = getLine(lineNo), text = lineObj.text;
1697
var tw = options.lineWrapping, innerOff = tw ? heightPos - heightAtLine(doc, lineNo) : 0;
1698
if (x <= 0 && innerOff == 0) return {line: lineNo, ch: 0};
1699
var wrongLine = false;
1700
function getX(len) {
1701
var sp = measureLine(lineObj, len);
1703
var off = Math.round(sp.top / th);
1704
wrongLine = off != innerOff;
1705
return Math.max(0, sp.left + (off - innerOff) * scroller.clientWidth);
1709
var from = 0, fromX = 0, to = text.length, toX;
1710
// Guess a suitable upper bound for our search.
1711
var estimated = Math.min(to, Math.ceil((x + innerOff * scroller.clientWidth * .9) / cw));
1713
var estX = getX(estimated);
1714
if (estX <= x && estimated < to) estimated = Math.min(to, Math.ceil(estimated * 1.2));
1715
else {toX = estX; to = estimated; break;}
1717
if (x > toX) return {line: lineNo, ch: to};
1718
// Try to guess a suitable lower bound as well.
1719
estimated = Math.floor(to * 0.8); estX = getX(estimated);
1720
if (estX < x) {from = estimated; fromX = estX;}
1721
// Do a binary search between these bounds.
1723
if (to - from <= 1) {
1724
var after = x - fromX < toX - x;
1725
return {line: lineNo, ch: after ? from : to, after: after};
1727
var middle = Math.ceil((from + to) / 2), middleX = getX(middle);
1728
if (middleX > x) {to = middle; toX = middleX; if (wrongLine) toX += 1000; }
1729
else {from = middle; fromX = middleX;}
1732
function pageCoords(pos) {
1733
var local = localCoords(pos, true), off = eltOffset(lineSpace);
1734
return {x: off.left + local.x, y: off.top + local.y, yBot: off.top + local.yBot};
1737
var cachedHeight, cachedHeightFor, measurePre;
1738
function textHeight() {
1739
if (measurePre == null) {
1740
measurePre = elt("pre");
1741
for (var i = 0; i < 49; ++i) {
1742
measurePre.appendChild(document.createTextNode("x"));
1743
measurePre.appendChild(elt("br"));
1745
measurePre.appendChild(document.createTextNode("x"));
1747
var offsetHeight = lineDiv.clientHeight;
1748
if (offsetHeight == cachedHeightFor) return cachedHeight;
1749
cachedHeightFor = offsetHeight;
1750
removeChildrenAndAdd(measure, measurePre.cloneNode(true));
1751
cachedHeight = measure.firstChild.offsetHeight / 50 || 1;
1752
removeChildren(measure);
1753
return cachedHeight;
1755
var cachedWidth, cachedWidthFor = 0;
1756
function charWidth() {
1757
if (scroller.clientWidth == cachedWidthFor) return cachedWidth;
1758
cachedWidthFor = scroller.clientWidth;
1759
var anchor = elt("span", "x");
1760
var pre = elt("pre", [anchor]);
1761
removeChildrenAndAdd(measure, pre);
1762
return (cachedWidth = anchor.offsetWidth || 10);
1764
function paddingTop() {return lineSpace.offsetTop;}
1765
function paddingLeft() {return lineSpace.offsetLeft;}
1767
function posFromMouse(e, liberal) {
1768
var offW = eltOffset(scroller, true), x, y;
1769
// Fails unpredictably on IE[67] when mouse is dragged around quickly.
1770
try { x = e.clientX; y = e.clientY; } catch (e) { return null; }
1771
// This is a mess of a heuristic to try and determine whether a
1772
// scroll-bar was clicked or not, and to return null if one was
1774
if (!liberal && (x - offW.left > scroller.clientWidth || y - offW.top > scroller.clientHeight))
1776
var offL = eltOffset(lineSpace, true);
1777
return coordsChar(x - offL.left, y - offL.top);
1779
var detectingSelectAll;
1780
function onContextMenu(e) {
1781
var pos = posFromMouse(e), scrollPos = scrollbar.scrollTop;
1782
if (!pos || opera) return; // Opera is difficult.
1783
if (posEq(sel.from, sel.to) || posLess(pos, sel.from) || !posLess(pos, sel.to))
1784
operation(setCursor)(pos.line, pos.ch);
1786
var oldCSS = input.style.cssText;
1787
inputDiv.style.position = "absolute";
1788
input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) +
1789
"px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: white; " +
1790
"border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";
1793
// Adds "Select all" to context menu in FF
1794
if (posEq(sel.from, sel.to)) input.value = prevInput = " ";
1797
inputDiv.style.position = "relative";
1798
input.style.cssText = oldCSS;
1799
if (ie_lt9) scrollbar.scrollTop = scrollPos;
1802
// Try to detect the user choosing select-all
1803
if (input.selectionStart != null) {
1804
clearTimeout(detectingSelectAll);
1805
var extval = input.value = " " + (posEq(sel.from, sel.to) ? "" : input.value), i = 0;
1807
input.selectionStart = 1; input.selectionEnd = extval.length;
1808
detectingSelectAll = setTimeout(function poll(){
1809
if (prevInput == " " && input.selectionStart == 0)
1810
operation(commands.selectAll)(instance);
1811
else if (i++ < 10) detectingSelectAll = setTimeout(poll, 500);
1819
var mouseup = connect(window, "mouseup", function() {
1821
setTimeout(rehide, 20);
1824
setTimeout(rehide, 50);
1829
function restartBlink() {
1830
clearInterval(blinker);
1832
cursor.style.visibility = "";
1833
blinker = setInterval(function() {
1834
cursor.style.visibility = (on = !on) ? "" : "hidden";
1835
}, options.cursorBlinkRate);
1838
var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"};
1839
function matchBrackets(autoclear) {
1840
var head = sel.inverted ? sel.from : sel.to, line = getLine(head.line), pos = head.ch - 1;
1841
var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)];
1843
var ch = match.charAt(0), forward = match.charAt(1) == ">", d = forward ? 1 : -1, st = line.styles;
1844
for (var off = pos + 1, i = 0, e = st.length; i < e; i+=2)
1845
if ((off -= st[i].length) <= 0) {var style = st[i+1]; break;}
1847
var stack = [line.text.charAt(pos)], re = /[(){}[\]]/;
1848
function scan(line, from, to) {
1849
if (!line.text) return;
1850
var st = line.styles, pos = forward ? 0 : line.text.length - 1, cur;
1851
for (var i = forward ? 0 : st.length - 2, e = forward ? st.length : -2; i != e; i += 2*d) {
1853
if (st[i+1] != style) {pos += d * text.length; continue;}
1854
for (var j = forward ? 0 : text.length - 1, te = forward ? text.length : -1; j != te; j += d, pos+=d) {
1855
if (pos >= from && pos < to && re.test(cur = text.charAt(j))) {
1856
var match = matching[cur];
1857
if (match.charAt(1) == ">" == forward) stack.push(cur);
1858
else if (stack.pop() != match.charAt(0)) return {pos: pos, match: false};
1859
else if (!stack.length) return {pos: pos, match: true};
1864
for (var i = head.line, e = forward ? Math.min(i + 100, doc.size) : Math.max(-1, i - 100); i != e; i+=d) {
1865
var line = getLine(i), first = i == head.line;
1866
var found = scan(line, first && forward ? pos + 1 : 0, first && !forward ? pos : line.text.length);
1869
if (!found) found = {pos: null, match: false};
1870
var style = found.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket";
1871
var one = markText({line: head.line, ch: pos}, {line: head.line, ch: pos+1}, style),
1872
two = found.pos != null && markText({line: i, ch: found.pos}, {line: i, ch: found.pos + 1}, style);
1873
var clear = operation(function(){one.clear(); two && two.clear();});
1874
if (autoclear) setTimeout(clear, 800);
1875
else bracketHighlighted = clear;
1878
// Finds the line to start with when starting a parse. Tries to
1879
// find a line with a stateAfter, so that it can start with a
1880
// valid state. If that fails, it returns the line with the
1881
// smallest indentation, which tends to need the least context to
1883
function findStartLine(n) {
1884
var minindent, minline;
1885
for (var search = n, lim = n - 40; search > lim; --search) {
1886
if (search == 0) return 0;
1887
var line = getLine(search-1);
1888
if (line.stateAfter) return search;
1889
var indented = line.indentation(options.tabSize);
1890
if (minline == null || minindent > indented) {
1891
minline = search - 1;
1892
minindent = indented;
1897
function getStateBefore(n) {
1898
var pos = findStartLine(n), state = pos && getLine(pos-1).stateAfter;
1899
if (!state) state = startState(mode);
1900
else state = copyState(mode, state);
1901
doc.iter(pos, n, function(line) {
1902
line.process(mode, state, options.tabSize);
1903
line.stateAfter = (pos == n - 1 || pos % 5 == 0) ? copyState(mode, state) : null;
1907
function highlightWorker() {
1908
if (frontier >= showingTo) return;
1909
var end = +new Date + options.workTime, state = copyState(mode, getStateBefore(frontier));
1910
var startFrontier = frontier;
1911
doc.iter(frontier, showingTo, function(line) {
1912
if (frontier >= showingFrom) { // Visible
1913
line.highlight(mode, state, options.tabSize);
1914
line.stateAfter = copyState(mode, state);
1916
line.process(mode, state, options.tabSize);
1917
line.stateAfter = frontier % 5 == 0 ? copyState(mode, state) : null;
1920
if (+new Date > end) {
1921
startWorker(options.workDelay);
1925
if (showingTo > startFrontier && frontier >= showingFrom)
1926
operation(function() {changes.push({from: startFrontier, to: frontier});})();
1928
function startWorker(time) {
1929
if (frontier < showingTo)
1930
highlight.set(time, highlightWorker);
1933
// Operations are used to wrap changes in such a way that each
1934
// change won't have to update the cursor and display (which would
1935
// be awkward, slow, and error-prone), but instead updates are
1936
// batched and then all combined and executed at once.
1937
function startOperation() {
1938
updateInput = userSelChange = textChanged = null;
1939
changes = []; selectionChanged = false; callbacks = [];
1941
function endOperation() {
1942
if (updateMaxLine) computeMaxLength();
1943
if (maxLineChanged && !options.lineWrapping) {
1944
var cursorWidth = widthForcer.offsetWidth, left = measureLine(maxLine, maxLine.text.length).left;
1946
widthForcer.style.left = left + "px";
1947
lineSpace.style.minWidth = (left + cursorWidth) + "px";
1949
maxLineChanged = false;
1951
var newScrollPos, updated;
1952
if (selectionChanged) {
1953
var coords = calculateCursorCoords();
1954
newScrollPos = calculateScrollPos(coords.x, coords.y, coords.x, coords.yBot);
1956
if (changes.length || newScrollPos && newScrollPos.scrollTop != null)
1957
updated = updateDisplay(changes, true, newScrollPos && newScrollPos.scrollTop);
1959
if (selectionChanged) updateSelection();
1960
if (gutterDirty) updateGutter();
1962
if (newScrollPos) scrollCursorIntoView();
1963
if (selectionChanged) restartBlink();
1965
if (focused && (updateInput === true || (updateInput !== false && selectionChanged)))
1966
resetInput(userSelChange);
1968
if (selectionChanged && options.matchBrackets)
1969
setTimeout(operation(function() {
1970
if (bracketHighlighted) {bracketHighlighted(); bracketHighlighted = null;}
1971
if (posEq(sel.from, sel.to)) matchBrackets(false);
1973
var sc = selectionChanged, cbs = callbacks; // these can be reset by callbacks
1974
if (textChanged && options.onChange && instance)
1975
options.onChange(instance, textChanged);
1976
if (sc && options.onCursorActivity)
1977
options.onCursorActivity(instance);
1978
for (var i = 0; i < cbs.length; ++i) cbs[i](instance);
1979
if (updated && options.onUpdate) options.onUpdate(instance);
1981
var nestedOperation = 0;
1982
function operation(f) {
1984
if (!nestedOperation++) startOperation();
1985
try {var result = f.apply(this, arguments);}
1986
finally {if (!--nestedOperation) endOperation();}
1991
function compoundChange(f) {
1992
history.startCompound();
1993
try { return f(); } finally { history.endCompound(); }
1996
for (var ext in extensions)
1997
if (extensions.propertyIsEnumerable(ext) &&
1998
!instance.propertyIsEnumerable(ext))
1999
instance[ext] = extensions[ext];
2000
for (var i = 0; i < initHooks.length; ++i) initHooks[i](instance);
2002
} // (end of function CodeMirror)
2004
// The default configuration options.
2005
CodeMirror.defaults = {
2010
indentWithTabs: false,
2015
electricChars: true,
2016
autoClearEmptyLines: false,
2019
lineWrapping: false,
2024
showCursorWhenSelecting: false,
2028
onCursorActivity: null,
2029
onViewportChange: null,
2030
onGutterClick: null,
2032
onFocus: null, onBlur: null, onScroll: null,
2033
matchBrackets: false,
2034
cursorBlinkRate: 530,
2041
lineNumberFormatter: function(integer) { return integer; }
2044
var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent);
2045
var mac = ios || /Mac/.test(navigator.platform);
2046
var win = /Win/.test(navigator.platform);
2048
// Known modes, by name and by MIME
2049
var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
2050
CodeMirror.defineMode = function(name, mode) {
2051
if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name;
2052
if (arguments.length > 2) {
2053
mode.dependencies = [];
2054
for (var i = 2; i < arguments.length; ++i) mode.dependencies.push(arguments[i]);
2058
CodeMirror.defineMIME = function(mime, spec) {
2059
mimeModes[mime] = spec;
2061
CodeMirror.resolveMode = function(spec) {
2062
if (typeof spec == "string" && mimeModes.hasOwnProperty(spec))
2063
spec = mimeModes[spec];
2064
else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec))
2065
return CodeMirror.resolveMode("application/xml");
2066
if (typeof spec == "string") return {name: spec};
2067
else return spec || {name: "null"};
2069
CodeMirror.getMode = function(options, spec) {
2070
var spec = CodeMirror.resolveMode(spec);
2071
var mfactory = modes[spec.name];
2072
if (!mfactory) return CodeMirror.getMode(options, "text/plain");
2073
var modeObj = mfactory(options, spec);
2074
if (modeExtensions.hasOwnProperty(spec.name)) {
2075
var exts = modeExtensions[spec.name];
2076
for (var prop in exts) {
2077
if (!exts.hasOwnProperty(prop)) continue;
2078
if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop];
2079
modeObj[prop] = exts[prop];
2082
modeObj.name = spec.name;
2085
CodeMirror.listModes = function() {
2087
for (var m in modes)
2088
if (modes.propertyIsEnumerable(m)) list.push(m);
2091
CodeMirror.listMIMEs = function() {
2093
for (var m in mimeModes)
2094
if (mimeModes.propertyIsEnumerable(m)) list.push({mime: m, mode: mimeModes[m]});
2098
var extensions = CodeMirror.extensions = {};
2099
CodeMirror.defineExtension = function(name, func) {
2100
extensions[name] = func;
2104
CodeMirror.defineInitHook = function(f) {initHooks.push(f);};
2106
var modeExtensions = CodeMirror.modeExtensions = {};
2107
CodeMirror.extendMode = function(mode, properties) {
2108
var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
2109
for (var prop in properties) if (properties.hasOwnProperty(prop))
2110
exts[prop] = properties[prop];
2113
var commands = CodeMirror.commands = {
2114
selectAll: function(cm) {cm.setSelection({line: 0, ch: 0}, {line: cm.lineCount() - 1});},
2115
killLine: function(cm) {
2116
var from = cm.getCursor(true), to = cm.getCursor(false), sel = !posEq(from, to);
2117
if (!sel && cm.getLine(from.line).length == from.ch) cm.replaceRange("", from, {line: from.line + 1, ch: 0});
2118
else cm.replaceRange("", from, sel ? to : {line: from.line});
2120
deleteLine: function(cm) {var l = cm.getCursor().line; cm.replaceRange("", {line: l, ch: 0}, {line: l});},
2121
undo: function(cm) {cm.undo();},
2122
redo: function(cm) {cm.redo();},
2123
goDocStart: function(cm) {cm.setCursor(0, 0, true);},
2124
goDocEnd: function(cm) {cm.setSelection({line: cm.lineCount() - 1}, null, true);},
2125
goLineStart: function(cm) {cm.setCursor(cm.getCursor().line, 0, true);},
2126
goLineStartSmart: function(cm) {
2127
var cur = cm.getCursor();
2128
var text = cm.getLine(cur.line), firstNonWS = Math.max(0, text.search(/\S/));
2129
cm.setCursor(cur.line, cur.ch <= firstNonWS && cur.ch ? 0 : firstNonWS, true);
2131
goLineEnd: function(cm) {cm.setSelection({line: cm.getCursor().line}, null, true);},
2132
goLineUp: function(cm) {cm.moveV(-1, "line");},
2133
goLineDown: function(cm) {cm.moveV(1, "line");},
2134
goPageUp: function(cm) {cm.moveV(-1, "page");},
2135
goPageDown: function(cm) {cm.moveV(1, "page");},
2136
goCharLeft: function(cm) {cm.moveH(-1, "char");},
2137
goCharRight: function(cm) {cm.moveH(1, "char");},
2138
goColumnLeft: function(cm) {cm.moveH(-1, "column");},
2139
goColumnRight: function(cm) {cm.moveH(1, "column");},
2140
goWordLeft: function(cm) {cm.moveH(-1, "word");},
2141
goWordRight: function(cm) {cm.moveH(1, "word");},
2142
delCharLeft: function(cm) {cm.deleteH(-1, "char");},
2143
delCharRight: function(cm) {cm.deleteH(1, "char");},
2144
delWordLeft: function(cm) {cm.deleteH(-1, "word");},
2145
delWordRight: function(cm) {cm.deleteH(1, "word");},
2146
indentAuto: function(cm) {cm.indentSelection("smart");},
2147
indentMore: function(cm) {cm.indentSelection("add");},
2148
indentLess: function(cm) {cm.indentSelection("subtract");},
2149
insertTab: function(cm) {cm.replaceSelection("\t", "end");},
2150
defaultTab: function(cm) {
2151
if (cm.somethingSelected()) cm.indentSelection("add");
2152
else cm.replaceSelection("\t", "end");
2154
transposeChars: function(cm) {
2155
var cur = cm.getCursor(), line = cm.getLine(cur.line);
2156
if (cur.ch > 0 && cur.ch < line.length - 1)
2157
cm.replaceRange(line.charAt(cur.ch) + line.charAt(cur.ch - 1),
2158
{line: cur.line, ch: cur.ch - 1}, {line: cur.line, ch: cur.ch + 1});
2160
newlineAndIndent: function(cm) {
2161
cm.replaceSelection("\n", "end");
2162
cm.indentLine(cm.getCursor().line);
2164
toggleOverwrite: function(cm) {cm.toggleOverwrite();}
2167
var keyMap = CodeMirror.keyMap = {};
2169
"Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown",
2170
"End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown",
2171
"Delete": "delCharRight", "Backspace": "delCharLeft", "Tab": "defaultTab", "Shift-Tab": "indentAuto",
2172
"Enter": "newlineAndIndent", "Insert": "toggleOverwrite"
2174
// Note that the save and find-related commands aren't defined by
2175
// default. Unknown commands are simply ignored.
2176
keyMap.pcDefault = {
2177
"Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo",
2178
"Ctrl-Home": "goDocStart", "Alt-Up": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Down": "goDocEnd",
2179
"Ctrl-Left": "goWordLeft", "Ctrl-Right": "goWordRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd",
2180
"Ctrl-Backspace": "delWordLeft", "Ctrl-Delete": "delWordRight", "Ctrl-S": "save", "Ctrl-F": "find",
2181
"Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
2182
"Ctrl-[": "indentLess", "Ctrl-]": "indentMore",
2183
fallthrough: "basic"
2185
keyMap.macDefault = {
2186
"Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo",
2187
"Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goWordLeft",
2188
"Alt-Right": "goWordRight", "Cmd-Left": "goLineStart", "Cmd-Right": "goLineEnd", "Alt-Backspace": "delWordLeft",
2189
"Ctrl-Alt-Backspace": "delWordRight", "Alt-Delete": "delWordRight", "Cmd-S": "save", "Cmd-F": "find",
2190
"Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
2191
"Cmd-[": "indentLess", "Cmd-]": "indentMore",
2192
fallthrough: ["basic", "emacsy"]
2194
keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault;
2196
"Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
2197
"Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
2198
"Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharRight", "Ctrl-H": "delCharLeft",
2199
"Alt-D": "delWordRight", "Alt-Backspace": "delWordLeft", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars"
2202
function getKeyMap(val) {
2203
if (typeof val == "string") return keyMap[val];
2206
function lookupKey(name, extraMap, map, handle, stop) {
2207
function lookup(map) {
2208
map = getKeyMap(map);
2209
var found = map[name];
2210
if (found === false) {
2214
if (found != null && handle(found)) return true;
2215
if (map.nofallthrough) {
2219
var fallthrough = map.fallthrough;
2220
if (fallthrough == null) return false;
2221
if (Object.prototype.toString.call(fallthrough) != "[object Array]")
2222
return lookup(fallthrough);
2223
for (var i = 0, e = fallthrough.length; i < e; ++i) {
2224
if (lookup(fallthrough[i])) return true;
2228
if (extraMap && lookup(extraMap)) return true;
2231
function isModifierKey(event) {
2232
var name = keyNames[e_prop(event, "keyCode")];
2233
return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod";
2235
CodeMirror.isModifierKey = isModifierKey;
2237
CodeMirror.fromTextArea = function(textarea, options) {
2238
if (!options) options = {};
2239
options.value = textarea.value;
2240
if (!options.tabindex && textarea.tabindex)
2241
options.tabindex = textarea.tabindex;
2242
// Set autofocus to true if this textarea is focused, or if it has
2243
// autofocus and no other element is focused.
2244
if (options.autofocus == null) {
2245
var hasFocus = document.body;
2246
// doc.activeElement occasionally throws on IE
2247
try { hasFocus = document.activeElement; } catch(e) {}
2248
options.autofocus = hasFocus == textarea ||
2249
textarea.getAttribute("autofocus") != null && hasFocus == document.body;
2252
function save() {textarea.value = instance.getValue();}
2253
if (textarea.form) {
2254
// Deplorable hack to make the submit method do the right thing.
2255
var rmSubmit = connect(textarea.form, "submit", save, true);
2256
var form = textarea.form, realSubmit = form.submit;
2257
textarea.form.submit = function wrappedSubmit() {
2259
form.submit = realSubmit;
2261
form.submit = wrappedSubmit;
2265
textarea.style.display = "none";
2266
var instance = CodeMirror(function(node) {
2267
textarea.parentNode.insertBefore(node, textarea.nextSibling);
2269
instance.save = save;
2270
instance.getTextArea = function() { return textarea; };
2271
instance.toTextArea = function() {
2273
textarea.parentNode.removeChild(instance.getWrapperElement());
2274
textarea.style.display = "";
2275
if (textarea.form) {
2277
if (typeof textarea.form.submit == "function")
2278
textarea.form.submit = realSubmit;
2284
var gecko = /gecko\/\d/i.test(navigator.userAgent);
2285
var ie = /MSIE \d/.test(navigator.userAgent);
2286
var ie_lt8 = /MSIE [1-7]\b/.test(navigator.userAgent);
2287
var ie_lt9 = /MSIE [1-8]\b/.test(navigator.userAgent);
2288
var quirksMode = ie && document.documentMode == 5;
2289
var webkit = /WebKit\//.test(navigator.userAgent);
2290
var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(navigator.userAgent);
2291
var chrome = /Chrome\//.test(navigator.userAgent);
2292
var opera = /Opera\//.test(navigator.userAgent);
2293
var safari = /Apple Computer/.test(navigator.vendor);
2294
var khtml = /KHTML\//.test(navigator.userAgent);
2295
var mac_geLion = /Mac OS X 10\D([7-9]|\d\d)\D/.test(navigator.userAgent);
2297
var opera_version = opera && navigator.userAgent.match(/Version\/(\d*\.\d*)/);
2298
if (opera_version) opera_version = Number(opera_version[1]);
2299
// Some browsers use the wrong event properties to signal cmd/ctrl on OS X
2300
var flipCtrlCmd = mac && (qtwebkit || opera && (opera_version == null || opera_version < 12.11));
2302
// Utility functions for working with state. Exported because modes
2303
// sometimes need to do this.
2304
function copyState(mode, state) {
2305
if (state === true) return state;
2306
if (mode.copyState) return mode.copyState(state);
2308
for (var n in state) {
2310
if (val instanceof Array) val = val.concat([]);
2315
CodeMirror.copyState = copyState;
2316
function startState(mode, a1, a2) {
2317
return mode.startState ? mode.startState(a1, a2) : true;
2319
CodeMirror.startState = startState;
2320
CodeMirror.innerMode = function(mode, state) {
2321
while (mode.innerMode) {
2322
var info = mode.innerMode(state);
2326
return info || {mode: mode, state: state};
2329
// The character stream used by a mode's parser.
2330
function StringStream(string, tabSize) {
2331
this.pos = this.start = 0;
2332
this.string = string;
2333
this.tabSize = tabSize || 8;
2335
StringStream.prototype = {
2336
eol: function() {return this.pos >= this.string.length;},
2337
sol: function() {return this.pos == 0;},
2338
peek: function() {return this.string.charAt(this.pos) || undefined;},
2340
if (this.pos < this.string.length)
2341
return this.string.charAt(this.pos++);
2343
eat: function(match) {
2344
var ch = this.string.charAt(this.pos);
2345
if (typeof match == "string") var ok = ch == match;
2346
else var ok = ch && (match.test ? match.test(ch) : match(ch));
2347
if (ok) {++this.pos; return ch;}
2349
eatWhile: function(match) {
2350
var start = this.pos;
2351
while (this.eat(match)){}
2352
return this.pos > start;
2354
eatSpace: function() {
2355
var start = this.pos;
2356
while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
2357
return this.pos > start;
2359
skipToEnd: function() {this.pos = this.string.length;},
2360
skipTo: function(ch) {
2361
var found = this.string.indexOf(ch, this.pos);
2362
if (found > -1) {this.pos = found; return true;}
2364
backUp: function(n) {this.pos -= n;},
2365
column: function() {return countColumn(this.string, this.start, this.tabSize);},
2366
indentation: function() {return countColumn(this.string, null, this.tabSize);},
2367
match: function(pattern, consume, caseInsensitive) {
2368
if (typeof pattern == "string") {
2369
var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
2370
if (cased(this.string).indexOf(cased(pattern), this.pos) == this.pos) {
2371
if (consume !== false) this.pos += pattern.length;
2375
var match = this.string.slice(this.pos).match(pattern);
2376
if (match && match.index > 0) return null;
2377
if (match && consume !== false) this.pos += match[0].length;
2381
current: function(){return this.string.slice(this.start, this.pos);}
2383
CodeMirror.StringStream = StringStream;
2385
function MarkedSpan(from, to, marker) {
2386
this.from = from; this.to = to; this.marker = marker;
2389
function getMarkedSpanFor(spans, marker) {
2390
if (spans) for (var i = 0; i < spans.length; ++i) {
2391
var span = spans[i];
2392
if (span.marker == marker) return span;
2396
function removeMarkedSpan(spans, span) {
2398
for (var i = 0; i < spans.length; ++i)
2399
if (spans[i] != span) (r || (r = [])).push(spans[i]);
2403
function markedSpansBefore(old, startCh, endCh) {
2404
if (old) for (var i = 0, nw; i < old.length; ++i) {
2405
var span = old[i], marker = span.marker;
2406
var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh);
2407
if (startsBefore || marker.type == "bookmark" && span.from == startCh && span.from != endCh) {
2408
var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh);
2409
(nw || (nw = [])).push({from: span.from,
2410
to: endsAfter ? null : span.to,
2417
function markedSpansAfter(old, endCh) {
2418
if (old) for (var i = 0, nw; i < old.length; ++i) {
2419
var span = old[i], marker = span.marker;
2420
var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh);
2421
if (endsAfter || marker.type == "bookmark" && span.from == endCh) {
2422
var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh);
2423
(nw || (nw = [])).push({from: startsBefore ? null : span.from - endCh,
2424
to: span.to == null ? null : span.to - endCh,
2431
function updateMarkedSpans(oldFirst, oldLast, startCh, endCh, newText) {
2432
if (!oldFirst && !oldLast) return newText;
2433
// Get the spans that 'stick out' on both sides
2434
var first = markedSpansBefore(oldFirst, startCh);
2435
var last = markedSpansAfter(oldLast, endCh);
2437
// Next, merge those two ends
2438
var sameLine = newText.length == 1, offset = lst(newText).length + (sameLine ? startCh : 0);
2440
// Fix up .to properties of first
2441
for (var i = 0; i < first.length; ++i) {
2442
var span = first[i];
2443
if (span.to == null) {
2444
var found = getMarkedSpanFor(last, span.marker);
2445
if (!found) span.to = startCh;
2446
else if (sameLine) span.to = found.to == null ? null : found.to + offset;
2451
// Fix up .from in last (or move them into first in case of sameLine)
2452
for (var i = 0; i < last.length; ++i) {
2454
if (span.to != null) span.to += offset;
2455
if (span.from == null) {
2456
var found = getMarkedSpanFor(first, span.marker);
2459
if (sameLine) (first || (first = [])).push(span);
2462
span.from += offset;
2463
if (sameLine) (first || (first = [])).push(span);
2468
var newMarkers = [newHL(newText[0], first)];
2470
// Fill gap with whole-line-spans
2471
var gap = newText.length - 2, gapMarkers;
2472
if (gap > 0 && first)
2473
for (var i = 0; i < first.length; ++i)
2474
if (first[i].to == null)
2475
(gapMarkers || (gapMarkers = [])).push({from: null, to: null, marker: first[i].marker});
2476
for (var i = 0; i < gap; ++i)
2477
newMarkers.push(newHL(newText[i+1], gapMarkers));
2478
newMarkers.push(newHL(lst(newText), last));
2483
// hl stands for history-line, a data structure that can be either a
2484
// string (line without markers) or a {text, markedSpans} object.
2485
function hlText(val) { return typeof val == "string" ? val : val.text; }
2486
function hlSpans(val) {
2487
if (typeof val == "string") return null;
2488
var spans = val.markedSpans, out = null;
2489
for (var i = 0; i < spans.length; ++i) {
2490
if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i); }
2491
else if (out) out.push(spans[i]);
2493
return !out ? spans : out.length ? out : null;
2495
function newHL(text, spans) { return spans ? {text: text, markedSpans: spans} : text; }
2497
function detachMarkedSpans(line) {
2498
var spans = line.markedSpans;
2500
for (var i = 0; i < spans.length; ++i) {
2501
var lines = spans[i].marker.lines;
2502
var ix = indexOf(lines, line);
2503
lines.splice(ix, 1);
2505
line.markedSpans = null;
2508
function attachMarkedSpans(line, spans) {
2510
for (var i = 0; i < spans.length; ++i)
2511
var marker = spans[i].marker.lines.push(line);
2512
line.markedSpans = spans;
2515
// When measuring the position of the end of a line, different
2516
// browsers require different approaches. If an empty span is added,
2517
// many browsers report bogus offsets. Of those, some (Webkit,
2518
// recent IE) will accept a space without moving the whole span to
2519
// the next line when wrapping it, others work with a zero-width
2521
var eolSpanContent = " ";
2522
if (gecko || (ie && !ie_lt8)) eolSpanContent = "\u200b";
2523
else if (opera) eolSpanContent = "";
2525
// Line objects. These hold state related to a line, including
2526
// highlighting info (the styles array).
2527
function Line(text, markedSpans) {
2530
attachMarkedSpans(this, markedSpans);
2533
update: function(text, markedSpans) {
2535
this.stateAfter = this.styles = null;
2536
detachMarkedSpans(this);
2537
attachMarkedSpans(this, markedSpans);
2539
// Run the given mode's parser over a line, update the styles
2540
// array, which contains alternating fragments of text and CSS
2542
highlight: function(mode, state, tabSize) {
2543
var stream = new StringStream(this.text, tabSize), st = this.styles || (this.styles = []);
2544
var pos = st.length = 0;
2545
if (this.text == "" && mode.blankLine) mode.blankLine(state);
2546
while (!stream.eol()) {
2547
var style = mode.token(stream, state), substr = stream.current();
2548
stream.start = stream.pos;
2549
if (pos && st[pos-1] == style) {
2550
st[pos-2] += substr;
2551
} else if (substr) {
2552
st[pos++] = substr; st[pos++] = style;
2554
// Give up when line is ridiculously long
2555
if (stream.pos > 5000) {
2556
st[pos++] = this.text.slice(stream.pos); st[pos++] = null;
2561
process: function(mode, state, tabSize) {
2562
var stream = new StringStream(this.text, tabSize);
2563
if (this.text == "" && mode.blankLine) mode.blankLine(state);
2564
while (!stream.eol() && stream.pos <= 5000) {
2565
mode.token(stream, state);
2566
stream.start = stream.pos;
2569
// Fetch the parser token for a given character. Useful for hacks
2570
// that want to inspect the mode state (say, for completion).
2571
getTokenAt: function(mode, state, tabSize, ch) {
2572
var txt = this.text, stream = new StringStream(txt, tabSize);
2573
while (stream.pos < ch && !stream.eol()) {
2574
stream.start = stream.pos;
2575
var style = mode.token(stream, state);
2577
return {start: stream.start,
2579
string: stream.current(),
2580
className: style || null,
2583
indentation: function(tabSize) {return countColumn(this.text, null, tabSize);},
2584
// Produces an HTML fragment for the line, taking selection,
2585
// marking, and highlighting into account.
2586
getContent: function(tabSize, wrapAt, compensateForWrapping) {
2587
var first = true, col = 0, specials = /[\t\u0000-\u0019\u200b\u2028\u2029\uFEFF]/g;
2588
var pre = elt("pre");
2589
function span_(html, text, style) {
2591
// Work around a bug where, in some compat modes, IE ignores leading spaces
2592
if (first && ie && text.charAt(0) == " ") text = "\u00a0" + text.slice(1);
2594
if (!specials.test(text)) {
2596
var content = document.createTextNode(text);
2598
var content = document.createDocumentFragment(), pos = 0;
2600
specials.lastIndex = pos;
2601
var m = specials.exec(text);
2602
var skipped = m ? m.index - pos : text.length - pos;
2604
content.appendChild(document.createTextNode(text.slice(pos, pos + skipped)));
2610
var tabWidth = tabSize - col % tabSize;
2611
content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab"));
2614
var token = elt("span", "\u2022", "cm-invalidchar");
2615
token.title = "\\u" + m[0].charCodeAt(0).toString(16);
2616
content.appendChild(token);
2621
if (style) html.appendChild(elt("span", [content], style));
2622
else html.appendChild(content);
2625
if (wrapAt != null) {
2626
var outPos = 0, anchor = pre.anchor = elt("span");
2627
span = function(html, text, style) {
2628
var l = text.length;
2629
if (wrapAt >= outPos && wrapAt < outPos + l) {
2630
var cut = wrapAt - outPos;
2632
span_(html, text.slice(0, cut), style);
2633
// See comment at the definition of spanAffectsWrapping
2634
if (compensateForWrapping) {
2635
var view = text.slice(cut - 1, cut + 1);
2636
if (spanAffectsWrapping.test(view)) html.appendChild(elt("wbr"));
2637
else if (!ie_lt8 && /\w\w/.test(view)) html.appendChild(document.createTextNode("\u200d"));
2640
html.appendChild(anchor);
2641
span_(anchor, opera ? text.slice(cut, cut + 1) : text.slice(cut), style);
2642
if (opera) span_(html, text.slice(cut + 1), style);
2647
span_(html, text, style);
2648
if (outPos == wrapAt && outPos == len) {
2649
setTextContent(anchor, eolSpanContent);
2650
html.appendChild(anchor);
2652
// Stop outputting HTML when gone sufficiently far beyond measure
2653
else if (outPos > wrapAt + 10 && /\s/.test(text)) span = function(){};
2658
var st = this.styles, allText = this.text, marked = this.markedSpans;
2659
var len = allText.length;
2660
function styleToClass(style) {
2661
if (!style) return null;
2662
return "cm-" + style.replace(/ +/g, " cm-");
2664
if (!allText && wrapAt == null) {
2666
} else if (!marked || !marked.length) {
2667
for (var i = 0, ch = 0; ch < len; i+=2) {
2668
var str = st[i], style = st[i+1], l = str.length;
2669
if (ch + l > len) str = str.slice(0, len - ch);
2671
span(pre, str, styleToClass(style));
2674
marked.sort(function(a, b) { return a.from - b.from; });
2675
var pos = 0, i = 0, text = "", style, sg = 0;
2676
var nextChange = marked[0].from || 0, marks = [], markpos = 0;
2677
var advanceMarks = function() {
2679
while (markpos < marked.length &&
2680
((m = marked[markpos]).from == pos || m.from == null)) {
2681
if (m.marker.type == "range") marks.push(m);
2684
nextChange = markpos < marked.length ? marked[markpos].from : Infinity;
2685
for (var i = 0; i < marks.length; ++i) {
2686
var to = marks[i].to;
2687
if (to == null) to = Infinity;
2688
if (to == pos) marks.splice(i--, 1);
2689
else nextChange = Math.min(to, nextChange);
2694
if (nextChange == pos) advanceMarks();
2695
var upto = Math.min(len, nextChange);
2698
var end = pos + text.length;
2699
var appliedStyle = style;
2700
for (var j = 0; j < marks.length; ++j) {
2701
var mark = marks[j];
2702
appliedStyle = (appliedStyle ? appliedStyle + " " : "") + mark.marker.style;
2703
if (mark.marker.endStyle && mark.to === Math.min(end, upto)) appliedStyle += " " + mark.marker.endStyle;
2704
if (mark.marker.startStyle && mark.from === pos) appliedStyle += " " + mark.marker.startStyle;
2706
span(pre, end > upto ? text.slice(0, upto - pos) : text, appliedStyle);
2707
if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;}
2710
text = st[i++]; style = styleToClass(st[i++]);
2716
cleanUp: function() {
2718
detachMarkedSpans(this);
2722
// Data structure that holds the sequence of lines.
2723
function LeafChunk(lines) {
2726
for (var i = 0, e = lines.length, height = 0; i < e; ++i) {
2727
lines[i].parent = this;
2728
height += lines[i].height;
2730
this.height = height;
2732
LeafChunk.prototype = {
2733
chunkSize: function() { return this.lines.length; },
2734
remove: function(at, n, callbacks) {
2735
for (var i = at, e = at + n; i < e; ++i) {
2736
var line = this.lines[i];
2737
this.height -= line.height;
2740
for (var j = 0; j < line.handlers.length; ++j) callbacks.push(line.handlers[j]);
2742
this.lines.splice(at, n);
2744
collapse: function(lines) {
2745
lines.splice.apply(lines, [lines.length, 0].concat(this.lines));
2747
insertHeight: function(at, lines, height) {
2748
this.height += height;
2749
this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at));
2750
for (var i = 0, e = lines.length; i < e; ++i) lines[i].parent = this;
2752
iterN: function(at, n, op) {
2753
for (var e = at + n; at < e; ++at)
2754
if (op(this.lines[at])) return true;
2757
function BranchChunk(children) {
2758
this.children = children;
2759
var size = 0, height = 0;
2760
for (var i = 0, e = children.length; i < e; ++i) {
2761
var ch = children[i];
2762
size += ch.chunkSize(); height += ch.height;
2766
this.height = height;
2769
BranchChunk.prototype = {
2770
chunkSize: function() { return this.size; },
2771
remove: function(at, n, callbacks) {
2773
for (var i = 0; i < this.children.length; ++i) {
2774
var child = this.children[i], sz = child.chunkSize();
2776
var rm = Math.min(n, sz - at), oldHeight = child.height;
2777
child.remove(at, rm, callbacks);
2778
this.height -= oldHeight - child.height;
2779
if (sz == rm) { this.children.splice(i--, 1); child.parent = null; }
2780
if ((n -= rm) == 0) break;
2784
if (this.size - n < 25) {
2786
this.collapse(lines);
2787
this.children = [new LeafChunk(lines)];
2788
this.children[0].parent = this;
2791
collapse: function(lines) {
2792
for (var i = 0, e = this.children.length; i < e; ++i) this.children[i].collapse(lines);
2794
insert: function(at, lines) {
2796
for (var i = 0, e = lines.length; i < e; ++i) height += lines[i].height;
2797
this.insertHeight(at, lines, height);
2799
insertHeight: function(at, lines, height) {
2800
this.size += lines.length;
2801
this.height += height;
2802
for (var i = 0, e = this.children.length; i < e; ++i) {
2803
var child = this.children[i], sz = child.chunkSize();
2805
child.insertHeight(at, lines, height);
2806
if (child.lines && child.lines.length > 50) {
2807
while (child.lines.length > 50) {
2808
var spilled = child.lines.splice(child.lines.length - 25, 25);
2809
var newleaf = new LeafChunk(spilled);
2810
child.height -= newleaf.height;
2811
this.children.splice(i + 1, 0, newleaf);
2812
newleaf.parent = this;
2821
maybeSpill: function() {
2822
if (this.children.length <= 10) return;
2825
var spilled = me.children.splice(me.children.length - 5, 5);
2826
var sibling = new BranchChunk(spilled);
2827
if (!me.parent) { // Become the parent node
2828
var copy = new BranchChunk(me.children);
2830
me.children = [copy, sibling];
2833
me.size -= sibling.size;
2834
me.height -= sibling.height;
2835
var myIndex = indexOf(me.parent.children, me);
2836
me.parent.children.splice(myIndex + 1, 0, sibling);
2838
sibling.parent = me.parent;
2839
} while (me.children.length > 10);
2840
me.parent.maybeSpill();
2842
iter: function(from, to, op) { this.iterN(from, to - from, op); },
2843
iterN: function(at, n, op) {
2844
for (var i = 0, e = this.children.length; i < e; ++i) {
2845
var child = this.children[i], sz = child.chunkSize();
2847
var used = Math.min(n, sz - at);
2848
if (child.iterN(at, used, op)) return true;
2849
if ((n -= used) == 0) break;
2856
function getLineAt(chunk, n) {
2857
while (!chunk.lines) {
2858
for (var i = 0;; ++i) {
2859
var child = chunk.children[i], sz = child.chunkSize();
2860
if (n < sz) { chunk = child; break; }
2864
return chunk.lines[n];
2866
function lineNo(line) {
2867
if (line.parent == null) return null;
2868
var cur = line.parent, no = indexOf(cur.lines, line);
2869
for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) {
2870
for (var i = 0; ; ++i) {
2871
if (chunk.children[i] == cur) break;
2872
no += chunk.children[i].chunkSize();
2877
function lineAtHeight(chunk, h) {
2880
for (var i = 0, e = chunk.children.length; i < e; ++i) {
2881
var child = chunk.children[i], ch = child.height;
2882
if (h < ch) { chunk = child; continue outer; }
2884
n += child.chunkSize();
2887
} while (!chunk.lines);
2888
for (var i = 0, e = chunk.lines.length; i < e; ++i) {
2889
var line = chunk.lines[i], lh = line.height;
2895
function heightAtLine(chunk, n) {
2898
for (var i = 0, e = chunk.children.length; i < e; ++i) {
2899
var child = chunk.children[i], sz = child.chunkSize();
2900
if (n < sz) { chunk = child; continue outer; }
2905
} while (!chunk.lines);
2906
for (var i = 0; i < n; ++i) h += chunk.lines[i].height;
2910
// The history object 'chunks' changes that are made close together
2911
// and at almost the same time into bigger undoable units.
2912
function History() {
2914
this.done = []; this.undone = [];
2916
this.closed = false;
2918
History.prototype = {
2919
addChange: function(start, added, old) {
2920
this.undone.length = 0;
2921
var time = +new Date, cur = lst(this.done), last = cur && lst(cur);
2922
var dtime = time - this.time;
2924
if (cur && !this.closed && this.compound) {
2925
cur.push({start: start, added: added, old: old});
2926
} else if (dtime > 400 || !last || this.closed ||
2927
last.start > start + old.length || last.start + last.added < start) {
2928
this.done.push([{start: start, added: added, old: old}]);
2929
this.closed = false;
2931
var startBefore = Math.max(0, last.start - start),
2932
endAfter = Math.max(0, (start + old.length) - (last.start + last.added));
2933
for (var i = startBefore; i > 0; --i) last.old.unshift(old[i - 1]);
2934
for (var i = endAfter; i > 0; --i) last.old.push(old[old.length - i]);
2935
if (startBefore) last.start = start;
2936
last.added += added - (old.length - startBefore - endAfter);
2940
startCompound: function() {
2941
if (!this.compound++) this.closed = true;
2943
endCompound: function() {
2944
if (!--this.compound) this.closed = true;
2948
function stopMethod() {e_stop(this);}
2949
// Ensure an event has a stop method.
2950
function addStop(event) {
2951
if (!event.stop) event.stop = stopMethod;
2955
function e_preventDefault(e) {
2956
if (e.preventDefault) e.preventDefault();
2957
else e.returnValue = false;
2959
function e_stopPropagation(e) {
2960
if (e.stopPropagation) e.stopPropagation();
2961
else e.cancelBubble = true;
2963
function e_stop(e) {e_preventDefault(e); e_stopPropagation(e);}
2964
CodeMirror.e_stop = e_stop;
2965
CodeMirror.e_preventDefault = e_preventDefault;
2966
CodeMirror.e_stopPropagation = e_stopPropagation;
2968
function e_target(e) {return e.target || e.srcElement;}
2969
function e_button(e) {
2972
if (e.button & 1) b = 1;
2973
else if (e.button & 2) b = 3;
2974
else if (e.button & 4) b = 2;
2976
if (mac && e.ctrlKey && b == 1) b = 3;
2980
// Allow 3rd-party code to override event properties by adding an override
2981
// object to an event object.
2982
function e_prop(e, prop) {
2983
var overridden = e.override && e.override.hasOwnProperty(prop);
2984
return overridden ? e.override[prop] : e[prop];
2987
// Event handler registration. If disconnect is true, it'll return a
2988
// function that unregisters the handler.
2989
function connect(node, type, handler, disconnect) {
2990
if (typeof node.addEventListener == "function") {
2991
node.addEventListener(type, handler, false);
2992
if (disconnect) return function() {node.removeEventListener(type, handler, false);};
2994
var wrapHandler = function(event) {handler(event || window.event);};
2995
node.attachEvent("on" + type, wrapHandler);
2996
if (disconnect) return function() {node.detachEvent("on" + type, wrapHandler);};
2999
CodeMirror.connect = connect;
3001
function Delayed() {this.id = null;}
3002
Delayed.prototype = {set: function(ms, f) {clearTimeout(this.id); this.id = setTimeout(f, ms);}};
3004
var Pass = CodeMirror.Pass = {toString: function(){return "CodeMirror.Pass";}};
3006
// Detect drag-and-drop
3007
var dragAndDrop = function() {
3008
// There is *some* kind of drag-and-drop support in IE6-8, but I
3009
// couldn't get it to work yet.
3010
if (ie_lt9) return false;
3011
var div = elt('div');
3012
return "draggable" in div || "dragDrop" in div;
3015
// Feature-detect whether newlines in textareas are converted to \r\n
3016
var lineSep = function () {
3017
var te = elt("textarea");
3018
te.value = "foo\nbar";
3019
if (te.value.indexOf("\r") > -1) return "\r\n";
3023
// For a reason I have yet to figure out, some browsers disallow
3024
// word wrapping between certain characters *only* if a new inline
3025
// element is started between them. This makes it hard to reliably
3026
// measure the position of things, since that requires inserting an
3027
// extra span. This terribly fragile set of regexps matches the
3028
// character combinations that suffer from this phenomenon on the
3029
// various browsers.
3030
var spanAffectsWrapping = /^$/; // Won't match any two-character string
3031
if (gecko) spanAffectsWrapping = /$'/;
3032
else if (safari) spanAffectsWrapping = /\-[^ \-?]|\?[^ !'\"\),.\-\/:;\?\]\}]/;
3033
else if (chrome) spanAffectsWrapping = /\-[^ \-\.?]|\?[^ \-\.?\]\}:;!'\"\),\/]|[\.!\"#&%\)*+,:;=>\]|\}~][\(\{\[<]|\$'/;
3035
// Counts the column offset in a string, taking tabs into account.
3036
// Used mostly to find indentation.
3037
function countColumn(string, end, tabSize) {
3039
end = string.search(/[^\s\u00a0]/);
3040
if (end == -1) end = string.length;
3042
for (var i = 0, n = 0; i < end; ++i) {
3043
if (string.charAt(i) == "\t") n += tabSize - (n % tabSize);
3049
function eltOffset(node, screen) {
3050
// Take the parts of bounding client rect that we are interested in so we are able to edit if need be,
3051
// since the returned value cannot be changed externally (they are kept in sync as the element moves within the page)
3052
try { var box = node.getBoundingClientRect(); box = { top: box.top, left: box.left }; }
3053
catch(e) { box = {top: 0, left: 0}; }
3055
// Get the toplevel scroll, working around browser differences.
3056
if (window.pageYOffset == null) {
3057
var t = document.documentElement || document.body.parentNode;
3058
if (t.scrollTop == null) t = document.body;
3059
box.top += t.scrollTop; box.left += t.scrollLeft;
3061
box.top += window.pageYOffset; box.left += window.pageXOffset;
3067
function eltText(node) {
3068
return node.textContent || node.innerText || node.nodeValue || "";
3071
var spaceStrs = [""];
3072
function spaceStr(n) {
3073
while (spaceStrs.length <= n)
3074
spaceStrs.push(lst(spaceStrs) + " ");
3075
return spaceStrs[n];
3078
function lst(arr) { return arr[arr.length-1]; }
3080
function selectInput(node) {
3081
if (ios) { // Mobile Safari apparently has a bug where select() is broken.
3082
node.selectionStart = 0;
3083
node.selectionEnd = node.value.length;
3084
} else node.select();
3087
// Operations on {line, ch} objects.
3088
function posEq(a, b) {return a.line == b.line && a.ch == b.ch;}
3089
function posLess(a, b) {return a.line < b.line || (a.line == b.line && a.ch < b.ch);}
3090
function copyPos(x) {return {line: x.line, ch: x.ch};}
3092
function elt(tag, content, className, style) {
3093
var e = document.createElement(tag);
3094
if (className) e.className = className;
3095
if (style) e.style.cssText = style;
3096
if (typeof content == "string") setTextContent(e, content);
3097
else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]);
3100
function removeChildren(e) {
3104
function removeChildrenAndAdd(parent, e) {
3105
removeChildren(parent).appendChild(e);
3107
function setTextContent(e, str) {
3110
e.appendChild(document.createTextNode(str));
3111
} else e.textContent = str;
3114
// Used to position the cursor after an undo/redo by finding the
3115
// last edited character.
3116
function editEnd(from, to) {
3118
if (!from) return to.length;
3119
for (var i = from.length, j = to.length; i >= 0 && j >= 0; --i, --j)
3120
if (from.charAt(i) != to.charAt(j)) break;
3124
function indexOf(collection, elt) {
3125
if (collection.indexOf) return collection.indexOf(elt);
3126
for (var i = 0, e = collection.length; i < e; ++i)
3127
if (collection[i] == elt) return i;
3130
var nonASCIISingleCaseWordChar = /[\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc]/;
3131
function isWordChar(ch) {
3132
return /\w/.test(ch) || ch > "\x80" &&
3133
(ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch));
3136
// See if "".split is the broken IE version, if so, provide an
3137
// alternative way to split lines.
3138
var splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) {
3139
var pos = 0, result = [], l = string.length;
3141
var nl = string.indexOf("\n", pos);
3142
if (nl == -1) nl = string.length;
3143
var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl);
3144
var rt = line.indexOf("\r");
3146
result.push(line.slice(0, rt));
3154
} : function(string){return string.split(/\r\n?|\n/);};
3155
CodeMirror.splitLines = splitLines;
3157
var hasSelection = window.getSelection ? function(te) {
3158
try { return te.selectionStart != te.selectionEnd; }
3159
catch(e) { return false; }
3161
try {var range = te.ownerDocument.selection.createRange();}
3163
if (!range || range.parentElement() != te) return false;
3164
return range.compareEndPoints("StartToEnd", range) != 0;
3167
CodeMirror.defineMode("null", function() {
3168
return {token: function(stream) {stream.skipToEnd();}};
3170
CodeMirror.defineMIME("text/plain", "null");
3172
var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
3173
19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
3174
36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
3175
46: "Delete", 59: ";", 91: "Mod", 92: "Mod", 93: "Mod", 109: "-", 107: "=", 127: "Delete",
3176
186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
3177
221: "]", 222: "'", 63276: "PageUp", 63277: "PageDown", 63275: "End", 63273: "Home",
3178
63234: "Left", 63232: "Up", 63235: "Right", 63233: "Down", 63302: "Insert", 63272: "Delete"};
3179
CodeMirror.keyNames = keyNames;
3182
for (var i = 0; i < 10; i++) keyNames[i + 48] = String(i);
3184
for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i);
3186
for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i;
3189
CodeMirror.version = "2.38";