diff --git a/butterfly/sass/_layout.sass b/butterfly/sass/_layout.sass index 1169cb4..d0980cc 100644 --- a/butterfly/sass/_layout.sass +++ b/butterfly/sass/_layout.sass @@ -93,5 +93,20 @@ body padding: .5em font-size: .75em + #input-view + position: fixed + z-index: 100 + padding: 0 + margin: 0 + text-decoration: underline + + #input-helper + position: fixed + z-index: -100 + opacity: 0 + white-space: nowrap + overflow: hidden + resize: none + .terminal outline: none diff --git a/butterfly/static/ext.js b/butterfly/static/ext.js index 899f1fd..82e4ba7 100644 --- a/butterfly/static/ext.js +++ b/butterfly/static/ext.js @@ -122,6 +122,7 @@ addEventListener('copy', copy = function(e) { var data, end, j, len1, line, ref, sel; + document.getElementsByTagName('body')[0].contentEditable = false; butterfly.bell("copied"); e.clipboardData.clearData(); sel = getSelection().toString().replace(/\u00A0/g, ' ').replace(/\u2007/g, ' '); @@ -143,6 +144,7 @@ addEventListener('paste', function(e) { var data, send, size; + document.getElementsByTagName('body')[0].contentEditable = false; butterfly.bell("pasted"); data = e.clipboardData.getData('text/plain'); data = data.replace(/\r\n/g, '\n').replace(/\n/g, '\r'); diff --git a/butterfly/static/ext.min.js b/butterfly/static/ext.min.js index 47255b1..dec1819 100644 --- a/butterfly/static/ext.min.js +++ b/butterfly/static/ext.min.js @@ -1,4 +1,4 @@ -/*! butterfly 2017-11-23 */ +/*! butterfly 2018-06-03 */ -(function(){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y=[].indexOf||function(a){for(var b=0,c=this.length;b=0&&c++,e="normal";break;case"csi":if("?>!$\" '".indexOf(b)>=0)break;if("0"<=b&&b<="9")break;if(";"===b)break;e="normal";break;case"osc":""!==b&&""!==b||(""===b&&c++,e="normal")}return d},t=function(a,b){var c;return c=function(d){var e,f,h;if(e=g(d.data.slice(1)),null===b||b.test(e))return butterfly.body.classList.remove("alarm"),f="Butterfly ["+butterfly.title+"]",a?(h=new Notification(f,{body:e,icon:"/static/images/favicon.png"}),h.onclick=function(){return window.focus(),h.close()}):alert(f+"\n"+e),butterfly.ws.shell.removeEventListener("message",c)},butterfly.ws.shell.addEventListener("message",c),butterfly.body.classList.add("alarm")},f=function(a){return a.preventDefault&&a.preventDefault(),a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0,!1},document.addEventListener("keydown",function(a){var b;if(!a.altKey||65!==a.keyCode)return!0;if(b=null,a.shiftKey){if(b=prompt("Ring alarm when encountering the following text: (can be a regexp)"),!b)return;b=new RegExp(b)}return Notification&&"default"===Notification.permission?Notification.requestPermission(function(){return t("granted"===Notification.permission,b)}):t("granted"===Notification.permission,b),f(a)}),addEventListener("copy",h=function(a){var b,c,d,e,f,g,h;for(butterfly.bell("copied"),a.clipboardData.clearData(),h=getSelection().toString().replace(/\u00A0/g," ").replace(/\u2007/g," "),b="",g=h.split("\n"),d=0,e=g.length;d-1))return a.returnValue="This terminal is active and not in session. Are you sure you want to kill it?"}),Terminal.on("change",function(a){if(y.call(a.classList,"extended")>=0)return a.addEventListener("click",function(a){return function(){var b,c;return y.call(a.classList,"expanded")>=0?a.classList.remove("expanded"):(c=a.getBoundingClientRect().height,a.classList.add("expanded"),b=a.getBoundingClientRect().height,document.body.scrollTop+=b-c)}}(a))}),x=function(a,b){var c,d,e,f,g;for(f=a.childNodes,g=[],d=0,e=f.length;d$&').replace(c,'$1$2').replace(b,'$&')},u={"&":"&","<":"<",">":">"},j=function(a){return a.replace(/[&<>]/g,function(a){return u[a]||a})},Terminal.on("change",function(a){return x(a,function(){var a,b,c;if(3===this.nodeType&&(c=this.nodeValue,a=m(j(c)),a!==c))return b=document.createElement("span"),b.innerHTML=a,this.parentElement.replaceChild(b,this),!0})}),document.addEventListener("keydown",function(a){return!a.altKey||79!==a.keyCode||(open(location.origin),f(a))}),v=null,p=1e3,l=100,n=function(){var a,b,c,d,e,f;if(butterfly.term.childElementCount>p+butterfly.rows){for(a=document.getElementById("packed"),e=document.createDocumentFragment("fragment"),b=c=0,f=p;0<=f?c<=f:c>=f;b=0<=f?++c:--c)e.appendChild(butterfly.term.firstChild);return d=document.createElement("div"),d.classList.add("pack"),d.appendChild(e),a.appendChild(d),a.childElementCount>l&&a.firstChild.remove(),v=setTimeout(n)}},Terminal.on("refresh",function(){return v&&clearTimeout(v),n()}),Terminal.on("clear",function(){var a,b;return b=document.createElement("div"),b.id="packed",a=document.getElementById("packed"),butterfly.body.replaceChild(b,a)}),a=function(){function a(){this.el=document.getElementById("popup"),this.bound_click_maybe_close=this.click_maybe_close.bind(this),this.bound_key_maybe_close=this.key_maybe_close.bind(this)}return a.prototype.open=function(a){return this.el.innerHTML=a,this.el.classList.remove("hidden"),"undefined"!=typeof InstallTrigger&&(document.body.contentEditable="false"),addEventListener("click",this.bound_click_maybe_close),addEventListener("keydown",this.bound_key_maybe_close)},a.prototype.close=function(){return removeEventListener("click",this.bound_click_maybe_close),removeEventListener("keydown",this.bound_key_maybe_close),"undefined"!=typeof InstallTrigger&&(document.body.contentEditable="true"),this.el.classList.add("hidden"),this.el.innerHTML=""},a.prototype.click_maybe_close=function(a){var b;for(b=a.target;b.parentElement;){if(Array.prototype.slice.call(this.el.children).indexOf(b)>-1)return!0;b=b.parentElement}return this.close(),f(a)},a.prototype.key_maybe_close=function(a){return 27!==a.keyCode||(this.close(),f(a))},a}(),q=new a,s=null,f=function(a){return a.preventDefault&&a.preventDefault(),a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0,!1},r=function(a){var b;for(b=a.previousSibling,b||(b=a.parentNode.previousSibling),b||(b=a.parentNode.parentNode.previousSibling);b.lastChild;)b=b.lastChild;return b},o=function(a){var b;for(b=a.nextSibling,b||(b=a.parentNode.nextSibling),b||(b=a.parentNode.parentNode.nextSibling);null!=b?b.firstChild:void 0;)b=b.firstChild;return b},b=function(){function a(){butterfly.body.classList.add("selection"),this.selection=getSelection()}return a.prototype.reset=function(){var a,b,c;for(this.selection=getSelection(),a=document.createRange(),a.setStart(this.selection.anchorNode,this.selection.anchorOffset),a.setEnd(this.selection.focusNode,this.selection.focusOffset),this.start={node:this.selection.anchorNode,offset:this.selection.anchorOffset},this.end={node:this.selection.focusNode,offset:this.selection.focusOffset},a.collapsed&&(b=[this.end,this.start],this.start=b[0],this.end=b[1]),this.startLine=this.start.node;!this.startLine.classList||y.call(this.startLine.classList,"line")<0;)this.startLine=this.startLine.parentNode;for(this.endLine=this.end.node,c=[];!this.endLine.classList||y.call(this.endLine.classList,"line")<0;)c.push(this.endLine=this.endLine.parentNode);return c},a.prototype.clear=function(){return this.selection.removeAllRanges()},a.prototype.destroy=function(){return butterfly.body.classList.remove("selection"),this.clear()},a.prototype.text=function(){return this.selection.toString().replace(/\u00A0/g," ").replace(/\u2007/g," ")},a.prototype.up=function(){return this.go(-1)},a.prototype.down=function(){return this.go(1)},a.prototype.go=function(a){var b;if(b=Array.prototype.indexOf.call(butterfly.term.childNodes,this.startLine)+a,0<=b&&b0;)if(f[--d].match(b))return{node:e,offset:d+1};e=r(e),f=null!=e?e.textContent:void 0,d=f.length}else for(;e;){for(;d=0)return!0;if(a.shiftKey&&13===a.keyCode&&!s&&!getSelection().isCollapsed)return butterfly.send(getSelection().toString()),getSelection().removeAllRanges(),f(a);if(s){if(s.reset(),!a.ctrlKey&&a.shiftKey&&37<=(e=a.keyCode)&&e<=40)return!0;if(a.shiftKey&&a.ctrlKey)38===a.keyCode?s.up():40===a.keyCode&&s.down();else if(39===a.keyCode)s.shrinkLeft();else if(38===a.keyCode)s.expandLeft();else if(37===a.keyCode)s.shrinkRight();else{if(40!==a.keyCode)return f(a);s.expandRight()}return null!=s&&s.apply(),f(a)}return!(!s&&a.ctrlKey&&a.shiftKey&&38===a.keyCode)||(c=Math.max(butterfly.term.childElementCount-butterfly.rows,0),s=new b,s.selectLine(c+butterfly.y-1),s.apply(),f(a))}),document.addEventListener("keyup",function(a){var b,c;if(b=a.keyCode,y.call([16,17,18,19],b)>=0)return!0;if(s){if(13===a.keyCode)return butterfly.send(s.text()),s.destroy(),s=null,f(a);if(c=a.keyCode,y.call([37,38,39,40],c)<0)return s.destroy(),s=null,!0}return!0}),document.addEventListener("dblclick",function(a){var b,c,d,e,f;if(!(a.ctrlKey||a.altkey||(f=getSelection(),f.isCollapsed||f.toString().match(/\s/)))){for(e=document.createRange(),e.setStart(f.anchorNode,f.anchorOffset),e.setEnd(f.focusNode,f.focusOffset),e.collapsed&&(f.removeAllRanges(),d=document.createRange(),d.setStart(f.focusNode,f.focusOffset),d.setEnd(f.anchorNode,f.anchorOffset),f.addRange(d));!f.toString().match(/\s/)&&f.toString();)f.modify("extend","forward","character");for(f.modify("extend","backward","character"),b=f.anchorNode,c=f.anchorOffset,f.collapseToEnd(),f.extend(b,c);!f.toString().match(/\s/)&&f.toString();)f.modify("extend","backward","character");return f.modify("extend","forward","character")}}),document.addEventListener("keydown",function(a){var b;return!a.altKey||69!==a.keyCode||(b=new XMLHttpRequest,b.addEventListener("load",function(){var a,b,c,d,e,f;if(e=JSON.parse(this.responseText),c="
",c+="

Session list

",0===e.sessions.length)c+="No current session for user "+e.user;else{for(c+="
    ",d=e.sessions,a=0,b=d.length;a'+f+"";c+="
"}return c+="
",q.open(c)}),b.open("GET","/sessions/list.json"),b.send(),f(a))}),c=function(a){var b;return document.getElementById("style").setAttribute("href",a),b=document.createElement("img"),b.onerror=function(){return setTimeout(function(){return"undefined"!=typeof butterfly&&null!==butterfly?butterfly.resize():void 0},250)},b.src=a},d="undefined"!=typeof localStorage&&null!==localStorage?localStorage.getItem("theme"):void 0,d&&c(d),this.set_theme=function(a){if(d=a,"undefined"!=typeof localStorage&&null!==localStorage&&localStorage.setItem("theme",a),a)return c(a)},document.addEventListener("keydown",function(a){var b,e;return!a.altKey||83!==a.keyCode||(a.shiftKey?(e=document.getElementById("style").getAttribute("href"),e=e.split("?")[0],c(e+"?"+(new Date).getTime()),f(a)):(b=new XMLHttpRequest,b.addEventListener("load",function(){var a,b,c,e,f,g,h,i,j,k,l,m;if(i=JSON.parse(this.responseText),a=i.builtin_themes,l=i.themes,b='
\n

Pick a theme:

\n ',h=function(a,c){return b+=""},h("/static/main.css","default"),l.length){for(b+='',c=0,f=l.length;c\n",q.open(b),k=document.getElementById("theme_list"),k.addEventListener("change",function(){return set_theme(k.value)})}),b.open("GET","/themes/list.json"),b.send(),f(a)))}),/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)&&(i=!1,e=!1,k=!0,w=document.createElement("input"),w.type="password",w.style.position="fixed",w.style.top=0,w.style.left=0,w.style.border="none",w.style.outline="none",w.style.opacity=0,w.value="0",document.body.appendChild(w),w.addEventListener("blur",function(){return setTimeout(function(a){return function(){return a.focus()}}(this),10)}),addEventListener("click",function(){return w.focus()}),addEventListener("touchstart",function(a){return 2===a.touches.length?i=!0:3===a.touches.length?(i=!1,e=!0):4===a.touches.length?(i=!0,e=!0):void 0}),w.addEventListener("keydown",function(a){return butterfly.keyDown(a),!0}),w.addEventListener("input",function(a){var b;return b=this.value.length,0===b?(a.keyCode=8,butterfly.keyDown(a),this.value="0",!0):(a.keyCode=this.value.charAt(1).charCodeAt(0),!i&&!e||k?(butterfly.keyPress(a),k=!1,this.value="0",!0):(a.keyCode=this.value.charAt(1).charCodeAt(0),a.ctrlKey=i,a.altKey=e,a.keyCode>=97&&a.keyCode<=122&&(a.keyCode-=32),butterfly.keyDown(a),this.value="0",i=e=!1,!0))}))}).call(this); //# sourceMappingURL=ext.min.js.map \ No newline at end of file diff --git a/butterfly/static/main.css b/butterfly/static/main.css index 27e6e64..90fffe6 100644 --- a/butterfly/static/main.css +++ b/butterfly/static/main.css @@ -2861,6 +2861,19 @@ body { display: block; padding: .5em; font-size: .75em; } + body #input-view { + position: fixed; + z-index: 100; + padding: 0; + margin: 0; + text-decoration: underline; } + body #input-helper { + position: fixed; + z-index: -100; + opacity: 0; + white-space: nowrap; + overflow: hidden; + resize: none; } .terminal { outline: none; } diff --git a/butterfly/static/main.js b/butterfly/static/main.js index ded8430..ec2b7bc 100644 --- a/butterfly/static/main.js +++ b/butterfly/static/main.js @@ -170,10 +170,14 @@ this.body = this.document.getElementsByTagName('body')[0]; this.term = this.document.getElementById('term'); this.forceWidth = this.body.getAttribute('data-force-unicode-width') === 'yes'; + this.inputHelper = this.document.getElementById('input-helper'); + this.inputView = this.document.getElementById('input-view'); this.body.className = 'terminal focus'; this.body.style.outline = 'none'; this.body.setAttribute('tabindex', 0); this.body.setAttribute('spellcheck', 'false'); + this.inputHelper.setAttribute('tabindex', 0); + this.inputHelper.setAttribute('spellcheck', 'false'); div = this.document.createElement('div'); div.className = 'line'; this.term.appendChild(div); @@ -185,11 +189,23 @@ this.termName = 'xterm'; this.cursorBlink = true; this.cursorState = 0; + this.inComposition = false; + this.compositionText = ""; this.resetVars(); this.focus(); this.startBlink(); + this.inputHelper.addEventListener('compositionstart', this.compositionStart.bind(this)); + this.inputHelper.addEventListener('compositionupdate', this.compositionUpdate.bind(this)); + this.inputHelper.addEventListener('compositionend', this.compositionEnd.bind(this)); + this.inputHelper.addEventListener('keydown', this.keyDown.bind(this)); + this.inputHelper.addEventListener('keypress', this.keyPress.bind(this)); addEventListener('keydown', this.keyDown.bind(this)); addEventListener('keypress', this.keyPress.bind(this)); + addEventListener('keyup', (function(_this) { + return function() { + return _this.inputHelper.focus(); + }; + })(this)); addEventListener('focus', this.focus.bind(this)); addEventListener('blur', this.blur.bind(this)); addEventListener('resize', (function(_this) { @@ -202,9 +218,6 @@ return _this.nativeScrollTo(); }; })(this), true); - if (typeof InstallTrigger !== "undefined") { - this.body.contentEditable = 'true'; - } this.initmouse(); addEventListener('load', (function(_this) { return function() { @@ -248,7 +261,8 @@ invisible: a.invisible, italic: a.italic, faint: a.faint, - crossed: a.crossed + crossed: a.crossed, + placeholder: false }; }; @@ -256,12 +270,18 @@ return a.bg === b.bg && a.fg === b.fg && a.bold === b.bold && a.underline === b.underline && a.blink === b.blink && a.inverse === b.inverse && a.invisible === b.invisible && a.italic === b.italic && a.faint === b.faint && a.crossed === b.crossed; }; - Terminal.prototype.putChar = function(c) { + Terminal.prototype.putChar = function(c, placeholder) { + var newChar; + if (placeholder == null) { + placeholder = false; + } + newChar = this.cloneAttr(this.curAttr, c); + newChar.placeholder = placeholder; if (this.insertMode) { - this.screen[this.y + this.shift].chars.splice(this.x, 0, this.cloneAttr(this.curAttr, c)); + this.screen[this.y + this.shift].chars.splice(this.x, 0, newChar); this.screen[this.y + this.shift].chars.pop(); } else { - this.screen[this.y + this.shift].chars[this.x] = this.cloneAttr(this.curAttr, c); + this.screen[this.y + this.shift].chars[this.x] = newChar; } return this.screen[this.y + this.shift].dirty = true; }; @@ -297,7 +317,8 @@ invisible: false, italic: false, faint: false, - crossed: false + crossed: false, + placeholder: false }; this.curAttr = this.cloneAttr(this.defAttr); this.params = []; @@ -342,6 +363,7 @@ this.showCursor(); this.body.classList.add('focus'); this.body.classList.remove('blur'); + this.inputHelper.focus(); this.resize(); return this.scrollLock = old_sl; }; @@ -581,8 +603,15 @@ return [classes, styles]; }; + Terminal.prototype.isCJK = function(ch) { + return ("\u4e00" <= ch && ch <= "\u9fff") || ("\u3040" <= ch && ch <= "\u30ff") || ("\u31f0" <= ch && ch <= "\u31ff") || ("\u3190" <= ch && ch <= "\u319f") || ("\u3301" <= ch && ch <= "\u3356") || ("\uac00" <= ch && ch <= "\ud7ff") || ("\u3000" <= ch && ch <= "\u303f") || ("\uff00" <= ch && ch <= "\uff60") || ("\uffe0" <= ch && ch <= "\uffe6"); + }; + Terminal.prototype.charToDom = function(data, attr, cursor) { var ch, char, classes, ref, styles; + if (data.placeholder) { + return; + } if (data.html) { return data.html; } @@ -621,12 +650,12 @@ default: if (ch <= " ") { char += " "; - } else if (!this.forceWidth) { + } else if (!(this.forceWidth || this.isCJK(ch))) { char += ch; } else { if (ch <= "~") { char += ch; - } else if (("\uff00" < ch && ch < "\uffef")) { + } else if (this.isCJK(ch)) { char += "" + ch + ""; } else { char += "" + ch + ""; @@ -733,6 +762,7 @@ dom = this.screenToDom(force); this.writeDom(dom); this.nativeScrollTo(); + this.updateInputViews(); return this.emit('refresh'); }; @@ -912,12 +942,8 @@ } this.putChar(ch); this.x++; - if (this.forceWidth && ("\uff00" < ch && ch < "\uffef")) { - if (this.cols < 2 || this.x >= this.cols) { - this.putChar(" "); - break; - } - this.putChar(" "); + if (this.isCJK(ch)) { + this.putChar(" ", true); this.x++; } } @@ -1409,8 +1435,75 @@ return this.write(data + "\r\n"); }; + Terminal.prototype.updateInputViews = function() { + var cursorPos; + cursorPos = this.cursor.getBoundingClientRect(); + this.inputView.style['left'] = cursorPos.left + "px"; + this.inputView.style['top'] = cursorPos.top + "px"; + this.inputHelper.style['left'] = cursorPos.left + "px"; + this.inputHelper.style['top'] = cursorPos.top + "px"; + return this.inputHelper.value = ""; + }; + + Terminal.prototype.compositionStart = function(ev) { + ev.preventDefault(); + ev.stopPropagation(); + this.updateInputViews(); + this.inputView.className = ""; + this.inputView.innerText = ""; + this.cursor.style['visibility'] = "hidden"; + this.inComposition = true; + this.compositionText = ""; + return false; + }; + + Terminal.prototype.compositionUpdate = function(ev) { + ev.preventDefault(); + ev.stopPropagation(); + this.compositionText = ev.data; + this.inputView.innerText = this.compositionText; + return false; + }; + + Terminal.prototype.compositionEnd = function(ev) { + ev.preventDefault(); + ev.stopPropagation(); + this.finishComposition(); + return false; + }; + + Terminal.prototype.finishComposition = function() { + this.inComposition = false; + this.showCursor(); + this.inputHelper.value = ""; + this.inputView.className = "hidden"; + this.send(this.compositionText); + this.compositionText = ""; + return this.inputHelper.focus(); + }; + Terminal.prototype.keyDown = function(ev) { var key, ref; + if (this.inComposition) { + if (ev.keyCode === 229) { + return false; + } else if (ev.keyCode === 16 || ev.keyCode === 17 || ev.keyCode === 18) { + return false; + } + this.finishComposition(); + } + if (ev.keyCode === 229) { + ev.preventDefault(); + ev.stopPropagation(); + setTimeout((function(_this) { + return function() { + if (!(_this.inComposition || _this.inputHelper.value.length > 1)) { + return _this.send(_this.inputHelper.value); + } + }; + })(this), 0); + return false; + } if (ev.keyCode > 15 && ev.keyCode < 19) { return true; } @@ -1424,6 +1517,7 @@ return true; } if ((ev.shiftKey && ev.ctrlKey) && ((ref = ev.keyCode) === 67 || ref === 86)) { + this.body.contentEditable = true; return true; } if (ev.altKey && ev.keyCode === 90 && !this.skipNextKey) { diff --git a/butterfly/static/main.min.js b/butterfly/static/main.min.js index 0b943ab..6623f59 100644 --- a/butterfly/static/main.min.js +++ b/butterfly/static/main.min.js @@ -1,5 +1,5 @@ -/*! butterfly 2017-11-23 */ +/*! butterfly 2018-06-03 */ -(function(){var a,b,c,d,e,f,g,h,i,j,k=[].indexOf||function(a){for(var b=0,c=this.length;b6e4?window.open("","_self").close():void 0},l=function(){return setTimeout(function(){if(!g)return j.shell=new WebSocket(q+"/ws"+k),h()},100)},o=function(a){if(n)return n.write(a)},p=function(a){return setTimeout(o,1,a.data)},b=function(a){var b;if(b=JSON.parse(a.data),"size"===b.cmd)return n.resize(b.cols,b.rows,!0)},h=function(){return j.shell.addEventListener("open",i),j.shell.addEventListener("message",p),j.shell.addEventListener("error",d),j.shell.addEventListener("close",l)},e=function(){return j.ctl.addEventListener("open",i),j.ctl.addEventListener("message",b),j.ctl.addEventListener("error",d),j.ctl.addEventListener("close",a)},h(),e(),addEventListener("beforeunload",function(){if(!g)return"This will exit the terminal session"})}),d=function(a){return a.preventDefault&&a.preventDefault(),a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0,!1},i=0,b={normal:i++,escaped:i++,csi:i++,osc:i++,charset:i++,dcs:i++,ignore:i++},c=function(){function a(a,b,c){var d;this.parent=a,this.out=b,this.ctl=null!=c?c:function(){},this.document=this.parent.ownerDocument,this.html=this.document.getElementsByTagName("html")[0],this.body=this.document.getElementsByTagName("body")[0],this.term=this.document.getElementById("term"),this.forceWidth="yes"===this.body.getAttribute("data-force-unicode-width"),this.body.className="terminal focus",this.body.style.outline="none",this.body.setAttribute("tabindex",0),this.body.setAttribute("spellcheck","false"),d=this.document.createElement("div"),d.className="line",this.term.appendChild(d),this.computeCharSize(),this.cols=Math.floor(this.body.clientWidth/this.charSize.width),this.rows=Math.floor(window.innerHeight/this.charSize.height),this.visualBell=100,this.convertEol=!1,this.termName="xterm",this.cursorBlink=!0,this.cursorState=0,this.resetVars(),this.focus(),this.startBlink(),addEventListener("keydown",this.keyDown.bind(this)),addEventListener("keypress",this.keyPress.bind(this)),addEventListener("focus",this.focus.bind(this)),addEventListener("blur",this.blur.bind(this)),addEventListener("resize",function(a){return function(){return a.resize()}}(this)),this.body.addEventListener("load",function(a){return function(){return a.nativeScrollTo()}}(this),!0),"undefined"!=typeof InstallTrigger&&(this.body.contentEditable="true"),this.initmouse(),addEventListener("load",function(a){return function(){return a.resize()}}(this)),this.emit("load"),this.active=null}return a.hooks={},a.on=function(b,c){return null==a.hooks[b]&&(a.hooks[b]=[]),a.hooks[b].push(c)},a.off=function(b,c){return null==a.hooks[b]&&(a.hooks[b]=[]),a.hooks[b].pop(c)},a.prototype.emit=function(b,c){var d,e,f,g,h;for(null==a.hooks[b]&&(a.hooks[b]=[]),g=a.hooks[b],h=[],e=0,f=g.length;e=c;d=0<=c?++a:--a)this.screen.push(this.blankLine(!1,!1));return this.setupStops(),this.skipNextKey=null},a.prototype.computeCharSize=function(){var a,b;return b=document.createElement("span"),b.textContent="0123456789",a=this.term.firstChild,a.appendChild(b),this.charSize={width:b.getBoundingClientRect().width/10,height:a.getBoundingClientRect().height},a.removeChild(b)},a.prototype.eraseAttr=function(){var a;return a=this.cloneAttr(this.defAttr),a.bg=this.curAttr.bg,a},a.prototype.focus=function(){var a;return a=this.scrollLock,this.scrollLock=!0,this.sendFocus&&this.send(""),this.showCursor(),this.body.classList.add("focus"),this.body.classList.remove("blur"),this.resize(),this.scrollLock=a},a.prototype.blur=function(){var a;return a=this.scrollLock,this.scrollLock=!0,this.cursorState=1,this.screen[this.y+this.shift].dirty=!0,this.refresh(),this.sendFocus&&this.send(""),this.body.classList.add("blur"),this.body.classList.remove("focus"),this.scrollLock=a},a.prototype.initmouse=function(){var a,b,c,e,f,g,h;return e=32,f=function(a){var d,f;if(d=b(a),f=c(a))return g(d,f,a.type),e=d},h=function(a){var b,d;if(b=e,d=c(a))return b+=32,g(b,d,a.type)},a=function(a){return function(b,c){return a.utfMouse?2047===c?b.push(0):c<127?b.push(c):(c>2047&&(c=2047),b.push(192|c>>6),b.push(128|63&c)):255===c?b.push(0):(c>127&&(c=127),b.push(c))}}(this),g=function(b){return function(c,d,e){var f;return b.urxvtMouse?(d.x-=32,d.y-=32,d.x++,d.y++,void b.send("["+c+";"+d.x+";"+d.y+"M")):b.sgrMouse?(d.x-=32,d.y-=32,c-=32,void b.send("[<"+c+";"+d.x+";"+d.y+("mouseup"===e?"m":"M"))):(f=[],a(f,c),a(f,d.x),a(f,d.y),b.send(""+String.fromCharCode.apply(String,f)))}}(this),b=function(a){return function(b){var c,d,e,f,g;switch(b.type){case"mousedown":c=null!=b.button?+b.button:null!=b.which?b.which-1:null;break;case"mouseup":c=3;break;case"wheel":c=b.deltaY<0?64:65}return g=b.shiftKey?4:0,e=b.metaKey?8:0,d=b.ctrlKey?16:0,f=g|e|d,a.vt200Mouse?f&=d:a.normalMouse||(f=0),32+(f<<2)+c}}(this),c=function(a){return function(b){var c,d,e,f;return e=b.pageX,f=b.pageY-window.scrollY,d=a.body.clientWidth,c=window.innerHeight,e=Math.ceil(e/d*a.cols),f=Math.ceil(f/c*a.rows),e<0&&(e=0),e>a.cols&&(e=a.cols),f<0&&(f=0),f>a.rows&&(f=a.rows),e+=32,f+=32,{x:e,y:f,type:b.type}}}(this),addEventListener("contextmenu",function(a){return function(b){if(a.mouseEvents)return d(b)}}(this)),addEventListener("mousedown",function(a){return function(b){var c,e;if(a.mouseEvents)return f(b),c=h.bind(a),addEventListener("mousemove",c),a.x10Mouse||addEventListener("mouseup",e=function(a){return f(a),removeEventListener("mousemove",c),removeEventListener("mouseup",e),d(a)}),d(b)}}(this)),addEventListener("wheel",function(a){return function(b){if(a.mouseEvents){if(a.x10Mouse)return;return f(b),d(b)}}}(this))},a.prototype.getClasses=function(a){var b,c,d;return b=[],d=[],a.bold&&b.push("bold"),a.underline&&b.push("underline"),1===a.blink&&b.push("blink"),2===a.blink&&b.push("blink-fast"),a.inverse&&b.push("reverse-video"),a.invisible&&b.push("invisible"),a.italic&&b.push("italic"),a.faint&&b.push("faint"),a.crossed&&b.push("crossed"),"number"==typeof a.fg?(c=a.fg,a.bold&&c<8&&(c+=8),b.push("fg-color-"+c)):"string"==typeof a.fg&&d.push("color: "+a.fg),"number"==typeof a.bg?b.push("bg-color-"+a.bg):"string"==typeof a.bg&&d.push("background-color: "+a.bg),[b,d]},a.prototype.charToDom=function(a,b,c){var d,e,f,g,h;if(a.html)return a.html;switch(b=b||this.cloneAttr(this.defAttr),d=a.ch,e="",this.equalAttr(a,b)||(this.equalAttr(b,this.defAttr)||(e+=""),this.equalAttr(a,this.defAttr)||(g=this.getClasses(a),f=g[0],h=g[1],e+=''),d){case"&":e+="&";break;case"<":e+="<";break;case">":e+=">";break;case" ":e+='';break;default:e+=d<=" "?" ":this.forceWidth?d<="~"?d:"＀"'+d+"":''+d+"":d}return c&&(e+=""),e},a.prototype.lineToDom=function(a,b,c){var d,e,f,g,h,i;for(c&&(d=this.x),h=[],i=f=0,g=this.cols;0<=g?f<=g:f>=g;i=0<=g?++f:--f)i!==this.cols?h.push(this.charToDom(b.chars[i],b.chars[i-1],i===d)):(e="",this.equalAttr(b.chars[i-1],this.defAttr)||(e+=""),b.wrap&&(e+="⏎"),b.extra?h.push(e+=''+b.extra+""):h.push(void 0));return h},a.prototype.screenToDom=function(a){var b,c,d,e,f,g,h,i;for(g=this.screen,h=[],i=d=0,e=g.length;d=d;a=c<=d?++b:--b)e.push(this.screen[a+this.shift].dirty=!0);return e}return this.screen.push(this.blankLine()),this.shift++},a.prototype.unscroll=function(){var a,b,c,d,e;for(this.screen.splice(this.shift+this.scrollTop,0,this.blankLine(!0)),this.screen.splice(this.shift+this.scrollBottom+1,1),e=[],a=b=c=this.scrollTop,d=this.scrollBottom;c<=d?b<=d:b>=d;a=c<=d?++b:--b)e.push(this.screen[a+this.shift].dirty=!0);return e},a.prototype.nativeScrollTo=function(a){if(null==a&&(a=2e9),!this.scrollLock)return window.scrollTo(0,a)},a.prototype.scrollDisplay=function(a){return this.nativeScrollTo(window.scrollY+a*this.charSize.height)},a.prototype.nextLine=function(){if(this.y++,this.y>this.scrollBottom)return this.y--,this.scroll()},a.prototype.prevLine=function(){if(this.y--,this.y=this.cols&&this.x--,this.x>0&&this.x--;break;case"\t":this.x=this.nextStop();break;case"":this.setgLevel(1);break;case"":this.setgLevel(0);break;case"":this.state=b.escaped;break;default:if("̀"<=g&&g<="ͯ"||"᪰"<=g&&g<="᫿"||"᷀"<=g&&g<="᷿"||"⃐"<=g&&g<="⃿"||"︠"<=g&&g<="︯"){if(z=this.x,A=this.y+this.shift,this.x>0)z-=1;else{if(!(this.y>0))break;A-=1,z=this.cols-1}this.screen[A].chars[z].ch+=g;break}if(g>=" "&&((null!=(s=this.charset)?s[g]:void 0)&&(g=this.charset[g]),this.x>=this.cols&&(this.horizontalWrap?this.screen[this.y+this.shift].extra+=g:(this.autowrap&&(this.screen[this.y+this.shift].wrap=!0,this.nextLine()),this.x=0)),this.putChar(g),this.x++,this.forceWidth&&"＀"=this.cols){this.putChar(" ");break}this.putChar(" "),this.x++}}break;case b.escaped:switch(g){case"[":this.params=[],this.currentParam=0,this.state=b.csi;break;case"]":this.params=[],this.currentParam=0,this.state=b.osc;break;case"P":this.params=[],this.currentParam=0,this.state=b.dcs;break;case"_":this.state=b.ignore;break;case"^":this.state=b.ignore;break;case"c":this.clearScrollback(),this.reset();break;case"E":this.x=0,this.index();break;case"D":this.index();break;case"M":this.reverseIndex();break;case"%":this.setgLevel(0),this.setgCharset(0,a.prototype.charsets.US),this.state=b.normal,j++;break;case"(":case")":case"*":case"+":case"-":case".":switch(g){case"(":this.gcharset=0;break;case")":case"-":this.gcharset=1;break;case"*":case".":this.gcharset=2;break;case"+":this.gcharset=3}this.state=b.charset;break;case"/":this.gcharset=3,this.state=b.charset,j--;break;case"n":this.setgLevel(2);break;case"o":this.setgLevel(3);break;case"|":this.setgLevel(3);break;case"}":this.setgLevel(2);break;case"~":this.setgLevel(1);break;case"7":this.saveCursor(),this.state=b.normal;break;case"8":this.restoreCursor(),this.state=b.normal;break;case"#":switch(this.state=b.normal,j++,q=c.charAt(j)){case"3":break;case"4":break;case"5":break;case"6":break;case"8":for(t=this.screen,k=0,m=t.length;k=u;f=0<=u?++o:--o)n.chars[f]=this.cloneAttr(this.curAttr,"E");this.x=this.y=0}break;case"H":this.tabSet();break;case"=":this.applicationKeypad=!0,this.state=b.normal;break;case">":this.applicationKeypad=!1,this.state=b.normal;break;default:this.state=b.normal,console.log("Unknown ESC control:",g)}break;case b.charset:switch(g){case"0":i=a.prototype.charsets.SCLD;break;case"A":i=a.prototype.charsets.UK;break;case"B":i=a.prototype.charsets.US;break;case"4":i=a.prototype.charsets.Dutch;break;case"C":case"5":i=a.prototype.charsets.Finnish;break;case"R":i=a.prototype.charsets.French;break;case"Q":i=a.prototype.charsets.FrenchCanadian;break;case"K":i=a.prototype.charsets.German;break;case"Y":i=a.prototype.charsets.Italian;break;case"E":case"6":i=a.prototype.charsets.NorwegianDanish;break;case"Z":i=a.prototype.charsets.Spanish;break;case"H":case"7":i=a.prototype.charsets.Swedish;break;case"=":i=a.prototype.charsets.Swiss;break;case"/":i=a.prototype.charsets.ISOLatin,j++;break;default:i=a.prototype.charsets.US}this.setgCharset(this.gcharset,i),this.gcharset=null,this.state=b.normal;break;case b.osc:if(""===g||""===g){switch(""===g&&j++,this.params.push(this.currentParam),this.params[0]){case 0:case 1:case 2:this.params[1]&&(this.title=this.params[1]+" - ƸӜƷ butterfly",this.handleTitle(this.title))}this.params=[],this.currentParam=0,this.state=b.normal}else this.params.length?this.currentParam+=g:g>="0"&&g<="9"?this.currentParam=10*this.currentParam+g.charCodeAt(0)-48:";"===g&&(this.params.push(this.currentParam),this.currentParam="");break;case b.csi:if("?"===g||">"===g||"!"===g){this.prefix=g;break}if(g>="0"&&g<="9"){this.currentParam=10*this.currentParam+g.charCodeAt(0)-48;break}if("$"===g||'"'===g||" "===g||"'"===g)break;if(g<=" "||g>="~"){"\b"===g&&(this.currentParam=this.currentParam/10&1),"\r"===g&&(this.x=0),["\n","\x0B","\f"].indexOf(g)>=0&&(this.screen[this.y+this.shift].dirty=!0,this.nextLine());break}if(this.params.push(this.currentParam),this.currentParam=0,";"===g)break;switch(this.state=b.normal,g){case"A":this.cursorUp(this.params);break;case"B":this.cursorDown(this.params);break;case"C":this.cursorForward(this.params);break;case"D":this.cursorBackward(this.params);break;case"H":this.cursorPos(this.params);break;case"J":this.eraseInDisplay(this.params);break;case"K":this.eraseInLine(this.params);break;case"m":this.prefix||this.charAttributes(this.params);break;case"n":this.deviceStatus(this.params);break;case"@":this.insertChars(this.params);break;case"E":this.cursorNextLine(this.params);break;case"F":this.cursorPrecedingLine(this.params);break;case"G":this.cursorCharAbsolute(this.params);break;case"L":this.insertLines(this.params);break;case"M":this.deleteLines(this.params);break;case"P":this.deleteChars(this.params);break;case"X":this.eraseChars(this.params);break;case"`":this.charPosAbsolute(this.params);break;case"a":this.HPositionRelative(this.params);break;case"c":this.sendDeviceAttributes(this.params);break;case"d":this.linePosAbsolute(this.params);break;case"e":this.VPositionRelative(this.params);break;case"f":this.HVPosition(this.params);break;case"h":this.setMode(this.params);break;case"l":this.resetMode(this.params);break;case"r":this.setScrollRegion(this.params);break;case"s":this.saveCursor(this.params);break;case"u":this.restoreCursor(this.params);break;case"I":this.cursorForwardTab(this.params);break;case"S":this.scrollUp(this.params);break;case"T":this.params.length<2&&!this.prefix&&this.scrollDown(this.params);break;case"Z":this.cursorBackwardTab(this.params);break;case"b":this.repeatPrecedingCharacter(this.params);break;case"g":this.tabClear(this.params);break;case"p":"!"===this.prefix&&this.softReset(this.params);break;default:console.error("Unknown CSI code: %s (%d).",g,g.charCodeAt(0))}this.prefix="";break;case b.dcs:if(""===g||""===g){switch(""===g&&j++,this.prefix){case"":if(r=this.currentParam,";"!==r[0]){console.error("Unknown DECUDK: "+r);break}if(r=r.slice(1),v=r.split("|",2),x=v[0],h=v[1],!h){console.error("No type for inline DECUDK: "+r);break}switch(x){case"HTML":w=html_sanitize(h,function(a){return a}),d=this.cloneAttr(this.curAttr),d.html='
'+w+"
",this.screen[this.y+this.shift].chars[this.x]=d,this.resetLine(this.screen[this.y+this.shift]),this.nextLine();break;case"IMAGE":h=encodeURI(h),h.indexOf(";")?(p=h.slice(0,h.indexOf(";")),e=h.slice(h.indexOf(";")+1)):(p="image",e=h),d=this.cloneAttr(this.curAttr),d.html='',this.screen[this.y+this.shift].chars[this.x]=d,this.resetLine(this.screen[this.y+this.shift]);break;case"PROMPT":this.send(h);break;case"TEXT":l+=h.length,c=c.slice(0,j+1)+h+c.slice(j+1);break;default:console.error("Unknown type "+x+" for DECUDK")}break;case"$q":switch(r=this.currentParam,y=!1,r){case'"q':r='0"q';break;case'"p':r='61"p';break;case"r":r=""+(this.scrollTop+1)+";"+(this.scrollBottom+1)+"r";break;case"m":r="0m";break;default:console.error("Unknown DCS Pt: %s.",r),r=""}this.send("P"+ +y+"$r"+r+"\\");break;case"+q":r=this.currentParam,y=!1,this.send("P"+ +y+"+r"+r+"\\");break;default:console.error("Unknown DCS prefix: %s.",this.prefix)}this.currentParam=0,this.prefix="",this.state=b.normal}else this.currentParam?this.currentParam+=g:this.prefix||"$"===g||"+"===g?2===this.prefix.length?this.currentParam=g:this.prefix+=g:this.currentParam=g;break;case b.ignore:""!==g&&""!==g||(""===g&&j++,this.state=b.normal)}j++}return this.screen[this.y+this.shift].dirty=!0,this.refresh()},a.prototype.writeln=function(a){return this.write(a+"\r\n")},a.prototype.keyDown=function(a){var b,c;if(a.keyCode>15&&a.keyCode<19)return!0;if(19===a.keyCode)return this.body.classList.add("stopped"),this.out(""),this.ws.shell.close(),!1;if((a.shiftKey||a.ctrlKey)&&45===a.keyCode)return!0;if(a.shiftKey&&a.ctrlKey&&(67===(c=a.keyCode)||86===c))return!0;if(a.altKey&&90===a.keyCode&&!this.skipNextKey)return this.skipNextKey=!0,this.body.classList.add("skip"),d(a);if(this.skipNextKey)return this.skipNextKey=!1,this.body.classList.remove("skip"),!0;switch(a.keyCode){case 8:if(b=a.altKey?"":"",a.shiftKey){b+="\b";break}b+="";break;case 9:if(a.shiftKey){b="";break}b="\t";break;case 13:b="\r";break;case 27:b="";break;case 37:if(this.applicationCursor){b="OD";break}b="";break;case 39:if(this.applicationCursor){b="OC";break}b="";break;case 38:if(this.applicationCursor){b="OA";break}if(a.ctrlKey)return this.scrollDisplay(-1),d(a);b="";break;case 40:if(this.applicationCursor){b="OB";break}if(a.ctrlKey)return this.scrollDisplay(1),d(a);b="";break;case 46:b="[3~";break;case 45:b="[2~";break;case 36:if(this.applicationKeypad){b="OH";break}b="";break;case 35:if(this.applicationKeypad){b="OF";break}b="";break;case 33:if(a.shiftKey){if(a.ctrlKey)break;return this.scrollDisplay(-(this.rows-1)),d(a)}b="[5~";break;case 34:if(a.shiftKey){if(a.ctrlKey)break;return this.scrollDisplay(this.rows-1),d(a)}b="[6~";break;case 112:b="OP";break;case 113:b="OQ";break;case 114:b="OR";break;case 115:b="OS";break;case 116:b="[15~";break;case 117:b="[17~";break;case 118:b="[18~";break;case 119:b="[19~";break;case 120:b="[20~";break;case 121:b="[21~";break;case 122:b="[23~";break;case 123:b="[24~";break;case 145:return this.scrollLock=!this.scrollLock,this.scrollLock?this.body.classList.add("locked"):this.body.classList.remove("locked"),d(a);default:a.ctrlKey?a.keyCode>=65&&a.keyCode<=90?b=String.fromCharCode(a.keyCode-64):32===a.keyCode?b=String.fromCharCode(0):a.keyCode>=51&&a.keyCode<=55?b=String.fromCharCode(a.keyCode-51+27):56===a.keyCode?b=String.fromCharCode(127):219===a.keyCode?b=String.fromCharCode(27):221===a.keyCode&&(b=String.fromCharCode(29)):(a.altKey&&k.call(navigator.platform,"Mac")<0||a.metaKey&&k.call(navigator.platform,"Mac")>=0)&&(a.keyCode>=65&&a.keyCode<=90?b=""+String.fromCharCode(a.keyCode+32):192===a.keyCode?b="`":a.keyCode>=48&&a.keyCode<=57&&(b=""+(a.keyCode-48)))}return a.keyCode>=37&&a.keyCode<=40&&(a.ctrlKey?b=b.slice(0,-1)+"1;5"+b.slice(-1):a.altKey?b=b.slice(0,-1)+"1;3"+b.slice(-1):a.shiftKey&&(b=b.slice(0,-1)+"1;4"+b.slice(-1))),!b||(this.showCursor(),this.send(b),d(a))},a.prototype.setgLevel=function(a){return this.glevel=a,this.charset=this.charsets[a]},a.prototype.setgCharset=function(a,b){if(this.charsets[a]=b,this.glevel===a)return this.charset=b},a.prototype.keyPress=function(a){var b,c;if(this.skipNextKey===!1)return this.skipNextKey=null,!0;if(a.keyCode>15&&a.keyCode<19)return!0;if((a.shiftKey||a.ctrlKey)&&45===a.keyCode)return!0;if(a.shiftKey&&a.ctrlKey&&(67===(c=a.keyCode)||86===c))return!0;if(d(a),a.charCode)b=a.charCode;else if(null==a.which)b=a.keyCode;else{if(0===a.which||0===a.charCode)return!1;b=a.which}return!(!b||a.ctrlKey||a.altKey||a.metaKey)&&(b=String.fromCharCode(b),this.showCursor(),this.send(b),!1)},a.prototype.bell=function(a){if(null==a&&(a="bell"),this.visualBell)return this.body.classList.add(a),this.t_bell=setTimeout(function(b){return function(){return b.body.classList.remove(a)}}(this),this.visualBell)},a.prototype.resize=function(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;if(null==a&&(a=null),null==b&&(b=null),null==c&&(c=!1),o=this.cols,p=this.rows,this.computeCharSize(),u=this.body.clientWidth,d=this.html.clientHeight,0===this.charSize.width||0===this.charSize.height)return void console.error("Null size in refresh");if(this.cols=a||Math.floor(u/this.charSize.width),this.rows=b||Math.floor(d/this.charSize.height),this.cols=Math.max(1,this.cols),this.rows=Math.max(1,this.rows),this.nativeScrollTo(),a||b||o!==this.cols||p!==this.rows){if(c||this.ctl(JSON.stringify({cmd:"size",cols:this.cols,rows:this.rows})),this.cols>o){for(q=this.screen,f=0,g=q.length;fthis.cols;)k.chars.pop();if(this.normal)for(t=this.normal.screen,n=0,j=t.length;nthis.cols;)k.chars.pop()}for(this.setupStops(o),this.term.childElementCount>=this.rows?(this.y+=this.rows-p,e="unshift"):e="push";this.screen.length>this.rows;)this.screen.shift();for(;this.screen.lengththis.rows;)this.normal.screen.shift();for(;this.normal.screen.length=this.rows&&(this.y=this.rows-1),this.y<0&&(this.y=0),this.x>=this.cols&&(this.x=this.cols-1),this.scrollTop=0,this.scrollBottom=this.rows-1,this.refresh(),c||!a&&!b?void 0:this.reset()}},a.prototype.resizeWindowPlease=function(a){var b,c;return b=window.innerWidth-this.body.clientWidth,c=a*this.charSize.width+b,resizeTo(c,window.innerHeight)},a.prototype.setupStops=function(a){var b;for(null!=a?this.tabs[a]||(a=this.prevStop(a)):(this.tabs={},a=0),b=[];a0;);return a>=this.cols?this.cols-1:a<0?0:a},a.prototype.nextStop=function(a){for(null==a&&(a=this.x);!this.tabs[++a]&&a=this.cols?this.cols-1:a<0?0:a},a.prototype.eraseRight=function(a,b){var c;for(c=this.screen[b+this.shift].chars;athis.rows;)this.term.firstChild.remove();return this.emit("clear")},a.prototype.tabSet=function(){return this.tabs[this.x]=!0,this.state=b.normal},a.prototype.cursorUp=function(a){var b;if(b=a[0],b<1&&(b=1),this.y-=b,this.y<0)return this.y=0},a.prototype.cursorDown=function(a){var b;if(b=a[0],b<1&&(b=1),this.y+=b,this.y>=this.rows)return this.y=this.rows-1},a.prototype.cursorForward=function(a){var b;if(b=a[0],b<1&&(b=1),this.x+=b,this.x>=this.cols)return this.x=this.cols-1},a.prototype.cursorBackward=function(a){var b;if(b=a[0],b<1&&(b=1),this.x-=b,this.x<0)return this.x=0},a.prototype.cursorPos=function(a){var b,c;return c=a[0]-1,b=a.length>=2?a[1]-1:0,c<0?c=0:c>=this.rows&&(c=this.rows-1),b<0?b=0:b>=this.cols&&(b=this.cols-1),this.x=b,this.y=c+(this.originMode?this.scrollTop:0)},a.prototype.eraseInDisplay=function(a){var b,c,d,e;switch(a[0]){case 0:for(this.eraseRight(this.x,this.y),b=this.y+1,c=[];b=30&&d<=37?this.curAttr.fg=d-30:d>=40&&d<=47?this.curAttr.bg=d-40:d>=90&&d<=97?(d+=8,this.curAttr.fg=d-90):d>=100&&d<=107?(d+=8,this.curAttr.bg=d-100):0===d?this.curAttr=this.cloneAttr(this.defAttr):1===d?this.curAttr.bold=!0:2===d?this.curAttr.faint=!0:3===d?this.curAttr.italic=!0:4===d?this.curAttr.underline=!0:5===d?this.curAttr.blink=1:6===d?this.curAttr.blink=2:7===d?this.curAttr.inverse=!0:8===d?this.curAttr.invisible=!0:9===d?this.curAttr.crossed=!0:10===d||(21===d?this.curAttr.bold=!1:22===d?(this.curAttr.bold=!1,this.curAttr.faint=!1):23===d?this.curAttr.italic=!1:24===d?this.curAttr.underline=!1:25===d?this.curAttr.blink=!1:27===d?this.curAttr.inverse=!1:28===d?this.curAttr.invisible=!1:29===d?this.curAttr.crossed=!1:39===d?this.curAttr.fg=257:49===d?this.curAttr.bg=256:38===d?2===a[b+1]?(b+=2,this.curAttr.fg="rgb("+a[b]+", "+a[b+1]+", "+a[b+2]+")",b+=2):5===a[b+1]&&(b+=2,this.curAttr.fg=255&a[b]):48===d?2===a[b+1]?(b+=2,this.curAttr.bg="rgb("+a[b]+", "+a[b+1]+", "+a[b+2]+")",b+=2):5===a[b+1]&&(b+=2,this.curAttr.bg=255&a[b]):100===d?(this.curAttr.fg=257,this.curAttr.bg=256):console.error("Unknown SGR attribute: %d.",d)),e.push(b++);return e},a.prototype.deviceStatus=function(a){var b,c;if(this.prefix){if("?"===this.prefix&&(6===a[0]&&this.send("[?"+(this.y+1)+";"+(this.x+1)+"R"),99===a[0]))return null==(null!=(b=navigator.geolocation)?b.getCurrentPosition:void 0)?void this.send("[?R"):null!=(c=navigator.geolocation)?c.getCurrentPosition(function(a){return function(b){return a.send("[?"+b.coords.latitude+";"+b.coords.longitude+"R")}}(this),function(a){return function(b){return a.send("[?R")}}(this)):void 0}else switch(a[0]){case 5:return this.send("");case 6:return this.send("["+(this.y+1)+";"+(this.x+1)+"R")}},a.prototype.insertChars=function(a){var b,c,d;for(c=a[0],c<1&&(c=1),d=this.y,b=this.x;c--&&b=this.rows&&(this.y=this.rows-1),this.x=0},a.prototype.cursorPrecedingLine=function(a){var b;return b=a[0],b<1&&(b=1),this.y-=b,this.y<0&&(this.y=0),this.x=0; -},a.prototype.cursorCharAbsolute=function(a){var b;return b=a[0],b<1&&(b=1),this.x=b-1},a.prototype.insertLines=function(a){var b,c,d,e,f,g;for(d=a[0],d<1&&(d=1);d--;)this.screen.splice(this.y+this.shift,0,this.blankLine(!0)),this.screen.splice(this.scrollBottom+1+this.shift,1);for(g=[],b=c=e=this.y+this.shift,f=this.screen.length-1;e<=f?c<=f:c>=f;b=e<=f?++c:--c)g.push(this.screen[b].dirty=!0);return g},a.prototype.deleteLines=function(a){var b,c,d,e,f,g,h;for(e=a[0],e<1&&(e=1);e--;)this.screen.splice(this.scrollBottom+this.shift,0,this.blankLine(!0)),this.screen.splice(this.y+this.shift,1),this.normal||0!==this.scrollTop||this.scrollBottom!==this.rows-1||(d=this.term.childElementCount-this.rows+this.y+this.shift,this.term.childNodes[d].remove());if(this.normal||0!==this.scrollTop||this.scrollBottom!==this.rows-1){for(h=[],b=c=f=this.y+this.shift,g=this.screen.length-1;f<=g?c<=g:c>=g;b=f<=g?++c:--c)h.push(this.screen[b].dirty=!0);return h}},a.prototype.deleteChars=function(a){var b;for(b=a[0],b<1&&(b=1);b--;)this.screen[this.y+this.shift].chars.splice(this.x,1),this.screen[this.y+this.shift].chars.push(this.eraseAttr());return this.resetLine(this.screen[this.y+this.shift])},a.prototype.eraseChars=function(a){var b,c;for(c=a[0],c<1&&(c=1),b=this.x;c--&&b=this.cols)return this.x=this.cols-1},a.prototype.HPositionRelative=function(a){var b;if(b=a[0],b<1&&(b=1),this.x+=b,this.x>=this.cols)return this.x=this.cols-1},a.prototype.sendDeviceAttributes=function(a){if(!(a[0]>0))if(this.prefix){if(">"===this.prefix){if(this.isterm("xterm"))return this.send("[>0;276;0c");if(this.isterm("rxvt-unicode"))return this.send("[>85;95;0c");if(this.isterm("linux"))return this.send(a[0]+"c");if(this.isterm("screen"))return this.send("[>83;40003;0c")}}else{if(this.isterm("xterm")||this.isterm("rxvt-unicode")||this.isterm("screen"))return this.send("[?1;2c");if(this.isterm("linux"))return this.send("[?6c")}},a.prototype.linePosAbsolute=function(a){var b;if(b=a[0],b<1&&(b=1),this.y=b-1,this.y>=this.rows)return this.y=this.rows-1},a.prototype.VPositionRelative=function(a){var b;if(b=a[0],b<1&&(b=1),this.y+=b,this.y>=this.rows)return this.y=this.rows-1},a.prototype.HVPosition=function(a){if(a[0]<1&&(a[0]=1),a[1]<1&&(a[1]=1),this.y=a[0]-1,this.y>=this.rows&&(this.y=this.rows-1),this.x=a[1]-1,this.x>=this.cols)return this.x=this.cols-1},a.prototype.setMode=function(b){var c,d,e;if("object"!=typeof b)if(this.prefix){if("?"===this.prefix)switch(b){case 1:return this.applicationCursor=!0;case 2:return this.setgCharset(0,a.prototype.charsets.US),this.setgCharset(1,a.prototype.charsets.US),this.setgCharset(2,a.prototype.charsets.US),this.setgCharset(3,a.prototype.charsets.US);case 3:return this.savedCols=this.cols,this.resize(132,this.rows),this.resizeWindowPlease(132),this.reset();case 6:return this.originMode=!0;case 7:return this.autowrap=!0;case 66:return this.applicationKeypad=!0;case 77:return this.horizontalWrap=!0;case 9:case 1e3:case 1002:case 1003:return this.x10Mouse=9===b,this.vt200Mouse=1e3===b,this.normalMouse=b>1e3,this.mouseEvents=!0,this.body.style.cursor="pointer";case 1004:return this.sendFocus=!0;case 1005:return this.utfMouse=!0;case 1006:return this.sgrMouse=!0;case 1015:return this.urxvtMouse=!0;case 25:return this.cursorHidden=!1;case 1049:case 47:case 1047:if(!this.normal)return e={screen:this.screen,x:this.x,y:this.y,shift:this.shift,scrollTop:this.scrollTop,scrollBottom:this.scrollBottom,tabs:this.tabs,curAttr:this.curAttr},this.reset(),this.normal=e,this.showCursor()}}else switch(b){case 4:this.insertMode=!0;break;case 20:this.convertEol=!0}else for(d=b.length,c=0;c=f;b=e<=f?++c:--c)g.push(this.screen[b+this.shift].dirty=!0);return g},a.prototype.scrollDown=function(a){var b,c,d,e,f,g;for(d=a[0]||1;d--;)this.screen.splice(this.scrollBottom,1),this.screen.splice(this.scrollTop,0,this.blankLine());for(g=[],b=c=e=this.scrollTop,f=this.scrollBottom;e<=f?c<=f:c>=f;b=e<=f?++c:--c)g.push(this.screen[b+this.shift].dirty=!0);return g},a.prototype.initMouseTracking=function(a){},a.prototype.resetTitleModes=function(a){},a.prototype.cursorBackwardTab=function(a){var b,c;for(b=a[0]||1,c=[];b--;)c.push(this.x=this.prevStop());return c},a.prototype.repeatPrecedingCharacter=function(a){var b,c,d;for(d=a[0]||1,c=this.screen[this.y+this.shift].chars,b=c[this.x-1]||this.defAttr;d--;)c[this.x++]=b;return this.screen[this.y+this.shift].dirty=!0},a.prototype.tabClear=function(a){var b;return b=a[0],b<=0?delete this.tabs[this.x]:3===b?this.tabs={}:void 0},a.prototype.mediaCopy=function(a){},a.prototype.setResources=function(a){},a.prototype.disableModifiers=function(a){},a.prototype.setPointerMode=function(a){},a.prototype.softReset=function(a){return this.cursorHidden=!1,this.insertMode=!1,this.originMode=!1,this.autowrap=!0,this.applicationKeypad=!1,this.applicationCursor=!1,this.scrollTop=0,this.scrollBottom=this.rows-1,this.curAttr=this.defAttr,this.x=this.y=0,this.charset=null,this.glevel=0,this.charsets=[null]},a.prototype.requestAnsiMode=function(a){},a.prototype.requestPrivateMode=function(a){},a.prototype.setConformanceLevel=function(a){},a.prototype.loadLEDs=function(a){},a.prototype.setCursorStyle=function(a){},a.prototype.setCharProtectionAttr=function(a){},a.prototype.restorePrivateValues=function(a){},a.prototype.setAttrInRectangle=function(a){var b,c,d,e,f,g,h,i;for(i=a[0],e=a[1],c=a[2],g=a[3],b=a[4],h=[];i0},a.prototype.eraseRectangle=function(a){var b,c,d,e,f,g,h;for(h=a[0],d=a[1],b=a[2],f=a[3],g=[];h6e4?window.open("","_self").close():void 0},l=function(){return setTimeout(function(){if(!g)return j.shell=new WebSocket(q+"/ws"+k),h()},100)},o=function(a){if(n)return n.write(a)},p=function(a){return setTimeout(o,1,a.data)},b=function(a){var b;if(b=JSON.parse(a.data),"size"===b.cmd)return n.resize(b.cols,b.rows,!0)},h=function(){return j.shell.addEventListener("open",i),j.shell.addEventListener("message",p),j.shell.addEventListener("error",d),j.shell.addEventListener("close",l)},e=function(){return j.ctl.addEventListener("open",i),j.ctl.addEventListener("message",b),j.ctl.addEventListener("error",d),j.ctl.addEventListener("close",a)},h(),e(),addEventListener("beforeunload",function(){if(!g)return"This will exit the terminal session"})}),d=function(a){return a.preventDefault&&a.preventDefault(),a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0,!1},i=0,b={normal:i++,escaped:i++,csi:i++,osc:i++,charset:i++,dcs:i++,ignore:i++},c=function(){function a(a,b,c){var d;this.parent=a,this.out=b,this.ctl=null!=c?c:function(){},this.document=this.parent.ownerDocument,this.html=this.document.getElementsByTagName("html")[0],this.body=this.document.getElementsByTagName("body")[0],this.term=this.document.getElementById("term"),this.forceWidth="yes"===this.body.getAttribute("data-force-unicode-width"),this.inputHelper=this.document.getElementById("input-helper"),this.inputView=this.document.getElementById("input-view"),this.body.className="terminal focus",this.body.style.outline="none",this.body.setAttribute("tabindex",0),this.body.setAttribute("spellcheck","false"),this.inputHelper.setAttribute("tabindex",0),this.inputHelper.setAttribute("spellcheck","false"),d=this.document.createElement("div"),d.className="line",this.term.appendChild(d),this.computeCharSize(),this.cols=Math.floor(this.body.clientWidth/this.charSize.width),this.rows=Math.floor(window.innerHeight/this.charSize.height),this.visualBell=100,this.convertEol=!1,this.termName="xterm",this.cursorBlink=!0,this.cursorState=0,this.inComposition=!1,this.compositionText="",this.resetVars(),this.focus(),this.startBlink(),this.inputHelper.addEventListener("compositionstart",this.compositionStart.bind(this)),this.inputHelper.addEventListener("compositionupdate",this.compositionUpdate.bind(this)),this.inputHelper.addEventListener("compositionend",this.compositionEnd.bind(this)),this.inputHelper.addEventListener("keydown",this.keyDown.bind(this)),this.inputHelper.addEventListener("keypress",this.keyPress.bind(this)),addEventListener("keydown",this.keyDown.bind(this)),addEventListener("keypress",this.keyPress.bind(this)),addEventListener("keyup",function(a){return function(){return a.inputHelper.focus()}}(this)),addEventListener("focus",this.focus.bind(this)),addEventListener("blur",this.blur.bind(this)),addEventListener("resize",function(a){return function(){return a.resize()}}(this)),this.body.addEventListener("load",function(a){return function(){return a.nativeScrollTo()}}(this),!0),this.initmouse(),addEventListener("load",function(a){return function(){return a.resize()}}(this)),this.emit("load"),this.active=null}return a.hooks={},a.on=function(b,c){return null==a.hooks[b]&&(a.hooks[b]=[]),a.hooks[b].push(c)},a.off=function(b,c){return null==a.hooks[b]&&(a.hooks[b]=[]),a.hooks[b].pop(c)},a.prototype.emit=function(b,c){var d,e,f,g,h;for(null==a.hooks[b]&&(a.hooks[b]=[]),g=a.hooks[b],h=[],e=0,f=g.length;e=c;d=0<=c?++a:--a)this.screen.push(this.blankLine(!1,!1));return this.setupStops(),this.skipNextKey=null},a.prototype.computeCharSize=function(){var a,b;return b=document.createElement("span"),b.textContent="0123456789",a=this.term.firstChild,a.appendChild(b),this.charSize={width:b.getBoundingClientRect().width/10,height:a.getBoundingClientRect().height},a.removeChild(b)},a.prototype.eraseAttr=function(){var a;return a=this.cloneAttr(this.defAttr),a.bg=this.curAttr.bg,a},a.prototype.focus=function(){var a;return a=this.scrollLock,this.scrollLock=!0,this.sendFocus&&this.send(""),this.showCursor(),this.body.classList.add("focus"),this.body.classList.remove("blur"),this.inputHelper.focus(),this.resize(),this.scrollLock=a},a.prototype.blur=function(){var a;return a=this.scrollLock,this.scrollLock=!0,this.cursorState=1,this.screen[this.y+this.shift].dirty=!0,this.refresh(),this.sendFocus&&this.send(""),this.body.classList.add("blur"),this.body.classList.remove("focus"),this.scrollLock=a},a.prototype.initmouse=function(){var a,b,c,e,f,g,h;return e=32,f=function(a){var d,f;if(d=b(a),f=c(a))return g(d,f,a.type),e=d},h=function(a){var b,d;if(b=e,d=c(a))return b+=32,g(b,d,a.type)},a=function(a){return function(b,c){return a.utfMouse?2047===c?b.push(0):c<127?b.push(c):(c>2047&&(c=2047),b.push(192|c>>6),b.push(128|63&c)):255===c?b.push(0):(c>127&&(c=127),b.push(c))}}(this),g=function(b){return function(c,d,e){var f;return b.urxvtMouse?(d.x-=32,d.y-=32,d.x++,d.y++,void b.send("["+c+";"+d.x+";"+d.y+"M")):b.sgrMouse?(d.x-=32,d.y-=32,c-=32,void b.send("[<"+c+";"+d.x+";"+d.y+("mouseup"===e?"m":"M"))):(f=[],a(f,c),a(f,d.x),a(f,d.y),b.send(""+String.fromCharCode.apply(String,f)))}}(this),b=function(a){return function(b){var c,d,e,f,g;switch(b.type){case"mousedown":c=null!=b.button?+b.button:null!=b.which?b.which-1:null;break;case"mouseup":c=3;break;case"wheel":c=b.deltaY<0?64:65}return g=b.shiftKey?4:0,e=b.metaKey?8:0,d=b.ctrlKey?16:0,f=g|e|d,a.vt200Mouse?f&=d:a.normalMouse||(f=0),32+(f<<2)+c}}(this),c=function(a){return function(b){var c,d,e,f;return e=b.pageX,f=b.pageY-window.scrollY,d=a.body.clientWidth,c=window.innerHeight,e=Math.ceil(e/d*a.cols),f=Math.ceil(f/c*a.rows),e<0&&(e=0),e>a.cols&&(e=a.cols),f<0&&(f=0),f>a.rows&&(f=a.rows),e+=32,f+=32,{x:e,y:f,type:b.type}}}(this),addEventListener("contextmenu",function(a){return function(b){if(a.mouseEvents)return d(b)}}(this)),addEventListener("mousedown",function(a){return function(b){var c,e;if(a.mouseEvents)return f(b),c=h.bind(a),addEventListener("mousemove",c),a.x10Mouse||addEventListener("mouseup",e=function(a){return f(a),removeEventListener("mousemove",c),removeEventListener("mouseup",e),d(a)}),d(b)}}(this)),addEventListener("wheel",function(a){return function(b){if(a.mouseEvents){if(a.x10Mouse)return;return f(b),d(b)}}}(this))},a.prototype.getClasses=function(a){var b,c,d;return b=[],d=[],a.bold&&b.push("bold"),a.underline&&b.push("underline"),1===a.blink&&b.push("blink"),2===a.blink&&b.push("blink-fast"),a.inverse&&b.push("reverse-video"),a.invisible&&b.push("invisible"),a.italic&&b.push("italic"),a.faint&&b.push("faint"),a.crossed&&b.push("crossed"),"number"==typeof a.fg?(c=a.fg,a.bold&&c<8&&(c+=8),b.push("fg-color-"+c)):"string"==typeof a.fg&&d.push("color: "+a.fg),"number"==typeof a.bg?b.push("bg-color-"+a.bg):"string"==typeof a.bg&&d.push("background-color: "+a.bg),[b,d]},a.prototype.isCJK=function(a){return"一"<=a&&a<="鿿"||"぀"<=a&&a<="ヿ"||"ㇰ"<=a&&a<="ㇿ"||"㆐"<=a&&a<="㆟"||"㌁"<=a&&a<="㍖"||"가"<=a&&a<="퟿"||" "<=a&&a<="〿"||"＀"<=a&&a<="⦆"||"¢"<=a&&a<="₩"},a.prototype.charToDom=function(a,b,c){var d,e,f,g,h;if(!a.placeholder){if(a.html)return a.html;switch(b=b||this.cloneAttr(this.defAttr),d=a.ch,e="",this.equalAttr(a,b)||(this.equalAttr(b,this.defAttr)||(e+=""),this.equalAttr(a,this.defAttr)||(g=this.getClasses(a),f=g[0],h=g[1],e+=''),d){case"&":e+="&";break;case"<":e+="<";break;case">":e+=">";break;case" ":e+='';break;default:e+=d<=" "?" ":this.forceWidth||this.isCJK(d)?d<="~"?d:this.isCJK(d)?''+d+"":''+d+"":d}return c&&(e+=""),e}},a.prototype.lineToDom=function(a,b,c){var d,e,f,g,h,i;for(c&&(d=this.x),h=[],i=f=0,g=this.cols;0<=g?f<=g:f>=g;i=0<=g?++f:--f)i!==this.cols?h.push(this.charToDom(b.chars[i],b.chars[i-1],i===d)):(e="",this.equalAttr(b.chars[i-1],this.defAttr)||(e+=""),b.wrap&&(e+="⏎"),b.extra?h.push(e+=''+b.extra+""):h.push(void 0));return h},a.prototype.screenToDom=function(a){var b,c,d,e,f,g,h,i;for(g=this.screen,h=[],i=d=0,e=g.length;d=d;a=c<=d?++b:--b)e.push(this.screen[a+this.shift].dirty=!0);return e}return this.screen.push(this.blankLine()),this.shift++},a.prototype.unscroll=function(){var a,b,c,d,e;for(this.screen.splice(this.shift+this.scrollTop,0,this.blankLine(!0)),this.screen.splice(this.shift+this.scrollBottom+1,1),e=[],a=b=c=this.scrollTop,d=this.scrollBottom;c<=d?b<=d:b>=d;a=c<=d?++b:--b)e.push(this.screen[a+this.shift].dirty=!0);return e},a.prototype.nativeScrollTo=function(a){if(null==a&&(a=2e9),!this.scrollLock)return window.scrollTo(0,a)},a.prototype.scrollDisplay=function(a){return this.nativeScrollTo(window.scrollY+a*this.charSize.height)},a.prototype.nextLine=function(){if(this.y++,this.y>this.scrollBottom)return this.y--,this.scroll()},a.prototype.prevLine=function(){if(this.y--,this.y=this.cols&&this.x--,this.x>0&&this.x--;break;case"\t":this.x=this.nextStop();break;case"":this.setgLevel(1);break;case"":this.setgLevel(0);break;case"":this.state=b.escaped;break;default:if("̀"<=g&&g<="ͯ"||"᪰"<=g&&g<="᫿"||"᷀"<=g&&g<="᷿"||"⃐"<=g&&g<="⃿"||"︠"<=g&&g<="︯"){if(z=this.x,A=this.y+this.shift,this.x>0)z-=1;else{if(!(this.y>0))break;A-=1,z=this.cols-1}this.screen[A].chars[z].ch+=g;break}g>=" "&&((null!=(s=this.charset)?s[g]:void 0)&&(g=this.charset[g]),this.x>=this.cols&&(this.horizontalWrap?this.screen[this.y+this.shift].extra+=g:(this.autowrap&&(this.screen[this.y+this.shift].wrap=!0,this.nextLine()),this.x=0)),this.putChar(g),this.x++,this.isCJK(g)&&(this.putChar(" ",!0),this.x++))}break;case b.escaped:switch(g){case"[":this.params=[],this.currentParam=0,this.state=b.csi;break;case"]":this.params=[],this.currentParam=0,this.state=b.osc;break;case"P":this.params=[],this.currentParam=0,this.state=b.dcs;break;case"_":this.state=b.ignore;break;case"^":this.state=b.ignore;break;case"c":this.clearScrollback(),this.reset();break;case"E":this.x=0,this.index();break;case"D":this.index();break;case"M":this.reverseIndex();break;case"%":this.setgLevel(0),this.setgCharset(0,a.prototype.charsets.US),this.state=b.normal,j++;break;case"(":case")":case"*":case"+":case"-":case".":switch(g){case"(":this.gcharset=0;break;case")":case"-":this.gcharset=1;break;case"*":case".":this.gcharset=2;break;case"+":this.gcharset=3}this.state=b.charset;break;case"/":this.gcharset=3,this.state=b.charset,j--;break;case"n":this.setgLevel(2);break;case"o":this.setgLevel(3);break;case"|":this.setgLevel(3);break;case"}":this.setgLevel(2);break;case"~":this.setgLevel(1);break;case"7":this.saveCursor(),this.state=b.normal;break;case"8":this.restoreCursor(),this.state=b.normal;break;case"#":switch(this.state=b.normal,j++,q=c.charAt(j)){case"3":break;case"4":break;case"5":break;case"6":break;case"8":for(t=this.screen,k=0,m=t.length;k=u;f=0<=u?++o:--o)n.chars[f]=this.cloneAttr(this.curAttr,"E");this.x=this.y=0}break;case"H":this.tabSet();break;case"=":this.applicationKeypad=!0,this.state=b.normal;break;case">":this.applicationKeypad=!1,this.state=b.normal;break;default:this.state=b.normal,console.log("Unknown ESC control:",g)}break;case b.charset:switch(g){case"0":i=a.prototype.charsets.SCLD;break;case"A":i=a.prototype.charsets.UK;break;case"B":i=a.prototype.charsets.US;break;case"4":i=a.prototype.charsets.Dutch;break;case"C":case"5":i=a.prototype.charsets.Finnish;break;case"R":i=a.prototype.charsets.French;break;case"Q":i=a.prototype.charsets.FrenchCanadian;break;case"K":i=a.prototype.charsets.German;break;case"Y":i=a.prototype.charsets.Italian;break;case"E":case"6":i=a.prototype.charsets.NorwegianDanish;break;case"Z":i=a.prototype.charsets.Spanish;break;case"H":case"7":i=a.prototype.charsets.Swedish;break;case"=":i=a.prototype.charsets.Swiss;break;case"/":i=a.prototype.charsets.ISOLatin,j++;break;default:i=a.prototype.charsets.US}this.setgCharset(this.gcharset,i),this.gcharset=null,this.state=b.normal;break;case b.osc:if(""===g||""===g){switch(""===g&&j++,this.params.push(this.currentParam),this.params[0]){case 0:case 1:case 2:this.params[1]&&(this.title=this.params[1]+" - ƸӜƷ butterfly",this.handleTitle(this.title))}this.params=[],this.currentParam=0,this.state=b.normal}else this.params.length?this.currentParam+=g:g>="0"&&g<="9"?this.currentParam=10*this.currentParam+g.charCodeAt(0)-48:";"===g&&(this.params.push(this.currentParam),this.currentParam="");break;case b.csi:if("?"===g||">"===g||"!"===g){this.prefix=g;break}if(g>="0"&&g<="9"){this.currentParam=10*this.currentParam+g.charCodeAt(0)-48;break}if("$"===g||'"'===g||" "===g||"'"===g)break;if(g<=" "||g>="~"){"\b"===g&&(this.currentParam=this.currentParam/10&1),"\r"===g&&(this.x=0),["\n","\x0B","\f"].indexOf(g)>=0&&(this.screen[this.y+this.shift].dirty=!0,this.nextLine());break}if(this.params.push(this.currentParam),this.currentParam=0,";"===g)break;switch(this.state=b.normal,g){case"A":this.cursorUp(this.params);break;case"B":this.cursorDown(this.params);break;case"C":this.cursorForward(this.params);break;case"D":this.cursorBackward(this.params);break;case"H":this.cursorPos(this.params);break;case"J":this.eraseInDisplay(this.params);break;case"K":this.eraseInLine(this.params);break;case"m":this.prefix||this.charAttributes(this.params);break;case"n":this.deviceStatus(this.params);break;case"@":this.insertChars(this.params);break;case"E":this.cursorNextLine(this.params);break;case"F":this.cursorPrecedingLine(this.params);break;case"G":this.cursorCharAbsolute(this.params);break;case"L":this.insertLines(this.params);break;case"M":this.deleteLines(this.params);break;case"P":this.deleteChars(this.params);break;case"X":this.eraseChars(this.params);break;case"`":this.charPosAbsolute(this.params);break;case"a":this.HPositionRelative(this.params);break;case"c":this.sendDeviceAttributes(this.params);break;case"d":this.linePosAbsolute(this.params);break;case"e":this.VPositionRelative(this.params);break;case"f":this.HVPosition(this.params);break;case"h":this.setMode(this.params);break;case"l":this.resetMode(this.params);break;case"r":this.setScrollRegion(this.params);break;case"s":this.saveCursor(this.params);break;case"u":this.restoreCursor(this.params);break;case"I":this.cursorForwardTab(this.params);break;case"S":this.scrollUp(this.params);break;case"T":this.params.length<2&&!this.prefix&&this.scrollDown(this.params);break;case"Z":this.cursorBackwardTab(this.params);break;case"b":this.repeatPrecedingCharacter(this.params);break;case"g":this.tabClear(this.params);break;case"p":"!"===this.prefix&&this.softReset(this.params);break;default:console.error("Unknown CSI code: %s (%d).",g,g.charCodeAt(0))}this.prefix="";break;case b.dcs:if(""===g||""===g){switch(""===g&&j++,this.prefix){case"":if(r=this.currentParam,";"!==r[0]){console.error("Unknown DECUDK: "+r);break}if(r=r.slice(1),v=r.split("|",2),x=v[0],h=v[1],!h){console.error("No type for inline DECUDK: "+r);break}switch(x){case"HTML":w=html_sanitize(h,function(a){return a}),d=this.cloneAttr(this.curAttr),d.html='
'+w+"
",this.screen[this.y+this.shift].chars[this.x]=d,this.resetLine(this.screen[this.y+this.shift]),this.nextLine();break;case"IMAGE":h=encodeURI(h),h.indexOf(";")?(p=h.slice(0,h.indexOf(";")),e=h.slice(h.indexOf(";")+1)):(p="image",e=h),d=this.cloneAttr(this.curAttr),d.html='',this.screen[this.y+this.shift].chars[this.x]=d,this.resetLine(this.screen[this.y+this.shift]);break;case"PROMPT":this.send(h);break;case"TEXT":l+=h.length,c=c.slice(0,j+1)+h+c.slice(j+1);break;default:console.error("Unknown type "+x+" for DECUDK")}break;case"$q":switch(r=this.currentParam,y=!1,r){case'"q':r='0"q';break;case'"p':r='61"p';break;case"r":r=""+(this.scrollTop+1)+";"+(this.scrollBottom+1)+"r";break;case"m":r="0m";break;default:console.error("Unknown DCS Pt: %s.",r),r=""}this.send("P"+ +y+"$r"+r+"\\");break;case"+q":r=this.currentParam,y=!1,this.send("P"+ +y+"+r"+r+"\\");break;default:console.error("Unknown DCS prefix: %s.",this.prefix)}this.currentParam=0,this.prefix="",this.state=b.normal}else this.currentParam?this.currentParam+=g:this.prefix||"$"===g||"+"===g?2===this.prefix.length?this.currentParam=g:this.prefix+=g:this.currentParam=g;break;case b.ignore:""!==g&&""!==g||(""===g&&j++,this.state=b.normal)}j++}return this.screen[this.y+this.shift].dirty=!0,this.refresh()},a.prototype.writeln=function(a){return this.write(a+"\r\n")},a.prototype.updateInputViews=function(){var a;return a=this.cursor.getBoundingClientRect(),this.inputView.style.left=a.left+"px",this.inputView.style.top=a.top+"px",this.inputHelper.style.left=a.left+"px",this.inputHelper.style.top=a.top+"px",this.inputHelper.value=""},a.prototype.compositionStart=function(a){return a.preventDefault(),a.stopPropagation(),this.updateInputViews(),this.inputView.className="",this.inputView.innerText="",this.cursor.style.visibility="hidden",this.inComposition=!0,this.compositionText="",!1},a.prototype.compositionUpdate=function(a){return a.preventDefault(),a.stopPropagation(),this.compositionText=a.data,this.inputView.innerText=this.compositionText,!1},a.prototype.compositionEnd=function(a){return a.preventDefault(),a.stopPropagation(),this.finishComposition(),!1},a.prototype.finishComposition=function(){return this.inComposition=!1,this.showCursor(),this.inputHelper.value="",this.inputView.className="hidden",this.send(this.compositionText),this.compositionText="",this.inputHelper.focus()},a.prototype.keyDown=function(a){var b,c;if(this.inComposition){if(229===a.keyCode)return!1;if(16===a.keyCode||17===a.keyCode||18===a.keyCode)return!1;this.finishComposition()}if(229===a.keyCode)return a.preventDefault(),a.stopPropagation(),setTimeout(function(a){return function(){if(!(a.inComposition||a.inputHelper.value.length>1))return a.send(a.inputHelper.value)}}(this),0),!1;if(a.keyCode>15&&a.keyCode<19)return!0;if(19===a.keyCode)return this.body.classList.add("stopped"),this.out(""),this.ws.shell.close(),!1;if((a.shiftKey||a.ctrlKey)&&45===a.keyCode)return!0;if(a.shiftKey&&a.ctrlKey&&(67===(c=a.keyCode)||86===c))return this.body.contentEditable=!0,!0;if(a.altKey&&90===a.keyCode&&!this.skipNextKey)return this.skipNextKey=!0,this.body.classList.add("skip"),d(a);if(this.skipNextKey)return this.skipNextKey=!1,this.body.classList.remove("skip"),!0;switch(a.keyCode){case 8:if(b=a.altKey?"":"",a.shiftKey){b+="\b";break}b+="";break;case 9:if(a.shiftKey){b="";break}b="\t";break;case 13:b="\r";break;case 27:b="";break;case 37:if(this.applicationCursor){b="OD";break}b="";break;case 39:if(this.applicationCursor){b="OC";break}b="";break;case 38:if(this.applicationCursor){b="OA";break}if(a.ctrlKey)return this.scrollDisplay(-1),d(a);b="";break;case 40:if(this.applicationCursor){b="OB";break}if(a.ctrlKey)return this.scrollDisplay(1),d(a);b="";break;case 46:b="[3~";break;case 45:b="[2~";break;case 36:if(this.applicationKeypad){b="OH";break}b="";break;case 35:if(this.applicationKeypad){b="OF";break}b="";break;case 33:if(a.shiftKey){if(a.ctrlKey)break;return this.scrollDisplay(-(this.rows-1)),d(a)}b="[5~";break;case 34:if(a.shiftKey){if(a.ctrlKey)break;return this.scrollDisplay(this.rows-1),d(a)}b="[6~";break;case 112:b="OP";break;case 113:b="OQ";break;case 114:b="OR";break;case 115:b="OS";break;case 116:b="[15~";break;case 117:b="[17~";break;case 118:b="[18~";break;case 119:b="[19~";break;case 120:b="[20~";break;case 121:b="[21~";break;case 122:b="[23~";break;case 123:b="[24~";break;case 145:return this.scrollLock=!this.scrollLock,this.scrollLock?this.body.classList.add("locked"):this.body.classList.remove("locked"),d(a);default:a.ctrlKey?a.keyCode>=65&&a.keyCode<=90?b=String.fromCharCode(a.keyCode-64):32===a.keyCode?b=String.fromCharCode(0):a.keyCode>=51&&a.keyCode<=55?b=String.fromCharCode(a.keyCode-51+27):56===a.keyCode?b=String.fromCharCode(127):219===a.keyCode?b=String.fromCharCode(27):221===a.keyCode&&(b=String.fromCharCode(29)):(a.altKey&&k.call(navigator.platform,"Mac")<0||a.metaKey&&k.call(navigator.platform,"Mac")>=0)&&(a.keyCode>=65&&a.keyCode<=90?b=""+String.fromCharCode(a.keyCode+32):192===a.keyCode?b="`":a.keyCode>=48&&a.keyCode<=57&&(b=""+(a.keyCode-48)))}return a.keyCode>=37&&a.keyCode<=40&&(a.ctrlKey?b=b.slice(0,-1)+"1;5"+b.slice(-1):a.altKey?b=b.slice(0,-1)+"1;3"+b.slice(-1):a.shiftKey&&(b=b.slice(0,-1)+"1;4"+b.slice(-1))),!b||(this.showCursor(),this.send(b),d(a))},a.prototype.setgLevel=function(a){return this.glevel=a,this.charset=this.charsets[a]},a.prototype.setgCharset=function(a,b){if(this.charsets[a]=b,this.glevel===a)return this.charset=b},a.prototype.keyPress=function(a){var b,c;if(this.skipNextKey===!1)return this.skipNextKey=null,!0;if(a.keyCode>15&&a.keyCode<19)return!0;if((a.shiftKey||a.ctrlKey)&&45===a.keyCode)return!0;if(a.shiftKey&&a.ctrlKey&&(67===(c=a.keyCode)||86===c))return!0;if(d(a),a.charCode)b=a.charCode;else if(null==a.which)b=a.keyCode;else{if(0===a.which||0===a.charCode)return!1;b=a.which}return!(!b||a.ctrlKey||a.altKey||a.metaKey)&&(b=String.fromCharCode(b),this.showCursor(),this.send(b),!1)},a.prototype.bell=function(a){if(null==a&&(a="bell"),this.visualBell)return this.body.classList.add(a),this.t_bell=setTimeout(function(b){return function(){return b.body.classList.remove(a)}}(this),this.visualBell)},a.prototype.resize=function(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;if(null==a&&(a=null),null==b&&(b=null),null==c&&(c=!1),o=this.cols,p=this.rows,this.computeCharSize(),u=this.body.clientWidth,d=this.html.clientHeight,0===this.charSize.width||0===this.charSize.height)return void console.error("Null size in refresh");if(this.cols=a||Math.floor(u/this.charSize.width),this.rows=b||Math.floor(d/this.charSize.height),this.cols=Math.max(1,this.cols),this.rows=Math.max(1,this.rows),this.nativeScrollTo(),a||b||o!==this.cols||p!==this.rows){if(c||this.ctl(JSON.stringify({cmd:"size",cols:this.cols,rows:this.rows})),this.cols>o){for(q=this.screen,f=0,g=q.length;fthis.cols;)k.chars.pop();if(this.normal)for(t=this.normal.screen,n=0,j=t.length;nthis.cols;)k.chars.pop()}for(this.setupStops(o),this.term.childElementCount>=this.rows?(this.y+=this.rows-p,e="unshift"):e="push";this.screen.length>this.rows;)this.screen.shift();for(;this.screen.lengththis.rows;)this.normal.screen.shift();for(;this.normal.screen.length=this.rows&&(this.y=this.rows-1),this.y<0&&(this.y=0),this.x>=this.cols&&(this.x=this.cols-1),this.scrollTop=0,this.scrollBottom=this.rows-1,this.refresh(),c||!a&&!b?void 0:this.reset()}},a.prototype.resizeWindowPlease=function(a){var b,c;return b=window.innerWidth-this.body.clientWidth,c=a*this.charSize.width+b,resizeTo(c,window.innerHeight)},a.prototype.setupStops=function(a){var b;for(null!=a?this.tabs[a]||(a=this.prevStop(a)):(this.tabs={},a=0),b=[];a0;);return a>=this.cols?this.cols-1:a<0?0:a},a.prototype.nextStop=function(a){for(null==a&&(a=this.x);!this.tabs[++a]&&a=this.cols?this.cols-1:a<0?0:a},a.prototype.eraseRight=function(a,b){var c;for(c=this.screen[b+this.shift].chars;athis.rows;)this.term.firstChild.remove();return this.emit("clear")},a.prototype.tabSet=function(){return this.tabs[this.x]=!0,this.state=b.normal},a.prototype.cursorUp=function(a){var b;if(b=a[0],b<1&&(b=1),this.y-=b,this.y<0)return this.y=0},a.prototype.cursorDown=function(a){var b;if(b=a[0],b<1&&(b=1),this.y+=b,this.y>=this.rows)return this.y=this.rows-1},a.prototype.cursorForward=function(a){var b;if(b=a[0],b<1&&(b=1),this.x+=b,this.x>=this.cols)return this.x=this.cols-1},a.prototype.cursorBackward=function(a){var b;if(b=a[0],b<1&&(b=1),this.x-=b,this.x<0)return this.x=0},a.prototype.cursorPos=function(a){var b,c;return c=a[0]-1,b=a.length>=2?a[1]-1:0,c<0?c=0:c>=this.rows&&(c=this.rows-1),b<0?b=0:b>=this.cols&&(b=this.cols-1),this.x=b,this.y=c+(this.originMode?this.scrollTop:0)},a.prototype.eraseInDisplay=function(a){var b,c,d,e;switch(a[0]){case 0:for(this.eraseRight(this.x,this.y),b=this.y+1,c=[];b=30&&d<=37?this.curAttr.fg=d-30:d>=40&&d<=47?this.curAttr.bg=d-40:d>=90&&d<=97?(d+=8,this.curAttr.fg=d-90):d>=100&&d<=107?(d+=8,this.curAttr.bg=d-100):0===d?this.curAttr=this.cloneAttr(this.defAttr):1===d?this.curAttr.bold=!0:2===d?this.curAttr.faint=!0:3===d?this.curAttr.italic=!0:4===d?this.curAttr.underline=!0:5===d?this.curAttr.blink=1:6===d?this.curAttr.blink=2:7===d?this.curAttr.inverse=!0:8===d?this.curAttr.invisible=!0:9===d?this.curAttr.crossed=!0:10===d||(21===d?this.curAttr.bold=!1:22===d?(this.curAttr.bold=!1,this.curAttr.faint=!1):23===d?this.curAttr.italic=!1:24===d?this.curAttr.underline=!1:25===d?this.curAttr.blink=!1:27===d?this.curAttr.inverse=!1:28===d?this.curAttr.invisible=!1:29===d?this.curAttr.crossed=!1:39===d?this.curAttr.fg=257:49===d?this.curAttr.bg=256:38===d?2===a[b+1]?(b+=2,this.curAttr.fg="rgb("+a[b]+", "+a[b+1]+", "+a[b+2]+")",b+=2):5===a[b+1]&&(b+=2,this.curAttr.fg=255&a[b]):48===d?2===a[b+1]?(b+=2,this.curAttr.bg="rgb("+a[b]+", "+a[b+1]+", "+a[b+2]+")",b+=2):5===a[b+1]&&(b+=2,this.curAttr.bg=255&a[b]):100===d?(this.curAttr.fg=257,this.curAttr.bg=256):console.error("Unknown SGR attribute: %d.",d)),e.push(b++);return e},a.prototype.deviceStatus=function(a){var b,c;if(this.prefix){if("?"===this.prefix&&(6===a[0]&&this.send("[?"+(this.y+1)+";"+(this.x+1)+"R"),99===a[0]))return null==(null!=(b=navigator.geolocation)?b.getCurrentPosition:void 0)?void this.send("[?R"):null!=(c=navigator.geolocation)?c.getCurrentPosition(function(a){return function(b){return a.send("[?"+b.coords.latitude+";"+b.coords.longitude+"R")}}(this),function(a){return function(b){return a.send("[?R")}}(this)):void 0}else switch(a[0]){case 5:return this.send("");case 6:return this.send("["+(this.y+1)+";"+(this.x+1)+"R")}},a.prototype.insertChars=function(a){var b,c,d;for(c=a[0],c<1&&(c=1),d=this.y,b=this.x;c--&&b=this.rows&&(this.y=this.rows-1),this.x=0},a.prototype.cursorPrecedingLine=function(a){var b;return b=a[0],b<1&&(b=1),this.y-=b,this.y<0&&(this.y=0),this.x=0},a.prototype.cursorCharAbsolute=function(a){var b;return b=a[0],b<1&&(b=1),this.x=b-1},a.prototype.insertLines=function(a){var b,c,d,e,f,g;for(d=a[0],d<1&&(d=1);d--;)this.screen.splice(this.y+this.shift,0,this.blankLine(!0)),this.screen.splice(this.scrollBottom+1+this.shift,1);for(g=[],b=c=e=this.y+this.shift,f=this.screen.length-1;e<=f?c<=f:c>=f;b=e<=f?++c:--c)g.push(this.screen[b].dirty=!0);return g},a.prototype.deleteLines=function(a){var b,c,d,e,f,g,h;for(e=a[0],e<1&&(e=1);e--;)this.screen.splice(this.scrollBottom+this.shift,0,this.blankLine(!0)),this.screen.splice(this.y+this.shift,1),this.normal||0!==this.scrollTop||this.scrollBottom!==this.rows-1||(d=this.term.childElementCount-this.rows+this.y+this.shift,this.term.childNodes[d].remove());if(this.normal||0!==this.scrollTop||this.scrollBottom!==this.rows-1){for(h=[],b=c=f=this.y+this.shift,g=this.screen.length-1;f<=g?c<=g:c>=g;b=f<=g?++c:--c)h.push(this.screen[b].dirty=!0);return h}},a.prototype.deleteChars=function(a){var b;for(b=a[0],b<1&&(b=1);b--;)this.screen[this.y+this.shift].chars.splice(this.x,1),this.screen[this.y+this.shift].chars.push(this.eraseAttr());return this.resetLine(this.screen[this.y+this.shift])},a.prototype.eraseChars=function(a){var b,c;for(c=a[0],c<1&&(c=1),b=this.x;c--&&b=this.cols)return this.x=this.cols-1},a.prototype.HPositionRelative=function(a){var b;if(b=a[0],b<1&&(b=1),this.x+=b,this.x>=this.cols)return this.x=this.cols-1},a.prototype.sendDeviceAttributes=function(a){if(!(a[0]>0))if(this.prefix){if(">"===this.prefix){if(this.isterm("xterm"))return this.send("[>0;276;0c");if(this.isterm("rxvt-unicode"))return this.send("[>85;95;0c");if(this.isterm("linux"))return this.send(a[0]+"c");if(this.isterm("screen"))return this.send("[>83;40003;0c")}}else{if(this.isterm("xterm")||this.isterm("rxvt-unicode")||this.isterm("screen"))return this.send("[?1;2c");if(this.isterm("linux"))return this.send("[?6c")}},a.prototype.linePosAbsolute=function(a){var b;if(b=a[0],b<1&&(b=1),this.y=b-1,this.y>=this.rows)return this.y=this.rows-1},a.prototype.VPositionRelative=function(a){var b;if(b=a[0],b<1&&(b=1),this.y+=b,this.y>=this.rows)return this.y=this.rows-1},a.prototype.HVPosition=function(a){if(a[0]<1&&(a[0]=1),a[1]<1&&(a[1]=1),this.y=a[0]-1,this.y>=this.rows&&(this.y=this.rows-1),this.x=a[1]-1,this.x>=this.cols)return this.x=this.cols-1},a.prototype.setMode=function(b){var c,d,e;if("object"!=typeof b)if(this.prefix){if("?"===this.prefix)switch(b){case 1:return this.applicationCursor=!0;case 2:return this.setgCharset(0,a.prototype.charsets.US),this.setgCharset(1,a.prototype.charsets.US),this.setgCharset(2,a.prototype.charsets.US),this.setgCharset(3,a.prototype.charsets.US);case 3:return this.savedCols=this.cols,this.resize(132,this.rows),this.resizeWindowPlease(132),this.reset();case 6:return this.originMode=!0;case 7:return this.autowrap=!0;case 66:return this.applicationKeypad=!0;case 77:return this.horizontalWrap=!0;case 9:case 1e3:case 1002:case 1003:return this.x10Mouse=9===b,this.vt200Mouse=1e3===b,this.normalMouse=b>1e3,this.mouseEvents=!0,this.body.style.cursor="pointer";case 1004:return this.sendFocus=!0;case 1005:return this.utfMouse=!0;case 1006:return this.sgrMouse=!0;case 1015:return this.urxvtMouse=!0;case 25:return this.cursorHidden=!1;case 1049:case 47:case 1047:if(!this.normal)return e={screen:this.screen,x:this.x,y:this.y,shift:this.shift,scrollTop:this.scrollTop,scrollBottom:this.scrollBottom,tabs:this.tabs,curAttr:this.curAttr},this.reset(),this.normal=e,this.showCursor()}}else switch(b){case 4:this.insertMode=!0;break;case 20:this.convertEol=!0}else for(d=b.length,c=0;c=f;b=e<=f?++c:--c)g.push(this.screen[b+this.shift].dirty=!0);return g},a.prototype.scrollDown=function(a){var b,c,d,e,f,g;for(d=a[0]||1;d--;)this.screen.splice(this.scrollBottom,1),this.screen.splice(this.scrollTop,0,this.blankLine());for(g=[],b=c=e=this.scrollTop,f=this.scrollBottom;e<=f?c<=f:c>=f;b=e<=f?++c:--c)g.push(this.screen[b+this.shift].dirty=!0);return g},a.prototype.initMouseTracking=function(a){},a.prototype.resetTitleModes=function(a){},a.prototype.cursorBackwardTab=function(a){var b,c;for(b=a[0]||1,c=[];b--;)c.push(this.x=this.prevStop());return c},a.prototype.repeatPrecedingCharacter=function(a){var b,c,d;for(d=a[0]||1,c=this.screen[this.y+this.shift].chars,b=c[this.x-1]||this.defAttr;d--;)c[this.x++]=b;return this.screen[this.y+this.shift].dirty=!0},a.prototype.tabClear=function(a){var b;return b=a[0],b<=0?delete this.tabs[this.x]:3===b?this.tabs={}:void 0},a.prototype.mediaCopy=function(a){},a.prototype.setResources=function(a){},a.prototype.disableModifiers=function(a){},a.prototype.setPointerMode=function(a){},a.prototype.softReset=function(a){return this.cursorHidden=!1,this.insertMode=!1,this.originMode=!1,this.autowrap=!0,this.applicationKeypad=!1,this.applicationCursor=!1,this.scrollTop=0,this.scrollBottom=this.rows-1,this.curAttr=this.defAttr,this.x=this.y=0,this.charset=null,this.glevel=0,this.charsets=[null]},a.prototype.requestAnsiMode=function(a){},a.prototype.requestPrivateMode=function(a){},a.prototype.setConformanceLevel=function(a){},a.prototype.loadLEDs=function(a){},a.prototype.setCursorStyle=function(a){},a.prototype.setCharProtectionAttr=function(a){},a.prototype.restorePrivateValues=function(a){},a.prototype.setAttrInRectangle=function(a){var b,c,d,e,f,g,h,i;for(i=a[0],e=a[1],c=a[2],g=a[3],b=a[4],h=[];i0},a.prototype.eraseRectangle=function(a){var b,c,d,e,f,g,h;for(h=a[0],d=a[1],b=a[2],f=a[3],g=[];h + + diff --git a/coffees/ext/clipboard.coffee b/coffees/ext/clipboard.coffee index bbf7ad5..37e6ae5 100644 --- a/coffees/ext/clipboard.coffee +++ b/coffees/ext/clipboard.coffee @@ -16,6 +16,7 @@ # along with this program. If not, see . addEventListener 'copy', copy = (e) -> + document.getElementsByTagName('body')[0].contentEditable = false butterfly.bell "copied" e.clipboardData.clearData() sel = getSelection().toString().replace( @@ -35,6 +36,7 @@ addEventListener 'copy', copy = (e) -> addEventListener 'paste', (e) -> + document.getElementsByTagName('body')[0].contentEditable = false butterfly.bell "pasted" data = e.clipboardData.getData 'text/plain' data = data.replace(/\r\n/g, '\n').replace(/\n/g, '\r') diff --git a/coffees/term.coffee b/coffees/term.coffee index 8d4f34b..572dba9 100644 --- a/coffees/term.coffee +++ b/coffees/term.coffee @@ -67,11 +67,23 @@ class Terminal @forceWidth = @body.getAttribute( 'data-force-unicode-width') is 'yes' + # A hidden textarea to capture all input events + # This allows the body to receive IME composition events + # without being `contentEditable`, which will mess up + # the layout + @inputHelper = @document.getElementById('input-helper') + + # A simple div to take place of the IME input preview + # which is now hidden due to the textarea + @inputView = @document.getElementById('input-view') + # Main terminal element @body.className = 'terminal focus' @body.style.outline = 'none' @body.setAttribute 'tabindex', 0 @body.setAttribute 'spellcheck', 'false' + @inputHelper.setAttribute 'tabindex', 0 + @inputHelper.setAttribute 'spellcheck', 'false' # Adding one line to compute char size div = @document.createElement('div') @@ -87,14 +99,31 @@ class Terminal @termName = 'xterm' @cursorBlink = true @cursorState = 0 + @inComposition = false + @compositionText = "" @resetVars() @focus() @startBlink() + # IME Events should be registered to the textarea + # The textarea helps guiding the IME to pop up + # at the correct position + @inputHelper.addEventListener 'compositionstart', + @compositionStart.bind(@) + @inputHelper.addEventListener 'compositionupdate', + @compositionUpdate.bind(@) + @inputHelper.addEventListener 'compositionend', + @compositionEnd.bind(@) + @inputHelper.addEventListener 'keydown', + @keyDown.bind(@) + @inputHelper.addEventListener 'keypress', + @keyPress.bind(@) addEventListener 'keydown', @keyDown.bind(@) addEventListener 'keypress', @keyPress.bind(@) + # Always focus on the inputHelper textarea + addEventListener 'keyup', => @inputHelper.focus() addEventListener 'focus', @focus.bind(@) addEventListener 'blur', @blur.bind(@) addEventListener 'resize', => @resize() @@ -102,10 +131,6 @@ class Terminal @nativeScrollTo() , true - # # Horrible Firefox paste workaround - if typeof InstallTrigger isnt "undefined" - @body.contentEditable = 'true' - @initmouse() addEventListener 'load', => @resize() @emit 'load' @@ -131,6 +156,7 @@ class Terminal italic: a.italic faint: a.faint crossed: a.crossed + placeholder: false equalAttr: (a, b) -> # Not testing char @@ -140,12 +166,14 @@ class Terminal a.italic is b.italic and a.faint is b.faint and a.crossed is b.crossed) - putChar: (c) -> + putChar: (c, placeholder = false) -> + newChar = @cloneAttr @curAttr, c + newChar.placeholder = placeholder if @insertMode - @screen[@y + @shift].chars.splice(@x, 0, @cloneAttr @curAttr, c) + @screen[@y + @shift].chars.splice(@x, 0, newChar) @screen[@y + @shift].chars.pop() else - @screen[@y + @shift].chars[@x] = @cloneAttr @curAttr, c + @screen[@y + @shift].chars[@x] = newChar @screen[@y + @shift].dirty = true @@ -187,6 +215,7 @@ class Terminal italic: false faint: false crossed: false + placeholder: false @curAttr = @cloneAttr @defAttr @params = [] @@ -222,6 +251,7 @@ class Terminal @showCursor() @body.classList.add('focus') @body.classList.remove('blur') + @inputHelper.focus() # Always focus on the textarea @resize() @scrollLock = old_sl @@ -450,7 +480,21 @@ class Terminal [classes, styles] + # Fullwidth (CJK) character ranges + isCJK: (ch) -> + "\u4e00" <= ch <= "\u9fff" or # CJK Unified Ideographs + "\u3040" <= ch <= "\u30ff" or # Japanese Hiragana and Katakana + "\u31f0" <= ch <= "\u31ff" or # Japanese Katakana Phonetic Extensions + "\u3190" <= ch <= "\u319f" or # Japanese Kanbun symbols + "\u3301" <= ch <= "\u3356" or # Japanese compound characters Kumimoji (組文字) + "\uac00" <= ch <= "\ud7ff" or # Hangul precomposed syllables + "\u3000" <= ch <= "\u303f" or # CJK Punctuations and Symbols + "\uff00" <= ch <= "\uff60" or # Fullwidth forms + "\uffe0" <= ch <= "\uffe6" # Fullwidth forms + charToDom: (data, attr, cursor) -> + # Just do not render if we see any placeholder characters + return if data.placeholder return data.html if data.html attr = attr or @cloneAttr @defAttr ch = data.ch @@ -478,12 +522,13 @@ class Terminal else if ch <= " " char += " " - else unless @forceWidth + # CJK characters should always be forced to be fullwidth + else unless @forceWidth or @isCJK ch char += ch else if ch <= "~" # Ascii chars char += ch - else if "\uff00" < ch < "\uffef" + else if @isCJK ch # CJK always fullwidth char += "#{ch}" else @@ -544,6 +589,7 @@ class Terminal dom = @screenToDom(force) @writeDom dom @nativeScrollTo() + @updateInputViews() @emit 'refresh' _cursorBlink: -> @@ -692,12 +738,15 @@ class Terminal @x = 0 @putChar ch @x++ - if @forceWidth and "\uff00" < ch < "\uffef" - if @cols < 2 or @x >= @cols - @putChar " " - break - - @putChar " " + if @isCJK ch + # Add a dummy, placeholder character + # for double-width, CJK characters + # In order to fix counting of characters + # when calculating for remaining cols + # They are always considered to be + # @forceWidth because otherwise they + # do not render properly at all + @putChar " ", true @x++ when State.escaped @@ -1251,7 +1300,81 @@ class Terminal writeln: (data) -> @write "#{data}\r\n" + updateInputViews: -> + # Re-position the textarea and the preview box + # to the current position of the cursor + cursorPos = @cursor.getBoundingClientRect() + @inputView.style['left'] = cursorPos.left + "px" + @inputView.style['top'] = cursorPos.top + "px" + @inputHelper.style['left'] = cursorPos.left + "px" + @inputHelper.style['top'] = cursorPos.top + "px" + # Clear the textarea as often as possible + @inputHelper.value = "" + + compositionStart: (ev) -> + ev.preventDefault() + ev.stopPropagation() + @updateInputViews() + + # Show the preview box + @inputView.className = "" + @inputView.innerText = "" + + # Hide the blinking cursor + @cursor.style['visibility'] = "hidden" + + @inComposition = true + @compositionText = "" + return false + + compositionUpdate: (ev) -> + ev.preventDefault() + ev.stopPropagation() + # Update the composition text + @compositionText = ev.data + @inputView.innerText = @compositionText + return false + + compositionEnd: (ev) -> + ev.preventDefault() + ev.stopPropagation() + @finishComposition() + return false + + finishComposition: -> + @inComposition = false + @showCursor() + @inputHelper.value = "" + @inputView.className = "hidden" + @send @compositionText + @compositionText = "" + # Force focus on the inputHelper + @inputHelper.focus() + keyDown: (ev) -> + if @inComposition + # Continue IME composition if the character is + # composition key or modifier key + if ev.keyCode is 229 + return false + else if ev.keyCode is 16 || ev.keyCode is 17 || ev.keyCode is 18 + return false + # Otherwise, if we receive a keyDown, abort the composition + @finishComposition() + + if ev.keyCode is 229 + ev.preventDefault() + ev.stopPropagation() + # If the composition key is sent while IME not active + # it means that some character have been input while IME + # enabled, i.e. punctuations + # in which case we just fetch it from the text area + setTimeout => + unless @inComposition || @inputHelper.value.length > 1 + @send @inputHelper.value + , 0 + return false + # Key Resources: # https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent # Don't handle modifiers alone @@ -1268,7 +1391,11 @@ class Terminal return true if (ev.shiftKey or ev.ctrlKey) and ev.keyCode is 45 # Let the ctrl+shift+c, ctrl+shift+v go through to handle native copy paste - return true if (ev.shiftKey and ev.ctrlKey) and ev.keyCode in [67, 86] + if (ev.shiftKey and ev.ctrlKey) and ev.keyCode in [67, 86] + # Make the content temporarily ediatble, to allow the paste event + # to propagate (this does not work for the textarea if not set like this) + @body.contentEditable = true + return true # Alt-z works as an escape to relay the following keys to the browser. # usefull to trigger browser shortcuts, i.e.: Alt+Z F5 to reload