]> git.proxmox.com Git - pve-xtermjs.git/commitdiff
update xterm.js sources to 3.13.2 and move away from tarballs
authorThomas Lamprecht <t.lamprecht@proxmox.com>
Wed, 22 May 2019 18:02:06 +0000 (20:02 +0200)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Wed, 22 May 2019 18:42:20 +0000 (20:42 +0200)
instead just extract the build parts where we want them too

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
Makefile
src/www/addons/fit/fit.js [new file with mode: 0644]
src/www/addons/fit/fit.js.map [new file with mode: 0644]
src/www/xterm.css [new file with mode: 0644]
src/www/xterm.js [new file with mode: 0644]
src/www/xterm.js.map [new file with mode: 0644]
xterm-3.12.0.tgz [deleted file]

index 16e25f091ad7f61dde458d2b1b094644b8328b24..865a2afbfc067626350a46611de173cfb638a21b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -4,10 +4,8 @@ PACKAGE=pve-xtermjs
 
 export VERSION=${DEB_VERSION_UPSTREAM_REVISION}
 
-XTERMJSVER=3.12.0
+XTERMJSVER=3.13.2
 XTERMJSTGZ=xterm-${XTERMJSVER}.tgz
-XTERMJSDIR=package
-XTERMDATA = ${XTERMJSDIR}/dist/
 
 SRCDIR=src
 
@@ -20,24 +18,24 @@ all: ${DEB}
 
 .PHONY: deb
 deb: ${DEB}
-${DEB}: ${XTERMDATA}
+${DEB}:
        rm -rf ${SRCDIR}.tmp
        cp -rpa ${SRCDIR} ${SRCDIR}.tmp
        cp -a debian ${SRCDIR}.tmp/
-       cp -ar ${XTERMJSDIR}/dist/* ${SRCDIR}.tmp/www
        echo "git clone git://git.proxmox.com/git/pve-xtermjs.git\\ngit checkout ${GITVERSION}" > ${SRCDIR}.tmp/debian/SOURCE
        cd ${SRCDIR}.tmp; dpkg-buildpackage -b -uc -us
        lintian ${DEB}
        @echo ${DEB}
 
-${XTERMDATA}: ${XTERMJSTGZ}
-       rm -rf ${XTTERMDIR}
-       tar -xf ${XTERMJSTGZ}
 
+X_EXCLUSIONS=--exclude=addons/attach --exclude=addons/fullscreen --exclude=addons/search \
+  --exclude=addons/terminado --exclude=addons/webLinks --exclude=addons/zmodem
 .PHONY: download
-download ${XTERMJSTGZ}:
+download:
        wget https://registry.npmjs.org/xterm/-/${XTERMJSTGZ} -O ${XTERMJSTGZ}.tmp
        mv ${XTERMJSTGZ}.tmp ${XTERMJSTGZ}
+       tar -C $(SRCDIR)/www -xf ${XTERMJSTGZ} package/dist --strip-components=2 ${X_EXCLUSIONS}
+       rm ${XTERMJSTGZ}
 
 .PHONY: upload
 upload: ${DEB}
diff --git a/src/www/addons/fit/fit.js b/src/www/addons/fit/fit.js
new file mode 100644 (file)
index 0000000..b137d99
--- /dev/null
@@ -0,0 +1,51 @@
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.fit = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+function proposeGeometry(term) {
+    if (!term.element.parentElement) {
+        return null;
+    }
+    var parentElementStyle = window.getComputedStyle(term.element.parentElement);
+    var parentElementHeight = parseInt(parentElementStyle.getPropertyValue('height'));
+    var parentElementWidth = Math.max(0, parseInt(parentElementStyle.getPropertyValue('width')));
+    var elementStyle = window.getComputedStyle(term.element);
+    var elementPadding = {
+        top: parseInt(elementStyle.getPropertyValue('padding-top')),
+        bottom: parseInt(elementStyle.getPropertyValue('padding-bottom')),
+        right: parseInt(elementStyle.getPropertyValue('padding-right')),
+        left: parseInt(elementStyle.getPropertyValue('padding-left'))
+    };
+    var elementPaddingVer = elementPadding.top + elementPadding.bottom;
+    var elementPaddingHor = elementPadding.right + elementPadding.left;
+    var availableHeight = parentElementHeight - elementPaddingVer;
+    var availableWidth = parentElementWidth - elementPaddingHor - term._core.viewport.scrollBarWidth;
+    var geometry = {
+        cols: Math.floor(availableWidth / term._core.renderer.dimensions.actualCellWidth),
+        rows: Math.floor(availableHeight / term._core.renderer.dimensions.actualCellHeight)
+    };
+    return geometry;
+}
+exports.proposeGeometry = proposeGeometry;
+function fit(term) {
+    var geometry = proposeGeometry(term);
+    if (geometry) {
+        if (term.rows !== geometry.rows || term.cols !== geometry.cols) {
+            term._core.renderer.clear();
+            term.resize(geometry.cols, geometry.rows);
+        }
+    }
+}
+exports.fit = fit;
+function apply(terminalConstructor) {
+    terminalConstructor.prototype.proposeGeometry = function () {
+        return proposeGeometry(this);
+    };
+    terminalConstructor.prototype.fit = function () {
+        fit(this);
+    };
+}
+exports.apply = apply;
+
+},{}]},{},[1])(1)
+});
+//# sourceMappingURL=fit.js.map
diff --git a/src/www/addons/fit/fit.js.map b/src/www/addons/fit/fit.js.map
new file mode 100644 (file)
index 0000000..5f1042e
--- /dev/null
@@ -0,0 +1 @@
+{"version":3,"file":"fit.js","sources":["../../../src/addons/fit/fit.ts","../../../node_modules/browser-pack/_prelude.js"],"sourcesContent":["/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Fit terminal columns and rows to the dimensions of its DOM element.\n *\n * ## Approach\n *\n *    Rows: Truncate the division of the terminal parent element height by the\n *          terminal row height.\n * Columns: Truncate the division of the terminal parent element width by the\n *          terminal character width (apply display: inline at the terminal\n *          row and truncate its width with the current number of columns).\n */\n\nimport { Terminal } from 'xterm';\n\nexport interface IGeometry {\n  rows: number;\n  cols: number;\n}\n\nexport function proposeGeometry(term: Terminal): IGeometry {\n  if (!term.element.parentElement) {\n    return null;\n  }\n  const parentElementStyle = window.getComputedStyle(term.element.parentElement);\n  const parentElementHeight = parseInt(parentElementStyle.getPropertyValue('height'));\n  const parentElementWidth = Math.max(0, parseInt(parentElementStyle.getPropertyValue('width')));\n  const elementStyle = window.getComputedStyle(term.element);\n  const elementPadding = {\n    top: parseInt(elementStyle.getPropertyValue('padding-top')),\n    bottom: parseInt(elementStyle.getPropertyValue('padding-bottom')),\n    right: parseInt(elementStyle.getPropertyValue('padding-right')),\n    left: parseInt(elementStyle.getPropertyValue('padding-left'))\n  };\n  const elementPaddingVer = elementPadding.top + elementPadding.bottom;\n  const elementPaddingHor = elementPadding.right + elementPadding.left;\n  const availableHeight = parentElementHeight - elementPaddingVer;\n  const availableWidth = parentElementWidth - elementPaddingHor - (<any>term)._core.viewport.scrollBarWidth;\n  const geometry = {\n    cols: Math.floor(availableWidth / (<any>term)._core.renderer.dimensions.actualCellWidth),\n    rows: Math.floor(availableHeight / (<any>term)._core.renderer.dimensions.actualCellHeight)\n  };\n  return geometry;\n}\n\nexport function fit(term: Terminal): void {\n  const geometry = proposeGeometry(term);\n  if (geometry) {\n    // Force a full render\n    if (term.rows !== geometry.rows || term.cols !== geometry.cols) {\n      (<any>term)._core.renderer.clear();\n      term.resize(geometry.cols, geometry.rows);\n    }\n  }\n}\n\nexport function apply(terminalConstructor: typeof Terminal): void {\n  (<any>terminalConstructor.prototype).proposeGeometry = function (): IGeometry {\n    return proposeGeometry(this);\n  };\n\n  (<any>terminalConstructor.prototype).fit = function (): void {\n    fit(this);\n  };\n}\n",null],"names":[],"mappings":"ACAA;;;ADsBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAvBA;AAyBA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AATA;AAWA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AARA;"}
\ No newline at end of file
diff --git a/src/www/xterm.css b/src/www/xterm.css
new file mode 100644 (file)
index 0000000..5448b5a
--- /dev/null
@@ -0,0 +1,171 @@
+/**
+ * Copyright (c) 2014 The xterm.js authors. All rights reserved.
+ * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
+ * https://github.com/chjj/term.js
+ * @license MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * Originally forked from (with the author's permission):
+ *   Fabrice Bellard's javascript vt100 for jslinux:
+ *   http://bellard.org/jslinux/
+ *   Copyright (c) 2011 Fabrice Bellard
+ *   The original design remains. The terminal itself
+ *   has been extended to include xterm CSI codes, among
+ *   other features.
+ */
+
+/**
+ *  Default styles for xterm.js
+ */
+
+.xterm {
+    font-feature-settings: "liga" 0;
+    position: relative;
+    user-select: none;
+    -ms-user-select: none;
+    -webkit-user-select: none;
+}
+
+.xterm.focus,
+.xterm:focus {
+    outline: none;
+}
+
+.xterm .xterm-helpers {
+    position: absolute;
+    top: 0;
+    /**
+     * The z-index of the helpers must be higher than the canvases in order for
+     * IMEs to appear on top.
+     */
+    z-index: 10;
+}
+
+.xterm .xterm-helper-textarea {
+    /*
+     * HACK: to fix IE's blinking cursor
+     * Move textarea out of the screen to the far left, so that the cursor is not visible.
+     */
+    position: absolute;
+    opacity: 0;
+    left: -9999em;
+    top: 0;
+    width: 0;
+    height: 0;
+    z-index: -10;
+    /** Prevent wrapping so the IME appears against the textarea at the correct position */
+    white-space: nowrap;
+    overflow: hidden;
+    resize: none;
+}
+
+.xterm .composition-view {
+    /* TODO: Composition position got messed up somewhere */
+    background: #000;
+    color: #FFF;
+    display: none;
+    position: absolute;
+    white-space: nowrap;
+    z-index: 1;
+}
+
+.xterm .composition-view.active {
+    display: block;
+}
+
+.xterm .xterm-viewport {
+    /* On OS X this is required in order for the scroll bar to appear fully opaque */
+    background-color: #000;
+    overflow-y: scroll;
+    cursor: default;
+    position: absolute;
+    right: 0;
+    left: 0;
+    top: 0;
+    bottom: 0;
+}
+
+.xterm .xterm-screen {
+    position: relative;
+}
+
+.xterm .xterm-screen canvas {
+    position: absolute;
+    left: 0;
+    top: 0;
+}
+
+.xterm .xterm-scroll-area {
+    visibility: hidden;
+}
+
+.xterm-char-measure-element {
+    display: inline-block;
+    visibility: hidden;
+    position: absolute;
+    top: 0;
+    left: -9999em;
+    line-height: normal;
+}
+
+.xterm {
+    cursor: text;
+}
+
+.xterm.enable-mouse-events {
+    /* When mouse events are enabled (eg. tmux), revert to the standard pointer cursor */
+    cursor: default;
+}
+
+.xterm.xterm-cursor-pointer {
+    cursor: pointer;
+}
+
+.xterm.column-select.focus {
+    /* Column selection mode */
+    cursor: crosshair;
+}
+
+.xterm .xterm-accessibility,
+.xterm .xterm-message {
+    position: absolute;
+    left: 0;
+    top: 0;
+    bottom: 0;
+    right: 0;
+    z-index: 100;
+    color: transparent;
+}
+
+.xterm .live-region {
+    position: absolute;
+    left: -9999px;
+    width: 1px;
+    height: 1px;
+    overflow: hidden;
+}
+
+.xterm-dim {
+    opacity: 0.5;
+}
+
+.xterm-underline {
+    text-decoration: underline;
+}
diff --git a/src/www/xterm.js b/src/www/xterm.js
new file mode 100644 (file)
index 0000000..cf27b6a
--- /dev/null
@@ -0,0 +1,10217 @@
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Terminal = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = function (d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var Strings = require("./Strings");
+var Platform_1 = require("./common/Platform");
+var RenderDebouncer_1 = require("./ui/RenderDebouncer");
+var Lifecycle_1 = require("./ui/Lifecycle");
+var Lifecycle_2 = require("./common/Lifecycle");
+var MAX_ROWS_TO_READ = 20;
+var AccessibilityManager = (function (_super) {
+    __extends(AccessibilityManager, _super);
+    function AccessibilityManager(_terminal) {
+        var _this = _super.call(this) || this;
+        _this._terminal = _terminal;
+        _this._liveRegionLineCount = 0;
+        _this._charsToConsume = [];
+        _this._accessibilityTreeRoot = document.createElement('div');
+        _this._accessibilityTreeRoot.classList.add('xterm-accessibility');
+        _this._rowContainer = document.createElement('div');
+        _this._rowContainer.classList.add('xterm-accessibility-tree');
+        _this._rowElements = [];
+        for (var i = 0; i < _this._terminal.rows; i++) {
+            _this._rowElements[i] = _this._createAccessibilityTreeNode();
+            _this._rowContainer.appendChild(_this._rowElements[i]);
+        }
+        _this._topBoundaryFocusListener = function (e) { return _this._onBoundaryFocus(e, 0); };
+        _this._bottomBoundaryFocusListener = function (e) { return _this._onBoundaryFocus(e, 1); };
+        _this._rowElements[0].addEventListener('focus', _this._topBoundaryFocusListener);
+        _this._rowElements[_this._rowElements.length - 1].addEventListener('focus', _this._bottomBoundaryFocusListener);
+        _this._refreshRowsDimensions();
+        _this._accessibilityTreeRoot.appendChild(_this._rowContainer);
+        _this._renderRowsDebouncer = new RenderDebouncer_1.RenderDebouncer(_this._renderRows.bind(_this));
+        _this._refreshRows();
+        _this._liveRegion = document.createElement('div');
+        _this._liveRegion.classList.add('live-region');
+        _this._liveRegion.setAttribute('aria-live', 'assertive');
+        _this._accessibilityTreeRoot.appendChild(_this._liveRegion);
+        _this._terminal.element.insertAdjacentElement('afterbegin', _this._accessibilityTreeRoot);
+        _this.register(_this._renderRowsDebouncer);
+        _this.register(_this._terminal.onResize(function (e) { return _this._onResize(e.rows); }));
+        _this.register(_this._terminal.onRender(function (e) { return _this._refreshRows(e.start, e.end); }));
+        _this.register(_this._terminal.onScroll(function () { return _this._refreshRows(); }));
+        _this.register(_this._terminal.addDisposableListener('a11y.char', function (char) { return _this._onChar(char); }));
+        _this.register(_this._terminal.onLineFeed(function () { return _this._onChar('\n'); }));
+        _this.register(_this._terminal.addDisposableListener('a11y.tab', function (spaceCount) { return _this._onTab(spaceCount); }));
+        _this.register(_this._terminal.onKey(function (e) { return _this._onKey(e.key); }));
+        _this.register(_this._terminal.addDisposableListener('blur', function () { return _this._clearLiveRegion(); }));
+        _this.register(_this._terminal.addDisposableListener('dprchange', function () { return _this._refreshRowsDimensions(); }));
+        _this.register(_this._terminal.renderer.onCanvasResize(function () { return _this._refreshRowsDimensions(); }));
+        _this.register(Lifecycle_1.addDisposableDomListener(window, 'resize', function () { return _this._refreshRowsDimensions(); }));
+        return _this;
+    }
+    AccessibilityManager.prototype.dispose = function () {
+        _super.prototype.dispose.call(this);
+        this._terminal.element.removeChild(this._accessibilityTreeRoot);
+        this._rowElements.length = 0;
+    };
+    AccessibilityManager.prototype._onBoundaryFocus = function (e, position) {
+        var boundaryElement = e.target;
+        var beforeBoundaryElement = this._rowElements[position === 0 ? 1 : this._rowElements.length - 2];
+        var posInSet = boundaryElement.getAttribute('aria-posinset');
+        var lastRowPos = position === 0 ? '1' : "" + this._terminal.buffer.lines.length;
+        if (posInSet === lastRowPos) {
+            return;
+        }
+        if (e.relatedTarget !== beforeBoundaryElement) {
+            return;
+        }
+        var topBoundaryElement;
+        var bottomBoundaryElement;
+        if (position === 0) {
+            topBoundaryElement = boundaryElement;
+            bottomBoundaryElement = this._rowElements.pop();
+            this._rowContainer.removeChild(bottomBoundaryElement);
+        }
+        else {
+            topBoundaryElement = this._rowElements.shift();
+            bottomBoundaryElement = boundaryElement;
+            this._rowContainer.removeChild(topBoundaryElement);
+        }
+        topBoundaryElement.removeEventListener('focus', this._topBoundaryFocusListener);
+        bottomBoundaryElement.removeEventListener('focus', this._bottomBoundaryFocusListener);
+        if (position === 0) {
+            var newElement = this._createAccessibilityTreeNode();
+            this._rowElements.unshift(newElement);
+            this._rowContainer.insertAdjacentElement('afterbegin', newElement);
+        }
+        else {
+            var newElement = this._createAccessibilityTreeNode();
+            this._rowElements.push(newElement);
+            this._rowContainer.appendChild(newElement);
+        }
+        this._rowElements[0].addEventListener('focus', this._topBoundaryFocusListener);
+        this._rowElements[this._rowElements.length - 1].addEventListener('focus', this._bottomBoundaryFocusListener);
+        this._terminal.scrollLines(position === 0 ? -1 : 1);
+        this._rowElements[position === 0 ? 1 : this._rowElements.length - 2].focus();
+        e.preventDefault();
+        e.stopImmediatePropagation();
+    };
+    AccessibilityManager.prototype._onResize = function (rows) {
+        this._rowElements[this._rowElements.length - 1].removeEventListener('focus', this._bottomBoundaryFocusListener);
+        for (var i = this._rowContainer.children.length; i < this._terminal.rows; i++) {
+            this._rowElements[i] = this._createAccessibilityTreeNode();
+            this._rowContainer.appendChild(this._rowElements[i]);
+        }
+        while (this._rowElements.length > rows) {
+            this._rowContainer.removeChild(this._rowElements.pop());
+        }
+        this._rowElements[this._rowElements.length - 1].addEventListener('focus', this._bottomBoundaryFocusListener);
+        this._refreshRowsDimensions();
+    };
+    AccessibilityManager.prototype._createAccessibilityTreeNode = function () {
+        var element = document.createElement('div');
+        element.setAttribute('role', 'listitem');
+        element.tabIndex = -1;
+        this._refreshRowDimensions(element);
+        return element;
+    };
+    AccessibilityManager.prototype._onTab = function (spaceCount) {
+        for (var i = 0; i < spaceCount; i++) {
+            this._onChar(' ');
+        }
+    };
+    AccessibilityManager.prototype._onChar = function (char) {
+        var _this = this;
+        if (this._liveRegionLineCount < MAX_ROWS_TO_READ + 1) {
+            if (this._charsToConsume.length > 0) {
+                var shiftedChar = this._charsToConsume.shift();
+                if (shiftedChar !== char) {
+                    this._announceCharacter(char);
+                }
+            }
+            else {
+                this._announceCharacter(char);
+            }
+            if (char === '\n') {
+                this._liveRegionLineCount++;
+                if (this._liveRegionLineCount === MAX_ROWS_TO_READ + 1) {
+                    this._liveRegion.textContent += Strings.tooMuchOutput;
+                }
+            }
+            if (Platform_1.isMac) {
+                if (this._liveRegion.textContent && this._liveRegion.textContent.length > 0 && !this._liveRegion.parentNode) {
+                    setTimeout(function () {
+                        _this._accessibilityTreeRoot.appendChild(_this._liveRegion);
+                    }, 0);
+                }
+            }
+        }
+    };
+    AccessibilityManager.prototype._clearLiveRegion = function () {
+        this._liveRegion.textContent = '';
+        this._liveRegionLineCount = 0;
+        if (Platform_1.isMac) {
+            if (this._liveRegion.parentNode) {
+                this._accessibilityTreeRoot.removeChild(this._liveRegion);
+            }
+        }
+    };
+    AccessibilityManager.prototype._onKey = function (keyChar) {
+        this._clearLiveRegion();
+        this._charsToConsume.push(keyChar);
+    };
+    AccessibilityManager.prototype._refreshRows = function (start, end) {
+        this._renderRowsDebouncer.refresh(start, end, this._terminal.rows);
+    };
+    AccessibilityManager.prototype._renderRows = function (start, end) {
+        var buffer = this._terminal.buffer;
+        var setSize = buffer.lines.length.toString();
+        for (var i = start; i <= end; i++) {
+            var lineData = buffer.translateBufferLineToString(buffer.ydisp + i, true);
+            var posInSet = (buffer.ydisp + i + 1).toString();
+            var element = this._rowElements[i];
+            if (element) {
+                element.textContent = lineData.length === 0 ? Strings.blankLine : lineData;
+                element.setAttribute('aria-posinset', posInSet);
+                element.setAttribute('aria-setsize', setSize);
+            }
+        }
+    };
+    AccessibilityManager.prototype._refreshRowsDimensions = function () {
+        if (!this._terminal.renderer.dimensions.actualCellHeight) {
+            return;
+        }
+        if (this._rowElements.length !== this._terminal.rows) {
+            this._onResize(this._terminal.rows);
+        }
+        for (var i = 0; i < this._terminal.rows; i++) {
+            this._refreshRowDimensions(this._rowElements[i]);
+        }
+    };
+    AccessibilityManager.prototype._refreshRowDimensions = function (element) {
+        element.style.height = this._terminal.renderer.dimensions.actualCellHeight + "px";
+    };
+    AccessibilityManager.prototype._announceCharacter = function (char) {
+        if (char === ' ') {
+            this._liveRegion.innerHTML += '&nbsp;';
+        }
+        else {
+            this._liveRegion.textContent += char;
+        }
+    };
+    return AccessibilityManager;
+}(Lifecycle_2.Disposable));
+exports.AccessibilityManager = AccessibilityManager;
+
+},{"./Strings":18,"./common/Lifecycle":26,"./common/Platform":27,"./ui/Lifecycle":55,"./ui/RenderDebouncer":56}],2:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = function (d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var CircularList_1 = require("./common/CircularList");
+var BufferLine_1 = require("./BufferLine");
+var BufferReflow_1 = require("./BufferReflow");
+var Types_1 = require("./renderer/atlas/Types");
+var EventEmitter2_1 = require("./common/EventEmitter2");
+var Lifecycle_1 = require("../lib/common/Lifecycle");
+exports.DEFAULT_ATTR = (0 << 18) | (Types_1.DEFAULT_COLOR << 9) | (256 << 0);
+exports.DEFAULT_ATTR_DATA = new BufferLine_1.AttributeData();
+exports.CHAR_DATA_ATTR_INDEX = 0;
+exports.CHAR_DATA_CHAR_INDEX = 1;
+exports.CHAR_DATA_WIDTH_INDEX = 2;
+exports.CHAR_DATA_CODE_INDEX = 3;
+exports.MAX_BUFFER_SIZE = 4294967295;
+exports.NULL_CELL_CHAR = '';
+exports.NULL_CELL_WIDTH = 1;
+exports.NULL_CELL_CODE = 0;
+exports.WHITESPACE_CELL_CHAR = ' ';
+exports.WHITESPACE_CELL_WIDTH = 1;
+exports.WHITESPACE_CELL_CODE = 32;
+var Buffer = (function () {
+    function Buffer(_terminal, _hasScrollback) {
+        this._terminal = _terminal;
+        this._hasScrollback = _hasScrollback;
+        this.savedCurAttrData = exports.DEFAULT_ATTR_DATA.clone();
+        this.markers = [];
+        this._nullCell = BufferLine_1.CellData.fromCharData([0, exports.NULL_CELL_CHAR, exports.NULL_CELL_WIDTH, exports.NULL_CELL_CODE]);
+        this._whitespaceCell = BufferLine_1.CellData.fromCharData([0, exports.WHITESPACE_CELL_CHAR, exports.WHITESPACE_CELL_WIDTH, exports.WHITESPACE_CELL_CODE]);
+        this._cols = this._terminal.cols;
+        this._rows = this._terminal.rows;
+        this.clear();
+    }
+    Buffer.prototype.getNullCell = function (attr) {
+        if (attr) {
+            this._nullCell.fg = attr.fg;
+            this._nullCell.bg = attr.bg;
+        }
+        else {
+            this._nullCell.fg = 0;
+            this._nullCell.bg = 0;
+        }
+        return this._nullCell;
+    };
+    Buffer.prototype.getWhitespaceCell = function (attr) {
+        if (attr) {
+            this._whitespaceCell.fg = attr.fg;
+            this._whitespaceCell.bg = attr.bg;
+        }
+        else {
+            this._whitespaceCell.fg = 0;
+            this._whitespaceCell.bg = 0;
+        }
+        return this._whitespaceCell;
+    };
+    Buffer.prototype.getBlankLine = function (attr, isWrapped) {
+        return new BufferLine_1.BufferLine(this._terminal.cols, this.getNullCell(attr), isWrapped);
+    };
+    Object.defineProperty(Buffer.prototype, "hasScrollback", {
+        get: function () {
+            return this._hasScrollback && this.lines.maxLength > this._rows;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Buffer.prototype, "isCursorInViewport", {
+        get: function () {
+            var absoluteY = this.ybase + this.y;
+            var relativeY = absoluteY - this.ydisp;
+            return (relativeY >= 0 && relativeY < this._rows);
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Buffer.prototype._getCorrectBufferLength = function (rows) {
+        if (!this._hasScrollback) {
+            return rows;
+        }
+        var correctBufferLength = rows + this._terminal.options.scrollback;
+        return correctBufferLength > exports.MAX_BUFFER_SIZE ? exports.MAX_BUFFER_SIZE : correctBufferLength;
+    };
+    Buffer.prototype.fillViewportRows = function (fillAttr) {
+        if (this.lines.length === 0) {
+            if (fillAttr === undefined) {
+                fillAttr = exports.DEFAULT_ATTR_DATA;
+            }
+            var i = this._rows;
+            while (i--) {
+                this.lines.push(this.getBlankLine(fillAttr));
+            }
+        }
+    };
+    Buffer.prototype.clear = function () {
+        this.ydisp = 0;
+        this.ybase = 0;
+        this.y = 0;
+        this.x = 0;
+        this.lines = new CircularList_1.CircularList(this._getCorrectBufferLength(this._rows));
+        this.scrollTop = 0;
+        this.scrollBottom = this._rows - 1;
+        this.setupTabStops();
+    };
+    Buffer.prototype.resize = function (newCols, newRows) {
+        var nullCell = this.getNullCell(exports.DEFAULT_ATTR_DATA);
+        var newMaxLength = this._getCorrectBufferLength(newRows);
+        if (newMaxLength > this.lines.maxLength) {
+            this.lines.maxLength = newMaxLength;
+        }
+        if (this.lines.length > 0) {
+            if (this._cols < newCols) {
+                for (var i = 0; i < this.lines.length; i++) {
+                    this.lines.get(i).resize(newCols, nullCell);
+                }
+            }
+            var addToY = 0;
+            if (this._rows < newRows) {
+                for (var y = this._rows; y < newRows; y++) {
+                    if (this.lines.length < newRows + this.ybase) {
+                        if (this.ybase > 0 && this.lines.length <= this.ybase + this.y + addToY + 1) {
+                            this.ybase--;
+                            addToY++;
+                            if (this.ydisp > 0) {
+                                this.ydisp--;
+                            }
+                        }
+                        else {
+                            this.lines.push(new BufferLine_1.BufferLine(newCols, nullCell));
+                        }
+                    }
+                }
+            }
+            else {
+                for (var y = this._rows; y > newRows; y--) {
+                    if (this.lines.length > newRows + this.ybase) {
+                        if (this.lines.length > this.ybase + this.y + 1) {
+                            this.lines.pop();
+                        }
+                        else {
+                            this.ybase++;
+                            this.ydisp++;
+                        }
+                    }
+                }
+            }
+            if (newMaxLength < this.lines.maxLength) {
+                var amountToTrim = this.lines.length - newMaxLength;
+                if (amountToTrim > 0) {
+                    this.lines.trimStart(amountToTrim);
+                    this.ybase = Math.max(this.ybase - amountToTrim, 0);
+                    this.ydisp = Math.max(this.ydisp - amountToTrim, 0);
+                }
+                this.lines.maxLength = newMaxLength;
+            }
+            this.x = Math.min(this.x, newCols - 1);
+            this.y = Math.min(this.y, newRows - 1);
+            if (addToY) {
+                this.y += addToY;
+            }
+            this.savedY = Math.min(this.savedY, newRows - 1);
+            this.savedX = Math.min(this.savedX, newCols - 1);
+            this.scrollTop = 0;
+        }
+        this.scrollBottom = newRows - 1;
+        if (this._isReflowEnabled) {
+            this._reflow(newCols, newRows);
+            if (this._cols > newCols) {
+                for (var i = 0; i < this.lines.length; i++) {
+                    this.lines.get(i).resize(newCols, nullCell);
+                }
+            }
+        }
+        this._cols = newCols;
+        this._rows = newRows;
+    };
+    Object.defineProperty(Buffer.prototype, "_isReflowEnabled", {
+        get: function () {
+            return this._hasScrollback && !this._terminal.options.windowsMode;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Buffer.prototype._reflow = function (newCols, newRows) {
+        if (this._cols === newCols) {
+            return;
+        }
+        if (newCols > this._cols) {
+            this._reflowLarger(newCols, newRows);
+        }
+        else {
+            this._reflowSmaller(newCols, newRows);
+        }
+    };
+    Buffer.prototype._reflowLarger = function (newCols, newRows) {
+        var toRemove = BufferReflow_1.reflowLargerGetLinesToRemove(this.lines, this._cols, newCols, this.ybase + this.y, this.getNullCell(exports.DEFAULT_ATTR_DATA));
+        if (toRemove.length > 0) {
+            var newLayoutResult = BufferReflow_1.reflowLargerCreateNewLayout(this.lines, toRemove);
+            BufferReflow_1.reflowLargerApplyNewLayout(this.lines, newLayoutResult.layout);
+            this._reflowLargerAdjustViewport(newCols, newRows, newLayoutResult.countRemoved);
+        }
+    };
+    Buffer.prototype._reflowLargerAdjustViewport = function (newCols, newRows, countRemoved) {
+        var nullCell = this.getNullCell(exports.DEFAULT_ATTR_DATA);
+        var viewportAdjustments = countRemoved;
+        while (viewportAdjustments-- > 0) {
+            if (this.ybase === 0) {
+                if (this.y > 0) {
+                    this.y--;
+                }
+                if (this.lines.length < newRows) {
+                    this.lines.push(new BufferLine_1.BufferLine(newCols, nullCell));
+                }
+            }
+            else {
+                if (this.ydisp === this.ybase) {
+                    this.ydisp--;
+                }
+                this.ybase--;
+            }
+        }
+    };
+    Buffer.prototype._reflowSmaller = function (newCols, newRows) {
+        var nullCell = this.getNullCell(exports.DEFAULT_ATTR_DATA);
+        var toInsert = [];
+        var countToInsert = 0;
+        for (var y = this.lines.length - 1; y >= 0; y--) {
+            var nextLine = this.lines.get(y);
+            if (!nextLine.isWrapped && nextLine.getTrimmedLength() <= newCols) {
+                continue;
+            }
+            var wrappedLines = [nextLine];
+            while (nextLine.isWrapped && y > 0) {
+                nextLine = this.lines.get(--y);
+                wrappedLines.unshift(nextLine);
+            }
+            var absoluteY = this.ybase + this.y;
+            if (absoluteY >= y && absoluteY < y + wrappedLines.length) {
+                continue;
+            }
+            var lastLineLength = wrappedLines[wrappedLines.length - 1].getTrimmedLength();
+            var destLineLengths = BufferReflow_1.reflowSmallerGetNewLineLengths(wrappedLines, this._cols, newCols);
+            var linesToAdd = destLineLengths.length - wrappedLines.length;
+            var trimmedLines = void 0;
+            if (this.ybase === 0 && this.y !== this.lines.length - 1) {
+                trimmedLines = Math.max(0, this.y - this.lines.maxLength + linesToAdd);
+            }
+            else {
+                trimmedLines = Math.max(0, this.lines.length - this.lines.maxLength + linesToAdd);
+            }
+            var newLines = [];
+            for (var i = 0; i < linesToAdd; i++) {
+                var newLine = this.getBlankLine(exports.DEFAULT_ATTR_DATA, true);
+                newLines.push(newLine);
+            }
+            if (newLines.length > 0) {
+                toInsert.push({
+                    start: y + wrappedLines.length + countToInsert,
+                    newLines: newLines
+                });
+                countToInsert += newLines.length;
+            }
+            wrappedLines.push.apply(wrappedLines, newLines);
+            var destLineIndex = destLineLengths.length - 1;
+            var destCol = destLineLengths[destLineIndex];
+            if (destCol === 0) {
+                destLineIndex--;
+                destCol = destLineLengths[destLineIndex];
+            }
+            var srcLineIndex = wrappedLines.length - linesToAdd - 1;
+            var srcCol = lastLineLength;
+            while (srcLineIndex >= 0) {
+                var cellsToCopy = Math.min(srcCol, destCol);
+                wrappedLines[destLineIndex].copyCellsFrom(wrappedLines[srcLineIndex], srcCol - cellsToCopy, destCol - cellsToCopy, cellsToCopy, true);
+                destCol -= cellsToCopy;
+                if (destCol === 0) {
+                    destLineIndex--;
+                    destCol = destLineLengths[destLineIndex];
+                }
+                srcCol -= cellsToCopy;
+                if (srcCol === 0) {
+                    srcLineIndex--;
+                    var wrappedLinesIndex = Math.max(srcLineIndex, 0);
+                    srcCol = BufferReflow_1.getWrappedLineTrimmedLength(wrappedLines, wrappedLinesIndex, this._cols);
+                }
+            }
+            for (var i = 0; i < wrappedLines.length; i++) {
+                if (destLineLengths[i] < newCols) {
+                    wrappedLines[i].setCell(destLineLengths[i], nullCell);
+                }
+            }
+            var viewportAdjustments = linesToAdd - trimmedLines;
+            while (viewportAdjustments-- > 0) {
+                if (this.ybase === 0) {
+                    if (this.y < newRows - 1) {
+                        this.y++;
+                        this.lines.pop();
+                    }
+                    else {
+                        this.ybase++;
+                        this.ydisp++;
+                    }
+                }
+                else {
+                    if (this.ybase < Math.min(this.lines.maxLength, this.lines.length + countToInsert) - newRows) {
+                        if (this.ybase === this.ydisp) {
+                            this.ydisp++;
+                        }
+                        this.ybase++;
+                    }
+                }
+            }
+        }
+        if (toInsert.length > 0) {
+            var insertEvents = [];
+            var originalLines = [];
+            for (var i = 0; i < this.lines.length; i++) {
+                originalLines.push(this.lines.get(i));
+            }
+            var originalLinesLength = this.lines.length;
+            var originalLineIndex = originalLinesLength - 1;
+            var nextToInsertIndex = 0;
+            var nextToInsert = toInsert[nextToInsertIndex];
+            this.lines.length = Math.min(this.lines.maxLength, this.lines.length + countToInsert);
+            var countInsertedSoFar = 0;
+            for (var i = Math.min(this.lines.maxLength - 1, originalLinesLength + countToInsert - 1); i >= 0; i--) {
+                if (nextToInsert && nextToInsert.start > originalLineIndex + countInsertedSoFar) {
+                    for (var nextI = nextToInsert.newLines.length - 1; nextI >= 0; nextI--) {
+                        this.lines.set(i--, nextToInsert.newLines[nextI]);
+                    }
+                    i++;
+                    insertEvents.push({
+                        index: originalLineIndex + 1,
+                        amount: nextToInsert.newLines.length
+                    });
+                    countInsertedSoFar += nextToInsert.newLines.length;
+                    nextToInsert = toInsert[++nextToInsertIndex];
+                }
+                else {
+                    this.lines.set(i, originalLines[originalLineIndex--]);
+                }
+            }
+            var insertCountEmitted = 0;
+            for (var i = insertEvents.length - 1; i >= 0; i--) {
+                insertEvents[i].index += insertCountEmitted;
+                this.lines.onInsertEmitter.fire(insertEvents[i]);
+                insertCountEmitted += insertEvents[i].amount;
+            }
+            var amountToTrim = Math.max(0, originalLinesLength + countToInsert - this.lines.maxLength);
+            if (amountToTrim > 0) {
+                this.lines.onTrimEmitter.fire(amountToTrim);
+            }
+        }
+    };
+    Buffer.prototype.stringIndexToBufferIndex = function (lineIndex, stringIndex, trimRight) {
+        if (trimRight === void 0) { trimRight = false; }
+        while (stringIndex) {
+            var line = this.lines.get(lineIndex);
+            if (!line) {
+                return [-1, -1];
+            }
+            var length_1 = (trimRight) ? line.getTrimmedLength() : line.length;
+            for (var i = 0; i < length_1; ++i) {
+                if (line.get(i)[exports.CHAR_DATA_WIDTH_INDEX]) {
+                    stringIndex -= line.get(i)[exports.CHAR_DATA_CHAR_INDEX].length || 1;
+                }
+                if (stringIndex < 0) {
+                    return [lineIndex, i];
+                }
+            }
+            lineIndex++;
+        }
+        return [lineIndex, 0];
+    };
+    Buffer.prototype.translateBufferLineToString = function (lineIndex, trimRight, startCol, endCol) {
+        if (startCol === void 0) { startCol = 0; }
+        var line = this.lines.get(lineIndex);
+        if (!line) {
+            return '';
+        }
+        return line.translateToString(trimRight, startCol, endCol);
+    };
+    Buffer.prototype.getWrappedRangeForLine = function (y) {
+        var first = y;
+        var last = y;
+        while (first > 0 && this.lines.get(first).isWrapped) {
+            first--;
+        }
+        while (last + 1 < this.lines.length && this.lines.get(last + 1).isWrapped) {
+            last++;
+        }
+        return { first: first, last: last };
+    };
+    Buffer.prototype.setupTabStops = function (i) {
+        if (i !== null && i !== undefined) {
+            if (!this.tabs[i]) {
+                i = this.prevStop(i);
+            }
+        }
+        else {
+            this.tabs = {};
+            i = 0;
+        }
+        for (; i < this._cols; i += this._terminal.options.tabStopWidth) {
+            this.tabs[i] = true;
+        }
+    };
+    Buffer.prototype.prevStop = function (x) {
+        if (x === null || x === undefined) {
+            x = this.x;
+        }
+        while (!this.tabs[--x] && x > 0)
+            ;
+        return x >= this._cols ? this._cols - 1 : x < 0 ? 0 : x;
+    };
+    Buffer.prototype.nextStop = function (x) {
+        if (x === null || x === undefined) {
+            x = this.x;
+        }
+        while (!this.tabs[++x] && x < this._cols)
+            ;
+        return x >= this._cols ? this._cols - 1 : x < 0 ? 0 : x;
+    };
+    Buffer.prototype.addMarker = function (y) {
+        var _this = this;
+        var marker = new Marker(y);
+        this.markers.push(marker);
+        marker.register(this.lines.onTrim(function (amount) {
+            marker.line -= amount;
+            if (marker.line < 0) {
+                marker.dispose();
+            }
+        }));
+        marker.register(this.lines.onInsert(function (event) {
+            if (marker.line >= event.index) {
+                marker.line += event.amount;
+            }
+        }));
+        marker.register(this.lines.onDelete(function (event) {
+            if (marker.line >= event.index && marker.line < event.index + event.amount) {
+                marker.dispose();
+            }
+            if (marker.line > event.index) {
+                marker.line -= event.amount;
+            }
+        }));
+        marker.register(marker.onDispose(function () { return _this._removeMarker(marker); }));
+        return marker;
+    };
+    Buffer.prototype._removeMarker = function (marker) {
+        this.markers.splice(this.markers.indexOf(marker), 1);
+    };
+    Buffer.prototype.iterator = function (trimRight, startIndex, endIndex, startOverscan, endOverscan) {
+        return new BufferStringIterator(this, trimRight, startIndex, endIndex, startOverscan, endOverscan);
+    };
+    return Buffer;
+}());
+exports.Buffer = Buffer;
+var Marker = (function (_super) {
+    __extends(Marker, _super);
+    function Marker(line) {
+        var _this = _super.call(this) || this;
+        _this.line = line;
+        _this._id = Marker._nextId++;
+        _this.isDisposed = false;
+        _this._onDispose = new EventEmitter2_1.EventEmitter2();
+        return _this;
+    }
+    Object.defineProperty(Marker.prototype, "id", {
+        get: function () { return this._id; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Marker.prototype, "onDispose", {
+        get: function () { return this._onDispose.event; },
+        enumerable: true,
+        configurable: true
+    });
+    Marker.prototype.dispose = function () {
+        if (this.isDisposed) {
+            return;
+        }
+        this.isDisposed = true;
+        this._onDispose.fire();
+    };
+    Marker._nextId = 1;
+    return Marker;
+}(Lifecycle_1.Disposable));
+exports.Marker = Marker;
+var BufferStringIterator = (function () {
+    function BufferStringIterator(_buffer, _trimRight, _startIndex, _endIndex, _startOverscan, _endOverscan) {
+        if (_startIndex === void 0) { _startIndex = 0; }
+        if (_endIndex === void 0) { _endIndex = _buffer.lines.length; }
+        if (_startOverscan === void 0) { _startOverscan = 0; }
+        if (_endOverscan === void 0) { _endOverscan = 0; }
+        this._buffer = _buffer;
+        this._trimRight = _trimRight;
+        this._startIndex = _startIndex;
+        this._endIndex = _endIndex;
+        this._startOverscan = _startOverscan;
+        this._endOverscan = _endOverscan;
+        if (this._startIndex < 0) {
+            this._startIndex = 0;
+        }
+        if (this._endIndex > this._buffer.lines.length) {
+            this._endIndex = this._buffer.lines.length;
+        }
+        this._current = this._startIndex;
+    }
+    BufferStringIterator.prototype.hasNext = function () {
+        return this._current < this._endIndex;
+    };
+    BufferStringIterator.prototype.next = function () {
+        var range = this._buffer.getWrappedRangeForLine(this._current);
+        if (range.first < this._startIndex - this._startOverscan) {
+            range.first = this._startIndex - this._startOverscan;
+        }
+        if (range.last > this._endIndex + this._endOverscan) {
+            range.last = this._endIndex + this._endOverscan;
+        }
+        range.first = Math.max(range.first, 0);
+        range.last = Math.min(range.last, this._buffer.lines.length);
+        var result = '';
+        for (var i = range.first; i <= range.last; ++i) {
+            result += this._buffer.translateBufferLineToString(i, this._trimRight);
+        }
+        this._current = range.last + 1;
+        return { range: range, content: result };
+    };
+    return BufferStringIterator;
+}());
+exports.BufferStringIterator = BufferStringIterator;
+
+},{"../lib/common/Lifecycle":26,"./BufferLine":3,"./BufferReflow":4,"./common/CircularList":22,"./common/EventEmitter2":25,"./renderer/atlas/Types":52}],3:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = function (d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var Buffer_1 = require("./Buffer");
+var TextDecoder_1 = require("./core/input/TextDecoder");
+var CELL_SIZE = 3;
+var AttributeData = (function () {
+    function AttributeData() {
+        this.fg = 0;
+        this.bg = 0;
+    }
+    AttributeData.toColorRGB = function (value) {
+        return [
+            value >>> 16 & 255,
+            value >>> 8 & 255,
+            value & 255
+        ];
+    };
+    AttributeData.fromColorRGB = function (value) {
+        return (value[0] & 255) << 16 | (value[1] & 255) << 8 | value[2] & 255;
+    };
+    AttributeData.prototype.clone = function () {
+        var newObj = new AttributeData();
+        newObj.fg = this.fg;
+        newObj.bg = this.bg;
+        return newObj;
+    };
+    AttributeData.prototype.isInverse = function () { return this.fg & 67108864; };
+    AttributeData.prototype.isBold = function () { return this.fg & 134217728; };
+    AttributeData.prototype.isUnderline = function () { return this.fg & 268435456; };
+    AttributeData.prototype.isBlink = function () { return this.fg & 536870912; };
+    AttributeData.prototype.isInvisible = function () { return this.fg & 1073741824; };
+    AttributeData.prototype.isItalic = function () { return this.bg & 67108864; };
+    AttributeData.prototype.isDim = function () { return this.bg & 134217728; };
+    AttributeData.prototype.getFgColorMode = function () { return this.fg & 50331648; };
+    AttributeData.prototype.getBgColorMode = function () { return this.bg & 50331648; };
+    AttributeData.prototype.isFgRGB = function () { return (this.fg & 50331648) === 50331648; };
+    AttributeData.prototype.isBgRGB = function () { return (this.bg & 50331648) === 50331648; };
+    AttributeData.prototype.isFgPalette = function () { return (this.fg & 50331648) === 16777216 || (this.fg & 50331648) === 33554432; };
+    AttributeData.prototype.isBgPalette = function () { return (this.bg & 50331648) === 16777216 || (this.bg & 50331648) === 33554432; };
+    AttributeData.prototype.isFgDefault = function () { return (this.fg & 50331648) === 0; };
+    AttributeData.prototype.isBgDefault = function () { return (this.bg & 50331648) === 0; };
+    AttributeData.prototype.getFgColor = function () {
+        switch (this.fg & 50331648) {
+            case 16777216:
+            case 33554432: return this.fg & 255;
+            case 50331648: return this.fg & 16777215;
+            default: return -1;
+        }
+    };
+    AttributeData.prototype.getBgColor = function () {
+        switch (this.bg & 50331648) {
+            case 16777216:
+            case 33554432: return this.bg & 255;
+            case 50331648: return this.bg & 16777215;
+            default: return -1;
+        }
+    };
+    return AttributeData;
+}());
+exports.AttributeData = AttributeData;
+var CellData = (function (_super) {
+    __extends(CellData, _super);
+    function CellData() {
+        var _this = _super !== null && _super.apply(this, arguments) || this;
+        _this.content = 0;
+        _this.fg = 0;
+        _this.bg = 0;
+        _this.combinedData = '';
+        return _this;
+    }
+    CellData.fromCharData = function (value) {
+        var obj = new CellData();
+        obj.setFromCharData(value);
+        return obj;
+    };
+    CellData.prototype.isCombined = function () {
+        return this.content & 2097152;
+    };
+    CellData.prototype.getWidth = function () {
+        return this.content >> 22;
+    };
+    CellData.prototype.getChars = function () {
+        if (this.content & 2097152) {
+            return this.combinedData;
+        }
+        if (this.content & 2097151) {
+            return TextDecoder_1.stringFromCodePoint(this.content & 2097151);
+        }
+        return '';
+    };
+    CellData.prototype.getCode = function () {
+        return (this.isCombined())
+            ? this.combinedData.charCodeAt(this.combinedData.length - 1)
+            : this.content & 2097151;
+    };
+    CellData.prototype.setFromCharData = function (value) {
+        this.fg = value[Buffer_1.CHAR_DATA_ATTR_INDEX];
+        this.bg = 0;
+        var combined = false;
+        if (value[Buffer_1.CHAR_DATA_CHAR_INDEX].length > 2) {
+            combined = true;
+        }
+        else if (value[Buffer_1.CHAR_DATA_CHAR_INDEX].length === 2) {
+            var code = value[Buffer_1.CHAR_DATA_CHAR_INDEX].charCodeAt(0);
+            if (0xD800 <= code && code <= 0xDBFF) {
+                var second = value[Buffer_1.CHAR_DATA_CHAR_INDEX].charCodeAt(1);
+                if (0xDC00 <= second && second <= 0xDFFF) {
+                    this.content = ((code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000) | (value[Buffer_1.CHAR_DATA_WIDTH_INDEX] << 22);
+                }
+                else {
+                    combined = true;
+                }
+            }
+            else {
+                combined = true;
+            }
+        }
+        else {
+            this.content = value[Buffer_1.CHAR_DATA_CHAR_INDEX].charCodeAt(0) | (value[Buffer_1.CHAR_DATA_WIDTH_INDEX] << 22);
+        }
+        if (combined) {
+            this.combinedData = value[Buffer_1.CHAR_DATA_CHAR_INDEX];
+            this.content = 2097152 | (value[Buffer_1.CHAR_DATA_WIDTH_INDEX] << 22);
+        }
+    };
+    CellData.prototype.getAsCharData = function () {
+        return [this.fg, this.getChars(), this.getWidth(), this.getCode()];
+    };
+    return CellData;
+}(AttributeData));
+exports.CellData = CellData;
+var BufferLine = (function () {
+    function BufferLine(cols, fillCellData, isWrapped) {
+        if (isWrapped === void 0) { isWrapped = false; }
+        this.isWrapped = isWrapped;
+        this._data = null;
+        this._combined = {};
+        if (cols) {
+            this._data = new Uint32Array(cols * CELL_SIZE);
+            var cell = fillCellData || CellData.fromCharData([0, Buffer_1.NULL_CELL_CHAR, Buffer_1.NULL_CELL_WIDTH, Buffer_1.NULL_CELL_CODE]);
+            for (var i = 0; i < cols; ++i) {
+                this.setCell(i, cell);
+            }
+        }
+        this.length = cols;
+    }
+    BufferLine.prototype.get = function (index) {
+        var content = this._data[index * CELL_SIZE + 0];
+        var cp = content & 2097151;
+        return [
+            this._data[index * CELL_SIZE + 1],
+            (content & 2097152)
+                ? this._combined[index]
+                : (cp) ? TextDecoder_1.stringFromCodePoint(cp) : '',
+            content >> 22,
+            (content & 2097152)
+                ? this._combined[index].charCodeAt(this._combined[index].length - 1)
+                : cp
+        ];
+    };
+    BufferLine.prototype.set = function (index, value) {
+        this._data[index * CELL_SIZE + 1] = value[Buffer_1.CHAR_DATA_ATTR_INDEX];
+        if (value[Buffer_1.CHAR_DATA_CHAR_INDEX].length > 1) {
+            this._combined[index] = value[1];
+            this._data[index * CELL_SIZE + 0] = index | 2097152 | (value[Buffer_1.CHAR_DATA_WIDTH_INDEX] << 22);
+        }
+        else {
+            this._data[index * CELL_SIZE + 0] = value[Buffer_1.CHAR_DATA_CHAR_INDEX].charCodeAt(0) | (value[Buffer_1.CHAR_DATA_WIDTH_INDEX] << 22);
+        }
+    };
+    BufferLine.prototype.getWidth = function (index) {
+        return this._data[index * CELL_SIZE + 0] >> 22;
+    };
+    BufferLine.prototype.hasWidth = function (index) {
+        return this._data[index * CELL_SIZE + 0] & 12582912;
+    };
+    BufferLine.prototype.getFg = function (index) {
+        return this._data[index * CELL_SIZE + 1];
+    };
+    BufferLine.prototype.getBg = function (index) {
+        return this._data[index * CELL_SIZE + 2];
+    };
+    BufferLine.prototype.hasContent = function (index) {
+        return this._data[index * CELL_SIZE + 0] & 4194303;
+    };
+    BufferLine.prototype.getCodePoint = function (index) {
+        var content = this._data[index * CELL_SIZE + 0];
+        if (content & 2097152) {
+            return this._combined[index].charCodeAt(this._combined[index].length - 1);
+        }
+        return content & 2097151;
+    };
+    BufferLine.prototype.isCombined = function (index) {
+        return this._data[index * CELL_SIZE + 0] & 2097152;
+    };
+    BufferLine.prototype.getString = function (index) {
+        var content = this._data[index * CELL_SIZE + 0];
+        if (content & 2097152) {
+            return this._combined[index];
+        }
+        if (content & 2097151) {
+            return TextDecoder_1.stringFromCodePoint(content & 2097151);
+        }
+        return '';
+    };
+    BufferLine.prototype.loadCell = function (index, cell) {
+        var startIndex = index * CELL_SIZE;
+        cell.content = this._data[startIndex + 0];
+        cell.fg = this._data[startIndex + 1];
+        cell.bg = this._data[startIndex + 2];
+        if (cell.content & 2097152) {
+            cell.combinedData = this._combined[index];
+        }
+        return cell;
+    };
+    BufferLine.prototype.setCell = function (index, cell) {
+        if (cell.content & 2097152) {
+            this._combined[index] = cell.combinedData;
+        }
+        this._data[index * CELL_SIZE + 0] = cell.content;
+        this._data[index * CELL_SIZE + 1] = cell.fg;
+        this._data[index * CELL_SIZE + 2] = cell.bg;
+    };
+    BufferLine.prototype.setCellFromCodePoint = function (index, codePoint, width, fg, bg) {
+        this._data[index * CELL_SIZE + 0] = codePoint | (width << 22);
+        this._data[index * CELL_SIZE + 1] = fg;
+        this._data[index * CELL_SIZE + 2] = bg;
+    };
+    BufferLine.prototype.addCodepointToCell = function (index, codePoint) {
+        var content = this._data[index * CELL_SIZE + 0];
+        if (content & 2097152) {
+            this._combined[index] += TextDecoder_1.stringFromCodePoint(codePoint);
+        }
+        else {
+            if (content & 2097151) {
+                this._combined[index] = TextDecoder_1.stringFromCodePoint(content & 2097151) + TextDecoder_1.stringFromCodePoint(codePoint);
+                content &= ~2097151;
+                content |= 2097152;
+            }
+            else {
+                content = codePoint | (1 << 22);
+            }
+            this._data[index * CELL_SIZE + 0] = content;
+        }
+    };
+    BufferLine.prototype.insertCells = function (pos, n, fillCellData) {
+        pos %= this.length;
+        if (n < this.length - pos) {
+            var cell = new CellData();
+            for (var i = this.length - pos - n - 1; i >= 0; --i) {
+                this.setCell(pos + n + i, this.loadCell(pos + i, cell));
+            }
+            for (var i = 0; i < n; ++i) {
+                this.setCell(pos + i, fillCellData);
+            }
+        }
+        else {
+            for (var i = pos; i < this.length; ++i) {
+                this.setCell(i, fillCellData);
+            }
+        }
+    };
+    BufferLine.prototype.deleteCells = function (pos, n, fillCellData) {
+        pos %= this.length;
+        if (n < this.length - pos) {
+            var cell = new CellData();
+            for (var i = 0; i < this.length - pos - n; ++i) {
+                this.setCell(pos + i, this.loadCell(pos + n + i, cell));
+            }
+            for (var i = this.length - n; i < this.length; ++i) {
+                this.setCell(i, fillCellData);
+            }
+        }
+        else {
+            for (var i = pos; i < this.length; ++i) {
+                this.setCell(i, fillCellData);
+            }
+        }
+    };
+    BufferLine.prototype.replaceCells = function (start, end, fillCellData) {
+        while (start < end && start < this.length) {
+            this.setCell(start++, fillCellData);
+        }
+    };
+    BufferLine.prototype.resize = function (cols, fillCellData) {
+        if (cols === this.length) {
+            return;
+        }
+        if (cols > this.length) {
+            var data = new Uint32Array(cols * CELL_SIZE);
+            if (this.length) {
+                if (cols * CELL_SIZE < this._data.length) {
+                    data.set(this._data.subarray(0, cols * CELL_SIZE));
+                }
+                else {
+                    data.set(this._data);
+                }
+            }
+            this._data = data;
+            for (var i = this.length; i < cols; ++i) {
+                this.setCell(i, fillCellData);
+            }
+        }
+        else {
+            if (cols) {
+                var data = new Uint32Array(cols * CELL_SIZE);
+                data.set(this._data.subarray(0, cols * CELL_SIZE));
+                this._data = data;
+                var keys = Object.keys(this._combined);
+                for (var i = 0; i < keys.length; i++) {
+                    var key = parseInt(keys[i], 10);
+                    if (key >= cols) {
+                        delete this._combined[key];
+                    }
+                }
+            }
+            else {
+                this._data = null;
+                this._combined = {};
+            }
+        }
+        this.length = cols;
+    };
+    BufferLine.prototype.fill = function (fillCellData) {
+        this._combined = {};
+        for (var i = 0; i < this.length; ++i) {
+            this.setCell(i, fillCellData);
+        }
+    };
+    BufferLine.prototype.copyFrom = function (line) {
+        if (this.length !== line.length) {
+            this._data = new Uint32Array(line._data);
+        }
+        else {
+            this._data.set(line._data);
+        }
+        this.length = line.length;
+        this._combined = {};
+        for (var el in line._combined) {
+            this._combined[el] = line._combined[el];
+        }
+        this.isWrapped = line.isWrapped;
+    };
+    BufferLine.prototype.clone = function () {
+        var newLine = new BufferLine(0);
+        newLine._data = new Uint32Array(this._data);
+        newLine.length = this.length;
+        for (var el in this._combined) {
+            newLine._combined[el] = this._combined[el];
+        }
+        newLine.isWrapped = this.isWrapped;
+        return newLine;
+    };
+    BufferLine.prototype.getTrimmedLength = function () {
+        for (var i = this.length - 1; i >= 0; --i) {
+            if ((this._data[i * CELL_SIZE + 0] & 4194303)) {
+                return i + (this._data[i * CELL_SIZE + 0] >> 22);
+            }
+        }
+        return 0;
+    };
+    BufferLine.prototype.copyCellsFrom = function (src, srcCol, destCol, length, applyInReverse) {
+        var srcData = src._data;
+        if (applyInReverse) {
+            for (var cell = length - 1; cell >= 0; cell--) {
+                for (var i = 0; i < CELL_SIZE; i++) {
+                    this._data[(destCol + cell) * CELL_SIZE + i] = srcData[(srcCol + cell) * CELL_SIZE + i];
+                }
+            }
+        }
+        else {
+            for (var cell = 0; cell < length; cell++) {
+                for (var i = 0; i < CELL_SIZE; i++) {
+                    this._data[(destCol + cell) * CELL_SIZE + i] = srcData[(srcCol + cell) * CELL_SIZE + i];
+                }
+            }
+        }
+        var srcCombinedKeys = Object.keys(src._combined);
+        for (var i = 0; i < srcCombinedKeys.length; i++) {
+            var key = parseInt(srcCombinedKeys[i], 10);
+            if (key >= srcCol) {
+                this._combined[key - srcCol + destCol] = src._combined[key];
+            }
+        }
+    };
+    BufferLine.prototype.translateToString = function (trimRight, startCol, endCol) {
+        if (trimRight === void 0) { trimRight = false; }
+        if (startCol === void 0) { startCol = 0; }
+        if (endCol === void 0) { endCol = this.length; }
+        if (trimRight) {
+            endCol = Math.min(endCol, this.getTrimmedLength());
+        }
+        var result = '';
+        while (startCol < endCol) {
+            var content = this._data[startCol * CELL_SIZE + 0];
+            var cp = content & 2097151;
+            result += (content & 2097152) ? this._combined[startCol] : (cp) ? TextDecoder_1.stringFromCodePoint(cp) : Buffer_1.WHITESPACE_CELL_CHAR;
+            startCol += (content >> 22) || 1;
+        }
+        return result;
+    };
+    return BufferLine;
+}());
+exports.BufferLine = BufferLine;
+
+},{"./Buffer":2,"./core/input/TextDecoder":32}],4:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+function reflowLargerGetLinesToRemove(lines, oldCols, newCols, bufferAbsoluteY, nullCell) {
+    var toRemove = [];
+    for (var y = 0; y < lines.length - 1; y++) {
+        var i = y;
+        var nextLine = lines.get(++i);
+        if (!nextLine.isWrapped) {
+            continue;
+        }
+        var wrappedLines = [lines.get(y)];
+        while (i < lines.length && nextLine.isWrapped) {
+            wrappedLines.push(nextLine);
+            nextLine = lines.get(++i);
+        }
+        if (bufferAbsoluteY >= y && bufferAbsoluteY < i) {
+            y += wrappedLines.length - 1;
+            continue;
+        }
+        var destLineIndex = 0;
+        var destCol = getWrappedLineTrimmedLength(wrappedLines, destLineIndex, oldCols);
+        var srcLineIndex = 1;
+        var srcCol = 0;
+        while (srcLineIndex < wrappedLines.length) {
+            var srcTrimmedTineLength = getWrappedLineTrimmedLength(wrappedLines, srcLineIndex, oldCols);
+            var srcRemainingCells = srcTrimmedTineLength - srcCol;
+            var destRemainingCells = newCols - destCol;
+            var cellsToCopy = Math.min(srcRemainingCells, destRemainingCells);
+            wrappedLines[destLineIndex].copyCellsFrom(wrappedLines[srcLineIndex], srcCol, destCol, cellsToCopy, false);
+            destCol += cellsToCopy;
+            if (destCol === newCols) {
+                destLineIndex++;
+                destCol = 0;
+            }
+            srcCol += cellsToCopy;
+            if (srcCol === srcTrimmedTineLength) {
+                srcLineIndex++;
+                srcCol = 0;
+            }
+            if (destCol === 0 && destLineIndex !== 0) {
+                if (wrappedLines[destLineIndex - 1].getWidth(newCols - 1) === 2) {
+                    wrappedLines[destLineIndex].copyCellsFrom(wrappedLines[destLineIndex - 1], newCols - 1, destCol++, 1, false);
+                    wrappedLines[destLineIndex - 1].setCell(newCols - 1, nullCell);
+                }
+            }
+        }
+        wrappedLines[destLineIndex].replaceCells(destCol, newCols, nullCell);
+        var countToRemove = 0;
+        for (var i_1 = wrappedLines.length - 1; i_1 > 0; i_1--) {
+            if (i_1 > destLineIndex || wrappedLines[i_1].getTrimmedLength() === 0) {
+                countToRemove++;
+            }
+            else {
+                break;
+            }
+        }
+        if (countToRemove > 0) {
+            toRemove.push(y + wrappedLines.length - countToRemove);
+            toRemove.push(countToRemove);
+        }
+        y += wrappedLines.length - 1;
+    }
+    return toRemove;
+}
+exports.reflowLargerGetLinesToRemove = reflowLargerGetLinesToRemove;
+function reflowLargerCreateNewLayout(lines, toRemove) {
+    var layout = [];
+    var nextToRemoveIndex = 0;
+    var nextToRemoveStart = toRemove[nextToRemoveIndex];
+    var countRemovedSoFar = 0;
+    for (var i = 0; i < lines.length; i++) {
+        if (nextToRemoveStart === i) {
+            var countToRemove = toRemove[++nextToRemoveIndex];
+            lines.onDeleteEmitter.fire({
+                index: i - countRemovedSoFar,
+                amount: countToRemove
+            });
+            i += countToRemove - 1;
+            countRemovedSoFar += countToRemove;
+            nextToRemoveStart = toRemove[++nextToRemoveIndex];
+        }
+        else {
+            layout.push(i);
+        }
+    }
+    return {
+        layout: layout,
+        countRemoved: countRemovedSoFar
+    };
+}
+exports.reflowLargerCreateNewLayout = reflowLargerCreateNewLayout;
+function reflowLargerApplyNewLayout(lines, newLayout) {
+    var newLayoutLines = [];
+    for (var i = 0; i < newLayout.length; i++) {
+        newLayoutLines.push(lines.get(newLayout[i]));
+    }
+    for (var i = 0; i < newLayoutLines.length; i++) {
+        lines.set(i, newLayoutLines[i]);
+    }
+    lines.length = newLayout.length;
+}
+exports.reflowLargerApplyNewLayout = reflowLargerApplyNewLayout;
+function reflowSmallerGetNewLineLengths(wrappedLines, oldCols, newCols) {
+    var newLineLengths = [];
+    var cellsNeeded = wrappedLines.map(function (l, i) { return getWrappedLineTrimmedLength(wrappedLines, i, oldCols); }).reduce(function (p, c) { return p + c; });
+    var srcCol = 0;
+    var srcLine = 0;
+    var cellsAvailable = 0;
+    while (cellsAvailable < cellsNeeded) {
+        if (cellsNeeded - cellsAvailable < newCols) {
+            newLineLengths.push(cellsNeeded - cellsAvailable);
+            break;
+        }
+        srcCol += newCols;
+        var oldTrimmedLength = getWrappedLineTrimmedLength(wrappedLines, srcLine, oldCols);
+        if (srcCol > oldTrimmedLength) {
+            srcCol -= oldTrimmedLength;
+            srcLine++;
+        }
+        var endsWithWide = wrappedLines[srcLine].getWidth(srcCol - 1) === 2;
+        if (endsWithWide) {
+            srcCol--;
+        }
+        var lineLength = endsWithWide ? newCols - 1 : newCols;
+        newLineLengths.push(lineLength);
+        cellsAvailable += lineLength;
+    }
+    return newLineLengths;
+}
+exports.reflowSmallerGetNewLineLengths = reflowSmallerGetNewLineLengths;
+function getWrappedLineTrimmedLength(lines, i, cols) {
+    if (i === lines.length - 1) {
+        return lines[i].getTrimmedLength();
+    }
+    var endsInNull = !(lines[i].hasContent(cols - 1)) && lines[i].getWidth(cols - 1) === 1;
+    var followingLineStartsWithWide = lines[i + 1].getWidth(0) === 2;
+    if (endsInNull && followingLineStartsWithWide) {
+        return cols - 1;
+    }
+    return cols;
+}
+exports.getWrappedLineTrimmedLength = getWrappedLineTrimmedLength;
+
+},{}],5:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var Buffer_1 = require("./Buffer");
+var EventEmitter2_1 = require("./common/EventEmitter2");
+var BufferSet = (function () {
+    function BufferSet(_terminal) {
+        this._terminal = _terminal;
+        this._onBufferActivate = new EventEmitter2_1.EventEmitter2();
+        this._normal = new Buffer_1.Buffer(this._terminal, true);
+        this._normal.fillViewportRows();
+        this._alt = new Buffer_1.Buffer(this._terminal, false);
+        this._activeBuffer = this._normal;
+        this.setupTabStops();
+    }
+    Object.defineProperty(BufferSet.prototype, "onBufferActivate", {
+        get: function () { return this._onBufferActivate.event; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(BufferSet.prototype, "alt", {
+        get: function () {
+            return this._alt;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(BufferSet.prototype, "active", {
+        get: function () {
+            return this._activeBuffer;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(BufferSet.prototype, "normal", {
+        get: function () {
+            return this._normal;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    BufferSet.prototype.activateNormalBuffer = function () {
+        if (this._activeBuffer === this._normal) {
+            return;
+        }
+        this._normal.x = this._alt.x;
+        this._normal.y = this._alt.y;
+        this._alt.clear();
+        this._activeBuffer = this._normal;
+        this._onBufferActivate.fire({
+            activeBuffer: this._normal,
+            inactiveBuffer: this._alt
+        });
+    };
+    BufferSet.prototype.activateAltBuffer = function (fillAttr) {
+        if (this._activeBuffer === this._alt) {
+            return;
+        }
+        this._alt.fillViewportRows(fillAttr);
+        this._alt.x = this._normal.x;
+        this._alt.y = this._normal.y;
+        this._activeBuffer = this._alt;
+        this._onBufferActivate.fire({
+            activeBuffer: this._alt,
+            inactiveBuffer: this._normal
+        });
+    };
+    BufferSet.prototype.resize = function (newCols, newRows) {
+        this._normal.resize(newCols, newRows);
+        this._alt.resize(newCols, newRows);
+    };
+    BufferSet.prototype.setupTabStops = function (i) {
+        this._normal.setupTabStops(i);
+        this._alt.setupTabStops(i);
+    };
+    return BufferSet;
+}());
+exports.BufferSet = BufferSet;
+
+},{"./Buffer":2,"./common/EventEmitter2":25}],6:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var EventEmitter2_1 = require("./common/EventEmitter2");
+var CharMeasure = (function () {
+    function CharMeasure(document, parentElement) {
+        this._onCharSizeChanged = new EventEmitter2_1.EventEmitter2();
+        this._document = document;
+        this._parentElement = parentElement;
+        this._measureElement = this._document.createElement('span');
+        this._measureElement.classList.add('xterm-char-measure-element');
+        this._measureElement.textContent = 'W';
+        this._measureElement.setAttribute('aria-hidden', 'true');
+        this._parentElement.appendChild(this._measureElement);
+    }
+    Object.defineProperty(CharMeasure.prototype, "onCharSizeChanged", {
+        get: function () { return this._onCharSizeChanged.event; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(CharMeasure.prototype, "width", {
+        get: function () {
+            return this._width;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(CharMeasure.prototype, "height", {
+        get: function () {
+            return this._height;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    CharMeasure.prototype.measure = function (options) {
+        this._measureElement.style.fontFamily = options.fontFamily;
+        this._measureElement.style.fontSize = options.fontSize + "px";
+        var geometry = this._measureElement.getBoundingClientRect();
+        if (geometry.width === 0 || geometry.height === 0) {
+            return;
+        }
+        var adjustedHeight = Math.ceil(geometry.height);
+        if (this._width !== geometry.width || this._height !== adjustedHeight) {
+            this._width = geometry.width;
+            this._height = adjustedHeight;
+            this._onCharSizeChanged.fire();
+        }
+    };
+    return CharMeasure;
+}());
+exports.CharMeasure = CharMeasure;
+
+},{"./common/EventEmitter2":25}],7:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var TypedArrayUtils_1 = require("./common/TypedArrayUtils");
+exports.wcwidth = (function (opts) {
+    var COMBINING_BMP = [
+        [0x0300, 0x036F], [0x0483, 0x0486], [0x0488, 0x0489],
+        [0x0591, 0x05BD], [0x05BF, 0x05BF], [0x05C1, 0x05C2],
+        [0x05C4, 0x05C5], [0x05C7, 0x05C7], [0x0600, 0x0603],
+        [0x0610, 0x0615], [0x064B, 0x065E], [0x0670, 0x0670],
+        [0x06D6, 0x06E4], [0x06E7, 0x06E8], [0x06EA, 0x06ED],
+        [0x070F, 0x070F], [0x0711, 0x0711], [0x0730, 0x074A],
+        [0x07A6, 0x07B0], [0x07EB, 0x07F3], [0x0901, 0x0902],
+        [0x093C, 0x093C], [0x0941, 0x0948], [0x094D, 0x094D],
+        [0x0951, 0x0954], [0x0962, 0x0963], [0x0981, 0x0981],
+        [0x09BC, 0x09BC], [0x09C1, 0x09C4], [0x09CD, 0x09CD],
+        [0x09E2, 0x09E3], [0x0A01, 0x0A02], [0x0A3C, 0x0A3C],
+        [0x0A41, 0x0A42], [0x0A47, 0x0A48], [0x0A4B, 0x0A4D],
+        [0x0A70, 0x0A71], [0x0A81, 0x0A82], [0x0ABC, 0x0ABC],
+        [0x0AC1, 0x0AC5], [0x0AC7, 0x0AC8], [0x0ACD, 0x0ACD],
+        [0x0AE2, 0x0AE3], [0x0B01, 0x0B01], [0x0B3C, 0x0B3C],
+        [0x0B3F, 0x0B3F], [0x0B41, 0x0B43], [0x0B4D, 0x0B4D],
+        [0x0B56, 0x0B56], [0x0B82, 0x0B82], [0x0BC0, 0x0BC0],
+        [0x0BCD, 0x0BCD], [0x0C3E, 0x0C40], [0x0C46, 0x0C48],
+        [0x0C4A, 0x0C4D], [0x0C55, 0x0C56], [0x0CBC, 0x0CBC],
+        [0x0CBF, 0x0CBF], [0x0CC6, 0x0CC6], [0x0CCC, 0x0CCD],
+        [0x0CE2, 0x0CE3], [0x0D41, 0x0D43], [0x0D4D, 0x0D4D],
+        [0x0DCA, 0x0DCA], [0x0DD2, 0x0DD4], [0x0DD6, 0x0DD6],
+        [0x0E31, 0x0E31], [0x0E34, 0x0E3A], [0x0E47, 0x0E4E],
+        [0x0EB1, 0x0EB1], [0x0EB4, 0x0EB9], [0x0EBB, 0x0EBC],
+        [0x0EC8, 0x0ECD], [0x0F18, 0x0F19], [0x0F35, 0x0F35],
+        [0x0F37, 0x0F37], [0x0F39, 0x0F39], [0x0F71, 0x0F7E],
+        [0x0F80, 0x0F84], [0x0F86, 0x0F87], [0x0F90, 0x0F97],
+        [0x0F99, 0x0FBC], [0x0FC6, 0x0FC6], [0x102D, 0x1030],
+        [0x1032, 0x1032], [0x1036, 0x1037], [0x1039, 0x1039],
+        [0x1058, 0x1059], [0x1160, 0x11FF], [0x135F, 0x135F],
+        [0x1712, 0x1714], [0x1732, 0x1734], [0x1752, 0x1753],
+        [0x1772, 0x1773], [0x17B4, 0x17B5], [0x17B7, 0x17BD],
+        [0x17C6, 0x17C6], [0x17C9, 0x17D3], [0x17DD, 0x17DD],
+        [0x180B, 0x180D], [0x18A9, 0x18A9], [0x1920, 0x1922],
+        [0x1927, 0x1928], [0x1932, 0x1932], [0x1939, 0x193B],
+        [0x1A17, 0x1A18], [0x1B00, 0x1B03], [0x1B34, 0x1B34],
+        [0x1B36, 0x1B3A], [0x1B3C, 0x1B3C], [0x1B42, 0x1B42],
+        [0x1B6B, 0x1B73], [0x1DC0, 0x1DCA], [0x1DFE, 0x1DFF],
+        [0x200B, 0x200F], [0x202A, 0x202E], [0x2060, 0x2063],
+        [0x206A, 0x206F], [0x20D0, 0x20EF], [0x302A, 0x302F],
+        [0x3099, 0x309A], [0xA806, 0xA806], [0xA80B, 0xA80B],
+        [0xA825, 0xA826], [0xFB1E, 0xFB1E], [0xFE00, 0xFE0F],
+        [0xFE20, 0xFE23], [0xFEFF, 0xFEFF], [0xFFF9, 0xFFFB]
+    ];
+    var COMBINING_HIGH = [
+        [0x10A01, 0x10A03], [0x10A05, 0x10A06], [0x10A0C, 0x10A0F],
+        [0x10A38, 0x10A3A], [0x10A3F, 0x10A3F], [0x1D167, 0x1D169],
+        [0x1D173, 0x1D182], [0x1D185, 0x1D18B], [0x1D1AA, 0x1D1AD],
+        [0x1D242, 0x1D244], [0xE0001, 0xE0001], [0xE0020, 0xE007F],
+        [0xE0100, 0xE01EF]
+    ];
+    function bisearch(ucs, data) {
+        var min = 0;
+        var max = data.length - 1;
+        var mid;
+        if (ucs < data[0][0] || ucs > data[max][1]) {
+            return false;
+        }
+        while (max >= min) {
+            mid = (min + max) >> 1;
+            if (ucs > data[mid][1]) {
+                min = mid + 1;
+            }
+            else if (ucs < data[mid][0]) {
+                max = mid - 1;
+            }
+            else {
+                return true;
+            }
+        }
+        return false;
+    }
+    function wcwidthHigh(ucs) {
+        if (bisearch(ucs, COMBINING_HIGH)) {
+            return 0;
+        }
+        if ((ucs >= 0x20000 && ucs <= 0x2fffd) || (ucs >= 0x30000 && ucs <= 0x3fffd)) {
+            return 2;
+        }
+        return 1;
+    }
+    var control = opts.control | 0;
+    var table = new Uint8Array(65536);
+    TypedArrayUtils_1.fill(table, 1);
+    table[0] = opts.nul;
+    TypedArrayUtils_1.fill(table, opts.control, 1, 32);
+    TypedArrayUtils_1.fill(table, opts.control, 0x7f, 0xa0);
+    TypedArrayUtils_1.fill(table, 2, 0x1100, 0x1160);
+    table[0x2329] = 2;
+    table[0x232a] = 2;
+    TypedArrayUtils_1.fill(table, 2, 0x2e80, 0xa4d0);
+    table[0x303f] = 1;
+    TypedArrayUtils_1.fill(table, 2, 0xac00, 0xd7a4);
+    TypedArrayUtils_1.fill(table, 2, 0xf900, 0xfb00);
+    TypedArrayUtils_1.fill(table, 2, 0xfe10, 0xfe1a);
+    TypedArrayUtils_1.fill(table, 2, 0xfe30, 0xfe70);
+    TypedArrayUtils_1.fill(table, 2, 0xff00, 0xff61);
+    TypedArrayUtils_1.fill(table, 2, 0xffe0, 0xffe7);
+    for (var r = 0; r < COMBINING_BMP.length; ++r) {
+        TypedArrayUtils_1.fill(table, 0, COMBINING_BMP[r][0], COMBINING_BMP[r][1] + 1);
+    }
+    return function (num) {
+        if (num < 32) {
+            return control | 0;
+        }
+        if (num < 127) {
+            return 1;
+        }
+        if (num < 65536) {
+            return table[num];
+        }
+        return wcwidthHigh(num);
+    };
+})({ nul: 0, control: 0 });
+function getStringCellWidth(s) {
+    var result = 0;
+    var length = s.length;
+    for (var i = 0; i < length; ++i) {
+        var code = s.charCodeAt(i);
+        if (0xD800 <= code && code <= 0xDBFF) {
+            if (++i >= length) {
+                return result + exports.wcwidth(code);
+            }
+            var second = s.charCodeAt(i);
+            if (0xDC00 <= second && second <= 0xDFFF) {
+                code = (code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
+            }
+            else {
+                result += exports.wcwidth(second);
+            }
+        }
+        result += exports.wcwidth(code);
+    }
+    return result;
+}
+exports.getStringCellWidth = getStringCellWidth;
+
+},{"./common/TypedArrayUtils":28}],8:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+function prepareTextForTerminal(text) {
+    return text.replace(/\r?\n/g, '\r');
+}
+exports.prepareTextForTerminal = prepareTextForTerminal;
+function bracketTextForPaste(text, bracketedPasteMode) {
+    if (bracketedPasteMode) {
+        return '\x1b[200~' + text + '\x1b[201~';
+    }
+    return text;
+}
+exports.bracketTextForPaste = bracketTextForPaste;
+function copyHandler(ev, term, selectionManager) {
+    if (term.browser.isMSIE) {
+        window.clipboardData.setData('Text', selectionManager.selectionText);
+    }
+    else {
+        ev.clipboardData.setData('text/plain', selectionManager.selectionText);
+    }
+    ev.preventDefault();
+}
+exports.copyHandler = copyHandler;
+function pasteHandler(ev, term) {
+    ev.stopPropagation();
+    var text;
+    var dispatchPaste = function (text) {
+        text = prepareTextForTerminal(text);
+        text = bracketTextForPaste(text, term.bracketedPasteMode);
+        term.handler(text);
+        term.textarea.value = '';
+        term.emit('paste', text);
+        term.cancel(ev);
+    };
+    if (term.browser.isMSIE) {
+        if (window.clipboardData) {
+            text = window.clipboardData.getData('Text');
+            dispatchPaste(text);
+        }
+    }
+    else {
+        if (ev.clipboardData) {
+            text = ev.clipboardData.getData('text/plain');
+            dispatchPaste(text);
+        }
+    }
+}
+exports.pasteHandler = pasteHandler;
+function moveTextAreaUnderMouseCursor(ev, term) {
+    var pos = term.screenElement.getBoundingClientRect();
+    var left = ev.clientX - pos.left - 10;
+    var top = ev.clientY - pos.top - 10;
+    term.textarea.style.position = 'absolute';
+    term.textarea.style.width = '20px';
+    term.textarea.style.height = '20px';
+    term.textarea.style.left = left + "px";
+    term.textarea.style.top = top + "px";
+    term.textarea.style.zIndex = '1000';
+    term.textarea.focus();
+    setTimeout(function () {
+        term.textarea.style.position = null;
+        term.textarea.style.width = null;
+        term.textarea.style.height = null;
+        term.textarea.style.left = null;
+        term.textarea.style.top = null;
+        term.textarea.style.zIndex = null;
+    }, 200);
+}
+exports.moveTextAreaUnderMouseCursor = moveTextAreaUnderMouseCursor;
+function rightClickHandler(ev, term, selectionManager, shouldSelectWord) {
+    moveTextAreaUnderMouseCursor(ev, term);
+    if (shouldSelectWord && !selectionManager.isClickInSelection(ev)) {
+        selectionManager.selectWordAtCursor(ev);
+    }
+    term.textarea.value = selectionManager.selectionText;
+    term.textarea.select();
+}
+exports.rightClickHandler = rightClickHandler;
+
+},{}],9:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var CompositionHelper = (function () {
+    function CompositionHelper(_textarea, _compositionView, _terminal) {
+        this._textarea = _textarea;
+        this._compositionView = _compositionView;
+        this._terminal = _terminal;
+        this._isComposing = false;
+        this._isSendingComposition = false;
+        this._compositionPosition = { start: null, end: null };
+    }
+    CompositionHelper.prototype.compositionstart = function () {
+        this._isComposing = true;
+        this._compositionPosition.start = this._textarea.value.length;
+        this._compositionView.textContent = '';
+        this._compositionView.classList.add('active');
+    };
+    CompositionHelper.prototype.compositionupdate = function (ev) {
+        var _this = this;
+        this._compositionView.textContent = ev.data;
+        this.updateCompositionElements();
+        setTimeout(function () {
+            _this._compositionPosition.end = _this._textarea.value.length;
+        }, 0);
+    };
+    CompositionHelper.prototype.compositionend = function () {
+        this._finalizeComposition(true);
+    };
+    CompositionHelper.prototype.keydown = function (ev) {
+        if (this._isComposing || this._isSendingComposition) {
+            if (ev.keyCode === 229) {
+                return false;
+            }
+            else if (ev.keyCode === 16 || ev.keyCode === 17 || ev.keyCode === 18) {
+                return false;
+            }
+            this._finalizeComposition(false);
+        }
+        if (ev.keyCode === 229) {
+            this._handleAnyTextareaChanges();
+            return false;
+        }
+        return true;
+    };
+    CompositionHelper.prototype._finalizeComposition = function (waitForPropagation) {
+        var _this = this;
+        this._compositionView.classList.remove('active');
+        this._isComposing = false;
+        this._clearTextareaPosition();
+        if (!waitForPropagation) {
+            this._isSendingComposition = false;
+            var input = this._textarea.value.substring(this._compositionPosition.start, this._compositionPosition.end);
+            this._terminal.handler(input);
+        }
+        else {
+            var currentCompositionPosition_1 = {
+                start: this._compositionPosition.start,
+                end: this._compositionPosition.end
+            };
+            this._isSendingComposition = true;
+            setTimeout(function () {
+                if (_this._isSendingComposition) {
+                    _this._isSendingComposition = false;
+                    var input = void 0;
+                    if (_this._isComposing) {
+                        input = _this._textarea.value.substring(currentCompositionPosition_1.start, currentCompositionPosition_1.end);
+                    }
+                    else {
+                        input = _this._textarea.value.substring(currentCompositionPosition_1.start);
+                    }
+                    _this._terminal.handler(input);
+                }
+            }, 0);
+        }
+    };
+    CompositionHelper.prototype._handleAnyTextareaChanges = function () {
+        var _this = this;
+        var oldValue = this._textarea.value;
+        setTimeout(function () {
+            if (!_this._isComposing) {
+                var newValue = _this._textarea.value;
+                var diff = newValue.replace(oldValue, '');
+                if (diff.length > 0) {
+                    _this._terminal.handler(diff);
+                }
+            }
+        }, 0);
+    };
+    CompositionHelper.prototype.updateCompositionElements = function (dontRecurse) {
+        var _this = this;
+        if (!this._isComposing) {
+            return;
+        }
+        if (this._terminal.buffer.isCursorInViewport) {
+            var cellHeight = Math.ceil(this._terminal.charMeasure.height * this._terminal.options.lineHeight);
+            var cursorTop = this._terminal.buffer.y * cellHeight;
+            var cursorLeft = this._terminal.buffer.x * this._terminal.charMeasure.width;
+            this._compositionView.style.left = cursorLeft + 'px';
+            this._compositionView.style.top = cursorTop + 'px';
+            this._compositionView.style.height = cellHeight + 'px';
+            this._compositionView.style.lineHeight = cellHeight + 'px';
+            this._compositionView.style.fontFamily = this._terminal.options.fontFamily;
+            this._compositionView.style.fontSize = this._terminal.options.fontSize + 'px';
+            var compositionViewBounds = this._compositionView.getBoundingClientRect();
+            this._textarea.style.left = cursorLeft + 'px';
+            this._textarea.style.top = cursorTop + 'px';
+            this._textarea.style.width = compositionViewBounds.width + 'px';
+            this._textarea.style.height = compositionViewBounds.height + 'px';
+            this._textarea.style.lineHeight = compositionViewBounds.height + 'px';
+        }
+        if (!dontRecurse) {
+            setTimeout(function () { return _this.updateCompositionElements(true); }, 0);
+        }
+    };
+    CompositionHelper.prototype._clearTextareaPosition = function () {
+        this._textarea.style.left = '';
+        this._textarea.style.top = '';
+    };
+    return CompositionHelper;
+}());
+exports.CompositionHelper = CompositionHelper;
+
+},{}],10:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = function (d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var Lifecycle_1 = require("./common/Lifecycle");
+var TextDecoder_1 = require("./core/input/TextDecoder");
+function r(low, high) {
+    var c = high - low;
+    var arr = new Array(c);
+    while (c--) {
+        arr[c] = --high;
+    }
+    return arr;
+}
+var TransitionTable = (function () {
+    function TransitionTable(length) {
+        this.table = (typeof Uint8Array === 'undefined')
+            ? new Array(length)
+            : new Uint8Array(length);
+    }
+    TransitionTable.prototype.add = function (code, state, action, next) {
+        this.table[state << 8 | code] = ((action | 0) << 4) | ((next === undefined) ? state : next);
+    };
+    TransitionTable.prototype.addMany = function (codes, state, action, next) {
+        for (var i = 0; i < codes.length; i++) {
+            this.add(codes[i], state, action, next);
+        }
+    };
+    return TransitionTable;
+}());
+exports.TransitionTable = TransitionTable;
+var PRINTABLES = r(0x20, 0x7f);
+var EXECUTABLES = r(0x00, 0x18);
+EXECUTABLES.push(0x19);
+EXECUTABLES.push.apply(EXECUTABLES, r(0x1c, 0x20));
+var NON_ASCII_PRINTABLE = 0xA0;
+exports.VT500_TRANSITION_TABLE = (function () {
+    var table = new TransitionTable(4095);
+    var states = r(0, 13 + 1);
+    var state;
+    for (state in states) {
+        for (var code = 0; code <= NON_ASCII_PRINTABLE; ++code) {
+            table.add(code, state, 1, 0);
+        }
+    }
+    table.addMany(PRINTABLES, 0, 2, 0);
+    for (state in states) {
+        table.addMany([0x18, 0x1a, 0x99, 0x9a], state, 3, 0);
+        table.addMany(r(0x80, 0x90), state, 3, 0);
+        table.addMany(r(0x90, 0x98), state, 3, 0);
+        table.add(0x9c, state, 0, 0);
+        table.add(0x1b, state, 11, 1);
+        table.add(0x9d, state, 4, 8);
+        table.addMany([0x98, 0x9e, 0x9f], state, 0, 7);
+        table.add(0x9b, state, 11, 3);
+        table.add(0x90, state, 11, 9);
+    }
+    table.addMany(EXECUTABLES, 0, 3, 0);
+    table.addMany(EXECUTABLES, 1, 3, 1);
+    table.add(0x7f, 1, 0, 1);
+    table.addMany(EXECUTABLES, 8, 0, 8);
+    table.addMany(EXECUTABLES, 3, 3, 3);
+    table.add(0x7f, 3, 0, 3);
+    table.addMany(EXECUTABLES, 4, 3, 4);
+    table.add(0x7f, 4, 0, 4);
+    table.addMany(EXECUTABLES, 6, 3, 6);
+    table.addMany(EXECUTABLES, 5, 3, 5);
+    table.add(0x7f, 5, 0, 5);
+    table.addMany(EXECUTABLES, 2, 3, 2);
+    table.add(0x7f, 2, 0, 2);
+    table.add(0x5d, 1, 4, 8);
+    table.addMany(PRINTABLES, 8, 5, 8);
+    table.add(0x7f, 8, 5, 8);
+    table.addMany([0x9c, 0x1b, 0x18, 0x1a, 0x07], 8, 6, 0);
+    table.addMany(r(0x1c, 0x20), 8, 0, 8);
+    table.addMany([0x58, 0x5e, 0x5f], 1, 0, 7);
+    table.addMany(PRINTABLES, 7, 0, 7);
+    table.addMany(EXECUTABLES, 7, 0, 7);
+    table.add(0x9c, 7, 0, 0);
+    table.add(0x7f, 7, 0, 7);
+    table.add(0x5b, 1, 11, 3);
+    table.addMany(r(0x40, 0x7f), 3, 7, 0);
+    table.addMany(r(0x30, 0x3a), 3, 8, 4);
+    table.add(0x3b, 3, 8, 4);
+    table.addMany([0x3c, 0x3d, 0x3e, 0x3f], 3, 9, 4);
+    table.addMany(r(0x30, 0x3a), 4, 8, 4);
+    table.add(0x3b, 4, 8, 4);
+    table.addMany(r(0x40, 0x7f), 4, 7, 0);
+    table.addMany([0x3a, 0x3c, 0x3d, 0x3e, 0x3f], 4, 0, 6);
+    table.addMany(r(0x20, 0x40), 6, 0, 6);
+    table.add(0x7f, 6, 0, 6);
+    table.addMany(r(0x40, 0x7f), 6, 0, 0);
+    table.add(0x3a, 3, 0, 6);
+    table.addMany(r(0x20, 0x30), 3, 9, 5);
+    table.addMany(r(0x20, 0x30), 5, 9, 5);
+    table.addMany(r(0x30, 0x40), 5, 0, 6);
+    table.addMany(r(0x40, 0x7f), 5, 7, 0);
+    table.addMany(r(0x20, 0x30), 4, 9, 5);
+    table.addMany(r(0x20, 0x30), 1, 9, 2);
+    table.addMany(r(0x20, 0x30), 2, 9, 2);
+    table.addMany(r(0x30, 0x7f), 2, 10, 0);
+    table.addMany(r(0x30, 0x50), 1, 10, 0);
+    table.addMany(r(0x51, 0x58), 1, 10, 0);
+    table.addMany([0x59, 0x5a, 0x5c], 1, 10, 0);
+    table.addMany(r(0x60, 0x7f), 1, 10, 0);
+    table.add(0x50, 1, 11, 9);
+    table.addMany(EXECUTABLES, 9, 0, 9);
+    table.add(0x7f, 9, 0, 9);
+    table.addMany(r(0x1c, 0x20), 9, 0, 9);
+    table.addMany(r(0x20, 0x30), 9, 9, 12);
+    table.add(0x3a, 9, 0, 11);
+    table.addMany(r(0x30, 0x3a), 9, 8, 10);
+    table.add(0x3b, 9, 8, 10);
+    table.addMany([0x3c, 0x3d, 0x3e, 0x3f], 9, 9, 10);
+    table.addMany(EXECUTABLES, 11, 0, 11);
+    table.addMany(r(0x20, 0x80), 11, 0, 11);
+    table.addMany(r(0x1c, 0x20), 11, 0, 11);
+    table.addMany(EXECUTABLES, 10, 0, 10);
+    table.add(0x7f, 10, 0, 10);
+    table.addMany(r(0x1c, 0x20), 10, 0, 10);
+    table.addMany(r(0x30, 0x3a), 10, 8, 10);
+    table.add(0x3b, 10, 8, 10);
+    table.addMany([0x3a, 0x3c, 0x3d, 0x3e, 0x3f], 10, 0, 11);
+    table.addMany(r(0x20, 0x30), 10, 9, 12);
+    table.addMany(EXECUTABLES, 12, 0, 12);
+    table.add(0x7f, 12, 0, 12);
+    table.addMany(r(0x1c, 0x20), 12, 0, 12);
+    table.addMany(r(0x20, 0x30), 12, 9, 12);
+    table.addMany(r(0x30, 0x40), 12, 0, 11);
+    table.addMany(r(0x40, 0x7f), 12, 12, 13);
+    table.addMany(r(0x40, 0x7f), 10, 12, 13);
+    table.addMany(r(0x40, 0x7f), 9, 12, 13);
+    table.addMany(EXECUTABLES, 13, 13, 13);
+    table.addMany(PRINTABLES, 13, 13, 13);
+    table.add(0x7f, 13, 0, 13);
+    table.addMany([0x1b, 0x9c], 13, 14, 0);
+    table.add(NON_ASCII_PRINTABLE, 8, 5, 8);
+    return table;
+})();
+var DcsDummy = (function () {
+    function DcsDummy() {
+    }
+    DcsDummy.prototype.hook = function (collect, params, flag) { };
+    DcsDummy.prototype.put = function (data, start, end) { };
+    DcsDummy.prototype.unhook = function () { };
+    return DcsDummy;
+}());
+var EscapeSequenceParser = (function (_super) {
+    __extends(EscapeSequenceParser, _super);
+    function EscapeSequenceParser(TRANSITIONS) {
+        if (TRANSITIONS === void 0) { TRANSITIONS = exports.VT500_TRANSITION_TABLE; }
+        var _this = _super.call(this) || this;
+        _this.TRANSITIONS = TRANSITIONS;
+        _this.initialState = 0;
+        _this.currentState = _this.initialState;
+        _this._osc = '';
+        _this._params = [0];
+        _this._collect = '';
+        _this._printHandlerFb = function (data, start, end) { };
+        _this._executeHandlerFb = function (code) { };
+        _this._csiHandlerFb = function (collect, params, flag) { };
+        _this._escHandlerFb = function (collect, flag) { };
+        _this._oscHandlerFb = function (identifier, data) { };
+        _this._dcsHandlerFb = new DcsDummy();
+        _this._errorHandlerFb = function (state) { return state; };
+        _this._printHandler = _this._printHandlerFb;
+        _this._executeHandlers = Object.create(null);
+        _this._csiHandlers = Object.create(null);
+        _this._escHandlers = Object.create(null);
+        _this._oscHandlers = Object.create(null);
+        _this._dcsHandlers = Object.create(null);
+        _this._activeDcsHandler = null;
+        _this._errorHandler = _this._errorHandlerFb;
+        _this.setEscHandler('\\', function () { });
+        return _this;
+    }
+    EscapeSequenceParser.prototype.dispose = function () {
+        this._printHandlerFb = null;
+        this._executeHandlerFb = null;
+        this._csiHandlerFb = null;
+        this._escHandlerFb = null;
+        this._oscHandlerFb = null;
+        this._dcsHandlerFb = null;
+        this._errorHandlerFb = null;
+        this._printHandler = null;
+        this._executeHandlers = null;
+        this._escHandlers = null;
+        this._csiHandlers = null;
+        this._oscHandlers = null;
+        this._dcsHandlers = null;
+        this._activeDcsHandler = null;
+        this._errorHandler = null;
+    };
+    EscapeSequenceParser.prototype.setPrintHandler = function (callback) {
+        this._printHandler = callback;
+    };
+    EscapeSequenceParser.prototype.clearPrintHandler = function () {
+        this._printHandler = this._printHandlerFb;
+    };
+    EscapeSequenceParser.prototype.setExecuteHandler = function (flag, callback) {
+        this._executeHandlers[flag.charCodeAt(0)] = callback;
+    };
+    EscapeSequenceParser.prototype.clearExecuteHandler = function (flag) {
+        if (this._executeHandlers[flag.charCodeAt(0)])
+            delete this._executeHandlers[flag.charCodeAt(0)];
+    };
+    EscapeSequenceParser.prototype.setExecuteHandlerFallback = function (callback) {
+        this._executeHandlerFb = callback;
+    };
+    EscapeSequenceParser.prototype.addCsiHandler = function (flag, callback) {
+        var index = flag.charCodeAt(0);
+        if (this._csiHandlers[index] === undefined) {
+            this._csiHandlers[index] = [];
+        }
+        var handlerList = this._csiHandlers[index];
+        handlerList.push(callback);
+        return {
+            dispose: function () {
+                var handlerIndex = handlerList.indexOf(callback);
+                if (handlerIndex !== -1) {
+                    handlerList.splice(handlerIndex, 1);
+                }
+            }
+        };
+    };
+    EscapeSequenceParser.prototype.setCsiHandler = function (flag, callback) {
+        this._csiHandlers[flag.charCodeAt(0)] = [callback];
+    };
+    EscapeSequenceParser.prototype.clearCsiHandler = function (flag) {
+        if (this._csiHandlers[flag.charCodeAt(0)])
+            delete this._csiHandlers[flag.charCodeAt(0)];
+    };
+    EscapeSequenceParser.prototype.setCsiHandlerFallback = function (callback) {
+        this._csiHandlerFb = callback;
+    };
+    EscapeSequenceParser.prototype.setEscHandler = function (collectAndFlag, callback) {
+        this._escHandlers[collectAndFlag] = callback;
+    };
+    EscapeSequenceParser.prototype.clearEscHandler = function (collectAndFlag) {
+        if (this._escHandlers[collectAndFlag])
+            delete this._escHandlers[collectAndFlag];
+    };
+    EscapeSequenceParser.prototype.setEscHandlerFallback = function (callback) {
+        this._escHandlerFb = callback;
+    };
+    EscapeSequenceParser.prototype.addOscHandler = function (ident, callback) {
+        if (this._oscHandlers[ident] === undefined) {
+            this._oscHandlers[ident] = [];
+        }
+        var handlerList = this._oscHandlers[ident];
+        handlerList.push(callback);
+        return {
+            dispose: function () {
+                var handlerIndex = handlerList.indexOf(callback);
+                if (handlerIndex !== -1) {
+                    handlerList.splice(handlerIndex, 1);
+                }
+            }
+        };
+    };
+    EscapeSequenceParser.prototype.setOscHandler = function (ident, callback) {
+        this._oscHandlers[ident] = [callback];
+    };
+    EscapeSequenceParser.prototype.clearOscHandler = function (ident) {
+        if (this._oscHandlers[ident])
+            delete this._oscHandlers[ident];
+    };
+    EscapeSequenceParser.prototype.setOscHandlerFallback = function (callback) {
+        this._oscHandlerFb = callback;
+    };
+    EscapeSequenceParser.prototype.setDcsHandler = function (collectAndFlag, handler) {
+        this._dcsHandlers[collectAndFlag] = handler;
+    };
+    EscapeSequenceParser.prototype.clearDcsHandler = function (collectAndFlag) {
+        if (this._dcsHandlers[collectAndFlag])
+            delete this._dcsHandlers[collectAndFlag];
+    };
+    EscapeSequenceParser.prototype.setDcsHandlerFallback = function (handler) {
+        this._dcsHandlerFb = handler;
+    };
+    EscapeSequenceParser.prototype.setErrorHandler = function (callback) {
+        this._errorHandler = callback;
+    };
+    EscapeSequenceParser.prototype.clearErrorHandler = function () {
+        this._errorHandler = this._errorHandlerFb;
+    };
+    EscapeSequenceParser.prototype.reset = function () {
+        this.currentState = this.initialState;
+        this._osc = '';
+        this._params = [0];
+        this._collect = '';
+        this._activeDcsHandler = null;
+    };
+    EscapeSequenceParser.prototype.parse = function (data, length) {
+        var code = 0;
+        var transition = 0;
+        var error = false;
+        var currentState = this.currentState;
+        var print = -1;
+        var dcs = -1;
+        var osc = this._osc;
+        var collect = this._collect;
+        var params = this._params;
+        var table = this.TRANSITIONS.table;
+        var dcsHandler = this._activeDcsHandler;
+        var callback = null;
+        for (var i = 0; i < length; ++i) {
+            code = data[i];
+            if (currentState === 0 && code > 0x1f && code < 0x80) {
+                print = (~print) ? print : i;
+                do
+                    i++;
+                while (i < length && data[i] > 0x1f && data[i] < 0x80);
+                i--;
+                continue;
+            }
+            if (currentState === 4 && (code > 0x2f && code < 0x39)) {
+                params[params.length - 1] = params[params.length - 1] * 10 + code - 48;
+                continue;
+            }
+            transition = table[currentState << 8 | (code < 0xa0 ? code : NON_ASCII_PRINTABLE)];
+            switch (transition >> 4) {
+                case 2:
+                    print = (~print) ? print : i;
+                    break;
+                case 3:
+                    if (~print) {
+                        this._printHandler(data, print, i);
+                        print = -1;
+                    }
+                    callback = this._executeHandlers[code];
+                    if (callback)
+                        callback();
+                    else
+                        this._executeHandlerFb(code);
+                    break;
+                case 0:
+                    if (~print) {
+                        this._printHandler(data, print, i);
+                        print = -1;
+                    }
+                    else if (~dcs) {
+                        dcsHandler.put(data, dcs, i);
+                        dcs = -1;
+                    }
+                    break;
+                case 1:
+                    if (code > 0x9f) {
+                        switch (currentState) {
+                            case 0:
+                                print = (~print) ? print : i;
+                                break;
+                            case 6:
+                                transition |= 6;
+                                break;
+                            case 11:
+                                transition |= 11;
+                                break;
+                            case 13:
+                                dcs = (~dcs) ? dcs : i;
+                                transition |= 13;
+                                break;
+                            default:
+                                error = true;
+                        }
+                    }
+                    else {
+                        error = true;
+                    }
+                    if (error) {
+                        var inject = this._errorHandler({
+                            position: i,
+                            code: code,
+                            currentState: currentState,
+                            print: print,
+                            dcs: dcs,
+                            osc: osc,
+                            collect: collect,
+                            params: params,
+                            abort: false
+                        });
+                        if (inject.abort)
+                            return;
+                        error = false;
+                    }
+                    break;
+                case 7:
+                    var handlers = this._csiHandlers[code];
+                    var j = handlers ? handlers.length - 1 : -1;
+                    for (; j >= 0; j--) {
+                        if (handlers[j](params, collect) !== false) {
+                            break;
+                        }
+                    }
+                    if (j < 0) {
+                        this._csiHandlerFb(collect, params, code);
+                    }
+                    break;
+                case 8:
+                    if (code === 0x3b)
+                        params.push(0);
+                    else
+                        params[params.length - 1] = params[params.length - 1] * 10 + code - 48;
+                    break;
+                case 9:
+                    collect += String.fromCharCode(code);
+                    break;
+                case 10:
+                    callback = this._escHandlers[collect + String.fromCharCode(code)];
+                    if (callback)
+                        callback(collect, code);
+                    else
+                        this._escHandlerFb(collect, code);
+                    break;
+                case 11:
+                    if (~print) {
+                        this._printHandler(data, print, i);
+                        print = -1;
+                    }
+                    osc = '';
+                    params = [0];
+                    collect = '';
+                    dcs = -1;
+                    break;
+                case 12:
+                    dcsHandler = this._dcsHandlers[collect + String.fromCharCode(code)];
+                    if (!dcsHandler)
+                        dcsHandler = this._dcsHandlerFb;
+                    dcsHandler.hook(collect, params, code);
+                    break;
+                case 13:
+                    dcs = (~dcs) ? dcs : i;
+                    break;
+                case 14:
+                    if (dcsHandler) {
+                        if (~dcs)
+                            dcsHandler.put(data, dcs, i);
+                        dcsHandler.unhook();
+                        dcsHandler = null;
+                    }
+                    if (code === 0x1b)
+                        transition |= 1;
+                    osc = '';
+                    params = [0];
+                    collect = '';
+                    dcs = -1;
+                    break;
+                case 4:
+                    if (~print) {
+                        this._printHandler(data, print, i);
+                        print = -1;
+                    }
+                    osc = '';
+                    break;
+                case 5:
+                    for (var j_1 = i + 1;; j_1++) {
+                        if (j_1 >= length
+                            || (code = data[j_1]) < 0x20
+                            || (code > 0x7f && code <= 0x9f)) {
+                            osc += TextDecoder_1.utf32ToString(data, i, j_1);
+                            i = j_1 - 1;
+                            break;
+                        }
+                    }
+                    break;
+                case 6:
+                    if (osc && code !== 0x18 && code !== 0x1a) {
+                        var idx = osc.indexOf(';');
+                        if (idx === -1) {
+                            this._oscHandlerFb(-1, osc);
+                        }
+                        else {
+                            var identifier = parseInt(osc.substring(0, idx));
+                            var content = osc.substring(idx + 1);
+                            var handlers_1 = this._oscHandlers[identifier];
+                            var j_2 = handlers_1 ? handlers_1.length - 1 : -1;
+                            for (; j_2 >= 0; j_2--) {
+                                if (handlers_1[j_2](content) !== false) {
+                                    break;
+                                }
+                            }
+                            if (j_2 < 0) {
+                                this._oscHandlerFb(identifier, content);
+                            }
+                        }
+                    }
+                    if (code === 0x1b)
+                        transition |= 1;
+                    osc = '';
+                    params = [0];
+                    collect = '';
+                    dcs = -1;
+                    break;
+            }
+            currentState = transition & 15;
+        }
+        if (currentState === 0 && ~print) {
+            this._printHandler(data, print, length);
+        }
+        else if (currentState === 13 && ~dcs && dcsHandler) {
+            dcsHandler.put(data, dcs, length);
+        }
+        this._osc = osc;
+        this._collect = collect;
+        this._params = params;
+        this._activeDcsHandler = dcsHandler;
+        this.currentState = currentState;
+    };
+    return EscapeSequenceParser;
+}(Lifecycle_1.Disposable));
+exports.EscapeSequenceParser = EscapeSequenceParser;
+
+},{"./common/Lifecycle":26,"./core/input/TextDecoder":32}],11:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = function (d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var EscapeSequences_1 = require("./common/data/EscapeSequences");
+var Charsets_1 = require("./core/data/Charsets");
+var Buffer_1 = require("./Buffer");
+var CharWidth_1 = require("./CharWidth");
+var EscapeSequenceParser_1 = require("./EscapeSequenceParser");
+var Lifecycle_1 = require("./common/Lifecycle");
+var TypedArrayUtils_1 = require("./common/TypedArrayUtils");
+var TextDecoder_1 = require("./core/input/TextDecoder");
+var BufferLine_1 = require("./BufferLine");
+var EventEmitter2_1 = require("./common/EventEmitter2");
+var GLEVEL = { '(': 0, ')': 1, '*': 2, '+': 3, '-': 1, '.': 2 };
+var DECRQSS = (function () {
+    function DECRQSS(_terminal) {
+        this._terminal = _terminal;
+        this._data = new Uint32Array(0);
+    }
+    DECRQSS.prototype.hook = function (collect, params, flag) {
+        this._data = new Uint32Array(0);
+    };
+    DECRQSS.prototype.put = function (data, start, end) {
+        this._data = TypedArrayUtils_1.concat(this._data, data.subarray(start, end));
+    };
+    DECRQSS.prototype.unhook = function () {
+        var data = TextDecoder_1.utf32ToString(this._data);
+        this._data = new Uint32Array(0);
+        switch (data) {
+            case '"q':
+                return this._terminal.handler(EscapeSequences_1.C0.ESC + "P1$r0\"q" + EscapeSequences_1.C0.ESC + "\\");
+            case '"p':
+                return this._terminal.handler(EscapeSequences_1.C0.ESC + "P1$r61\"p" + EscapeSequences_1.C0.ESC + "\\");
+            case 'r':
+                var pt = '' + (this._terminal.buffer.scrollTop + 1) +
+                    ';' + (this._terminal.buffer.scrollBottom + 1) + 'r';
+                return this._terminal.handler(EscapeSequences_1.C0.ESC + "P1$r" + pt + EscapeSequences_1.C0.ESC + "\\");
+            case 'm':
+                return this._terminal.handler(EscapeSequences_1.C0.ESC + "P1$r0m" + EscapeSequences_1.C0.ESC + "\\");
+            case ' q':
+                var STYLES = { 'block': 2, 'underline': 4, 'bar': 6 };
+                var style = STYLES[this._terminal.getOption('cursorStyle')];
+                style -= this._terminal.getOption('cursorBlink');
+                return this._terminal.handler(EscapeSequences_1.C0.ESC + "P1$r" + style + " q" + EscapeSequences_1.C0.ESC + "\\");
+            default:
+                this._terminal.error('Unknown DCS $q %s', data);
+                this._terminal.handler(EscapeSequences_1.C0.ESC + "P0$r" + EscapeSequences_1.C0.ESC + "\\");
+        }
+    };
+    return DECRQSS;
+}());
+var InputHandler = (function (_super) {
+    __extends(InputHandler, _super);
+    function InputHandler(_terminal, _parser) {
+        if (_parser === void 0) { _parser = new EscapeSequenceParser_1.EscapeSequenceParser(); }
+        var _this = _super.call(this) || this;
+        _this._terminal = _terminal;
+        _this._parser = _parser;
+        _this._parseBuffer = new Uint32Array(4096);
+        _this._stringDecoder = new TextDecoder_1.StringToUtf32();
+        _this._workCell = new BufferLine_1.CellData();
+        _this._onCursorMove = new EventEmitter2_1.EventEmitter2();
+        _this._onData = new EventEmitter2_1.EventEmitter2();
+        _this._onLineFeed = new EventEmitter2_1.EventEmitter2();
+        _this._onScroll = new EventEmitter2_1.EventEmitter2();
+        _this.register(_this._parser);
+        _this._parser.setCsiHandlerFallback(function (collect, params, flag) {
+            _this._terminal.error('Unknown CSI code: ', { collect: collect, params: params, flag: String.fromCharCode(flag) });
+        });
+        _this._parser.setEscHandlerFallback(function (collect, flag) {
+            _this._terminal.error('Unknown ESC code: ', { collect: collect, flag: String.fromCharCode(flag) });
+        });
+        _this._parser.setExecuteHandlerFallback(function (code) {
+            _this._terminal.error('Unknown EXECUTE code: ', { code: code });
+        });
+        _this._parser.setOscHandlerFallback(function (identifier, data) {
+            _this._terminal.error('Unknown OSC code: ', { identifier: identifier, data: data });
+        });
+        _this._parser.setPrintHandler(function (data, start, end) { return _this.print(data, start, end); });
+        _this._parser.setCsiHandler('@', function (params, collect) { return _this.insertChars(params); });
+        _this._parser.setCsiHandler('A', function (params, collect) { return _this.cursorUp(params); });
+        _this._parser.setCsiHandler('B', function (params, collect) { return _this.cursorDown(params); });
+        _this._parser.setCsiHandler('C', function (params, collect) { return _this.cursorForward(params); });
+        _this._parser.setCsiHandler('D', function (params, collect) { return _this.cursorBackward(params); });
+        _this._parser.setCsiHandler('E', function (params, collect) { return _this.cursorNextLine(params); });
+        _this._parser.setCsiHandler('F', function (params, collect) { return _this.cursorPrecedingLine(params); });
+        _this._parser.setCsiHandler('G', function (params, collect) { return _this.cursorCharAbsolute(params); });
+        _this._parser.setCsiHandler('H', function (params, collect) { return _this.cursorPosition(params); });
+        _this._parser.setCsiHandler('I', function (params, collect) { return _this.cursorForwardTab(params); });
+        _this._parser.setCsiHandler('J', function (params, collect) { return _this.eraseInDisplay(params); });
+        _this._parser.setCsiHandler('K', function (params, collect) { return _this.eraseInLine(params); });
+        _this._parser.setCsiHandler('L', function (params, collect) { return _this.insertLines(params); });
+        _this._parser.setCsiHandler('M', function (params, collect) { return _this.deleteLines(params); });
+        _this._parser.setCsiHandler('P', function (params, collect) { return _this.deleteChars(params); });
+        _this._parser.setCsiHandler('S', function (params, collect) { return _this.scrollUp(params); });
+        _this._parser.setCsiHandler('T', function (params, collect) { return _this.scrollDown(params, collect); });
+        _this._parser.setCsiHandler('X', function (params, collect) { return _this.eraseChars(params); });
+        _this._parser.setCsiHandler('Z', function (params, collect) { return _this.cursorBackwardTab(params); });
+        _this._parser.setCsiHandler('`', function (params, collect) { return _this.charPosAbsolute(params); });
+        _this._parser.setCsiHandler('a', function (params, collect) { return _this.hPositionRelative(params); });
+        _this._parser.setCsiHandler('b', function (params, collect) { return _this.repeatPrecedingCharacter(params); });
+        _this._parser.setCsiHandler('c', function (params, collect) { return _this.sendDeviceAttributes(params, collect); });
+        _this._parser.setCsiHandler('d', function (params, collect) { return _this.linePosAbsolute(params); });
+        _this._parser.setCsiHandler('e', function (params, collect) { return _this.vPositionRelative(params); });
+        _this._parser.setCsiHandler('f', function (params, collect) { return _this.hVPosition(params); });
+        _this._parser.setCsiHandler('g', function (params, collect) { return _this.tabClear(params); });
+        _this._parser.setCsiHandler('h', function (params, collect) { return _this.setMode(params, collect); });
+        _this._parser.setCsiHandler('l', function (params, collect) { return _this.resetMode(params, collect); });
+        _this._parser.setCsiHandler('m', function (params, collect) { return _this.charAttributes(params); });
+        _this._parser.setCsiHandler('n', function (params, collect) { return _this.deviceStatus(params, collect); });
+        _this._parser.setCsiHandler('p', function (params, collect) { return _this.softReset(params, collect); });
+        _this._parser.setCsiHandler('q', function (params, collect) { return _this.setCursorStyle(params, collect); });
+        _this._parser.setCsiHandler('r', function (params, collect) { return _this.setScrollRegion(params, collect); });
+        _this._parser.setCsiHandler('s', function (params, collect) { return _this.saveCursor(params); });
+        _this._parser.setCsiHandler('u', function (params, collect) { return _this.restoreCursor(params); });
+        _this._parser.setExecuteHandler(EscapeSequences_1.C0.BEL, function () { return _this.bell(); });
+        _this._parser.setExecuteHandler(EscapeSequences_1.C0.LF, function () { return _this.lineFeed(); });
+        _this._parser.setExecuteHandler(EscapeSequences_1.C0.VT, function () { return _this.lineFeed(); });
+        _this._parser.setExecuteHandler(EscapeSequences_1.C0.FF, function () { return _this.lineFeed(); });
+        _this._parser.setExecuteHandler(EscapeSequences_1.C0.CR, function () { return _this.carriageReturn(); });
+        _this._parser.setExecuteHandler(EscapeSequences_1.C0.BS, function () { return _this.backspace(); });
+        _this._parser.setExecuteHandler(EscapeSequences_1.C0.HT, function () { return _this.tab(); });
+        _this._parser.setExecuteHandler(EscapeSequences_1.C0.SO, function () { return _this.shiftOut(); });
+        _this._parser.setExecuteHandler(EscapeSequences_1.C0.SI, function () { return _this.shiftIn(); });
+        _this._parser.setExecuteHandler(EscapeSequences_1.C1.IND, function () { return _this.index(); });
+        _this._parser.setExecuteHandler(EscapeSequences_1.C1.NEL, function () { return _this.nextLine(); });
+        _this._parser.setExecuteHandler(EscapeSequences_1.C1.HTS, function () { return _this.tabSet(); });
+        _this._parser.setOscHandler(0, function (data) { return _this.setTitle(data); });
+        _this._parser.setOscHandler(2, function (data) { return _this.setTitle(data); });
+        _this._parser.setEscHandler('7', function () { return _this.saveCursor([]); });
+        _this._parser.setEscHandler('8', function () { return _this.restoreCursor([]); });
+        _this._parser.setEscHandler('D', function () { return _this.index(); });
+        _this._parser.setEscHandler('E', function () { return _this.nextLine(); });
+        _this._parser.setEscHandler('H', function () { return _this.tabSet(); });
+        _this._parser.setEscHandler('M', function () { return _this.reverseIndex(); });
+        _this._parser.setEscHandler('=', function () { return _this.keypadApplicationMode(); });
+        _this._parser.setEscHandler('>', function () { return _this.keypadNumericMode(); });
+        _this._parser.setEscHandler('c', function () { return _this.reset(); });
+        _this._parser.setEscHandler('n', function () { return _this.setgLevel(2); });
+        _this._parser.setEscHandler('o', function () { return _this.setgLevel(3); });
+        _this._parser.setEscHandler('|', function () { return _this.setgLevel(3); });
+        _this._parser.setEscHandler('}', function () { return _this.setgLevel(2); });
+        _this._parser.setEscHandler('~', function () { return _this.setgLevel(1); });
+        _this._parser.setEscHandler('%@', function () { return _this.selectDefaultCharset(); });
+        _this._parser.setEscHandler('%G', function () { return _this.selectDefaultCharset(); });
+        var _loop_1 = function (flag) {
+            this_1._parser.setEscHandler('(' + flag, function () { return _this.selectCharset('(' + flag); });
+            this_1._parser.setEscHandler(')' + flag, function () { return _this.selectCharset(')' + flag); });
+            this_1._parser.setEscHandler('*' + flag, function () { return _this.selectCharset('*' + flag); });
+            this_1._parser.setEscHandler('+' + flag, function () { return _this.selectCharset('+' + flag); });
+            this_1._parser.setEscHandler('-' + flag, function () { return _this.selectCharset('-' + flag); });
+            this_1._parser.setEscHandler('.' + flag, function () { return _this.selectCharset('.' + flag); });
+            this_1._parser.setEscHandler('/' + flag, function () { return _this.selectCharset('/' + flag); });
+        };
+        var this_1 = this;
+        for (var flag in Charsets_1.CHARSETS) {
+            _loop_1(flag);
+        }
+        _this._parser.setErrorHandler(function (state) {
+            _this._terminal.error('Parsing error: ', state);
+            return state;
+        });
+        _this._parser.setDcsHandler('$q', new DECRQSS(_this._terminal));
+        return _this;
+    }
+    Object.defineProperty(InputHandler.prototype, "onCursorMove", {
+        get: function () { return this._onCursorMove.event; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(InputHandler.prototype, "onData", {
+        get: function () { return this._onData.event; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(InputHandler.prototype, "onLineFeed", {
+        get: function () { return this._onLineFeed.event; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(InputHandler.prototype, "onScroll", {
+        get: function () { return this._onScroll.event; },
+        enumerable: true,
+        configurable: true
+    });
+    InputHandler.prototype.dispose = function () {
+        _super.prototype.dispose.call(this);
+        this._terminal = null;
+    };
+    InputHandler.prototype.parse = function (data) {
+        if (!this._terminal) {
+            return;
+        }
+        var buffer = this._terminal.buffer;
+        var cursorStartX = buffer.x;
+        var cursorStartY = buffer.y;
+        if (this._terminal.debug) {
+            this._terminal.log('data: ' + data);
+        }
+        if (this._parseBuffer.length < data.length) {
+            this._parseBuffer = new Uint32Array(data.length);
+        }
+        this._parser.parse(this._parseBuffer, this._stringDecoder.decode(data, this._parseBuffer));
+        buffer = this._terminal.buffer;
+        if (buffer.x !== cursorStartX || buffer.y !== cursorStartY) {
+            this._onCursorMove.fire();
+        }
+    };
+    InputHandler.prototype.print = function (data, start, end) {
+        var code;
+        var chWidth;
+        var buffer = this._terminal.buffer;
+        var charset = this._terminal.charset;
+        var screenReaderMode = this._terminal.options.screenReaderMode;
+        var cols = this._terminal.cols;
+        var wraparoundMode = this._terminal.wraparoundMode;
+        var insertMode = this._terminal.insertMode;
+        var curAttr = this._terminal.curAttrData;
+        var bufferRow = buffer.lines.get(buffer.y + buffer.ybase);
+        this._terminal.updateRange(buffer.y);
+        for (var pos = start; pos < end; ++pos) {
+            code = data[pos];
+            chWidth = CharWidth_1.wcwidth(code);
+            if (code < 127 && charset) {
+                var ch = charset[String.fromCharCode(code)];
+                if (ch) {
+                    code = ch.charCodeAt(0);
+                }
+            }
+            if (screenReaderMode) {
+                this._terminal.emit('a11y.char', TextDecoder_1.stringFromCodePoint(code));
+            }
+            if (!chWidth && buffer.x) {
+                if (!bufferRow.getWidth(buffer.x - 1)) {
+                    bufferRow.addCodepointToCell(buffer.x - 2, code);
+                }
+                else {
+                    bufferRow.addCodepointToCell(buffer.x - 1, code);
+                }
+                continue;
+            }
+            if (buffer.x + chWidth - 1 >= cols) {
+                if (wraparoundMode) {
+                    buffer.x = 0;
+                    buffer.y++;
+                    if (buffer.y > buffer.scrollBottom) {
+                        buffer.y--;
+                        this._terminal.scroll(true);
+                    }
+                    else {
+                        buffer.lines.get(buffer.y).isWrapped = true;
+                    }
+                    bufferRow = buffer.lines.get(buffer.y + buffer.ybase);
+                }
+                else {
+                    if (chWidth === 2) {
+                        continue;
+                    }
+                }
+            }
+            if (insertMode) {
+                bufferRow.insertCells(buffer.x, chWidth, buffer.getNullCell(curAttr));
+                if (bufferRow.getWidth(cols - 1) === 2) {
+                    bufferRow.setCellFromCodePoint(cols - 1, Buffer_1.NULL_CELL_CODE, Buffer_1.NULL_CELL_WIDTH, curAttr.fg, curAttr.bg);
+                }
+            }
+            bufferRow.setCellFromCodePoint(buffer.x++, code, chWidth, curAttr.fg, curAttr.bg);
+            if (chWidth > 0) {
+                while (--chWidth) {
+                    bufferRow.setCellFromCodePoint(buffer.x++, 0, 0, curAttr.fg, curAttr.bg);
+                }
+            }
+        }
+        this._terminal.updateRange(buffer.y);
+    };
+    InputHandler.prototype.addCsiHandler = function (flag, callback) {
+        return this._parser.addCsiHandler(flag, callback);
+    };
+    InputHandler.prototype.addOscHandler = function (ident, callback) {
+        return this._parser.addOscHandler(ident, callback);
+    };
+    InputHandler.prototype.bell = function () {
+        this._terminal.bell();
+    };
+    InputHandler.prototype.lineFeed = function () {
+        var buffer = this._terminal.buffer;
+        if (this._terminal.options.convertEol) {
+            buffer.x = 0;
+        }
+        buffer.y++;
+        if (buffer.y > buffer.scrollBottom) {
+            buffer.y--;
+            this._terminal.scroll();
+        }
+        if (buffer.x >= this._terminal.cols) {
+            buffer.x--;
+        }
+        this._onLineFeed.fire();
+    };
+    InputHandler.prototype.carriageReturn = function () {
+        this._terminal.buffer.x = 0;
+    };
+    InputHandler.prototype.backspace = function () {
+        if (this._terminal.buffer.x > 0) {
+            this._terminal.buffer.x--;
+        }
+    };
+    InputHandler.prototype.tab = function () {
+        var originalX = this._terminal.buffer.x;
+        this._terminal.buffer.x = this._terminal.buffer.nextStop();
+        if (this._terminal.options.screenReaderMode) {
+            this._terminal.emit('a11y.tab', this._terminal.buffer.x - originalX);
+        }
+    };
+    InputHandler.prototype.shiftOut = function () {
+        this._terminal.setgLevel(1);
+    };
+    InputHandler.prototype.shiftIn = function () {
+        this._terminal.setgLevel(0);
+    };
+    InputHandler.prototype.insertChars = function (params) {
+        this._terminal.buffer.lines.get(this._terminal.buffer.y + this._terminal.buffer.ybase).insertCells(this._terminal.buffer.x, params[0] || 1, this._terminal.buffer.getNullCell(this._terminal.eraseAttrData()));
+        this._terminal.updateRange(this._terminal.buffer.y);
+    };
+    InputHandler.prototype.cursorUp = function (params) {
+        var param = params[0];
+        if (param < 1) {
+            param = 1;
+        }
+        this._terminal.buffer.y -= param;
+        if (this._terminal.buffer.y < 0) {
+            this._terminal.buffer.y = 0;
+        }
+    };
+    InputHandler.prototype.cursorDown = function (params) {
+        var param = params[0];
+        if (param < 1) {
+            param = 1;
+        }
+        this._terminal.buffer.y += param;
+        if (this._terminal.buffer.y >= this._terminal.rows) {
+            this._terminal.buffer.y = this._terminal.rows - 1;
+        }
+        if (this._terminal.buffer.x >= this._terminal.cols) {
+            this._terminal.buffer.x--;
+        }
+    };
+    InputHandler.prototype.cursorForward = function (params) {
+        var param = params[0];
+        if (param < 1) {
+            param = 1;
+        }
+        this._terminal.buffer.x += param;
+        if (this._terminal.buffer.x >= this._terminal.cols) {
+            this._terminal.buffer.x = this._terminal.cols - 1;
+        }
+    };
+    InputHandler.prototype.cursorBackward = function (params) {
+        var param = params[0];
+        if (param < 1) {
+            param = 1;
+        }
+        if (this._terminal.buffer.x >= this._terminal.cols) {
+            this._terminal.buffer.x--;
+        }
+        this._terminal.buffer.x -= param;
+        if (this._terminal.buffer.x < 0) {
+            this._terminal.buffer.x = 0;
+        }
+    };
+    InputHandler.prototype.cursorNextLine = function (params) {
+        var param = params[0];
+        if (param < 1) {
+            param = 1;
+        }
+        this._terminal.buffer.y += param;
+        if (this._terminal.buffer.y >= this._terminal.rows) {
+            this._terminal.buffer.y = this._terminal.rows - 1;
+        }
+        this._terminal.buffer.x = 0;
+    };
+    InputHandler.prototype.cursorPrecedingLine = function (params) {
+        var param = params[0];
+        if (param < 1) {
+            param = 1;
+        }
+        this._terminal.buffer.y -= param;
+        if (this._terminal.buffer.y < 0) {
+            this._terminal.buffer.y = 0;
+        }
+        this._terminal.buffer.x = 0;
+    };
+    InputHandler.prototype.cursorCharAbsolute = function (params) {
+        var param = params[0];
+        if (param < 1) {
+            param = 1;
+        }
+        this._terminal.buffer.x = param - 1;
+    };
+    InputHandler.prototype.cursorPosition = function (params) {
+        var col;
+        var row = params[0] - 1;
+        if (params.length >= 2) {
+            col = params[1] - 1;
+        }
+        else {
+            col = 0;
+        }
+        if (row < 0) {
+            row = 0;
+        }
+        else if (row >= this._terminal.rows) {
+            row = this._terminal.rows - 1;
+        }
+        if (col < 0) {
+            col = 0;
+        }
+        else if (col >= this._terminal.cols) {
+            col = this._terminal.cols - 1;
+        }
+        this._terminal.buffer.x = col;
+        this._terminal.buffer.y = row;
+    };
+    InputHandler.prototype.cursorForwardTab = function (params) {
+        var param = params[0] || 1;
+        while (param--) {
+            this._terminal.buffer.x = this._terminal.buffer.nextStop();
+        }
+    };
+    InputHandler.prototype._eraseInBufferLine = function (y, start, end, clearWrap) {
+        if (clearWrap === void 0) { clearWrap = false; }
+        var line = this._terminal.buffer.lines.get(this._terminal.buffer.ybase + y);
+        line.replaceCells(start, end, this._terminal.buffer.getNullCell(this._terminal.eraseAttrData()));
+        if (clearWrap) {
+            line.isWrapped = false;
+        }
+    };
+    InputHandler.prototype._resetBufferLine = function (y) {
+        this._eraseInBufferLine(y, 0, this._terminal.cols, true);
+    };
+    InputHandler.prototype.eraseInDisplay = function (params) {
+        var j;
+        switch (params[0]) {
+            case 0:
+                j = this._terminal.buffer.y;
+                this._terminal.updateRange(j);
+                this._eraseInBufferLine(j++, this._terminal.buffer.x, this._terminal.cols, this._terminal.buffer.x === 0);
+                for (; j < this._terminal.rows; j++) {
+                    this._resetBufferLine(j);
+                }
+                this._terminal.updateRange(j);
+                break;
+            case 1:
+                j = this._terminal.buffer.y;
+                this._terminal.updateRange(j);
+                this._eraseInBufferLine(j, 0, this._terminal.buffer.x + 1, true);
+                if (this._terminal.buffer.x + 1 >= this._terminal.cols) {
+                    this._terminal.buffer.lines.get(j + 1).isWrapped = false;
+                }
+                while (j--) {
+                    this._resetBufferLine(j);
+                }
+                this._terminal.updateRange(0);
+                break;
+            case 2:
+                j = this._terminal.rows;
+                this._terminal.updateRange(j - 1);
+                while (j--) {
+                    this._resetBufferLine(j);
+                }
+                this._terminal.updateRange(0);
+                break;
+            case 3:
+                var scrollBackSize = this._terminal.buffer.lines.length - this._terminal.rows;
+                if (scrollBackSize > 0) {
+                    this._terminal.buffer.lines.trimStart(scrollBackSize);
+                    this._terminal.buffer.ybase = Math.max(this._terminal.buffer.ybase - scrollBackSize, 0);
+                    this._terminal.buffer.ydisp = Math.max(this._terminal.buffer.ydisp - scrollBackSize, 0);
+                    this._onScroll.fire(0);
+                }
+                break;
+        }
+    };
+    InputHandler.prototype.eraseInLine = function (params) {
+        switch (params[0]) {
+            case 0:
+                this._eraseInBufferLine(this._terminal.buffer.y, this._terminal.buffer.x, this._terminal.cols);
+                break;
+            case 1:
+                this._eraseInBufferLine(this._terminal.buffer.y, 0, this._terminal.buffer.x + 1);
+                break;
+            case 2:
+                this._eraseInBufferLine(this._terminal.buffer.y, 0, this._terminal.cols);
+                break;
+        }
+        this._terminal.updateRange(this._terminal.buffer.y);
+    };
+    InputHandler.prototype.insertLines = function (params) {
+        var param = params[0];
+        if (param < 1) {
+            param = 1;
+        }
+        var buffer = this._terminal.buffer;
+        var row = buffer.y + buffer.ybase;
+        var scrollBottomRowsOffset = this._terminal.rows - 1 - buffer.scrollBottom;
+        var scrollBottomAbsolute = this._terminal.rows - 1 + buffer.ybase - scrollBottomRowsOffset + 1;
+        while (param--) {
+            buffer.lines.splice(scrollBottomAbsolute - 1, 1);
+            buffer.lines.splice(row, 0, buffer.getBlankLine(this._terminal.eraseAttrData()));
+        }
+        this._terminal.updateRange(buffer.y);
+        this._terminal.updateRange(buffer.scrollBottom);
+    };
+    InputHandler.prototype.deleteLines = function (params) {
+        var param = params[0];
+        if (param < 1) {
+            param = 1;
+        }
+        var buffer = this._terminal.buffer;
+        var row = buffer.y + buffer.ybase;
+        var j;
+        j = this._terminal.rows - 1 - buffer.scrollBottom;
+        j = this._terminal.rows - 1 + buffer.ybase - j;
+        while (param--) {
+            buffer.lines.splice(row, 1);
+            buffer.lines.splice(j, 0, buffer.getBlankLine(this._terminal.eraseAttrData()));
+        }
+        this._terminal.updateRange(buffer.y);
+        this._terminal.updateRange(buffer.scrollBottom);
+    };
+    InputHandler.prototype.deleteChars = function (params) {
+        this._terminal.buffer.lines.get(this._terminal.buffer.y + this._terminal.buffer.ybase).deleteCells(this._terminal.buffer.x, params[0] || 1, this._terminal.buffer.getNullCell(this._terminal.eraseAttrData()));
+        this._terminal.updateRange(this._terminal.buffer.y);
+    };
+    InputHandler.prototype.scrollUp = function (params) {
+        var param = params[0] || 1;
+        var buffer = this._terminal.buffer;
+        while (param--) {
+            buffer.lines.splice(buffer.ybase + buffer.scrollTop, 1);
+            buffer.lines.splice(buffer.ybase + buffer.scrollBottom, 0, buffer.getBlankLine(Buffer_1.DEFAULT_ATTR_DATA));
+        }
+        this._terminal.updateRange(buffer.scrollTop);
+        this._terminal.updateRange(buffer.scrollBottom);
+    };
+    InputHandler.prototype.scrollDown = function (params, collect) {
+        if (params.length < 2 && !collect) {
+            var param = params[0] || 1;
+            var buffer = this._terminal.buffer;
+            while (param--) {
+                buffer.lines.splice(buffer.ybase + buffer.scrollBottom, 1);
+                buffer.lines.splice(buffer.ybase + buffer.scrollTop, 0, buffer.getBlankLine(Buffer_1.DEFAULT_ATTR_DATA));
+            }
+            this._terminal.updateRange(buffer.scrollTop);
+            this._terminal.updateRange(buffer.scrollBottom);
+        }
+    };
+    InputHandler.prototype.eraseChars = function (params) {
+        this._terminal.buffer.lines.get(this._terminal.buffer.y + this._terminal.buffer.ybase).replaceCells(this._terminal.buffer.x, this._terminal.buffer.x + (params[0] || 1), this._terminal.buffer.getNullCell(this._terminal.eraseAttrData()));
+    };
+    InputHandler.prototype.cursorBackwardTab = function (params) {
+        var param = params[0] || 1;
+        var buffer = this._terminal.buffer;
+        while (param--) {
+            buffer.x = buffer.prevStop();
+        }
+    };
+    InputHandler.prototype.charPosAbsolute = function (params) {
+        var param = params[0];
+        if (param < 1) {
+            param = 1;
+        }
+        this._terminal.buffer.x = param - 1;
+        if (this._terminal.buffer.x >= this._terminal.cols) {
+            this._terminal.buffer.x = this._terminal.cols - 1;
+        }
+    };
+    InputHandler.prototype.hPositionRelative = function (params) {
+        var param = params[0];
+        if (param < 1) {
+            param = 1;
+        }
+        this._terminal.buffer.x += param;
+        if (this._terminal.buffer.x >= this._terminal.cols) {
+            this._terminal.buffer.x = this._terminal.cols - 1;
+        }
+    };
+    InputHandler.prototype.repeatPrecedingCharacter = function (params) {
+        var buffer = this._terminal.buffer;
+        var line = buffer.lines.get(buffer.ybase + buffer.y);
+        line.loadCell(buffer.x - 1, this._workCell);
+        line.replaceCells(buffer.x, buffer.x + (params[0] || 1), (this._workCell.content !== undefined) ? this._workCell : buffer.getNullCell(Buffer_1.DEFAULT_ATTR_DATA));
+    };
+    InputHandler.prototype.sendDeviceAttributes = function (params, collect) {
+        if (params[0] > 0) {
+            return;
+        }
+        if (!collect) {
+            if (this._terminal.is('xterm') || this._terminal.is('rxvt-unicode') || this._terminal.is('screen')) {
+                this._terminal.handler(EscapeSequences_1.C0.ESC + '[?1;2c');
+            }
+            else if (this._terminal.is('linux')) {
+                this._terminal.handler(EscapeSequences_1.C0.ESC + '[?6c');
+            }
+        }
+        else if (collect === '>') {
+            if (this._terminal.is('xterm')) {
+                this._terminal.handler(EscapeSequences_1.C0.ESC + '[>0;276;0c');
+            }
+            else if (this._terminal.is('rxvt-unicode')) {
+                this._terminal.handler(EscapeSequences_1.C0.ESC + '[>85;95;0c');
+            }
+            else if (this._terminal.is('linux')) {
+                this._terminal.handler(params[0] + 'c');
+            }
+            else if (this._terminal.is('screen')) {
+                this._terminal.handler(EscapeSequences_1.C0.ESC + '[>83;40003;0c');
+            }
+        }
+    };
+    InputHandler.prototype.linePosAbsolute = function (params) {
+        var param = params[0];
+        if (param < 1) {
+            param = 1;
+        }
+        this._terminal.buffer.y = param - 1;
+        if (this._terminal.buffer.y >= this._terminal.rows) {
+            this._terminal.buffer.y = this._terminal.rows - 1;
+        }
+    };
+    InputHandler.prototype.vPositionRelative = function (params) {
+        var param = params[0];
+        if (param < 1) {
+            param = 1;
+        }
+        this._terminal.buffer.y += param;
+        if (this._terminal.buffer.y >= this._terminal.rows) {
+            this._terminal.buffer.y = this._terminal.rows - 1;
+        }
+        if (this._terminal.buffer.x >= this._terminal.cols) {
+            this._terminal.buffer.x--;
+        }
+    };
+    InputHandler.prototype.hVPosition = function (params) {
+        if (params[0] < 1)
+            params[0] = 1;
+        if (params[1] < 1)
+            params[1] = 1;
+        this._terminal.buffer.y = params[0] - 1;
+        if (this._terminal.buffer.y >= this._terminal.rows) {
+            this._terminal.buffer.y = this._terminal.rows - 1;
+        }
+        this._terminal.buffer.x = params[1] - 1;
+        if (this._terminal.buffer.x >= this._terminal.cols) {
+            this._terminal.buffer.x = this._terminal.cols - 1;
+        }
+    };
+    InputHandler.prototype.tabClear = function (params) {
+        var param = params[0];
+        if (param <= 0) {
+            delete this._terminal.buffer.tabs[this._terminal.buffer.x];
+        }
+        else if (param === 3) {
+            this._terminal.buffer.tabs = {};
+        }
+    };
+    InputHandler.prototype.setMode = function (params, collect) {
+        if (params.length > 1) {
+            for (var i = 0; i < params.length; i++) {
+                this.setMode([params[i]]);
+            }
+            return;
+        }
+        if (!collect) {
+            switch (params[0]) {
+                case 4:
+                    this._terminal.insertMode = true;
+                    break;
+                case 20:
+                    break;
+            }
+        }
+        else if (collect === '?') {
+            switch (params[0]) {
+                case 1:
+                    this._terminal.applicationCursor = true;
+                    break;
+                case 2:
+                    this._terminal.setgCharset(0, Charsets_1.DEFAULT_CHARSET);
+                    this._terminal.setgCharset(1, Charsets_1.DEFAULT_CHARSET);
+                    this._terminal.setgCharset(2, Charsets_1.DEFAULT_CHARSET);
+                    this._terminal.setgCharset(3, Charsets_1.DEFAULT_CHARSET);
+                    break;
+                case 3:
+                    this._terminal.savedCols = this._terminal.cols;
+                    this._terminal.resize(132, this._terminal.rows);
+                    break;
+                case 6:
+                    this._terminal.originMode = true;
+                    break;
+                case 7:
+                    this._terminal.wraparoundMode = true;
+                    break;
+                case 12:
+                    break;
+                case 66:
+                    this._terminal.log('Serial port requested application keypad.');
+                    this._terminal.applicationKeypad = true;
+                    if (this._terminal.viewport) {
+                        this._terminal.viewport.syncScrollArea();
+                    }
+                    break;
+                case 9:
+                case 1000:
+                case 1002:
+                case 1003:
+                    this._terminal.x10Mouse = params[0] === 9;
+                    this._terminal.vt200Mouse = params[0] === 1000;
+                    this._terminal.normalMouse = params[0] > 1000;
+                    this._terminal.mouseEvents = true;
+                    if (this._terminal.element) {
+                        this._terminal.element.classList.add('enable-mouse-events');
+                    }
+                    if (this._terminal.selectionManager) {
+                        this._terminal.selectionManager.disable();
+                    }
+                    this._terminal.log('Binding to mouse events.');
+                    break;
+                case 1004:
+                    this._terminal.sendFocus = true;
+                    break;
+                case 1005:
+                    this._terminal.utfMouse = true;
+                    break;
+                case 1006:
+                    this._terminal.sgrMouse = true;
+                    break;
+                case 1015:
+                    this._terminal.urxvtMouse = true;
+                    break;
+                case 25:
+                    this._terminal.cursorHidden = false;
+                    break;
+                case 1048:
+                    this.saveCursor(params);
+                    break;
+                case 1049:
+                    this.saveCursor(params);
+                case 47:
+                case 1047:
+                    this._terminal.buffers.activateAltBuffer(this._terminal.eraseAttrData());
+                    this._terminal.refresh(0, this._terminal.rows - 1);
+                    if (this._terminal.viewport) {
+                        this._terminal.viewport.syncScrollArea();
+                    }
+                    this._terminal.showCursor();
+                    break;
+                case 2004:
+                    this._terminal.bracketedPasteMode = true;
+                    break;
+            }
+        }
+    };
+    InputHandler.prototype.resetMode = function (params, collect) {
+        if (params.length > 1) {
+            for (var i = 0; i < params.length; i++) {
+                this.resetMode([params[i]]);
+            }
+            return;
+        }
+        if (!collect) {
+            switch (params[0]) {
+                case 4:
+                    this._terminal.insertMode = false;
+                    break;
+                case 20:
+                    break;
+            }
+        }
+        else if (collect === '?') {
+            switch (params[0]) {
+                case 1:
+                    this._terminal.applicationCursor = false;
+                    break;
+                case 3:
+                    if (this._terminal.cols === 132 && this._terminal.savedCols) {
+                        this._terminal.resize(this._terminal.savedCols, this._terminal.rows);
+                    }
+                    delete this._terminal.savedCols;
+                    break;
+                case 6:
+                    this._terminal.originMode = false;
+                    break;
+                case 7:
+                    this._terminal.wraparoundMode = false;
+                    break;
+                case 12:
+                    break;
+                case 66:
+                    this._terminal.log('Switching back to normal keypad.');
+                    this._terminal.applicationKeypad = false;
+                    if (this._terminal.viewport) {
+                        this._terminal.viewport.syncScrollArea();
+                    }
+                    break;
+                case 9:
+                case 1000:
+                case 1002:
+                case 1003:
+                    this._terminal.x10Mouse = false;
+                    this._terminal.vt200Mouse = false;
+                    this._terminal.normalMouse = false;
+                    this._terminal.mouseEvents = false;
+                    if (this._terminal.element) {
+                        this._terminal.element.classList.remove('enable-mouse-events');
+                    }
+                    if (this._terminal.selectionManager) {
+                        this._terminal.selectionManager.enable();
+                    }
+                    break;
+                case 1004:
+                    this._terminal.sendFocus = false;
+                    break;
+                case 1005:
+                    this._terminal.utfMouse = false;
+                    break;
+                case 1006:
+                    this._terminal.sgrMouse = false;
+                    break;
+                case 1015:
+                    this._terminal.urxvtMouse = false;
+                    break;
+                case 25:
+                    this._terminal.cursorHidden = true;
+                    break;
+                case 1048:
+                    this.restoreCursor(params);
+                    break;
+                case 1049:
+                case 47:
+                case 1047:
+                    this._terminal.buffers.activateNormalBuffer();
+                    if (params[0] === 1049) {
+                        this.restoreCursor(params);
+                    }
+                    this._terminal.refresh(0, this._terminal.rows - 1);
+                    if (this._terminal.viewport) {
+                        this._terminal.viewport.syncScrollArea();
+                    }
+                    this._terminal.showCursor();
+                    break;
+                case 2004:
+                    this._terminal.bracketedPasteMode = false;
+                    break;
+            }
+        }
+    };
+    InputHandler.prototype.charAttributes = function (params) {
+        if (params.length === 1 && params[0] === 0) {
+            this._terminal.curAttrData.fg = Buffer_1.DEFAULT_ATTR_DATA.fg;
+            this._terminal.curAttrData.bg = Buffer_1.DEFAULT_ATTR_DATA.bg;
+            return;
+        }
+        var l = params.length;
+        var p;
+        var attr = this._terminal.curAttrData;
+        for (var i = 0; i < l; i++) {
+            p = params[i];
+            if (p >= 30 && p <= 37) {
+                attr.fg &= ~(50331648 | 255);
+                attr.fg |= 16777216 | (p - 30);
+            }
+            else if (p >= 40 && p <= 47) {
+                attr.bg &= ~(50331648 | 255);
+                attr.bg |= 16777216 | (p - 40);
+            }
+            else if (p >= 90 && p <= 97) {
+                attr.fg &= ~(50331648 | 255);
+                attr.fg |= 16777216 | (p - 90) | 8;
+            }
+            else if (p >= 100 && p <= 107) {
+                attr.bg &= ~(50331648 | 255);
+                attr.bg |= 16777216 | (p - 100) | 8;
+            }
+            else if (p === 0) {
+                attr.fg = Buffer_1.DEFAULT_ATTR_DATA.fg;
+                attr.bg = Buffer_1.DEFAULT_ATTR_DATA.bg;
+            }
+            else if (p === 1) {
+                attr.fg |= 134217728;
+            }
+            else if (p === 3) {
+                attr.bg |= 67108864;
+            }
+            else if (p === 4) {
+                attr.fg |= 268435456;
+            }
+            else if (p === 5) {
+                attr.fg |= 536870912;
+            }
+            else if (p === 7) {
+                attr.fg |= 67108864;
+            }
+            else if (p === 8) {
+                attr.fg |= 1073741824;
+            }
+            else if (p === 2) {
+                attr.bg |= 134217728;
+            }
+            else if (p === 22) {
+                attr.fg &= ~134217728;
+                attr.bg &= ~134217728;
+            }
+            else if (p === 23) {
+                attr.bg &= ~67108864;
+            }
+            else if (p === 24) {
+                attr.fg &= ~268435456;
+            }
+            else if (p === 25) {
+                attr.fg &= ~536870912;
+            }
+            else if (p === 27) {
+                attr.fg &= ~67108864;
+            }
+            else if (p === 28) {
+                attr.fg &= ~1073741824;
+            }
+            else if (p === 39) {
+                attr.fg &= ~(50331648 | 16777215);
+                attr.fg |= Buffer_1.DEFAULT_ATTR_DATA.fg & (255 | 16777215);
+            }
+            else if (p === 49) {
+                attr.bg &= ~(50331648 | 16777215);
+                attr.bg |= Buffer_1.DEFAULT_ATTR_DATA.bg & (255 | 16777215);
+            }
+            else if (p === 38) {
+                if (params[i + 1] === 2) {
+                    i += 2;
+                    attr.fg |= 50331648;
+                    attr.fg &= ~16777215;
+                    attr.fg |= BufferLine_1.AttributeData.fromColorRGB([params[i], params[i + 1], params[i + 2]]);
+                    i += 2;
+                }
+                else if (params[i + 1] === 5) {
+                    i += 2;
+                    p = params[i] & 0xff;
+                    attr.fg &= ~255;
+                    attr.fg |= 33554432 | p;
+                }
+            }
+            else if (p === 48) {
+                if (params[i + 1] === 2) {
+                    i += 2;
+                    attr.bg |= 50331648;
+                    attr.bg &= ~16777215;
+                    attr.bg |= BufferLine_1.AttributeData.fromColorRGB([params[i], params[i + 1], params[i + 2]]);
+                    i += 2;
+                }
+                else if (params[i + 1] === 5) {
+                    i += 2;
+                    p = params[i] & 0xff;
+                    attr.bg &= ~255;
+                    attr.bg |= 33554432 | p;
+                }
+            }
+            else if (p === 100) {
+                attr.fg &= ~(50331648 | 16777215);
+                attr.fg |= Buffer_1.DEFAULT_ATTR_DATA.fg & (255 | 16777215);
+                attr.bg &= ~(50331648 | 16777215);
+                attr.bg |= Buffer_1.DEFAULT_ATTR_DATA.bg & (255 | 16777215);
+            }
+            else {
+                this._terminal.error('Unknown SGR attribute: %d.', p);
+            }
+        }
+    };
+    InputHandler.prototype.deviceStatus = function (params, collect) {
+        if (!collect) {
+            switch (params[0]) {
+                case 5:
+                    this._onData.fire(EscapeSequences_1.C0.ESC + "[0n");
+                    break;
+                case 6:
+                    var y = this._terminal.buffer.y + 1;
+                    var x = this._terminal.buffer.x + 1;
+                    this._onData.fire(EscapeSequences_1.C0.ESC + "[" + y + ";" + x + "R");
+                    break;
+            }
+        }
+        else if (collect === '?') {
+            switch (params[0]) {
+                case 6:
+                    var y = this._terminal.buffer.y + 1;
+                    var x = this._terminal.buffer.x + 1;
+                    this._onData.fire(EscapeSequences_1.C0.ESC + "[?" + y + ";" + x + "R");
+                    break;
+                case 15:
+                    break;
+                case 25:
+                    break;
+                case 26:
+                    break;
+                case 53:
+                    break;
+            }
+        }
+    };
+    InputHandler.prototype.softReset = function (params, collect) {
+        if (collect === '!') {
+            this._terminal.cursorHidden = false;
+            this._terminal.insertMode = false;
+            this._terminal.originMode = false;
+            this._terminal.wraparoundMode = true;
+            this._terminal.applicationKeypad = false;
+            if (this._terminal.viewport) {
+                this._terminal.viewport.syncScrollArea();
+            }
+            this._terminal.applicationCursor = false;
+            this._terminal.buffer.scrollTop = 0;
+            this._terminal.buffer.scrollBottom = this._terminal.rows - 1;
+            this._terminal.curAttrData = Buffer_1.DEFAULT_ATTR_DATA;
+            this._terminal.buffer.x = this._terminal.buffer.y = 0;
+            this._terminal.charset = null;
+            this._terminal.glevel = 0;
+            this._terminal.charsets = [null];
+        }
+    };
+    InputHandler.prototype.setCursorStyle = function (params, collect) {
+        if (collect === ' ') {
+            var param = params[0] < 1 ? 1 : params[0];
+            switch (param) {
+                case 1:
+                case 2:
+                    this._terminal.setOption('cursorStyle', 'block');
+                    break;
+                case 3:
+                case 4:
+                    this._terminal.setOption('cursorStyle', 'underline');
+                    break;
+                case 5:
+                case 6:
+                    this._terminal.setOption('cursorStyle', 'bar');
+                    break;
+            }
+            var isBlinking = param % 2 === 1;
+            this._terminal.setOption('cursorBlink', isBlinking);
+        }
+    };
+    InputHandler.prototype.setScrollRegion = function (params, collect) {
+        if (collect) {
+            return;
+        }
+        this._terminal.buffer.scrollTop = (params[0] || 1) - 1;
+        this._terminal.buffer.scrollBottom = (params[1] && params[1] <= this._terminal.rows ? params[1] : this._terminal.rows) - 1;
+        this._terminal.buffer.x = 0;
+        this._terminal.buffer.y = 0;
+    };
+    InputHandler.prototype.saveCursor = function (params) {
+        this._terminal.buffer.savedX = this._terminal.buffer.x;
+        this._terminal.buffer.savedY = this._terminal.buffer.y;
+        this._terminal.buffer.savedCurAttrData.fg = this._terminal.curAttrData.fg;
+        this._terminal.buffer.savedCurAttrData.bg = this._terminal.curAttrData.bg;
+    };
+    InputHandler.prototype.restoreCursor = function (params) {
+        this._terminal.buffer.x = this._terminal.buffer.savedX || 0;
+        this._terminal.buffer.y = this._terminal.buffer.savedY || 0;
+        this._terminal.curAttrData.fg = this._terminal.buffer.savedCurAttrData.fg;
+        this._terminal.curAttrData.bg = this._terminal.buffer.savedCurAttrData.bg;
+    };
+    InputHandler.prototype.setTitle = function (data) {
+        this._terminal.handleTitle(data);
+    };
+    InputHandler.prototype.nextLine = function () {
+        this._terminal.buffer.x = 0;
+        this.index();
+    };
+    InputHandler.prototype.keypadApplicationMode = function () {
+        this._terminal.log('Serial port requested application keypad.');
+        this._terminal.applicationKeypad = true;
+        if (this._terminal.viewport) {
+            this._terminal.viewport.syncScrollArea();
+        }
+    };
+    InputHandler.prototype.keypadNumericMode = function () {
+        this._terminal.log('Switching back to normal keypad.');
+        this._terminal.applicationKeypad = false;
+        if (this._terminal.viewport) {
+            this._terminal.viewport.syncScrollArea();
+        }
+    };
+    InputHandler.prototype.selectDefaultCharset = function () {
+        this._terminal.setgLevel(0);
+        this._terminal.setgCharset(0, Charsets_1.DEFAULT_CHARSET);
+    };
+    InputHandler.prototype.selectCharset = function (collectAndFlag) {
+        if (collectAndFlag.length !== 2) {
+            this.selectDefaultCharset();
+            return;
+        }
+        if (collectAndFlag[0] === '/') {
+            return;
+        }
+        this._terminal.setgCharset(GLEVEL[collectAndFlag[0]], Charsets_1.CHARSETS[collectAndFlag[1]] || Charsets_1.DEFAULT_CHARSET);
+        return;
+    };
+    InputHandler.prototype.index = function () {
+        this._terminal.index();
+    };
+    InputHandler.prototype.tabSet = function () {
+        this._terminal.tabSet();
+    };
+    InputHandler.prototype.reverseIndex = function () {
+        this._terminal.reverseIndex();
+    };
+    InputHandler.prototype.reset = function () {
+        this._parser.reset();
+        this._terminal.reset();
+    };
+    InputHandler.prototype.setgLevel = function (level) {
+        this._terminal.setgLevel(level);
+    };
+    return InputHandler;
+}(Lifecycle_1.Disposable));
+exports.InputHandler = InputHandler;
+
+},{"./Buffer":2,"./BufferLine":3,"./CharWidth":7,"./EscapeSequenceParser":10,"./common/EventEmitter2":25,"./common/Lifecycle":26,"./common/TypedArrayUtils":28,"./common/data/EscapeSequences":29,"./core/data/Charsets":30,"./core/input/TextDecoder":32}],12:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var MouseZoneManager_1 = require("./MouseZoneManager");
+var CharWidth_1 = require("./CharWidth");
+var EventEmitter2_1 = require("./common/EventEmitter2");
+var Linkifier = (function () {
+    function Linkifier(_terminal) {
+        this._terminal = _terminal;
+        this._linkMatchers = [];
+        this._nextLinkMatcherId = 0;
+        this._onLinkHover = new EventEmitter2_1.EventEmitter2();
+        this._onLinkLeave = new EventEmitter2_1.EventEmitter2();
+        this._onLinkTooltip = new EventEmitter2_1.EventEmitter2();
+        this._rowsToLinkify = {
+            start: null,
+            end: null
+        };
+    }
+    Object.defineProperty(Linkifier.prototype, "onLinkHover", {
+        get: function () { return this._onLinkHover.event; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Linkifier.prototype, "onLinkLeave", {
+        get: function () { return this._onLinkLeave.event; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Linkifier.prototype, "onLinkTooltip", {
+        get: function () { return this._onLinkTooltip.event; },
+        enumerable: true,
+        configurable: true
+    });
+    Linkifier.prototype.attachToDom = function (mouseZoneManager) {
+        this._mouseZoneManager = mouseZoneManager;
+    };
+    Linkifier.prototype.linkifyRows = function (start, end) {
+        var _this = this;
+        if (!this._mouseZoneManager) {
+            return;
+        }
+        if (this._rowsToLinkify.start === null) {
+            this._rowsToLinkify.start = start;
+            this._rowsToLinkify.end = end;
+        }
+        else {
+            this._rowsToLinkify.start = Math.min(this._rowsToLinkify.start, start);
+            this._rowsToLinkify.end = Math.max(this._rowsToLinkify.end, end);
+        }
+        this._mouseZoneManager.clearAll(start, end);
+        if (this._rowsTimeoutId) {
+            clearTimeout(this._rowsTimeoutId);
+        }
+        this._rowsTimeoutId = setTimeout(function () { return _this._linkifyRows(); }, Linkifier.TIME_BEFORE_LINKIFY);
+    };
+    Linkifier.prototype._linkifyRows = function () {
+        this._rowsTimeoutId = null;
+        var buffer = this._terminal.buffer;
+        var absoluteRowIndexStart = buffer.ydisp + this._rowsToLinkify.start;
+        if (absoluteRowIndexStart >= buffer.lines.length) {
+            return;
+        }
+        var absoluteRowIndexEnd = buffer.ydisp + Math.min(this._rowsToLinkify.end, this._terminal.rows) + 1;
+        var overscanLineLimit = Math.ceil(Linkifier.OVERSCAN_CHAR_LIMIT / this._terminal.cols);
+        var iterator = this._terminal.buffer.iterator(false, absoluteRowIndexStart, absoluteRowIndexEnd, overscanLineLimit, overscanLineLimit);
+        while (iterator.hasNext()) {
+            var lineData = iterator.next();
+            for (var i = 0; i < this._linkMatchers.length; i++) {
+                this._doLinkifyRow(lineData.range.first, lineData.content, this._linkMatchers[i]);
+            }
+        }
+        this._rowsToLinkify.start = null;
+        this._rowsToLinkify.end = null;
+    };
+    Linkifier.prototype.registerLinkMatcher = function (regex, handler, options) {
+        if (options === void 0) { options = {}; }
+        if (!handler) {
+            throw new Error('handler must be defined');
+        }
+        var matcher = {
+            id: this._nextLinkMatcherId++,
+            regex: regex,
+            handler: handler,
+            matchIndex: options.matchIndex,
+            validationCallback: options.validationCallback,
+            hoverTooltipCallback: options.tooltipCallback,
+            hoverLeaveCallback: options.leaveCallback,
+            willLinkActivate: options.willLinkActivate,
+            priority: options.priority || 0
+        };
+        this._addLinkMatcherToList(matcher);
+        return matcher.id;
+    };
+    Linkifier.prototype._addLinkMatcherToList = function (matcher) {
+        if (this._linkMatchers.length === 0) {
+            this._linkMatchers.push(matcher);
+            return;
+        }
+        for (var i = this._linkMatchers.length - 1; i >= 0; i--) {
+            if (matcher.priority <= this._linkMatchers[i].priority) {
+                this._linkMatchers.splice(i + 1, 0, matcher);
+                return;
+            }
+        }
+        this._linkMatchers.splice(0, 0, matcher);
+    };
+    Linkifier.prototype.deregisterLinkMatcher = function (matcherId) {
+        for (var i = 0; i < this._linkMatchers.length; i++) {
+            if (this._linkMatchers[i].id === matcherId) {
+                this._linkMatchers.splice(i, 1);
+                return true;
+            }
+        }
+        return false;
+    };
+    Linkifier.prototype._doLinkifyRow = function (rowIndex, text, matcher) {
+        var _this = this;
+        var rex = new RegExp(matcher.regex.source, matcher.regex.flags + 'g');
+        var match;
+        var stringIndex = -1;
+        var _loop_1 = function () {
+            var uri = match[typeof matcher.matchIndex !== 'number' ? 0 : matcher.matchIndex];
+            if (!uri) {
+                if (this_1._terminal.debug) {
+                    console.log({ match: match, matcher: matcher });
+                    throw new Error('match found without corresponding matchIndex');
+                }
+                return "break";
+            }
+            stringIndex = text.indexOf(uri, stringIndex + 1);
+            rex.lastIndex = stringIndex + uri.length;
+            if (stringIndex < 0) {
+                return "break";
+            }
+            var bufferIndex = this_1._terminal.buffer.stringIndexToBufferIndex(rowIndex, stringIndex);
+            if (bufferIndex[0] < 0) {
+                return "break";
+            }
+            var line = this_1._terminal.buffer.lines.get(bufferIndex[0]);
+            var attr = line.getFg(bufferIndex[1]);
+            var fg;
+            if (attr) {
+                fg = (attr >> 9) & 0x1ff;
+            }
+            if (matcher.validationCallback) {
+                matcher.validationCallback(uri, function (isValid) {
+                    if (_this._rowsTimeoutId) {
+                        return;
+                    }
+                    if (isValid) {
+                        _this._addLink(bufferIndex[1], bufferIndex[0] - _this._terminal.buffer.ydisp, uri, matcher, fg);
+                    }
+                });
+            }
+            else {
+                this_1._addLink(bufferIndex[1], bufferIndex[0] - this_1._terminal.buffer.ydisp, uri, matcher, fg);
+            }
+        };
+        var this_1 = this;
+        while ((match = rex.exec(text)) !== null) {
+            var state_1 = _loop_1();
+            if (state_1 === "break")
+                break;
+        }
+    };
+    Linkifier.prototype._addLink = function (x, y, uri, matcher, fg) {
+        var _this = this;
+        var width = CharWidth_1.getStringCellWidth(uri);
+        var x1 = x % this._terminal.cols;
+        var y1 = y + Math.floor(x / this._terminal.cols);
+        var x2 = (x1 + width) % this._terminal.cols;
+        var y2 = y1 + Math.floor((x1 + width) / this._terminal.cols);
+        if (x2 === 0) {
+            x2 = this._terminal.cols;
+            y2--;
+        }
+        this._mouseZoneManager.add(new MouseZoneManager_1.MouseZone(x1 + 1, y1 + 1, x2 + 1, y2 + 1, function (e) {
+            if (matcher.handler) {
+                return matcher.handler(e, uri);
+            }
+            window.open(uri, '_blank');
+        }, function () {
+            _this._onLinkHover.fire(_this._createLinkHoverEvent(x1, y1, x2, y2, fg));
+            _this._terminal.element.classList.add('xterm-cursor-pointer');
+        }, function (e) {
+            _this._onLinkTooltip.fire(_this._createLinkHoverEvent(x1, y1, x2, y2, fg));
+            if (matcher.hoverTooltipCallback) {
+                matcher.hoverTooltipCallback(e, uri);
+            }
+        }, function () {
+            _this._onLinkLeave.fire(_this._createLinkHoverEvent(x1, y1, x2, y2, fg));
+            _this._terminal.element.classList.remove('xterm-cursor-pointer');
+            if (matcher.hoverLeaveCallback) {
+                matcher.hoverLeaveCallback();
+            }
+        }, function (e) {
+            if (matcher.willLinkActivate) {
+                return matcher.willLinkActivate(e, uri);
+            }
+            return true;
+        }));
+    };
+    Linkifier.prototype._createLinkHoverEvent = function (x1, y1, x2, y2, fg) {
+        return { x1: x1, y1: y1, x2: x2, y2: y2, cols: this._terminal.cols, fg: fg };
+    };
+    Linkifier.TIME_BEFORE_LINKIFY = 200;
+    Linkifier.OVERSCAN_CHAR_LIMIT = 2000;
+    return Linkifier;
+}());
+exports.Linkifier = Linkifier;
+
+},{"./CharWidth":7,"./MouseZoneManager":14,"./common/EventEmitter2":25}],13:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var MouseHelper = (function () {
+    function MouseHelper(_renderer) {
+        this._renderer = _renderer;
+    }
+    MouseHelper.prototype.setRenderer = function (renderer) {
+        this._renderer = renderer;
+    };
+    MouseHelper.getCoordsRelativeToElement = function (event, element) {
+        var rect = element.getBoundingClientRect();
+        return [event.clientX - rect.left, event.clientY - rect.top];
+    };
+    MouseHelper.prototype.getCoords = function (event, element, charMeasure, colCount, rowCount, isSelection) {
+        if (!charMeasure.width || !charMeasure.height) {
+            return null;
+        }
+        var coords = MouseHelper.getCoordsRelativeToElement(event, element);
+        if (!coords) {
+            return null;
+        }
+        coords[0] = Math.ceil((coords[0] + (isSelection ? this._renderer.dimensions.actualCellWidth / 2 : 0)) / this._renderer.dimensions.actualCellWidth);
+        coords[1] = Math.ceil(coords[1] / this._renderer.dimensions.actualCellHeight);
+        coords[0] = Math.min(Math.max(coords[0], 1), colCount + (isSelection ? 1 : 0));
+        coords[1] = Math.min(Math.max(coords[1], 1), rowCount);
+        return coords;
+    };
+    MouseHelper.prototype.getRawByteCoords = function (event, element, charMeasure, colCount, rowCount) {
+        var coords = this.getCoords(event, element, charMeasure, colCount, rowCount);
+        var x = coords[0];
+        var y = coords[1];
+        x += 32;
+        y += 32;
+        return { x: x, y: y };
+    };
+    return MouseHelper;
+}());
+exports.MouseHelper = MouseHelper;
+
+},{}],14:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = function (d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var Lifecycle_1 = require("./common/Lifecycle");
+var Lifecycle_2 = require("./ui/Lifecycle");
+var HOVER_DURATION = 500;
+var MouseZoneManager = (function (_super) {
+    __extends(MouseZoneManager, _super);
+    function MouseZoneManager(_terminal) {
+        var _this = _super.call(this) || this;
+        _this._terminal = _terminal;
+        _this._zones = [];
+        _this._areZonesActive = false;
+        _this._tooltipTimeout = null;
+        _this._currentZone = null;
+        _this._lastHoverCoords = [null, null];
+        _this.register(Lifecycle_2.addDisposableDomListener(_this._terminal.element, 'mousedown', function (e) { return _this._onMouseDown(e); }));
+        _this._mouseMoveListener = function (e) { return _this._onMouseMove(e); };
+        _this._mouseLeaveListener = function (e) { return _this._onMouseLeave(e); };
+        _this._clickListener = function (e) { return _this._onClick(e); };
+        return _this;
+    }
+    MouseZoneManager.prototype.dispose = function () {
+        _super.prototype.dispose.call(this);
+        this._deactivate();
+    };
+    MouseZoneManager.prototype.add = function (zone) {
+        this._zones.push(zone);
+        if (this._zones.length === 1) {
+            this._activate();
+        }
+    };
+    MouseZoneManager.prototype.clearAll = function (start, end) {
+        if (this._zones.length === 0) {
+            return;
+        }
+        if (!end) {
+            start = 0;
+            end = this._terminal.rows - 1;
+        }
+        for (var i = 0; i < this._zones.length; i++) {
+            var zone = this._zones[i];
+            if ((zone.y1 > start && zone.y1 <= end + 1) ||
+                (zone.y2 > start && zone.y2 <= end + 1) ||
+                (zone.y1 < start && zone.y2 > end + 1)) {
+                if (this._currentZone && this._currentZone === zone) {
+                    this._currentZone.leaveCallback();
+                    this._currentZone = null;
+                }
+                this._zones.splice(i--, 1);
+            }
+        }
+        if (this._zones.length === 0) {
+            this._deactivate();
+        }
+    };
+    MouseZoneManager.prototype._activate = function () {
+        if (!this._areZonesActive) {
+            this._areZonesActive = true;
+            this._terminal.element.addEventListener('mousemove', this._mouseMoveListener);
+            this._terminal.element.addEventListener('mouseleave', this._mouseLeaveListener);
+            this._terminal.element.addEventListener('click', this._clickListener);
+        }
+    };
+    MouseZoneManager.prototype._deactivate = function () {
+        if (this._areZonesActive) {
+            this._areZonesActive = false;
+            this._terminal.element.removeEventListener('mousemove', this._mouseMoveListener);
+            this._terminal.element.removeEventListener('mouseleave', this._mouseLeaveListener);
+            this._terminal.element.removeEventListener('click', this._clickListener);
+        }
+    };
+    MouseZoneManager.prototype._onMouseMove = function (e) {
+        if (this._lastHoverCoords[0] !== e.pageX || this._lastHoverCoords[1] !== e.pageY) {
+            this._onHover(e);
+            this._lastHoverCoords = [e.pageX, e.pageY];
+        }
+    };
+    MouseZoneManager.prototype._onHover = function (e) {
+        var _this = this;
+        var zone = this._findZoneEventAt(e);
+        if (zone === this._currentZone) {
+            return;
+        }
+        if (this._currentZone) {
+            this._currentZone.leaveCallback();
+            this._currentZone = null;
+            if (this._tooltipTimeout) {
+                clearTimeout(this._tooltipTimeout);
+            }
+        }
+        if (!zone) {
+            return;
+        }
+        this._currentZone = zone;
+        if (zone.hoverCallback) {
+            zone.hoverCallback(e);
+        }
+        this._tooltipTimeout = setTimeout(function () { return _this._onTooltip(e); }, HOVER_DURATION);
+    };
+    MouseZoneManager.prototype._onTooltip = function (e) {
+        this._tooltipTimeout = null;
+        var zone = this._findZoneEventAt(e);
+        if (zone && zone.tooltipCallback) {
+            zone.tooltipCallback(e);
+        }
+    };
+    MouseZoneManager.prototype._onMouseDown = function (e) {
+        this._initialSelectionLength = this._terminal.getSelection().length;
+        if (!this._areZonesActive) {
+            return;
+        }
+        var zone = this._findZoneEventAt(e);
+        if (zone) {
+            if (zone.willLinkActivate(e)) {
+                e.preventDefault();
+                e.stopImmediatePropagation();
+            }
+        }
+    };
+    MouseZoneManager.prototype._onMouseLeave = function (e) {
+        if (this._currentZone) {
+            this._currentZone.leaveCallback();
+            this._currentZone = null;
+            if (this._tooltipTimeout) {
+                clearTimeout(this._tooltipTimeout);
+            }
+        }
+    };
+    MouseZoneManager.prototype._onClick = function (e) {
+        var zone = this._findZoneEventAt(e);
+        var currentSelectionLength = this._terminal.getSelection().length;
+        if (zone && currentSelectionLength === this._initialSelectionLength) {
+            zone.clickCallback(e);
+            e.preventDefault();
+            e.stopImmediatePropagation();
+        }
+    };
+    MouseZoneManager.prototype._findZoneEventAt = function (e) {
+        var coords = this._terminal.mouseHelper.getCoords(e, this._terminal.screenElement, this._terminal.charMeasure, this._terminal.cols, this._terminal.rows);
+        if (!coords) {
+            return null;
+        }
+        var x = coords[0];
+        var y = coords[1];
+        for (var i = 0; i < this._zones.length; i++) {
+            var zone = this._zones[i];
+            if (zone.y1 === zone.y2) {
+                if (y === zone.y1 && x >= zone.x1 && x < zone.x2) {
+                    return zone;
+                }
+            }
+            else {
+                if ((y === zone.y1 && x >= zone.x1) ||
+                    (y === zone.y2 && x < zone.x2) ||
+                    (y > zone.y1 && y < zone.y2)) {
+                    return zone;
+                }
+            }
+        }
+        return null;
+    };
+    return MouseZoneManager;
+}(Lifecycle_1.Disposable));
+exports.MouseZoneManager = MouseZoneManager;
+var MouseZone = (function () {
+    function MouseZone(x1, y1, x2, y2, clickCallback, hoverCallback, tooltipCallback, leaveCallback, willLinkActivate) {
+        this.x1 = x1;
+        this.y1 = y1;
+        this.x2 = x2;
+        this.y2 = y2;
+        this.clickCallback = clickCallback;
+        this.hoverCallback = hoverCallback;
+        this.tooltipCallback = tooltipCallback;
+        this.leaveCallback = leaveCallback;
+        this.willLinkActivate = willLinkActivate;
+    }
+    return MouseZone;
+}());
+exports.MouseZone = MouseZone;
+
+},{"./common/Lifecycle":26,"./ui/Lifecycle":55}],15:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var MouseHelper_1 = require("./MouseHelper");
+var Browser = require("./common/Platform");
+var SelectionModel_1 = require("./SelectionModel");
+var AltClickHandler_1 = require("./handlers/AltClickHandler");
+var BufferLine_1 = require("./BufferLine");
+var EventEmitter2_1 = require("./common/EventEmitter2");
+var DRAG_SCROLL_MAX_THRESHOLD = 50;
+var DRAG_SCROLL_MAX_SPEED = 15;
+var DRAG_SCROLL_INTERVAL = 50;
+var ALT_CLICK_MOVE_CURSOR_TIME = 500;
+var WORD_SEPARATORS = ' ()[]{}\'"';
+var NON_BREAKING_SPACE_CHAR = String.fromCharCode(160);
+var ALL_NON_BREAKING_SPACE_REGEX = new RegExp(NON_BREAKING_SPACE_CHAR, 'g');
+var SelectionManager = (function () {
+    function SelectionManager(_terminal, _charMeasure) {
+        this._terminal = _terminal;
+        this._charMeasure = _charMeasure;
+        this._enabled = true;
+        this._workCell = new BufferLine_1.CellData();
+        this._onLinuxMouseSelection = new EventEmitter2_1.EventEmitter2();
+        this._onRedrawRequest = new EventEmitter2_1.EventEmitter2();
+        this._onSelectionChange = new EventEmitter2_1.EventEmitter2();
+        this._initListeners();
+        this.enable();
+        this._model = new SelectionModel_1.SelectionModel(_terminal);
+        this._activeSelectionMode = 0;
+    }
+    Object.defineProperty(SelectionManager.prototype, "onLinuxMouseSelection", {
+        get: function () { return this._onLinuxMouseSelection.event; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(SelectionManager.prototype, "onRedrawRequest", {
+        get: function () { return this._onRedrawRequest.event; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(SelectionManager.prototype, "onSelectionChange", {
+        get: function () { return this._onSelectionChange.event; },
+        enumerable: true,
+        configurable: true
+    });
+    SelectionManager.prototype.dispose = function () {
+        this._removeMouseDownListeners();
+    };
+    Object.defineProperty(SelectionManager.prototype, "_buffer", {
+        get: function () {
+            return this._terminal.buffers.active;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    SelectionManager.prototype._initListeners = function () {
+        var _this = this;
+        this._mouseMoveListener = function (event) { return _this._onMouseMove(event); };
+        this._mouseUpListener = function (event) { return _this._onMouseUp(event); };
+        this.initBuffersListeners();
+    };
+    SelectionManager.prototype.initBuffersListeners = function () {
+        var _this = this;
+        this._trimListener = this._terminal.buffer.lines.onTrim(function (amount) { return _this._onTrim(amount); });
+        this._terminal.buffers.onBufferActivate(function (e) { return _this._onBufferActivate(e); });
+    };
+    SelectionManager.prototype.disable = function () {
+        this.clearSelection();
+        this._enabled = false;
+    };
+    SelectionManager.prototype.enable = function () {
+        this._enabled = true;
+    };
+    Object.defineProperty(SelectionManager.prototype, "selectionStart", {
+        get: function () { return this._model.finalSelectionStart; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(SelectionManager.prototype, "selectionEnd", {
+        get: function () { return this._model.finalSelectionEnd; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(SelectionManager.prototype, "hasSelection", {
+        get: function () {
+            var start = this._model.finalSelectionStart;
+            var end = this._model.finalSelectionEnd;
+            if (!start || !end) {
+                return false;
+            }
+            return start[0] !== end[0] || start[1] !== end[1];
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(SelectionManager.prototype, "selectionText", {
+        get: function () {
+            var start = this._model.finalSelectionStart;
+            var end = this._model.finalSelectionEnd;
+            if (!start || !end) {
+                return '';
+            }
+            var result = [];
+            if (this._activeSelectionMode === 3) {
+                if (start[0] === end[0]) {
+                    return '';
+                }
+                for (var i = start[1]; i <= end[1]; i++) {
+                    var lineText = this._buffer.translateBufferLineToString(i, true, start[0], end[0]);
+                    result.push(lineText);
+                }
+            }
+            else {
+                var startRowEndCol = start[1] === end[1] ? end[0] : undefined;
+                result.push(this._buffer.translateBufferLineToString(start[1], true, start[0], startRowEndCol));
+                for (var i = start[1] + 1; i <= end[1] - 1; i++) {
+                    var bufferLine = this._buffer.lines.get(i);
+                    var lineText = this._buffer.translateBufferLineToString(i, true);
+                    if (bufferLine.isWrapped) {
+                        result[result.length - 1] += lineText;
+                    }
+                    else {
+                        result.push(lineText);
+                    }
+                }
+                if (start[1] !== end[1]) {
+                    var bufferLine = this._buffer.lines.get(end[1]);
+                    var lineText = this._buffer.translateBufferLineToString(end[1], true, 0, end[0]);
+                    if (bufferLine.isWrapped) {
+                        result[result.length - 1] += lineText;
+                    }
+                    else {
+                        result.push(lineText);
+                    }
+                }
+            }
+            var formattedResult = result.map(function (line) {
+                return line.replace(ALL_NON_BREAKING_SPACE_REGEX, ' ');
+            }).join(Browser.isMSWindows ? '\r\n' : '\n');
+            return formattedResult;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    SelectionManager.prototype.clearSelection = function () {
+        this._model.clearSelection();
+        this._removeMouseDownListeners();
+        this.refresh();
+    };
+    SelectionManager.prototype.refresh = function (isLinuxMouseSelection) {
+        var _this = this;
+        if (!this._refreshAnimationFrame) {
+            this._refreshAnimationFrame = window.requestAnimationFrame(function () { return _this._refresh(); });
+        }
+        if (Browser.isLinux && isLinuxMouseSelection) {
+            var selectionText = this.selectionText;
+            if (selectionText.length) {
+                this._onLinuxMouseSelection.fire(this.selectionText);
+            }
+        }
+    };
+    SelectionManager.prototype._refresh = function () {
+        this._refreshAnimationFrame = null;
+        this._onRedrawRequest.fire({
+            start: this._model.finalSelectionStart,
+            end: this._model.finalSelectionEnd,
+            columnSelectMode: this._activeSelectionMode === 3
+        });
+    };
+    SelectionManager.prototype.isClickInSelection = function (event) {
+        var coords = this._getMouseBufferCoords(event);
+        var start = this._model.finalSelectionStart;
+        var end = this._model.finalSelectionEnd;
+        if (!start || !end) {
+            return false;
+        }
+        return this._areCoordsInSelection(coords, start, end);
+    };
+    SelectionManager.prototype._areCoordsInSelection = function (coords, start, end) {
+        return (coords[1] > start[1] && coords[1] < end[1]) ||
+            (start[1] === end[1] && coords[1] === start[1] && coords[0] >= start[0] && coords[0] < end[0]) ||
+            (start[1] < end[1] && coords[1] === end[1] && coords[0] < end[0]) ||
+            (start[1] < end[1] && coords[1] === start[1] && coords[0] >= start[0]);
+    };
+    SelectionManager.prototype.selectWordAtCursor = function (event) {
+        var coords = this._getMouseBufferCoords(event);
+        if (coords) {
+            this._selectWordAt(coords, false);
+            this._model.selectionEnd = null;
+            this.refresh(true);
+        }
+    };
+    SelectionManager.prototype.selectAll = function () {
+        this._model.isSelectAllActive = true;
+        this.refresh();
+        this._onSelectionChange.fire();
+    };
+    SelectionManager.prototype.selectLines = function (start, end) {
+        this._model.clearSelection();
+        start = Math.max(start, 0);
+        end = Math.min(end, this._terminal.buffer.lines.length - 1);
+        this._model.selectionStart = [0, start];
+        this._model.selectionEnd = [this._terminal.cols, end];
+        this.refresh();
+        this._onSelectionChange.fire();
+    };
+    SelectionManager.prototype._onTrim = function (amount) {
+        var needsRefresh = this._model.onTrim(amount);
+        if (needsRefresh) {
+            this.refresh();
+        }
+    };
+    SelectionManager.prototype._getMouseBufferCoords = function (event) {
+        var coords = this._terminal.mouseHelper.getCoords(event, this._terminal.screenElement, this._charMeasure, this._terminal.cols, this._terminal.rows, true);
+        if (!coords) {
+            return null;
+        }
+        coords[0]--;
+        coords[1]--;
+        coords[1] += this._terminal.buffer.ydisp;
+        return coords;
+    };
+    SelectionManager.prototype._getMouseEventScrollAmount = function (event) {
+        var offset = MouseHelper_1.MouseHelper.getCoordsRelativeToElement(event, this._terminal.screenElement)[1];
+        var terminalHeight = this._terminal.rows * Math.ceil(this._charMeasure.height * this._terminal.options.lineHeight);
+        if (offset >= 0 && offset <= terminalHeight) {
+            return 0;
+        }
+        if (offset > terminalHeight) {
+            offset -= terminalHeight;
+        }
+        offset = Math.min(Math.max(offset, -DRAG_SCROLL_MAX_THRESHOLD), DRAG_SCROLL_MAX_THRESHOLD);
+        offset /= DRAG_SCROLL_MAX_THRESHOLD;
+        return (offset / Math.abs(offset)) + Math.round(offset * (DRAG_SCROLL_MAX_SPEED - 1));
+    };
+    SelectionManager.prototype.shouldForceSelection = function (event) {
+        if (Browser.isMac) {
+            return event.altKey && this._terminal.options.macOptionClickForcesSelection;
+        }
+        return event.shiftKey;
+    };
+    SelectionManager.prototype.onMouseDown = function (event) {
+        this._mouseDownTimeStamp = event.timeStamp;
+        if (event.button === 2 && this.hasSelection) {
+            return;
+        }
+        if (event.button !== 0) {
+            return;
+        }
+        if (!this._enabled) {
+            if (!this.shouldForceSelection(event)) {
+                return;
+            }
+            event.stopPropagation();
+        }
+        event.preventDefault();
+        this._dragScrollAmount = 0;
+        if (this._enabled && event.shiftKey) {
+            this._onIncrementalClick(event);
+        }
+        else {
+            if (event.detail === 1) {
+                this._onSingleClick(event);
+            }
+            else if (event.detail === 2) {
+                this._onDoubleClick(event);
+            }
+            else if (event.detail === 3) {
+                this._onTripleClick(event);
+            }
+        }
+        this._addMouseDownListeners();
+        this.refresh(true);
+    };
+    SelectionManager.prototype._addMouseDownListeners = function () {
+        var _this = this;
+        this._terminal.element.ownerDocument.addEventListener('mousemove', this._mouseMoveListener);
+        this._terminal.element.ownerDocument.addEventListener('mouseup', this._mouseUpListener);
+        this._dragScrollIntervalTimer = setInterval(function () { return _this._dragScroll(); }, DRAG_SCROLL_INTERVAL);
+    };
+    SelectionManager.prototype._removeMouseDownListeners = function () {
+        if (this._terminal.element.ownerDocument) {
+            this._terminal.element.ownerDocument.removeEventListener('mousemove', this._mouseMoveListener);
+            this._terminal.element.ownerDocument.removeEventListener('mouseup', this._mouseUpListener);
+        }
+        clearInterval(this._dragScrollIntervalTimer);
+        this._dragScrollIntervalTimer = null;
+    };
+    SelectionManager.prototype._onIncrementalClick = function (event) {
+        if (this._model.selectionStart) {
+            this._model.selectionEnd = this._getMouseBufferCoords(event);
+        }
+    };
+    SelectionManager.prototype._onSingleClick = function (event) {
+        this._model.selectionStartLength = 0;
+        this._model.isSelectAllActive = false;
+        this._activeSelectionMode = this.shouldColumnSelect(event) ? 3 : 0;
+        this._model.selectionStart = this._getMouseBufferCoords(event);
+        if (!this._model.selectionStart) {
+            return;
+        }
+        this._model.selectionEnd = null;
+        var line = this._buffer.lines.get(this._model.selectionStart[1]);
+        if (!line) {
+            return;
+        }
+        if (line.length >= this._model.selectionStart[0]) {
+            return;
+        }
+        if (line.hasWidth(this._model.selectionStart[0]) === 0) {
+            this._model.selectionStart[0]++;
+        }
+    };
+    SelectionManager.prototype._onDoubleClick = function (event) {
+        var coords = this._getMouseBufferCoords(event);
+        if (coords) {
+            this._activeSelectionMode = 1;
+            this._selectWordAt(coords, true);
+        }
+    };
+    SelectionManager.prototype._onTripleClick = function (event) {
+        var coords = this._getMouseBufferCoords(event);
+        if (coords) {
+            this._activeSelectionMode = 2;
+            this._selectLineAt(coords[1]);
+        }
+    };
+    SelectionManager.prototype.shouldColumnSelect = function (event) {
+        return event.altKey && !(Browser.isMac && this._terminal.options.macOptionClickForcesSelection);
+    };
+    SelectionManager.prototype._onMouseMove = function (event) {
+        event.stopImmediatePropagation();
+        var previousSelectionEnd = this._model.selectionEnd ? [this._model.selectionEnd[0], this._model.selectionEnd[1]] : null;
+        this._model.selectionEnd = this._getMouseBufferCoords(event);
+        if (!this._model.selectionEnd) {
+            this.refresh(true);
+            return;
+        }
+        if (this._activeSelectionMode === 2) {
+            if (this._model.selectionEnd[1] < this._model.selectionStart[1]) {
+                this._model.selectionEnd[0] = 0;
+            }
+            else {
+                this._model.selectionEnd[0] = this._terminal.cols;
+            }
+        }
+        else if (this._activeSelectionMode === 1) {
+            this._selectToWordAt(this._model.selectionEnd);
+        }
+        this._dragScrollAmount = this._getMouseEventScrollAmount(event);
+        if (this._activeSelectionMode !== 3) {
+            if (this._dragScrollAmount > 0) {
+                this._model.selectionEnd[0] = this._terminal.cols;
+            }
+            else if (this._dragScrollAmount < 0) {
+                this._model.selectionEnd[0] = 0;
+            }
+        }
+        if (this._model.selectionEnd[1] < this._buffer.lines.length) {
+            if (this._buffer.lines.get(this._model.selectionEnd[1]).hasWidth(this._model.selectionEnd[0]) === 0) {
+                this._model.selectionEnd[0]++;
+            }
+        }
+        if (!previousSelectionEnd ||
+            previousSelectionEnd[0] !== this._model.selectionEnd[0] ||
+            previousSelectionEnd[1] !== this._model.selectionEnd[1]) {
+            this.refresh(true);
+        }
+    };
+    SelectionManager.prototype._dragScroll = function () {
+        if (this._dragScrollAmount) {
+            this._terminal.scrollLines(this._dragScrollAmount, false);
+            if (this._dragScrollAmount > 0) {
+                if (this._activeSelectionMode !== 3) {
+                    this._model.selectionEnd[0] = this._terminal.cols;
+                }
+                this._model.selectionEnd[1] = Math.min(this._terminal.buffer.ydisp + this._terminal.rows, this._terminal.buffer.lines.length - 1);
+            }
+            else {
+                if (this._activeSelectionMode !== 3) {
+                    this._model.selectionEnd[0] = 0;
+                }
+                this._model.selectionEnd[1] = this._terminal.buffer.ydisp;
+            }
+            this.refresh();
+        }
+    };
+    SelectionManager.prototype._onMouseUp = function (event) {
+        var timeElapsed = event.timeStamp - this._mouseDownTimeStamp;
+        this._removeMouseDownListeners();
+        if (this.selectionText.length <= 1 && timeElapsed < ALT_CLICK_MOVE_CURSOR_TIME) {
+            (new AltClickHandler_1.AltClickHandler(event, this._terminal)).move();
+        }
+        else if (this.hasSelection) {
+            this._onSelectionChange.fire();
+        }
+    };
+    SelectionManager.prototype._onBufferActivate = function (e) {
+        var _this = this;
+        this.clearSelection();
+        if (this._trimListener) {
+            this._trimListener.dispose();
+        }
+        this._trimListener = e.activeBuffer.lines.onTrim(function (amount) { return _this._onTrim(amount); });
+    };
+    SelectionManager.prototype._convertViewportColToCharacterIndex = function (bufferLine, coords) {
+        var charIndex = coords[0];
+        for (var i = 0; coords[0] >= i; i++) {
+            var length_1 = bufferLine.loadCell(i, this._workCell).getChars().length;
+            if (this._workCell.getWidth() === 0) {
+                charIndex--;
+            }
+            else if (length_1 > 1 && coords[0] !== i) {
+                charIndex += length_1 - 1;
+            }
+        }
+        return charIndex;
+    };
+    SelectionManager.prototype.setSelection = function (col, row, length) {
+        this._model.clearSelection();
+        this._removeMouseDownListeners();
+        this._model.selectionStart = [col, row];
+        this._model.selectionStartLength = length;
+        this.refresh();
+    };
+    SelectionManager.prototype._getWordAt = function (coords, allowWhitespaceOnlySelection, followWrappedLinesAbove, followWrappedLinesBelow) {
+        if (followWrappedLinesAbove === void 0) { followWrappedLinesAbove = true; }
+        if (followWrappedLinesBelow === void 0) { followWrappedLinesBelow = true; }
+        if (coords[0] >= this._terminal.cols) {
+            return null;
+        }
+        var bufferLine = this._buffer.lines.get(coords[1]);
+        if (!bufferLine) {
+            return null;
+        }
+        var line = this._buffer.translateBufferLineToString(coords[1], false);
+        var startIndex = this._convertViewportColToCharacterIndex(bufferLine, coords);
+        var endIndex = startIndex;
+        var charOffset = coords[0] - startIndex;
+        var leftWideCharCount = 0;
+        var rightWideCharCount = 0;
+        var leftLongCharOffset = 0;
+        var rightLongCharOffset = 0;
+        if (line.charAt(startIndex) === ' ') {
+            while (startIndex > 0 && line.charAt(startIndex - 1) === ' ') {
+                startIndex--;
+            }
+            while (endIndex < line.length && line.charAt(endIndex + 1) === ' ') {
+                endIndex++;
+            }
+        }
+        else {
+            var startCol = coords[0];
+            var endCol = coords[0];
+            if (bufferLine.getWidth(startCol) === 0) {
+                leftWideCharCount++;
+                startCol--;
+            }
+            if (bufferLine.getWidth(endCol) === 2) {
+                rightWideCharCount++;
+                endCol++;
+            }
+            var length_2 = bufferLine.getString(endCol).length;
+            if (length_2 > 1) {
+                rightLongCharOffset += length_2 - 1;
+                endIndex += length_2 - 1;
+            }
+            while (startCol > 0 && startIndex > 0 && !this._isCharWordSeparator(bufferLine.loadCell(startCol - 1, this._workCell))) {
+                bufferLine.loadCell(startCol - 1, this._workCell);
+                var length_3 = this._workCell.getChars().length;
+                if (this._workCell.getWidth() === 0) {
+                    leftWideCharCount++;
+                    startCol--;
+                }
+                else if (length_3 > 1) {
+                    leftLongCharOffset += length_3 - 1;
+                    startIndex -= length_3 - 1;
+                }
+                startIndex--;
+                startCol--;
+            }
+            while (endCol < bufferLine.length && endIndex + 1 < line.length && !this._isCharWordSeparator(bufferLine.loadCell(endCol + 1, this._workCell))) {
+                bufferLine.loadCell(endCol + 1, this._workCell);
+                var length_4 = this._workCell.getChars().length;
+                if (this._workCell.getWidth() === 2) {
+                    rightWideCharCount++;
+                    endCol++;
+                }
+                else if (length_4 > 1) {
+                    rightLongCharOffset += length_4 - 1;
+                    endIndex += length_4 - 1;
+                }
+                endIndex++;
+                endCol++;
+            }
+        }
+        endIndex++;
+        var start = startIndex
+            + charOffset
+            - leftWideCharCount
+            + leftLongCharOffset;
+        var length = Math.min(this._terminal.cols, endIndex
+            - startIndex
+            + leftWideCharCount
+            + rightWideCharCount
+            - leftLongCharOffset
+            - rightLongCharOffset);
+        if (!allowWhitespaceOnlySelection && line.slice(startIndex, endIndex).trim() === '') {
+            return null;
+        }
+        if (followWrappedLinesAbove) {
+            if (start === 0 && bufferLine.getCodePoint(0) !== 32) {
+                var previousBufferLine = this._buffer.lines.get(coords[1] - 1);
+                if (previousBufferLine && bufferLine.isWrapped && previousBufferLine.getCodePoint(this._terminal.cols - 1) !== 32) {
+                    var previousLineWordPosition = this._getWordAt([this._terminal.cols - 1, coords[1] - 1], false, true, false);
+                    if (previousLineWordPosition) {
+                        var offset = this._terminal.cols - previousLineWordPosition.start;
+                        start -= offset;
+                        length += offset;
+                    }
+                }
+            }
+        }
+        if (followWrappedLinesBelow) {
+            if (start + length === this._terminal.cols && bufferLine.getCodePoint(this._terminal.cols - 1) !== 32) {
+                var nextBufferLine = this._buffer.lines.get(coords[1] + 1);
+                if (nextBufferLine && nextBufferLine.isWrapped && nextBufferLine.getCodePoint(0) !== 32) {
+                    var nextLineWordPosition = this._getWordAt([0, coords[1] + 1], false, false, true);
+                    if (nextLineWordPosition) {
+                        length += nextLineWordPosition.length;
+                    }
+                }
+            }
+        }
+        return { start: start, length: length };
+    };
+    SelectionManager.prototype._selectWordAt = function (coords, allowWhitespaceOnlySelection) {
+        var wordPosition = this._getWordAt(coords, allowWhitespaceOnlySelection);
+        if (wordPosition) {
+            while (wordPosition.start < 0) {
+                wordPosition.start += this._terminal.cols;
+                coords[1]--;
+            }
+            this._model.selectionStart = [wordPosition.start, coords[1]];
+            this._model.selectionStartLength = wordPosition.length;
+        }
+    };
+    SelectionManager.prototype._selectToWordAt = function (coords) {
+        var wordPosition = this._getWordAt(coords, true);
+        if (wordPosition) {
+            var endRow = coords[1];
+            while (wordPosition.start < 0) {
+                wordPosition.start += this._terminal.cols;
+                endRow--;
+            }
+            if (!this._model.areSelectionValuesReversed()) {
+                while (wordPosition.start + wordPosition.length > this._terminal.cols) {
+                    wordPosition.length -= this._terminal.cols;
+                    endRow++;
+                }
+            }
+            this._model.selectionEnd = [this._model.areSelectionValuesReversed() ? wordPosition.start : wordPosition.start + wordPosition.length, endRow];
+        }
+    };
+    SelectionManager.prototype._isCharWordSeparator = function (cell) {
+        if (cell.getWidth() === 0) {
+            return false;
+        }
+        return WORD_SEPARATORS.indexOf(cell.getChars()) >= 0;
+    };
+    SelectionManager.prototype._selectLineAt = function (line) {
+        var wrappedRange = this._buffer.getWrappedRangeForLine(line);
+        this._model.selectionStart = [0, wrappedRange.first];
+        this._model.selectionEnd = [this._terminal.cols, wrappedRange.last];
+        this._model.selectionStartLength = 0;
+    };
+    return SelectionManager;
+}());
+exports.SelectionManager = SelectionManager;
+
+},{"./BufferLine":3,"./MouseHelper":13,"./SelectionModel":16,"./common/EventEmitter2":25,"./common/Platform":27,"./handlers/AltClickHandler":33}],16:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var SelectionModel = (function () {
+    function SelectionModel(_terminal) {
+        this._terminal = _terminal;
+        this.clearSelection();
+    }
+    SelectionModel.prototype.clearSelection = function () {
+        this.selectionStart = null;
+        this.selectionEnd = null;
+        this.isSelectAllActive = false;
+        this.selectionStartLength = 0;
+    };
+    Object.defineProperty(SelectionModel.prototype, "finalSelectionStart", {
+        get: function () {
+            if (this.isSelectAllActive) {
+                return [0, 0];
+            }
+            if (!this.selectionEnd || !this.selectionStart) {
+                return this.selectionStart;
+            }
+            return this.areSelectionValuesReversed() ? this.selectionEnd : this.selectionStart;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(SelectionModel.prototype, "finalSelectionEnd", {
+        get: function () {
+            if (this.isSelectAllActive) {
+                return [this._terminal.cols, this._terminal.buffer.ybase + this._terminal.rows - 1];
+            }
+            if (!this.selectionStart) {
+                return null;
+            }
+            if (!this.selectionEnd || this.areSelectionValuesReversed()) {
+                var startPlusLength = this.selectionStart[0] + this.selectionStartLength;
+                if (startPlusLength > this._terminal.cols) {
+                    return [startPlusLength % this._terminal.cols, this.selectionStart[1] + Math.floor(startPlusLength / this._terminal.cols)];
+                }
+                return [startPlusLength, this.selectionStart[1]];
+            }
+            if (this.selectionStartLength) {
+                if (this.selectionEnd[1] === this.selectionStart[1]) {
+                    return [Math.max(this.selectionStart[0] + this.selectionStartLength, this.selectionEnd[0]), this.selectionEnd[1]];
+                }
+            }
+            return this.selectionEnd;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    SelectionModel.prototype.areSelectionValuesReversed = function () {
+        var start = this.selectionStart;
+        var end = this.selectionEnd;
+        if (!start || !end) {
+            return false;
+        }
+        return start[1] > end[1] || (start[1] === end[1] && start[0] > end[0]);
+    };
+    SelectionModel.prototype.onTrim = function (amount) {
+        if (this.selectionStart) {
+            this.selectionStart[1] -= amount;
+        }
+        if (this.selectionEnd) {
+            this.selectionEnd[1] -= amount;
+        }
+        if (this.selectionEnd && this.selectionEnd[1] < 0) {
+            this.clearSelection();
+            return true;
+        }
+        if (this.selectionStart && this.selectionStart[1] < 0) {
+            this.selectionStart[1] = 0;
+        }
+        return false;
+    };
+    return SelectionModel;
+}());
+exports.SelectionModel = SelectionModel;
+
+},{}],17:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.DEFAULT_BELL_SOUND = 'data:audio/wav;base64,UklGRigBAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQQBAADpAFgCwAMlBZoG/wdmCcoKRAypDQ8PbRDBEQQTOxRtFYcWlBePGIUZXhoiG88bcBz7HHIdzh0WHlMeZx51HmkeUx4WHs8dah0AHXwc3hs9G4saxRnyGBIYGBcQFv8U4RPAEoYRQBACD70NWwwHC6gJOwjWBloF7gOBAhABkf8b/qv8R/ve+Xf4Ife79W/0JfPZ8Z/wde9N7ijtE+wU6xvqM+lb6H7nw+YX5mrlxuQz5Mzje+Ma49fioeKD4nXiYeJy4pHitOL04j/jn+MN5IPkFOWs5U3mDefM55/ogOl36m7rdOyE7abuyu8D8Unyj/Pg9D/2qfcb+Yn6/vuK/Qj/lAAlAg==';
+var SoundManager = (function () {
+    function SoundManager(_terminal) {
+        this._terminal = _terminal;
+    }
+    Object.defineProperty(SoundManager, "audioContext", {
+        get: function () {
+            if (!SoundManager._audioContext) {
+                var audioContextCtor = window.AudioContext || window.webkitAudioContext;
+                if (!audioContextCtor) {
+                    console.warn('Web Audio API is not supported by this browser. Consider upgrading to the latest version');
+                    return null;
+                }
+                SoundManager._audioContext = new audioContextCtor();
+            }
+            return SoundManager._audioContext;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    SoundManager.prototype.playBellSound = function () {
+        var ctx = SoundManager.audioContext;
+        if (!ctx) {
+            return;
+        }
+        var bellAudioSource = ctx.createBufferSource();
+        ctx.decodeAudioData(this._base64ToArrayBuffer(this._removeMimeType(this._terminal.options.bellSound)), function (buffer) {
+            bellAudioSource.buffer = buffer;
+            bellAudioSource.connect(ctx.destination);
+            bellAudioSource.start(0);
+        });
+    };
+    SoundManager.prototype._base64ToArrayBuffer = function (base64) {
+        var binaryString = window.atob(base64);
+        var len = binaryString.length;
+        var bytes = new Uint8Array(len);
+        for (var i = 0; i < len; i++) {
+            bytes[i] = binaryString.charCodeAt(i);
+        }
+        return bytes.buffer;
+    };
+    SoundManager.prototype._removeMimeType = function (dataURI) {
+        var splitUri = dataURI.split(',');
+        return splitUri[1];
+    };
+    return SoundManager;
+}());
+exports.SoundManager = SoundManager;
+
+},{}],18:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.blankLine = 'Blank line';
+exports.promptLabel = 'Terminal input';
+exports.tooMuchOutput = 'Too much output to announce, navigate to rows manually to read';
+
+},{}],19:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = function (d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var BufferSet_1 = require("./BufferSet");
+var Buffer_1 = require("./Buffer");
+var CompositionHelper_1 = require("./CompositionHelper");
+var EventEmitter_1 = require("./common/EventEmitter");
+var Viewport_1 = require("./Viewport");
+var Clipboard_1 = require("./Clipboard");
+var EscapeSequences_1 = require("./common/data/EscapeSequences");
+var InputHandler_1 = require("./InputHandler");
+var Renderer_1 = require("./renderer/Renderer");
+var Linkifier_1 = require("./Linkifier");
+var SelectionManager_1 = require("./SelectionManager");
+var CharMeasure_1 = require("./CharMeasure");
+var Browser = require("./common/Platform");
+var Lifecycle_1 = require("./ui/Lifecycle");
+var Strings = require("./Strings");
+var MouseHelper_1 = require("./MouseHelper");
+var SoundManager_1 = require("./SoundManager");
+var MouseZoneManager_1 = require("./MouseZoneManager");
+var AccessibilityManager_1 = require("./AccessibilityManager");
+var ScreenDprMonitor_1 = require("./ui/ScreenDprMonitor");
+var CharAtlasCache_1 = require("./renderer/atlas/CharAtlasCache");
+var DomRenderer_1 = require("./renderer/dom/DomRenderer");
+var Keyboard_1 = require("./core/input/Keyboard");
+var Clone_1 = require("./common/Clone");
+var EventEmitter2_1 = require("./common/EventEmitter2");
+var WindowsMode_1 = require("./WindowsMode");
+var document = (typeof window !== 'undefined') ? window.document : null;
+var WRITE_BUFFER_PAUSE_THRESHOLD = 5;
+var WRITE_TIMEOUT_MS = 12;
+var MINIMUM_COLS = 2;
+var MINIMUM_ROWS = 1;
+var CONSTRUCTOR_ONLY_OPTIONS = ['cols', 'rows'];
+var DEFAULT_OPTIONS = {
+    cols: 80,
+    rows: 24,
+    convertEol: false,
+    termName: 'xterm',
+    cursorBlink: false,
+    cursorStyle: 'block',
+    bellSound: SoundManager_1.DEFAULT_BELL_SOUND,
+    bellStyle: 'none',
+    drawBoldTextInBrightColors: true,
+    enableBold: true,
+    experimentalCharAtlas: 'static',
+    fontFamily: 'courier-new, courier, monospace',
+    fontSize: 15,
+    fontWeight: 'normal',
+    fontWeightBold: 'bold',
+    lineHeight: 1.0,
+    letterSpacing: 0,
+    scrollback: 1000,
+    screenKeys: false,
+    screenReaderMode: false,
+    debug: false,
+    macOptionIsMeta: false,
+    macOptionClickForcesSelection: false,
+    cancelEvents: false,
+    disableStdin: false,
+    useFlowControl: false,
+    allowTransparency: false,
+    tabStopWidth: 8,
+    theme: null,
+    rightClickSelectsWord: Browser.isMac,
+    rendererType: 'canvas',
+    windowsMode: false
+};
+var Terminal = (function (_super) {
+    __extends(Terminal, _super);
+    function Terminal(options) {
+        if (options === void 0) { options = {}; }
+        var _this = _super.call(this) || this;
+        _this.browser = Browser;
+        _this._blankLine = null;
+        _this._onCursorMove = new EventEmitter2_1.EventEmitter2();
+        _this._onData = new EventEmitter2_1.EventEmitter2();
+        _this._onKey = new EventEmitter2_1.EventEmitter2();
+        _this._onLineFeed = new EventEmitter2_1.EventEmitter2();
+        _this._onRender = new EventEmitter2_1.EventEmitter2();
+        _this._onResize = new EventEmitter2_1.EventEmitter2();
+        _this._onScroll = new EventEmitter2_1.EventEmitter2();
+        _this._onSelectionChange = new EventEmitter2_1.EventEmitter2();
+        _this._onTitleChange = new EventEmitter2_1.EventEmitter2();
+        _this.options = Clone_1.clone(options);
+        _this._setup();
+        _this.onCursorMove(function () { return _this.emit('cursormove'); });
+        _this.onData(function (e) { return _this.emit('data', e); });
+        _this.onKey(function (e) { return _this.emit('key', e.key, e.domEvent); });
+        _this.onLineFeed(function () { return _this.emit('linefeed'); });
+        _this.onRender(function (e) { return _this.emit('refresh', e); });
+        _this.onResize(function (e) { return _this.emit('resize', e); });
+        _this.onSelectionChange(function () { return _this.emit('selection'); });
+        _this.onScroll(function (e) { return _this.emit('scroll', e); });
+        _this.onTitleChange(function (e) { return _this.emit('title', e); });
+        return _this;
+    }
+    Object.defineProperty(Terminal.prototype, "onCursorMove", {
+        get: function () { return this._onCursorMove.event; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Terminal.prototype, "onData", {
+        get: function () { return this._onData.event; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Terminal.prototype, "onKey", {
+        get: function () { return this._onKey.event; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Terminal.prototype, "onLineFeed", {
+        get: function () { return this._onLineFeed.event; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Terminal.prototype, "onRender", {
+        get: function () { return this._onRender.event; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Terminal.prototype, "onResize", {
+        get: function () { return this._onResize.event; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Terminal.prototype, "onScroll", {
+        get: function () { return this._onScroll.event; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Terminal.prototype, "onSelectionChange", {
+        get: function () { return this._onSelectionChange.event; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Terminal.prototype, "onTitleChange", {
+        get: function () { return this._onTitleChange.event; },
+        enumerable: true,
+        configurable: true
+    });
+    Terminal.prototype.dispose = function () {
+        _super.prototype.dispose.call(this);
+        if (this._windowsMode) {
+            this._windowsMode.dispose();
+            this._windowsMode = undefined;
+        }
+        this._customKeyEventHandler = null;
+        CharAtlasCache_1.removeTerminalFromCache(this);
+        this.handler = function () { };
+        this.write = function () { };
+        if (this.element && this.element.parentNode) {
+            this.element.parentNode.removeChild(this.element);
+        }
+    };
+    Terminal.prototype.destroy = function () {
+        this.dispose();
+    };
+    Terminal.prototype._setup = function () {
+        var _this = this;
+        Object.keys(DEFAULT_OPTIONS).forEach(function (key) {
+            if (_this.options[key] === null || _this.options[key] === undefined) {
+                _this.options[key] = DEFAULT_OPTIONS[key];
+            }
+        });
+        this._parent = document ? document.body : null;
+        this.cols = Math.max(this.options.cols, MINIMUM_COLS);
+        this.rows = Math.max(this.options.rows, MINIMUM_ROWS);
+        if (this.options.handler) {
+            this.onData(this.options.handler);
+        }
+        this.cursorState = 0;
+        this.cursorHidden = false;
+        this._customKeyEventHandler = null;
+        this.applicationKeypad = false;
+        this.applicationCursor = false;
+        this.originMode = false;
+        this.insertMode = false;
+        this.wraparoundMode = true;
+        this.bracketedPasteMode = false;
+        this.charset = null;
+        this.gcharset = null;
+        this.glevel = 0;
+        this.charsets = [null];
+        this.curAttrData = Buffer_1.DEFAULT_ATTR_DATA.clone();
+        this._eraseAttrData = Buffer_1.DEFAULT_ATTR_DATA.clone();
+        this.params = [];
+        this.currentParam = 0;
+        this.writeBuffer = [];
+        this._writeInProgress = false;
+        this._xoffSentToCatchUp = false;
+        this._userScrolling = false;
+        this._inputHandler = new InputHandler_1.InputHandler(this);
+        this._inputHandler.onCursorMove(function () { return _this._onCursorMove.fire(); });
+        this._inputHandler.onLineFeed(function () { return _this._onLineFeed.fire(); });
+        this._inputHandler.onData(function (e) { return _this._onData.fire(e); });
+        this.register(this._inputHandler);
+        this.renderer = this.renderer || null;
+        this.selectionManager = this.selectionManager || null;
+        this.linkifier = this.linkifier || new Linkifier_1.Linkifier(this);
+        this._mouseZoneManager = this._mouseZoneManager || null;
+        this.soundManager = this.soundManager || new SoundManager_1.SoundManager(this);
+        this.buffers = new BufferSet_1.BufferSet(this);
+        if (this.selectionManager) {
+            this.selectionManager.clearSelection();
+            this.selectionManager.initBuffersListeners();
+        }
+        if (this.options.windowsMode) {
+            this._windowsMode = WindowsMode_1.applyWindowsMode(this);
+        }
+    };
+    Object.defineProperty(Terminal.prototype, "buffer", {
+        get: function () {
+            return this.buffers.active;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Terminal.prototype.eraseAttrData = function () {
+        this._eraseAttrData.bg &= ~(50331648 | 0xFFFFFF);
+        this._eraseAttrData.bg |= this.curAttrData.bg & ~0xFC000000;
+        return this._eraseAttrData;
+    };
+    Terminal.prototype.focus = function () {
+        if (this.textarea) {
+            this.textarea.focus({ preventScroll: true });
+        }
+    };
+    Object.defineProperty(Terminal.prototype, "isFocused", {
+        get: function () {
+            return document.activeElement === this.textarea && document.hasFocus();
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Terminal.prototype.getOption = function (key) {
+        if (!(key in DEFAULT_OPTIONS)) {
+            throw new Error('No option with key "' + key + '"');
+        }
+        return this.options[key];
+    };
+    Terminal.prototype.setOption = function (key, value) {
+        if (!(key in DEFAULT_OPTIONS)) {
+            throw new Error('No option with key "' + key + '"');
+        }
+        if (CONSTRUCTOR_ONLY_OPTIONS.indexOf(key) !== -1) {
+            console.error("Option \"" + key + "\" can only be set in the constructor");
+        }
+        if (this.options[key] === value) {
+            return;
+        }
+        switch (key) {
+            case 'bellStyle':
+                if (!value) {
+                    value = 'none';
+                }
+                break;
+            case 'cursorStyle':
+                if (!value) {
+                    value = 'block';
+                }
+                break;
+            case 'fontWeight':
+                if (!value) {
+                    value = 'normal';
+                }
+                break;
+            case 'fontWeightBold':
+                if (!value) {
+                    value = 'bold';
+                }
+                break;
+            case 'lineHeight':
+                if (value < 1) {
+                    console.warn(key + " cannot be less than 1, value: " + value);
+                    return;
+                }
+            case 'rendererType':
+                if (!value) {
+                    value = 'canvas';
+                }
+                break;
+            case 'tabStopWidth':
+                if (value < 1) {
+                    console.warn(key + " cannot be less than 1, value: " + value);
+                    return;
+                }
+                break;
+            case 'theme':
+                if (this.renderer) {
+                    this._setTheme(value);
+                    return;
+                }
+                break;
+            case 'scrollback':
+                value = Math.min(value, Buffer_1.MAX_BUFFER_SIZE);
+                if (value < 0) {
+                    console.warn(key + " cannot be less than 0, value: " + value);
+                    return;
+                }
+                if (this.options[key] !== value) {
+                    var newBufferLength = this.rows + value;
+                    if (this.buffer.lines.length > newBufferLength) {
+                        var amountToTrim = this.buffer.lines.length - newBufferLength;
+                        var needsRefresh = (this.buffer.ydisp - amountToTrim < 0);
+                        this.buffer.lines.trimStart(amountToTrim);
+                        this.buffer.ybase = Math.max(this.buffer.ybase - amountToTrim, 0);
+                        this.buffer.ydisp = Math.max(this.buffer.ydisp - amountToTrim, 0);
+                        if (needsRefresh) {
+                            this.refresh(0, this.rows - 1);
+                        }
+                    }
+                }
+                break;
+        }
+        this.options[key] = value;
+        switch (key) {
+            case 'fontFamily':
+            case 'fontSize':
+                if (this.renderer) {
+                    this.renderer.clear();
+                    this.charMeasure.measure(this.options);
+                }
+                break;
+            case 'drawBoldTextInBrightColors':
+            case 'experimentalCharAtlas':
+            case 'enableBold':
+            case 'letterSpacing':
+            case 'lineHeight':
+            case 'fontWeight':
+            case 'fontWeightBold':
+                if (this.renderer) {
+                    this.renderer.clear();
+                    this.renderer.onResize(this.cols, this.rows);
+                    this.refresh(0, this.rows - 1);
+                }
+                break;
+            case 'rendererType':
+                if (this.renderer) {
+                    this.unregister(this.renderer);
+                    this.renderer.dispose();
+                    this.renderer = null;
+                }
+                this._setupRenderer();
+                this.renderer.onCharSizeChanged();
+                if (this._theme) {
+                    this.renderer.setTheme(this._theme);
+                }
+                this.mouseHelper.setRenderer(this.renderer);
+                break;
+            case 'scrollback':
+                this.buffers.resize(this.cols, this.rows);
+                if (this.viewport) {
+                    this.viewport.syncScrollArea();
+                }
+                break;
+            case 'screenReaderMode':
+                if (value) {
+                    if (!this._accessibilityManager) {
+                        this._accessibilityManager = new AccessibilityManager_1.AccessibilityManager(this);
+                    }
+                }
+                else {
+                    if (this._accessibilityManager) {
+                        this._accessibilityManager.dispose();
+                        this._accessibilityManager = null;
+                    }
+                }
+                break;
+            case 'tabStopWidth':
+                this.buffers.setupTabStops();
+                break;
+            case 'windowsMode':
+                if (value) {
+                    if (!this._windowsMode) {
+                        this._windowsMode = WindowsMode_1.applyWindowsMode(this);
+                    }
+                }
+                else {
+                    if (this._windowsMode) {
+                        this._windowsMode.dispose();
+                        this._windowsMode = undefined;
+                    }
+                }
+                break;
+        }
+        if (this.renderer) {
+            this.renderer.onOptionsChanged();
+        }
+    };
+    Terminal.prototype._onTextAreaFocus = function (ev) {
+        if (this.sendFocus) {
+            this.handler(EscapeSequences_1.C0.ESC + '[I');
+        }
+        this.updateCursorStyle(ev);
+        this.element.classList.add('focus');
+        this.showCursor();
+        this.emit('focus');
+    };
+    Terminal.prototype.blur = function () {
+        return this.textarea.blur();
+    };
+    Terminal.prototype._onTextAreaBlur = function () {
+        this.textarea.value = '';
+        this.refresh(this.buffer.y, this.buffer.y);
+        if (this.sendFocus) {
+            this.handler(EscapeSequences_1.C0.ESC + '[O');
+        }
+        this.element.classList.remove('focus');
+        this.emit('blur');
+    };
+    Terminal.prototype._initGlobal = function () {
+        var _this = this;
+        this._bindKeys();
+        this.register(Lifecycle_1.addDisposableDomListener(this.element, 'copy', function (event) {
+            if (!_this.hasSelection()) {
+                return;
+            }
+            Clipboard_1.copyHandler(event, _this, _this.selectionManager);
+        }));
+        var pasteHandlerWrapper = function (event) { return Clipboard_1.pasteHandler(event, _this); };
+        this.register(Lifecycle_1.addDisposableDomListener(this.textarea, 'paste', pasteHandlerWrapper));
+        this.register(Lifecycle_1.addDisposableDomListener(this.element, 'paste', pasteHandlerWrapper));
+        if (Browser.isFirefox) {
+            this.register(Lifecycle_1.addDisposableDomListener(this.element, 'mousedown', function (event) {
+                if (event.button === 2) {
+                    Clipboard_1.rightClickHandler(event, _this, _this.selectionManager, _this.options.rightClickSelectsWord);
+                }
+            }));
+        }
+        else {
+            this.register(Lifecycle_1.addDisposableDomListener(this.element, 'contextmenu', function (event) {
+                Clipboard_1.rightClickHandler(event, _this, _this.selectionManager, _this.options.rightClickSelectsWord);
+            }));
+        }
+        if (Browser.isLinux) {
+            this.register(Lifecycle_1.addDisposableDomListener(this.element, 'auxclick', function (event) {
+                if (event.button === 1) {
+                    Clipboard_1.moveTextAreaUnderMouseCursor(event, _this);
+                }
+            }));
+        }
+    };
+    Terminal.prototype._bindKeys = function () {
+        var _this = this;
+        var self = this;
+        this.register(Lifecycle_1.addDisposableDomListener(this.element, 'keydown', function (ev) {
+            if (document.activeElement !== this) {
+                return;
+            }
+            self._keyDown(ev);
+        }, true));
+        this.register(Lifecycle_1.addDisposableDomListener(this.element, 'keypress', function (ev) {
+            if (document.activeElement !== this) {
+                return;
+            }
+            self._keyPress(ev);
+        }, true));
+        this.register(Lifecycle_1.addDisposableDomListener(this.element, 'keyup', function (ev) {
+            if (!wasModifierKeyOnlyEvent(ev)) {
+                _this.focus();
+            }
+            self._keyUp(ev);
+        }, true));
+        this.register(Lifecycle_1.addDisposableDomListener(this.textarea, 'keydown', function (ev) { return _this._keyDown(ev); }, true));
+        this.register(Lifecycle_1.addDisposableDomListener(this.textarea, 'keypress', function (ev) { return _this._keyPress(ev); }, true));
+        this.register(Lifecycle_1.addDisposableDomListener(this.textarea, 'compositionstart', function () { return _this._compositionHelper.compositionstart(); }));
+        this.register(Lifecycle_1.addDisposableDomListener(this.textarea, 'compositionupdate', function (e) { return _this._compositionHelper.compositionupdate(e); }));
+        this.register(Lifecycle_1.addDisposableDomListener(this.textarea, 'compositionend', function () { return _this._compositionHelper.compositionend(); }));
+        this.register(this.onRender(function () { return _this._compositionHelper.updateCompositionElements(); }));
+        this.register(this.onRender(function (e) { return _this._queueLinkification(e.start, e.end); }));
+    };
+    Terminal.prototype.open = function (parent) {
+        var _this = this;
+        this._parent = parent || this._parent;
+        if (!this._parent) {
+            throw new Error('Terminal requires a parent element.');
+        }
+        this._context = this._parent.ownerDocument.defaultView;
+        this._document = this._parent.ownerDocument;
+        this._screenDprMonitor = new ScreenDprMonitor_1.ScreenDprMonitor();
+        this._screenDprMonitor.setListener(function () { return _this.emit('dprchange', window.devicePixelRatio); });
+        this.register(this._screenDprMonitor);
+        this.element = this._document.createElement('div');
+        this.element.dir = 'ltr';
+        this.element.classList.add('terminal');
+        this.element.classList.add('xterm');
+        this.element.setAttribute('tabindex', '0');
+        this._parent.appendChild(this.element);
+        var fragment = document.createDocumentFragment();
+        this._viewportElement = document.createElement('div');
+        this._viewportElement.classList.add('xterm-viewport');
+        fragment.appendChild(this._viewportElement);
+        this._viewportScrollArea = document.createElement('div');
+        this._viewportScrollArea.classList.add('xterm-scroll-area');
+        this._viewportElement.appendChild(this._viewportScrollArea);
+        this.screenElement = document.createElement('div');
+        this.screenElement.classList.add('xterm-screen');
+        this._helperContainer = document.createElement('div');
+        this._helperContainer.classList.add('xterm-helpers');
+        this.screenElement.appendChild(this._helperContainer);
+        fragment.appendChild(this.screenElement);
+        this._mouseZoneManager = new MouseZoneManager_1.MouseZoneManager(this);
+        this.register(this._mouseZoneManager);
+        this.register(this.onScroll(function () { return _this._mouseZoneManager.clearAll(); }));
+        this.linkifier.attachToDom(this._mouseZoneManager);
+        this.textarea = document.createElement('textarea');
+        this.textarea.classList.add('xterm-helper-textarea');
+        this.textarea.setAttribute('aria-label', Strings.promptLabel);
+        this.textarea.setAttribute('aria-multiline', 'false');
+        this.textarea.setAttribute('autocorrect', 'off');
+        this.textarea.setAttribute('autocapitalize', 'off');
+        this.textarea.setAttribute('spellcheck', 'false');
+        this.textarea.tabIndex = 0;
+        this.register(Lifecycle_1.addDisposableDomListener(this.textarea, 'focus', function (ev) { return _this._onTextAreaFocus(ev); }));
+        this.register(Lifecycle_1.addDisposableDomListener(this.textarea, 'blur', function () { return _this._onTextAreaBlur(); }));
+        this._helperContainer.appendChild(this.textarea);
+        this._compositionView = document.createElement('div');
+        this._compositionView.classList.add('composition-view');
+        this._compositionHelper = new CompositionHelper_1.CompositionHelper(this.textarea, this._compositionView, this);
+        this._helperContainer.appendChild(this._compositionView);
+        this.charMeasure = new CharMeasure_1.CharMeasure(document, this._helperContainer);
+        this.element.appendChild(fragment);
+        this._setupRenderer();
+        this._theme = this.options.theme;
+        this.options.theme = null;
+        this.viewport = new Viewport_1.Viewport(this, this._viewportElement, this._viewportScrollArea, this.charMeasure);
+        this.viewport.onThemeChanged(this.renderer.colorManager.colors);
+        this.register(this.viewport);
+        this.register(this.onCursorMove(function () { return _this.renderer.onCursorMove(); }));
+        this.register(this.onResize(function () { return _this.renderer.onResize(_this.cols, _this.rows); }));
+        this.register(this.addDisposableListener('blur', function () { return _this.renderer.onBlur(); }));
+        this.register(this.addDisposableListener('focus', function () { return _this.renderer.onFocus(); }));
+        this.register(this.addDisposableListener('dprchange', function () { return _this.renderer.onWindowResize(window.devicePixelRatio); }));
+        this.register(Lifecycle_1.addDisposableDomListener(window, 'resize', function () { return _this.renderer.onWindowResize(window.devicePixelRatio); }));
+        this.register(this.charMeasure.onCharSizeChanged(function () { return _this.renderer.onCharSizeChanged(); }));
+        this.register(this.renderer.onCanvasResize(function () { return _this.viewport.syncScrollArea(); }));
+        this.selectionManager = new SelectionManager_1.SelectionManager(this, this.charMeasure);
+        this.register(this.selectionManager.onSelectionChange(function () { return _this._onSelectionChange.fire(); }));
+        this.register(Lifecycle_1.addDisposableDomListener(this.element, 'mousedown', function (e) { return _this.selectionManager.onMouseDown(e); }));
+        this.register(this.selectionManager.onRedrawRequest(function (e) { return _this.renderer.onSelectionChanged(e.start, e.end, e.columnSelectMode); }));
+        this.register(this.selectionManager.onLinuxMouseSelection(function (text) {
+            _this.textarea.value = text;
+            _this.textarea.focus();
+            _this.textarea.select();
+        }));
+        this.register(this.onScroll(function () {
+            _this.viewport.syncScrollArea();
+            _this.selectionManager.refresh();
+        }));
+        this.register(Lifecycle_1.addDisposableDomListener(this._viewportElement, 'scroll', function () { return _this.selectionManager.refresh(); }));
+        this.mouseHelper = new MouseHelper_1.MouseHelper(this.renderer);
+        this.element.classList.toggle('enable-mouse-events', this.mouseEvents);
+        if (this.mouseEvents) {
+            this.selectionManager.disable();
+        }
+        else {
+            this.selectionManager.enable();
+        }
+        if (this.options.screenReaderMode) {
+            this._accessibilityManager = new AccessibilityManager_1.AccessibilityManager(this);
+        }
+        this.charMeasure.measure(this.options);
+        this.refresh(0, this.rows - 1);
+        this._initGlobal();
+        this.bindMouse();
+    };
+    Terminal.prototype._setupRenderer = function () {
+        var _this = this;
+        switch (this.options.rendererType) {
+            case 'canvas':
+                this.renderer = new Renderer_1.Renderer(this, this.options.theme);
+                break;
+            case 'dom':
+                this.renderer = new DomRenderer_1.DomRenderer(this, this.options.theme);
+                break;
+            default: throw new Error("Unrecognized rendererType \"" + this.options.rendererType + "\"");
+        }
+        this.renderer.onRender(function (e) { return _this._onRender.fire(e); });
+        this.register(this.renderer);
+    };
+    Terminal.prototype._setTheme = function (theme) {
+        this._theme = theme;
+        var colors = this.renderer.setTheme(theme);
+        if (this.viewport) {
+            this.viewport.onThemeChanged(colors);
+        }
+    };
+    Terminal.prototype.bindMouse = function () {
+        var _this = this;
+        var el = this.element;
+        var self = this;
+        var pressed = 32;
+        function sendButton(ev) {
+            var button;
+            var pos;
+            button = getButton(ev);
+            pos = self.mouseHelper.getRawByteCoords(ev, self.screenElement, self.charMeasure, self.cols, self.rows);
+            if (!pos)
+                return;
+            sendEvent(button, pos);
+            switch (ev.overrideType || ev.type) {
+                case 'mousedown':
+                    pressed = button;
+                    break;
+                case 'mouseup':
+                    pressed = 32;
+                    break;
+                case 'wheel':
+                    break;
+            }
+        }
+        function sendMove(ev) {
+            var button = pressed;
+            var pos = self.mouseHelper.getRawByteCoords(ev, self.screenElement, self.charMeasure, self.cols, self.rows);
+            if (!pos)
+                return;
+            button += 32;
+            sendEvent(button, pos);
+        }
+        function encode(data, ch) {
+            if (!self.utfMouse) {
+                if (ch === 255) {
+                    data.push(0);
+                    return;
+                }
+                if (ch > 127)
+                    ch = 127;
+                data.push(ch);
+            }
+            else {
+                if (ch > 2047) {
+                    data.push(2047);
+                    return;
+                }
+                data.push(ch);
+            }
+        }
+        function sendEvent(button, pos) {
+            if (self._vt300Mouse) {
+                button &= 3;
+                pos.x -= 32;
+                pos.y -= 32;
+                var data_1 = EscapeSequences_1.C0.ESC + '[24';
+                if (button === 0)
+                    data_1 += '1';
+                else if (button === 1)
+                    data_1 += '3';
+                else if (button === 2)
+                    data_1 += '5';
+                else if (button === 3)
+                    return;
+                else
+                    data_1 += '0';
+                data_1 += '~[' + pos.x + ',' + pos.y + ']\r';
+                self.handler(data_1);
+                return;
+            }
+            if (self._decLocator) {
+                button &= 3;
+                pos.x -= 32;
+                pos.y -= 32;
+                if (button === 0)
+                    button = 2;
+                else if (button === 1)
+                    button = 4;
+                else if (button === 2)
+                    button = 6;
+                else if (button === 3)
+                    button = 3;
+                self.handler(EscapeSequences_1.C0.ESC + '['
+                    + button
+                    + ';'
+                    + (button === 3 ? 4 : 0)
+                    + ';'
+                    + pos.y
+                    + ';'
+                    + pos.x
+                    + ';'
+                    + pos.page || 0
+                    + '&w');
+                return;
+            }
+            if (self.urxvtMouse) {
+                pos.x -= 32;
+                pos.y -= 32;
+                pos.x++;
+                pos.y++;
+                self.handler(EscapeSequences_1.C0.ESC + '[' + button + ';' + pos.x + ';' + pos.y + 'M');
+                return;
+            }
+            if (self.sgrMouse) {
+                pos.x -= 32;
+                pos.y -= 32;
+                self.handler(EscapeSequences_1.C0.ESC + '[<'
+                    + (((button & 3) === 3 ? button & ~3 : button) - 32)
+                    + ';'
+                    + pos.x
+                    + ';'
+                    + pos.y
+                    + ((button & 3) === 3 ? 'm' : 'M'));
+                return;
+            }
+            var data = [];
+            encode(data, button);
+            encode(data, pos.x);
+            encode(data, pos.y);
+            self.handler(EscapeSequences_1.C0.ESC + '[M' + String.fromCharCode.apply(String, data));
+        }
+        function getButton(ev) {
+            var button;
+            var shift;
+            var meta;
+            var ctrl;
+            var mod;
+            switch (ev.overrideType || ev.type) {
+                case 'mousedown':
+                    button = ev.button !== null && ev.button !== undefined
+                        ? +ev.button
+                        : ev.which !== null && ev.which !== undefined
+                            ? ev.which - 1
+                            : null;
+                    if (Browser.isMSIE) {
+                        button = button === 1 ? 0 : button === 4 ? 1 : button;
+                    }
+                    break;
+                case 'mouseup':
+                    button = 3;
+                    break;
+                case 'DOMMouseScroll':
+                    button = ev.detail < 0
+                        ? 64
+                        : 65;
+                    break;
+                case 'wheel':
+                    button = ev.deltaY < 0
+                        ? 64
+                        : 65;
+                    break;
+            }
+            shift = ev.shiftKey ? 4 : 0;
+            meta = ev.metaKey ? 8 : 0;
+            ctrl = ev.ctrlKey ? 16 : 0;
+            mod = shift | meta | ctrl;
+            if (self.vt200Mouse) {
+                mod &= ctrl;
+            }
+            else if (!self.normalMouse) {
+                mod = 0;
+            }
+            button = (32 + (mod << 2)) + button;
+            return button;
+        }
+        this.register(Lifecycle_1.addDisposableDomListener(el, 'mousedown', function (ev) {
+            ev.preventDefault();
+            _this.focus();
+            if (!_this.mouseEvents || _this.selectionManager.shouldForceSelection(ev)) {
+                return;
+            }
+            sendButton(ev);
+            if (_this.vt200Mouse) {
+                ev.overrideType = 'mouseup';
+                sendButton(ev);
+                return _this.cancel(ev);
+            }
+            var moveHandler;
+            if (_this.normalMouse) {
+                moveHandler = function (event) {
+                    if (!_this.normalMouse) {
+                        return;
+                    }
+                    sendMove(event);
+                };
+                _this._document.addEventListener('mousemove', moveHandler);
+            }
+            var handler = function (ev) {
+                if (_this.normalMouse && !_this.x10Mouse) {
+                    sendButton(ev);
+                }
+                if (moveHandler) {
+                    _this._document.removeEventListener('mousemove', moveHandler);
+                    moveHandler = null;
+                }
+                _this._document.removeEventListener('mouseup', handler);
+                return _this.cancel(ev);
+            };
+            _this._document.addEventListener('mouseup', handler);
+            return _this.cancel(ev);
+        }));
+        this.register(Lifecycle_1.addDisposableDomListener(el, 'wheel', function (ev) {
+            if (!_this.mouseEvents) {
+                if (!_this.buffer.hasScrollback) {
+                    var amount = _this.viewport.getLinesScrolled(ev);
+                    if (amount === 0) {
+                        return;
+                    }
+                    var sequence = EscapeSequences_1.C0.ESC + (_this.applicationCursor ? 'O' : '[') + (ev.deltaY < 0 ? 'A' : 'B');
+                    var data = '';
+                    for (var i = 0; i < Math.abs(amount); i++) {
+                        data += sequence;
+                    }
+                    _this.handler(data);
+                }
+                return;
+            }
+            if (_this.x10Mouse || _this._vt300Mouse || _this._decLocator)
+                return;
+            sendButton(ev);
+            ev.preventDefault();
+        }));
+        this.register(Lifecycle_1.addDisposableDomListener(el, 'wheel', function (ev) {
+            if (_this.mouseEvents)
+                return;
+            _this.viewport.onWheel(ev);
+            return _this.cancel(ev);
+        }));
+        this.register(Lifecycle_1.addDisposableDomListener(el, 'touchstart', function (ev) {
+            if (_this.mouseEvents)
+                return;
+            _this.viewport.onTouchStart(ev);
+            return _this.cancel(ev);
+        }));
+        this.register(Lifecycle_1.addDisposableDomListener(el, 'touchmove', function (ev) {
+            if (_this.mouseEvents)
+                return;
+            _this.viewport.onTouchMove(ev);
+            return _this.cancel(ev);
+        }));
+    };
+    Terminal.prototype.refresh = function (start, end) {
+        if (this.renderer) {
+            this.renderer.refreshRows(start, end);
+        }
+    };
+    Terminal.prototype._queueLinkification = function (start, end) {
+        if (this.linkifier) {
+            this.linkifier.linkifyRows(start, end);
+        }
+    };
+    Terminal.prototype.updateCursorStyle = function (ev) {
+        if (this.selectionManager && this.selectionManager.shouldColumnSelect(ev)) {
+            this.element.classList.add('column-select');
+        }
+        else {
+            this.element.classList.remove('column-select');
+        }
+    };
+    Terminal.prototype.showCursor = function () {
+        if (!this.cursorState) {
+            this.cursorState = 1;
+            this.refresh(this.buffer.y, this.buffer.y);
+        }
+    };
+    Terminal.prototype.scroll = function (isWrapped) {
+        if (isWrapped === void 0) { isWrapped = false; }
+        var newLine;
+        newLine = this._blankLine;
+        var eraseAttr = this.eraseAttrData();
+        if (!newLine || newLine.length !== this.cols || newLine.getFg(0) !== eraseAttr.fg || newLine.getBg(0) !== eraseAttr.bg) {
+            newLine = this.buffer.getBlankLine(eraseAttr, isWrapped);
+            this._blankLine = newLine;
+        }
+        newLine.isWrapped = isWrapped;
+        var topRow = this.buffer.ybase + this.buffer.scrollTop;
+        var bottomRow = this.buffer.ybase + this.buffer.scrollBottom;
+        if (this.buffer.scrollTop === 0) {
+            var willBufferBeTrimmed = this.buffer.lines.isFull;
+            if (bottomRow === this.buffer.lines.length - 1) {
+                if (willBufferBeTrimmed) {
+                    this.buffer.lines.recycle().copyFrom(newLine);
+                }
+                else {
+                    this.buffer.lines.push(newLine.clone());
+                }
+            }
+            else {
+                this.buffer.lines.splice(bottomRow + 1, 0, newLine.clone());
+            }
+            if (!willBufferBeTrimmed) {
+                this.buffer.ybase++;
+                if (!this._userScrolling) {
+                    this.buffer.ydisp++;
+                }
+            }
+            else {
+                if (this._userScrolling) {
+                    this.buffer.ydisp = Math.max(this.buffer.ydisp - 1, 0);
+                }
+            }
+        }
+        else {
+            var scrollRegionHeight = bottomRow - topRow + 1;
+            this.buffer.lines.shiftElements(topRow + 1, scrollRegionHeight - 1, -1);
+            this.buffer.lines.set(bottomRow, newLine.clone());
+        }
+        if (!this._userScrolling) {
+            this.buffer.ydisp = this.buffer.ybase;
+        }
+        this.updateRange(this.buffer.scrollTop);
+        this.updateRange(this.buffer.scrollBottom);
+        this._onScroll.fire(this.buffer.ydisp);
+    };
+    Terminal.prototype.scrollLines = function (disp, suppressScrollEvent) {
+        if (disp < 0) {
+            if (this.buffer.ydisp === 0) {
+                return;
+            }
+            this._userScrolling = true;
+        }
+        else if (disp + this.buffer.ydisp >= this.buffer.ybase) {
+            this._userScrolling = false;
+        }
+        var oldYdisp = this.buffer.ydisp;
+        this.buffer.ydisp = Math.max(Math.min(this.buffer.ydisp + disp, this.buffer.ybase), 0);
+        if (oldYdisp === this.buffer.ydisp) {
+            return;
+        }
+        if (!suppressScrollEvent) {
+            this._onScroll.fire(this.buffer.ydisp);
+        }
+        this.refresh(0, this.rows - 1);
+    };
+    Terminal.prototype.scrollPages = function (pageCount) {
+        this.scrollLines(pageCount * (this.rows - 1));
+    };
+    Terminal.prototype.scrollToTop = function () {
+        this.scrollLines(-this.buffer.ydisp);
+    };
+    Terminal.prototype.scrollToBottom = function () {
+        this.scrollLines(this.buffer.ybase - this.buffer.ydisp);
+    };
+    Terminal.prototype.scrollToLine = function (line) {
+        var scrollAmount = line - this.buffer.ydisp;
+        if (scrollAmount !== 0) {
+            this.scrollLines(scrollAmount);
+        }
+    };
+    Terminal.prototype.write = function (data) {
+        var _this = this;
+        if (this._isDisposed) {
+            return;
+        }
+        if (!data) {
+            return;
+        }
+        this.writeBuffer.push(data);
+        if (this.options.useFlowControl && !this._xoffSentToCatchUp && this.writeBuffer.length >= WRITE_BUFFER_PAUSE_THRESHOLD) {
+            this.handler(EscapeSequences_1.C0.DC3);
+            this._xoffSentToCatchUp = true;
+        }
+        if (!this._writeInProgress && this.writeBuffer.length > 0) {
+            this._writeInProgress = true;
+            setTimeout(function () {
+                _this._innerWrite();
+            });
+        }
+    };
+    Terminal.prototype._innerWrite = function (bufferOffset) {
+        var _this = this;
+        if (bufferOffset === void 0) { bufferOffset = 0; }
+        if (this._isDisposed) {
+            this.writeBuffer = [];
+        }
+        var startTime = Date.now();
+        while (this.writeBuffer.length > bufferOffset) {
+            var data = this.writeBuffer[bufferOffset];
+            bufferOffset++;
+            if (this._xoffSentToCatchUp && this.writeBuffer.length === bufferOffset) {
+                this.handler(EscapeSequences_1.C0.DC1);
+                this._xoffSentToCatchUp = false;
+            }
+            this._refreshStart = this.buffer.y;
+            this._refreshEnd = this.buffer.y;
+            this._inputHandler.parse(data);
+            this.updateRange(this.buffer.y);
+            this.refresh(this._refreshStart, this._refreshEnd);
+            if (Date.now() - startTime >= WRITE_TIMEOUT_MS) {
+                break;
+            }
+        }
+        if (this.writeBuffer.length > bufferOffset) {
+            setTimeout(function () { return _this._innerWrite(bufferOffset); }, 0);
+        }
+        else {
+            this._writeInProgress = false;
+            this.writeBuffer = [];
+        }
+    };
+    Terminal.prototype.writeln = function (data) {
+        this.write(data + '\r\n');
+    };
+    Terminal.prototype.attachCustomKeyEventHandler = function (customKeyEventHandler) {
+        this._customKeyEventHandler = customKeyEventHandler;
+    };
+    Terminal.prototype.addCsiHandler = function (flag, callback) {
+        return this._inputHandler.addCsiHandler(flag, callback);
+    };
+    Terminal.prototype.addOscHandler = function (ident, callback) {
+        return this._inputHandler.addOscHandler(ident, callback);
+    };
+    Terminal.prototype.registerLinkMatcher = function (regex, handler, options) {
+        var matcherId = this.linkifier.registerLinkMatcher(regex, handler, options);
+        this.refresh(0, this.rows - 1);
+        return matcherId;
+    };
+    Terminal.prototype.deregisterLinkMatcher = function (matcherId) {
+        if (this.linkifier.deregisterLinkMatcher(matcherId)) {
+            this.refresh(0, this.rows - 1);
+        }
+    };
+    Terminal.prototype.registerCharacterJoiner = function (handler) {
+        var joinerId = this.renderer.registerCharacterJoiner(handler);
+        this.refresh(0, this.rows - 1);
+        return joinerId;
+    };
+    Terminal.prototype.deregisterCharacterJoiner = function (joinerId) {
+        if (this.renderer.deregisterCharacterJoiner(joinerId)) {
+            this.refresh(0, this.rows - 1);
+        }
+    };
+    Object.defineProperty(Terminal.prototype, "markers", {
+        get: function () {
+            return this.buffer.markers;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Terminal.prototype.addMarker = function (cursorYOffset) {
+        if (this.buffer !== this.buffers.normal) {
+            return;
+        }
+        return this.buffer.addMarker(this.buffer.ybase + this.buffer.y + cursorYOffset);
+    };
+    Terminal.prototype.hasSelection = function () {
+        return this.selectionManager ? this.selectionManager.hasSelection : false;
+    };
+    Terminal.prototype.getSelection = function () {
+        return this.selectionManager ? this.selectionManager.selectionText : '';
+    };
+    Terminal.prototype.clearSelection = function () {
+        if (this.selectionManager) {
+            this.selectionManager.clearSelection();
+        }
+    };
+    Terminal.prototype.selectAll = function () {
+        if (this.selectionManager) {
+            this.selectionManager.selectAll();
+        }
+    };
+    Terminal.prototype.selectLines = function (start, end) {
+        if (this.selectionManager) {
+            this.selectionManager.selectLines(start, end);
+        }
+    };
+    Terminal.prototype._keyDown = function (event) {
+        if (this._customKeyEventHandler && this._customKeyEventHandler(event) === false) {
+            return false;
+        }
+        if (!this._compositionHelper.keydown(event)) {
+            if (this.buffer.ybase !== this.buffer.ydisp) {
+                this.scrollToBottom();
+            }
+            return false;
+        }
+        var result = Keyboard_1.evaluateKeyboardEvent(event, this.applicationCursor, this.browser.isMac, this.options.macOptionIsMeta);
+        this.updateCursorStyle(event);
+        if (result.type === 3 || result.type === 2) {
+            var scrollCount = this.rows - 1;
+            this.scrollLines(result.type === 2 ? -scrollCount : scrollCount);
+            return this.cancel(event, true);
+        }
+        if (result.type === 1) {
+            this.selectAll();
+        }
+        if (this._isThirdLevelShift(this.browser, event)) {
+            return true;
+        }
+        if (result.cancel) {
+            this.cancel(event, true);
+        }
+        if (!result.key) {
+            return true;
+        }
+        this.emit('keydown', event);
+        this._onKey.fire({ key: result.key, domEvent: event });
+        this.showCursor();
+        this.handler(result.key);
+        return this.cancel(event, true);
+    };
+    Terminal.prototype._isThirdLevelShift = function (browser, ev) {
+        var thirdLevelKey = (browser.isMac && !this.options.macOptionIsMeta && ev.altKey && !ev.ctrlKey && !ev.metaKey) ||
+            (browser.isMSWindows && ev.altKey && ev.ctrlKey && !ev.metaKey);
+        if (ev.type === 'keypress') {
+            return thirdLevelKey;
+        }
+        return thirdLevelKey && (!ev.keyCode || ev.keyCode > 47);
+    };
+    Terminal.prototype.setgLevel = function (g) {
+        this.glevel = g;
+        this.charset = this.charsets[g];
+    };
+    Terminal.prototype.setgCharset = function (g, charset) {
+        this.charsets[g] = charset;
+        if (this.glevel === g) {
+            this.charset = charset;
+        }
+    };
+    Terminal.prototype._keyUp = function (ev) {
+        this.updateCursorStyle(ev);
+    };
+    Terminal.prototype._keyPress = function (ev) {
+        var key;
+        if (this._customKeyEventHandler && this._customKeyEventHandler(ev) === false) {
+            return false;
+        }
+        this.cancel(ev);
+        if (ev.charCode) {
+            key = ev.charCode;
+        }
+        else if (ev.which === null || ev.which === undefined) {
+            key = ev.keyCode;
+        }
+        else if (ev.which !== 0 && ev.charCode !== 0) {
+            key = ev.which;
+        }
+        else {
+            return false;
+        }
+        if (!key || ((ev.altKey || ev.ctrlKey || ev.metaKey) && !this._isThirdLevelShift(this.browser, ev))) {
+            return false;
+        }
+        key = String.fromCharCode(key);
+        this.emit('keypress', key, ev);
+        this._onKey.fire({ key: key, domEvent: ev });
+        this.showCursor();
+        this.handler(key);
+        return true;
+    };
+    Terminal.prototype.bell = function () {
+        var _this = this;
+        this.emit('bell');
+        if (this._soundBell()) {
+            this.soundManager.playBellSound();
+        }
+        if (this._visualBell()) {
+            this.element.classList.add('visual-bell-active');
+            clearTimeout(this._visualBellTimer);
+            this._visualBellTimer = window.setTimeout(function () {
+                _this.element.classList.remove('visual-bell-active');
+            }, 200);
+        }
+    };
+    Terminal.prototype.log = function (text, data) {
+        if (!this.options.debug)
+            return;
+        if (!this._context.console || !this._context.console.log)
+            return;
+        this._context.console.log(text, data);
+    };
+    Terminal.prototype.error = function (text, data) {
+        if (!this.options.debug)
+            return;
+        if (!this._context.console || !this._context.console.error)
+            return;
+        this._context.console.error(text, data);
+    };
+    Terminal.prototype.resize = function (x, y) {
+        if (isNaN(x) || isNaN(y)) {
+            return;
+        }
+        if (x === this.cols && y === this.rows) {
+            if (this.charMeasure && (!this.charMeasure.width || !this.charMeasure.height)) {
+                this.charMeasure.measure(this.options);
+            }
+            return;
+        }
+        if (x < MINIMUM_COLS)
+            x = MINIMUM_COLS;
+        if (y < MINIMUM_ROWS)
+            y = MINIMUM_ROWS;
+        this.buffers.resize(x, y);
+        this.cols = x;
+        this.rows = y;
+        this.buffers.setupTabStops(this.cols);
+        if (this.charMeasure) {
+            this.charMeasure.measure(this.options);
+        }
+        this.refresh(0, this.rows - 1);
+        this._onResize.fire({ cols: x, rows: y });
+    };
+    Terminal.prototype.updateRange = function (y) {
+        if (y < this._refreshStart)
+            this._refreshStart = y;
+        if (y > this._refreshEnd)
+            this._refreshEnd = y;
+    };
+    Terminal.prototype.maxRange = function () {
+        this._refreshStart = 0;
+        this._refreshEnd = this.rows - 1;
+    };
+    Terminal.prototype.clear = function () {
+        if (this.buffer.ybase === 0 && this.buffer.y === 0) {
+            return;
+        }
+        this.buffer.lines.set(0, this.buffer.lines.get(this.buffer.ybase + this.buffer.y));
+        this.buffer.lines.length = 1;
+        this.buffer.ydisp = 0;
+        this.buffer.ybase = 0;
+        this.buffer.y = 0;
+        for (var i = 1; i < this.rows; i++) {
+            this.buffer.lines.push(this.buffer.getBlankLine(Buffer_1.DEFAULT_ATTR_DATA));
+        }
+        this.refresh(0, this.rows - 1);
+        this._onScroll.fire(this.buffer.ydisp);
+    };
+    Terminal.prototype.is = function (term) {
+        return (this.options.termName + '').indexOf(term) === 0;
+    };
+    Terminal.prototype.handler = function (data) {
+        if (this.options.disableStdin) {
+            return;
+        }
+        if (this.selectionManager && this.selectionManager.hasSelection) {
+            this.selectionManager.clearSelection();
+        }
+        if (this.buffer.ybase !== this.buffer.ydisp) {
+            this.scrollToBottom();
+        }
+        this._onData.fire(data);
+    };
+    Terminal.prototype.handleTitle = function (title) {
+        this._onTitleChange.fire(title);
+    };
+    Terminal.prototype.index = function () {
+        this.buffer.y++;
+        if (this.buffer.y > this.buffer.scrollBottom) {
+            this.buffer.y--;
+            this.scroll();
+        }
+        if (this.buffer.x >= this.cols) {
+            this.buffer.x--;
+        }
+    };
+    Terminal.prototype.reverseIndex = function () {
+        if (this.buffer.y === this.buffer.scrollTop) {
+            var scrollRegionHeight = this.buffer.scrollBottom - this.buffer.scrollTop;
+            this.buffer.lines.shiftElements(this.buffer.y + this.buffer.ybase, scrollRegionHeight, 1);
+            this.buffer.lines.set(this.buffer.y + this.buffer.ybase, this.buffer.getBlankLine(this.eraseAttrData()));
+            this.updateRange(this.buffer.scrollTop);
+            this.updateRange(this.buffer.scrollBottom);
+        }
+        else {
+            this.buffer.y--;
+        }
+    };
+    Terminal.prototype.reset = function () {
+        this.options.rows = this.rows;
+        this.options.cols = this.cols;
+        var customKeyEventHandler = this._customKeyEventHandler;
+        var inputHandler = this._inputHandler;
+        var cursorState = this.cursorState;
+        this._setup();
+        this._customKeyEventHandler = customKeyEventHandler;
+        this._inputHandler = inputHandler;
+        this.cursorState = cursorState;
+        this.refresh(0, this.rows - 1);
+        if (this.viewport) {
+            this.viewport.syncScrollArea();
+        }
+    };
+    Terminal.prototype.tabSet = function () {
+        this.buffer.tabs[this.buffer.x] = true;
+    };
+    Terminal.prototype.cancel = function (ev, force) {
+        if (!this.options.cancelEvents && !force) {
+            return;
+        }
+        ev.preventDefault();
+        ev.stopPropagation();
+        return false;
+    };
+    Terminal.prototype._visualBell = function () {
+        return false;
+    };
+    Terminal.prototype._soundBell = function () {
+        return this.options.bellStyle === 'sound';
+    };
+    return Terminal;
+}(EventEmitter_1.EventEmitter));
+exports.Terminal = Terminal;
+function wasModifierKeyOnlyEvent(ev) {
+    return ev.keyCode === 16 ||
+        ev.keyCode === 17 ||
+        ev.keyCode === 18;
+}
+
+},{"./AccessibilityManager":1,"./Buffer":2,"./BufferSet":5,"./CharMeasure":6,"./Clipboard":8,"./CompositionHelper":9,"./InputHandler":11,"./Linkifier":12,"./MouseHelper":13,"./MouseZoneManager":14,"./SelectionManager":15,"./SoundManager":17,"./Strings":18,"./Viewport":20,"./WindowsMode":21,"./common/Clone":23,"./common/EventEmitter":24,"./common/EventEmitter2":25,"./common/Platform":27,"./common/data/EscapeSequences":29,"./core/input/Keyboard":31,"./renderer/Renderer":41,"./renderer/atlas/CharAtlasCache":45,"./renderer/dom/DomRenderer":53,"./ui/Lifecycle":55,"./ui/ScreenDprMonitor":57}],20:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = function (d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var Lifecycle_1 = require("./common/Lifecycle");
+var Lifecycle_2 = require("./ui/Lifecycle");
+var FALLBACK_SCROLL_BAR_WIDTH = 15;
+var Viewport = (function (_super) {
+    __extends(Viewport, _super);
+    function Viewport(_terminal, _viewportElement, _scrollArea, _charMeasure) {
+        var _this = _super.call(this) || this;
+        _this._terminal = _terminal;
+        _this._viewportElement = _viewportElement;
+        _this._scrollArea = _scrollArea;
+        _this._charMeasure = _charMeasure;
+        _this.scrollBarWidth = 0;
+        _this._currentRowHeight = 0;
+        _this._lastRecordedBufferLength = 0;
+        _this._lastRecordedViewportHeight = 0;
+        _this._lastRecordedBufferHeight = 0;
+        _this._lastScrollTop = 0;
+        _this._wheelPartialScroll = 0;
+        _this._refreshAnimationFrame = null;
+        _this._ignoreNextScrollEvent = false;
+        _this.scrollBarWidth = (_this._viewportElement.offsetWidth - _this._scrollArea.offsetWidth) || FALLBACK_SCROLL_BAR_WIDTH;
+        _this.register(Lifecycle_2.addDisposableDomListener(_this._viewportElement, 'scroll', _this._onScroll.bind(_this)));
+        setTimeout(function () { return _this.syncScrollArea(); }, 0);
+        return _this;
+    }
+    Viewport.prototype.onThemeChanged = function (colors) {
+        this._viewportElement.style.backgroundColor = colors.background.css;
+    };
+    Viewport.prototype._refresh = function () {
+        var _this = this;
+        if (this._refreshAnimationFrame === null) {
+            this._refreshAnimationFrame = requestAnimationFrame(function () { return _this._innerRefresh(); });
+        }
+    };
+    Viewport.prototype._innerRefresh = function () {
+        if (this._charMeasure.height > 0) {
+            this._currentRowHeight = this._terminal.renderer.dimensions.scaledCellHeight / window.devicePixelRatio;
+            this._lastRecordedViewportHeight = this._viewportElement.offsetHeight;
+            var newBufferHeight = Math.round(this._currentRowHeight * this._lastRecordedBufferLength) + (this._lastRecordedViewportHeight - this._terminal.renderer.dimensions.canvasHeight);
+            if (this._lastRecordedBufferHeight !== newBufferHeight) {
+                this._lastRecordedBufferHeight = newBufferHeight;
+                this._scrollArea.style.height = this._lastRecordedBufferHeight + 'px';
+            }
+        }
+        var scrollTop = this._terminal.buffer.ydisp * this._currentRowHeight;
+        if (this._viewportElement.scrollTop !== scrollTop) {
+            this._ignoreNextScrollEvent = true;
+            this._viewportElement.scrollTop = scrollTop;
+        }
+        this._refreshAnimationFrame = null;
+    };
+    Viewport.prototype.syncScrollArea = function () {
+        if (this._lastRecordedBufferLength !== this._terminal.buffer.lines.length) {
+            this._lastRecordedBufferLength = this._terminal.buffer.lines.length;
+            this._refresh();
+            return;
+        }
+        if (this._lastRecordedViewportHeight !== this._terminal.renderer.dimensions.canvasHeight) {
+            this._refresh();
+            return;
+        }
+        var newScrollTop = this._terminal.buffer.ydisp * this._currentRowHeight;
+        if (this._lastScrollTop !== newScrollTop) {
+            this._refresh();
+            return;
+        }
+        if (this._lastScrollTop !== this._viewportElement.scrollTop) {
+            this._refresh();
+            return;
+        }
+        if (this._terminal.renderer.dimensions.scaledCellHeight / window.devicePixelRatio !== this._currentRowHeight) {
+            this._refresh();
+            return;
+        }
+    };
+    Viewport.prototype._onScroll = function (ev) {
+        this._lastScrollTop = this._viewportElement.scrollTop;
+        if (!this._viewportElement.offsetParent) {
+            return;
+        }
+        if (this._ignoreNextScrollEvent) {
+            this._ignoreNextScrollEvent = false;
+            return;
+        }
+        var newRow = Math.round(this._lastScrollTop / this._currentRowHeight);
+        var diff = newRow - this._terminal.buffer.ydisp;
+        this._terminal.scrollLines(diff, true);
+    };
+    Viewport.prototype.onWheel = function (ev) {
+        var amount = this._getPixelsScrolled(ev);
+        if (amount === 0) {
+            return;
+        }
+        this._viewportElement.scrollTop += amount;
+        ev.preventDefault();
+    };
+    Viewport.prototype._getPixelsScrolled = function (ev) {
+        if (ev.deltaY === 0) {
+            return 0;
+        }
+        var amount = ev.deltaY;
+        if (ev.deltaMode === WheelEvent.DOM_DELTA_LINE) {
+            amount *= this._currentRowHeight;
+        }
+        else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) {
+            amount *= this._currentRowHeight * this._terminal.rows;
+        }
+        return amount;
+    };
+    Viewport.prototype.getLinesScrolled = function (ev) {
+        if (ev.deltaY === 0) {
+            return 0;
+        }
+        var amount = ev.deltaY;
+        if (ev.deltaMode === WheelEvent.DOM_DELTA_PIXEL) {
+            amount /= this._currentRowHeight + 0.0;
+            this._wheelPartialScroll += amount;
+            amount = Math.floor(Math.abs(this._wheelPartialScroll)) * (this._wheelPartialScroll > 0 ? 1 : -1);
+            this._wheelPartialScroll %= 1;
+        }
+        else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) {
+            amount *= this._terminal.rows;
+        }
+        return amount;
+    };
+    Viewport.prototype.onTouchStart = function (ev) {
+        this._lastTouchY = ev.touches[0].pageY;
+    };
+    Viewport.prototype.onTouchMove = function (ev) {
+        var deltaY = this._lastTouchY - ev.touches[0].pageY;
+        this._lastTouchY = ev.touches[0].pageY;
+        if (deltaY === 0) {
+            return;
+        }
+        this._viewportElement.scrollTop += deltaY;
+        ev.preventDefault();
+    };
+    return Viewport;
+}(Lifecycle_1.Disposable));
+exports.Viewport = Viewport;
+
+},{"./common/Lifecycle":26,"./ui/Lifecycle":55}],21:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var Buffer_1 = require("./Buffer");
+function applyWindowsMode(terminal) {
+    return terminal.onLineFeed(function () {
+        var line = terminal.buffer.lines.get(terminal.buffer.ybase + terminal.buffer.y - 1);
+        var lastChar = line.get(terminal.cols - 1);
+        if (lastChar[Buffer_1.CHAR_DATA_CODE_INDEX] !== Buffer_1.NULL_CELL_CODE && lastChar[Buffer_1.CHAR_DATA_CODE_INDEX] !== Buffer_1.WHITESPACE_CELL_CODE) {
+            var nextLine = terminal.buffer.lines.get(terminal.buffer.ybase + terminal.buffer.y);
+            nextLine.isWrapped = true;
+        }
+    });
+}
+exports.applyWindowsMode = applyWindowsMode;
+
+},{"./Buffer":2}],22:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var EventEmitter2_1 = require("./EventEmitter2");
+var CircularList = (function () {
+    function CircularList(_maxLength) {
+        this._maxLength = _maxLength;
+        this.onDeleteEmitter = new EventEmitter2_1.EventEmitter2();
+        this.onInsertEmitter = new EventEmitter2_1.EventEmitter2();
+        this.onTrimEmitter = new EventEmitter2_1.EventEmitter2();
+        this._array = new Array(this._maxLength);
+        this._startIndex = 0;
+        this._length = 0;
+    }
+    Object.defineProperty(CircularList.prototype, "onDelete", {
+        get: function () { return this.onDeleteEmitter.event; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(CircularList.prototype, "onInsert", {
+        get: function () { return this.onInsertEmitter.event; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(CircularList.prototype, "onTrim", {
+        get: function () { return this.onTrimEmitter.event; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(CircularList.prototype, "maxLength", {
+        get: function () {
+            return this._maxLength;
+        },
+        set: function (newMaxLength) {
+            if (this._maxLength === newMaxLength) {
+                return;
+            }
+            var newArray = new Array(newMaxLength);
+            for (var i = 0; i < Math.min(newMaxLength, this.length); i++) {
+                newArray[i] = this._array[this._getCyclicIndex(i)];
+            }
+            this._array = newArray;
+            this._maxLength = newMaxLength;
+            this._startIndex = 0;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(CircularList.prototype, "length", {
+        get: function () {
+            return this._length;
+        },
+        set: function (newLength) {
+            if (newLength > this._length) {
+                for (var i = this._length; i < newLength; i++) {
+                    this._array[i] = undefined;
+                }
+            }
+            this._length = newLength;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    CircularList.prototype.get = function (index) {
+        return this._array[this._getCyclicIndex(index)];
+    };
+    CircularList.prototype.set = function (index, value) {
+        this._array[this._getCyclicIndex(index)] = value;
+    };
+    CircularList.prototype.push = function (value) {
+        this._array[this._getCyclicIndex(this._length)] = value;
+        if (this._length === this._maxLength) {
+            this._startIndex = ++this._startIndex % this._maxLength;
+            this.onTrimEmitter.fire(1);
+        }
+        else {
+            this._length++;
+        }
+    };
+    CircularList.prototype.recycle = function () {
+        if (this._length !== this._maxLength) {
+            throw new Error('Can only recycle when the buffer is full');
+        }
+        this._startIndex = ++this._startIndex % this._maxLength;
+        this.onTrimEmitter.fire(1);
+        return this._array[this._getCyclicIndex(this._length - 1)];
+    };
+    Object.defineProperty(CircularList.prototype, "isFull", {
+        get: function () {
+            return this._length === this._maxLength;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    CircularList.prototype.pop = function () {
+        return this._array[this._getCyclicIndex(this._length-- - 1)];
+    };
+    CircularList.prototype.splice = function (start, deleteCount) {
+        var items = [];
+        for (var _i = 2; _i < arguments.length; _i++) {
+            items[_i - 2] = arguments[_i];
+        }
+        if (deleteCount) {
+            for (var i = start; i < this._length - deleteCount; i++) {
+                this._array[this._getCyclicIndex(i)] = this._array[this._getCyclicIndex(i + deleteCount)];
+            }
+            this._length -= deleteCount;
+        }
+        for (var i = this._length - 1; i >= start; i--) {
+            this._array[this._getCyclicIndex(i + items.length)] = this._array[this._getCyclicIndex(i)];
+        }
+        for (var i = 0; i < items.length; i++) {
+            this._array[this._getCyclicIndex(start + i)] = items[i];
+        }
+        if (this._length + items.length > this._maxLength) {
+            var countToTrim = (this._length + items.length) - this._maxLength;
+            this._startIndex += countToTrim;
+            this._length = this._maxLength;
+            this.onTrimEmitter.fire(countToTrim);
+        }
+        else {
+            this._length += items.length;
+        }
+    };
+    CircularList.prototype.trimStart = function (count) {
+        if (count > this._length) {
+            count = this._length;
+        }
+        this._startIndex += count;
+        this._length -= count;
+        this.onTrimEmitter.fire(count);
+    };
+    CircularList.prototype.shiftElements = function (start, count, offset) {
+        if (count <= 0) {
+            return;
+        }
+        if (start < 0 || start >= this._length) {
+            throw new Error('start argument out of range');
+        }
+        if (start + offset < 0) {
+            throw new Error('Cannot shift elements in list beyond index 0');
+        }
+        if (offset > 0) {
+            for (var i = count - 1; i >= 0; i--) {
+                this.set(start + i + offset, this.get(start + i));
+            }
+            var expandListBy = (start + count + offset) - this._length;
+            if (expandListBy > 0) {
+                this._length += expandListBy;
+                while (this._length > this._maxLength) {
+                    this._length--;
+                    this._startIndex++;
+                    this.onTrimEmitter.fire(1);
+                }
+            }
+        }
+        else {
+            for (var i = 0; i < count; i++) {
+                this.set(start + i + offset, this.get(start + i));
+            }
+        }
+    };
+    CircularList.prototype._getCyclicIndex = function (index) {
+        return (this._startIndex + index) % this._maxLength;
+    };
+    return CircularList;
+}());
+exports.CircularList = CircularList;
+
+},{"./EventEmitter2":25}],23:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+function clone(val, depth) {
+    if (depth === void 0) { depth = 5; }
+    if (typeof val !== 'object') {
+        return val;
+    }
+    if (val === null) {
+        return null;
+    }
+    var clonedObject = Array.isArray(val) ? [] : {};
+    for (var key in val) {
+        clonedObject[key] = depth <= 1 ? val[key] : clone(val[key], depth - 1);
+    }
+    return clonedObject;
+}
+exports.clone = clone;
+
+},{}],24:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = function (d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var Lifecycle_1 = require("./Lifecycle");
+var EventEmitter = (function (_super) {
+    __extends(EventEmitter, _super);
+    function EventEmitter() {
+        var _this = _super.call(this) || this;
+        _this._events = _this._events || {};
+        return _this;
+    }
+    EventEmitter.prototype.on = function (type, listener) {
+        this._events[type] = this._events[type] || [];
+        this._events[type].push(listener);
+    };
+    EventEmitter.prototype.addDisposableListener = function (type, handler) {
+        var _this = this;
+        this.on(type, handler);
+        var disposed = false;
+        return {
+            dispose: function () {
+                if (disposed) {
+                    return;
+                }
+                _this.off(type, handler);
+                disposed = true;
+            }
+        };
+    };
+    EventEmitter.prototype.off = function (type, listener) {
+        if (!this._events[type]) {
+            return;
+        }
+        var obj = this._events[type];
+        var i = obj.length;
+        while (i--) {
+            if (obj[i] === listener) {
+                obj.splice(i, 1);
+                return;
+            }
+        }
+    };
+    EventEmitter.prototype.removeAllListeners = function (type) {
+        if (this._events[type]) {
+            delete this._events[type];
+        }
+    };
+    EventEmitter.prototype.emit = function (type) {
+        var args = [];
+        for (var _i = 1; _i < arguments.length; _i++) {
+            args[_i - 1] = arguments[_i];
+        }
+        if (!this._events[type]) {
+            return;
+        }
+        var obj = this._events[type];
+        for (var i = 0; i < obj.length; i++) {
+            obj[i].apply(this, args);
+        }
+    };
+    EventEmitter.prototype.emitMayRemoveListeners = function (type) {
+        var args = [];
+        for (var _i = 1; _i < arguments.length; _i++) {
+            args[_i - 1] = arguments[_i];
+        }
+        if (!this._events[type]) {
+            return;
+        }
+        var obj = this._events[type];
+        var length = obj.length;
+        for (var i = 0; i < obj.length; i++) {
+            obj[i].apply(this, args);
+            i -= length - obj.length;
+            length = obj.length;
+        }
+    };
+    EventEmitter.prototype.listeners = function (type) {
+        return this._events[type] || [];
+    };
+    EventEmitter.prototype.dispose = function () {
+        _super.prototype.dispose.call(this);
+        this._events = {};
+    };
+    return EventEmitter;
+}(Lifecycle_1.Disposable));
+exports.EventEmitter = EventEmitter;
+
+},{"./Lifecycle":26}],25:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var EventEmitter2 = (function () {
+    function EventEmitter2() {
+        this._listeners = [];
+    }
+    Object.defineProperty(EventEmitter2.prototype, "event", {
+        get: function () {
+            var _this = this;
+            if (!this._event) {
+                this._event = function (listener) {
+                    _this._listeners.push(listener);
+                    var disposable = {
+                        dispose: function () {
+                            for (var i = 0; i < _this._listeners.length; i++) {
+                                if (_this._listeners[i] === listener) {
+                                    _this._listeners.splice(i, 1);
+                                    return;
+                                }
+                            }
+                        }
+                    };
+                    return disposable;
+                };
+            }
+            return this._event;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    EventEmitter2.prototype.fire = function (data) {
+        var queue = [];
+        for (var i = 0; i < this._listeners.length; i++) {
+            queue.push(this._listeners[i]);
+        }
+        for (var i = 0; i < queue.length; i++) {
+            queue[i].call(undefined, data);
+        }
+    };
+    return EventEmitter2;
+}());
+exports.EventEmitter2 = EventEmitter2;
+
+},{}],26:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var Disposable = (function () {
+    function Disposable() {
+        this._disposables = [];
+        this._isDisposed = false;
+    }
+    Disposable.prototype.dispose = function () {
+        this._isDisposed = true;
+        this._disposables.forEach(function (d) { return d.dispose(); });
+        this._disposables.length = 0;
+    };
+    Disposable.prototype.register = function (d) {
+        this._disposables.push(d);
+    };
+    Disposable.prototype.unregister = function (d) {
+        var index = this._disposables.indexOf(d);
+        if (index !== -1) {
+            this._disposables.splice(index, 1);
+        }
+    };
+    return Disposable;
+}());
+exports.Disposable = Disposable;
+
+},{}],27:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var isNode = (typeof navigator === 'undefined') ? true : false;
+var userAgent = (isNode) ? 'node' : navigator.userAgent;
+var platform = (isNode) ? 'node' : navigator.platform;
+exports.isFirefox = !!~userAgent.indexOf('Firefox');
+exports.isSafari = /^((?!chrome|android).)*safari/i.test(userAgent);
+exports.isMSIE = !!~userAgent.indexOf('MSIE') || !!~userAgent.indexOf('Trident');
+exports.isMac = contains(['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'], platform);
+exports.isIpad = platform === 'iPad';
+exports.isIphone = platform === 'iPhone';
+exports.isMSWindows = contains(['Windows', 'Win16', 'Win32', 'WinCE'], platform);
+exports.isLinux = platform.indexOf('Linux') >= 0;
+function contains(arr, el) {
+    return arr.indexOf(el) >= 0;
+}
+
+},{}],28:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+function fill(array, value, start, end) {
+    if (array.fill) {
+        return array.fill(value, start, end);
+    }
+    return fillFallback(array, value, start, end);
+}
+exports.fill = fill;
+function fillFallback(array, value, start, end) {
+    if (start === void 0) { start = 0; }
+    if (end === void 0) { end = array.length; }
+    if (start >= array.length) {
+        return array;
+    }
+    start = (array.length + start) % array.length;
+    if (end >= array.length) {
+        end = array.length;
+    }
+    else {
+        end = (array.length + end) % array.length;
+    }
+    for (var i = start; i < end; ++i) {
+        array[i] = value;
+    }
+    return array;
+}
+exports.fillFallback = fillFallback;
+function concat(a, b) {
+    var result = new a.constructor(a.length + b.length);
+    result.set(a);
+    result.set(b, a.length);
+    return result;
+}
+exports.concat = concat;
+
+},{}],29:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var C0;
+(function (C0) {
+    C0.NUL = '\x00';
+    C0.SOH = '\x01';
+    C0.STX = '\x02';
+    C0.ETX = '\x03';
+    C0.EOT = '\x04';
+    C0.ENQ = '\x05';
+    C0.ACK = '\x06';
+    C0.BEL = '\x07';
+    C0.BS = '\x08';
+    C0.HT = '\x09';
+    C0.LF = '\x0a';
+    C0.VT = '\x0b';
+    C0.FF = '\x0c';
+    C0.CR = '\x0d';
+    C0.SO = '\x0e';
+    C0.SI = '\x0f';
+    C0.DLE = '\x10';
+    C0.DC1 = '\x11';
+    C0.DC2 = '\x12';
+    C0.DC3 = '\x13';
+    C0.DC4 = '\x14';
+    C0.NAK = '\x15';
+    C0.SYN = '\x16';
+    C0.ETB = '\x17';
+    C0.CAN = '\x18';
+    C0.EM = '\x19';
+    C0.SUB = '\x1a';
+    C0.ESC = '\x1b';
+    C0.FS = '\x1c';
+    C0.GS = '\x1d';
+    C0.RS = '\x1e';
+    C0.US = '\x1f';
+    C0.SP = '\x20';
+    C0.DEL = '\x7f';
+})(C0 = exports.C0 || (exports.C0 = {}));
+var C1;
+(function (C1) {
+    C1.PAD = '\x80';
+    C1.HOP = '\x81';
+    C1.BPH = '\x82';
+    C1.NBH = '\x83';
+    C1.IND = '\x84';
+    C1.NEL = '\x85';
+    C1.SSA = '\x86';
+    C1.ESA = '\x87';
+    C1.HTS = '\x88';
+    C1.HTJ = '\x89';
+    C1.VTS = '\x8a';
+    C1.PLD = '\x8b';
+    C1.PLU = '\x8c';
+    C1.RI = '\x8d';
+    C1.SS2 = '\x8e';
+    C1.SS3 = '\x8f';
+    C1.DCS = '\x90';
+    C1.PU1 = '\x91';
+    C1.PU2 = '\x92';
+    C1.STS = '\x93';
+    C1.CCH = '\x94';
+    C1.MW = '\x95';
+    C1.SPA = '\x96';
+    C1.EPA = '\x97';
+    C1.SOS = '\x98';
+    C1.SGCI = '\x99';
+    C1.SCI = '\x9a';
+    C1.CSI = '\x9b';
+    C1.ST = '\x9c';
+    C1.OSC = '\x9d';
+    C1.PM = '\x9e';
+    C1.APC = '\x9f';
+})(C1 = exports.C1 || (exports.C1 = {}));
+
+},{}],30:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.CHARSETS = {};
+exports.DEFAULT_CHARSET = exports.CHARSETS['B'];
+exports.CHARSETS['0'] = {
+    '`': '\u25c6',
+    'a': '\u2592',
+    'b': '\u0009',
+    'c': '\u000c',
+    'd': '\u000d',
+    'e': '\u000a',
+    'f': '\u00b0',
+    'g': '\u00b1',
+    'h': '\u2424',
+    'i': '\u000b',
+    'j': '\u2518',
+    'k': '\u2510',
+    'l': '\u250c',
+    'm': '\u2514',
+    'n': '\u253c',
+    'o': '\u23ba',
+    'p': '\u23bb',
+    'q': '\u2500',
+    'r': '\u23bc',
+    's': '\u23bd',
+    't': '\u251c',
+    'u': '\u2524',
+    'v': '\u2534',
+    'w': '\u252c',
+    'x': '\u2502',
+    'y': '\u2264',
+    'z': '\u2265',
+    '{': '\u03c0',
+    '|': '\u2260',
+    '}': '\u00a3',
+    '~': '\u00b7'
+};
+exports.CHARSETS['A'] = {
+    '#': '£'
+};
+exports.CHARSETS['B'] = null;
+exports.CHARSETS['4'] = {
+    '#': '£',
+    '@': '¾',
+    '[': 'ij',
+    '\\': '½',
+    ']': '|',
+    '{': '¨',
+    '|': 'f',
+    '}': '¼',
+    '~': '´'
+};
+exports.CHARSETS['C'] =
+    exports.CHARSETS['5'] = {
+        '[': 'Ä',
+        '\\': 'Ö',
+        ']': 'Å',
+        '^': 'Ü',
+        '`': 'é',
+        '{': 'ä',
+        '|': 'ö',
+        '}': 'å',
+        '~': 'ü'
+    };
+exports.CHARSETS['R'] = {
+    '#': '£',
+    '@': 'à',
+    '[': '°',
+    '\\': 'ç',
+    ']': '§',
+    '{': 'é',
+    '|': 'ù',
+    '}': 'è',
+    '~': '¨'
+};
+exports.CHARSETS['Q'] = {
+    '@': 'à',
+    '[': 'â',
+    '\\': 'ç',
+    ']': 'ê',
+    '^': 'î',
+    '`': 'ô',
+    '{': 'é',
+    '|': 'ù',
+    '}': 'è',
+    '~': 'û'
+};
+exports.CHARSETS['K'] = {
+    '@': '§',
+    '[': 'Ä',
+    '\\': 'Ö',
+    ']': 'Ü',
+    '{': 'ä',
+    '|': 'ö',
+    '}': 'ü',
+    '~': 'ß'
+};
+exports.CHARSETS['Y'] = {
+    '#': '£',
+    '@': '§',
+    '[': '°',
+    '\\': 'ç',
+    ']': 'é',
+    '`': 'ù',
+    '{': 'à',
+    '|': 'ò',
+    '}': 'è',
+    '~': 'ì'
+};
+exports.CHARSETS['E'] =
+    exports.CHARSETS['6'] = {
+        '@': 'Ä',
+        '[': 'Æ',
+        '\\': 'Ø',
+        ']': 'Å',
+        '^': 'Ü',
+        '`': 'ä',
+        '{': 'æ',
+        '|': 'ø',
+        '}': 'å',
+        '~': 'ü'
+    };
+exports.CHARSETS['Z'] = {
+    '#': '£',
+    '@': '§',
+    '[': '¡',
+    '\\': 'Ñ',
+    ']': '¿',
+    '{': '°',
+    '|': 'ñ',
+    '}': 'ç'
+};
+exports.CHARSETS['H'] =
+    exports.CHARSETS['7'] = {
+        '@': 'É',
+        '[': 'Ä',
+        '\\': 'Ö',
+        ']': 'Å',
+        '^': 'Ü',
+        '`': 'é',
+        '{': 'ä',
+        '|': 'ö',
+        '}': 'å',
+        '~': 'ü'
+    };
+exports.CHARSETS['='] = {
+    '#': 'ù',
+    '@': 'à',
+    '[': 'é',
+    '\\': 'ç',
+    ']': 'ê',
+    '^': 'î',
+    '_': 'è',
+    '`': 'ô',
+    '{': 'ä',
+    '|': 'ö',
+    '}': 'ü',
+    '~': 'û'
+};
+
+},{}],31:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var EscapeSequences_1 = require("../../common/data/EscapeSequences");
+var KEYCODE_KEY_MAPPINGS = {
+    48: ['0', ')'],
+    49: ['1', '!'],
+    50: ['2', '@'],
+    51: ['3', '#'],
+    52: ['4', '$'],
+    53: ['5', '%'],
+    54: ['6', '^'],
+    55: ['7', '&'],
+    56: ['8', '*'],
+    57: ['9', '('],
+    186: [';', ':'],
+    187: ['=', '+'],
+    188: [',', '<'],
+    189: ['-', '_'],
+    190: ['.', '>'],
+    191: ['/', '?'],
+    192: ['`', '~'],
+    219: ['[', '{'],
+    220: ['\\', '|'],
+    221: [']', '}'],
+    222: ['\'', '"']
+};
+function evaluateKeyboardEvent(ev, applicationCursorMode, isMac, macOptionIsMeta) {
+    var result = {
+        type: 0,
+        cancel: false,
+        key: undefined
+    };
+    var modifiers = (ev.shiftKey ? 1 : 0) | (ev.altKey ? 2 : 0) | (ev.ctrlKey ? 4 : 0) | (ev.metaKey ? 8 : 0);
+    switch (ev.keyCode) {
+        case 0:
+            if (ev.key === 'UIKeyInputUpArrow') {
+                if (applicationCursorMode) {
+                    result.key = EscapeSequences_1.C0.ESC + 'OA';
+                }
+                else {
+                    result.key = EscapeSequences_1.C0.ESC + '[A';
+                }
+            }
+            else if (ev.key === 'UIKeyInputLeftArrow') {
+                if (applicationCursorMode) {
+                    result.key = EscapeSequences_1.C0.ESC + 'OD';
+                }
+                else {
+                    result.key = EscapeSequences_1.C0.ESC + '[D';
+                }
+            }
+            else if (ev.key === 'UIKeyInputRightArrow') {
+                if (applicationCursorMode) {
+                    result.key = EscapeSequences_1.C0.ESC + 'OC';
+                }
+                else {
+                    result.key = EscapeSequences_1.C0.ESC + '[C';
+                }
+            }
+            else if (ev.key === 'UIKeyInputDownArrow') {
+                if (applicationCursorMode) {
+                    result.key = EscapeSequences_1.C0.ESC + 'OB';
+                }
+                else {
+                    result.key = EscapeSequences_1.C0.ESC + '[B';
+                }
+            }
+            break;
+        case 8:
+            if (ev.shiftKey) {
+                result.key = EscapeSequences_1.C0.BS;
+                break;
+            }
+            else if (ev.altKey) {
+                result.key = EscapeSequences_1.C0.ESC + EscapeSequences_1.C0.DEL;
+                break;
+            }
+            result.key = EscapeSequences_1.C0.DEL;
+            break;
+        case 9:
+            if (ev.shiftKey) {
+                result.key = EscapeSequences_1.C0.ESC + '[Z';
+                break;
+            }
+            result.key = EscapeSequences_1.C0.HT;
+            result.cancel = true;
+            break;
+        case 13:
+            result.key = EscapeSequences_1.C0.CR;
+            result.cancel = true;
+            break;
+        case 27:
+            result.key = EscapeSequences_1.C0.ESC;
+            result.cancel = true;
+            break;
+        case 37:
+            if (modifiers) {
+                result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'D';
+                if (result.key === EscapeSequences_1.C0.ESC + '[1;3D') {
+                    result.key = isMac ? EscapeSequences_1.C0.ESC + 'b' : EscapeSequences_1.C0.ESC + '[1;5D';
+                }
+            }
+            else if (applicationCursorMode) {
+                result.key = EscapeSequences_1.C0.ESC + 'OD';
+            }
+            else {
+                result.key = EscapeSequences_1.C0.ESC + '[D';
+            }
+            break;
+        case 39:
+            if (modifiers) {
+                result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'C';
+                if (result.key === EscapeSequences_1.C0.ESC + '[1;3C') {
+                    result.key = isMac ? EscapeSequences_1.C0.ESC + 'f' : EscapeSequences_1.C0.ESC + '[1;5C';
+                }
+            }
+            else if (applicationCursorMode) {
+                result.key = EscapeSequences_1.C0.ESC + 'OC';
+            }
+            else {
+                result.key = EscapeSequences_1.C0.ESC + '[C';
+            }
+            break;
+        case 38:
+            if (modifiers) {
+                result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'A';
+                if (result.key === EscapeSequences_1.C0.ESC + '[1;3A') {
+                    result.key = EscapeSequences_1.C0.ESC + '[1;5A';
+                }
+            }
+            else if (applicationCursorMode) {
+                result.key = EscapeSequences_1.C0.ESC + 'OA';
+            }
+            else {
+                result.key = EscapeSequences_1.C0.ESC + '[A';
+            }
+            break;
+        case 40:
+            if (modifiers) {
+                result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'B';
+                if (result.key === EscapeSequences_1.C0.ESC + '[1;3B') {
+                    result.key = EscapeSequences_1.C0.ESC + '[1;5B';
+                }
+            }
+            else if (applicationCursorMode) {
+                result.key = EscapeSequences_1.C0.ESC + 'OB';
+            }
+            else {
+                result.key = EscapeSequences_1.C0.ESC + '[B';
+            }
+            break;
+        case 45:
+            if (!ev.shiftKey && !ev.ctrlKey) {
+                result.key = EscapeSequences_1.C0.ESC + '[2~';
+            }
+            break;
+        case 46:
+            if (modifiers) {
+                result.key = EscapeSequences_1.C0.ESC + '[3;' + (modifiers + 1) + '~';
+            }
+            else {
+                result.key = EscapeSequences_1.C0.ESC + '[3~';
+            }
+            break;
+        case 36:
+            if (modifiers) {
+                result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'H';
+            }
+            else if (applicationCursorMode) {
+                result.key = EscapeSequences_1.C0.ESC + 'OH';
+            }
+            else {
+                result.key = EscapeSequences_1.C0.ESC + '[H';
+            }
+            break;
+        case 35:
+            if (modifiers) {
+                result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'F';
+            }
+            else if (applicationCursorMode) {
+                result.key = EscapeSequences_1.C0.ESC + 'OF';
+            }
+            else {
+                result.key = EscapeSequences_1.C0.ESC + '[F';
+            }
+            break;
+        case 33:
+            if (ev.shiftKey) {
+                result.type = 2;
+            }
+            else {
+                result.key = EscapeSequences_1.C0.ESC + '[5~';
+            }
+            break;
+        case 34:
+            if (ev.shiftKey) {
+                result.type = 3;
+            }
+            else {
+                result.key = EscapeSequences_1.C0.ESC + '[6~';
+            }
+            break;
+        case 112:
+            if (modifiers) {
+                result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'P';
+            }
+            else {
+                result.key = EscapeSequences_1.C0.ESC + 'OP';
+            }
+            break;
+        case 113:
+            if (modifiers) {
+                result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'Q';
+            }
+            else {
+                result.key = EscapeSequences_1.C0.ESC + 'OQ';
+            }
+            break;
+        case 114:
+            if (modifiers) {
+                result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'R';
+            }
+            else {
+                result.key = EscapeSequences_1.C0.ESC + 'OR';
+            }
+            break;
+        case 115:
+            if (modifiers) {
+                result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'S';
+            }
+            else {
+                result.key = EscapeSequences_1.C0.ESC + 'OS';
+            }
+            break;
+        case 116:
+            if (modifiers) {
+                result.key = EscapeSequences_1.C0.ESC + '[15;' + (modifiers + 1) + '~';
+            }
+            else {
+                result.key = EscapeSequences_1.C0.ESC + '[15~';
+            }
+            break;
+        case 117:
+            if (modifiers) {
+                result.key = EscapeSequences_1.C0.ESC + '[17;' + (modifiers + 1) + '~';
+            }
+            else {
+                result.key = EscapeSequences_1.C0.ESC + '[17~';
+            }
+            break;
+        case 118:
+            if (modifiers) {
+                result.key = EscapeSequences_1.C0.ESC + '[18;' + (modifiers + 1) + '~';
+            }
+            else {
+                result.key = EscapeSequences_1.C0.ESC + '[18~';
+            }
+            break;
+        case 119:
+            if (modifiers) {
+                result.key = EscapeSequences_1.C0.ESC + '[19;' + (modifiers + 1) + '~';
+            }
+            else {
+                result.key = EscapeSequences_1.C0.ESC + '[19~';
+            }
+            break;
+        case 120:
+            if (modifiers) {
+                result.key = EscapeSequences_1.C0.ESC + '[20;' + (modifiers + 1) + '~';
+            }
+            else {
+                result.key = EscapeSequences_1.C0.ESC + '[20~';
+            }
+            break;
+        case 121:
+            if (modifiers) {
+                result.key = EscapeSequences_1.C0.ESC + '[21;' + (modifiers + 1) + '~';
+            }
+            else {
+                result.key = EscapeSequences_1.C0.ESC + '[21~';
+            }
+            break;
+        case 122:
+            if (modifiers) {
+                result.key = EscapeSequences_1.C0.ESC + '[23;' + (modifiers + 1) + '~';
+            }
+            else {
+                result.key = EscapeSequences_1.C0.ESC + '[23~';
+            }
+            break;
+        case 123:
+            if (modifiers) {
+                result.key = EscapeSequences_1.C0.ESC + '[24;' + (modifiers + 1) + '~';
+            }
+            else {
+                result.key = EscapeSequences_1.C0.ESC + '[24~';
+            }
+            break;
+        default:
+            if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey) {
+                if (ev.keyCode >= 65 && ev.keyCode <= 90) {
+                    result.key = String.fromCharCode(ev.keyCode - 64);
+                }
+                else if (ev.keyCode === 32) {
+                    result.key = String.fromCharCode(0);
+                }
+                else if (ev.keyCode >= 51 && ev.keyCode <= 55) {
+                    result.key = String.fromCharCode(ev.keyCode - 51 + 27);
+                }
+                else if (ev.keyCode === 56) {
+                    result.key = String.fromCharCode(127);
+                }
+                else if (ev.keyCode === 219) {
+                    result.key = String.fromCharCode(27);
+                }
+                else if (ev.keyCode === 220) {
+                    result.key = String.fromCharCode(28);
+                }
+                else if (ev.keyCode === 221) {
+                    result.key = String.fromCharCode(29);
+                }
+            }
+            else if ((!isMac || macOptionIsMeta) && ev.altKey && !ev.metaKey) {
+                var keyMapping = KEYCODE_KEY_MAPPINGS[ev.keyCode];
+                var key = keyMapping && keyMapping[!ev.shiftKey ? 0 : 1];
+                if (key) {
+                    result.key = EscapeSequences_1.C0.ESC + key;
+                }
+                else if (ev.keyCode >= 65 && ev.keyCode <= 90) {
+                    var keyCode = ev.ctrlKey ? ev.keyCode - 64 : ev.keyCode + 32;
+                    result.key = EscapeSequences_1.C0.ESC + String.fromCharCode(keyCode);
+                }
+            }
+            else if (isMac && !ev.altKey && !ev.ctrlKey && ev.metaKey) {
+                if (ev.keyCode === 65) {
+                    result.type = 1;
+                }
+            }
+            else if (ev.key && !ev.ctrlKey && !ev.altKey && !ev.metaKey && ev.keyCode >= 48 && ev.key.length === 1) {
+                result.key = ev.key;
+            }
+            else if (ev.key && ev.ctrlKey) {
+                if (ev.key === '_') {
+                    result.key = EscapeSequences_1.C0.US;
+                }
+            }
+            break;
+    }
+    return result;
+}
+exports.evaluateKeyboardEvent = evaluateKeyboardEvent;
+
+},{"../../common/data/EscapeSequences":29}],32:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var StringToUtf32 = (function () {
+    function StringToUtf32() {
+        this._interim = 0;
+    }
+    StringToUtf32.prototype.clear = function () {
+        this._interim = 0;
+    };
+    StringToUtf32.prototype.decode = function (input, target) {
+        var length = input.length;
+        if (!length) {
+            return 0;
+        }
+        var size = 0;
+        var startPos = 0;
+        if (this._interim) {
+            var second = input.charCodeAt(startPos++);
+            if (0xDC00 <= second && second <= 0xDFFF) {
+                target[size++] = (this._interim - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
+            }
+            else {
+                target[size++] = this._interim;
+                target[size++] = second;
+            }
+            this._interim = 0;
+        }
+        for (var i = startPos; i < length; ++i) {
+            var code = input.charCodeAt(i);
+            if (0xD800 <= code && code <= 0xDBFF) {
+                if (++i >= length) {
+                    this._interim = code;
+                    return size;
+                }
+                var second = input.charCodeAt(i);
+                if (0xDC00 <= second && second <= 0xDFFF) {
+                    target[size++] = (code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
+                }
+                else {
+                    target[size++] = code;
+                    target[size++] = second;
+                }
+                continue;
+            }
+            target[size++] = code;
+        }
+        return size;
+    };
+    return StringToUtf32;
+}());
+exports.StringToUtf32 = StringToUtf32;
+function stringFromCodePoint(codePoint) {
+    if (codePoint > 0xFFFF) {
+        codePoint -= 0x10000;
+        return String.fromCharCode((codePoint >> 10) + 0xD800) + String.fromCharCode((codePoint % 0x400) + 0xDC00);
+    }
+    return String.fromCharCode(codePoint);
+}
+exports.stringFromCodePoint = stringFromCodePoint;
+function utf32ToString(data, start, end) {
+    if (start === void 0) { start = 0; }
+    if (end === void 0) { end = data.length; }
+    var result = '';
+    for (var i = start; i < end; ++i) {
+        var codepoint = data[i];
+        if (codepoint > 0xFFFF) {
+            codepoint -= 0x10000;
+            result += String.fromCharCode((codepoint >> 10) + 0xD800) + String.fromCharCode((codepoint % 0x400) + 0xDC00);
+        }
+        else {
+            result += String.fromCharCode(codepoint);
+        }
+    }
+    return result;
+}
+exports.utf32ToString = utf32ToString;
+
+},{}],33:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var EscapeSequences_1 = require("../common/data/EscapeSequences");
+var AltClickHandler = (function () {
+    function AltClickHandler(_mouseEvent, _terminal) {
+        var _a;
+        this._mouseEvent = _mouseEvent;
+        this._terminal = _terminal;
+        this._lines = this._terminal.buffer.lines;
+        this._startCol = this._terminal.buffer.x;
+        this._startRow = this._terminal.buffer.y;
+        var coordinates = this._terminal.mouseHelper.getCoords(this._mouseEvent, this._terminal.element, this._terminal.charMeasure, this._terminal.cols, this._terminal.rows, false);
+        if (coordinates) {
+            _a = coordinates.map(function (coordinate) {
+                return coordinate - 1;
+            }), this._endCol = _a[0], this._endRow = _a[1];
+        }
+    }
+    AltClickHandler.prototype.move = function () {
+        if (this._mouseEvent.altKey && this._endCol !== undefined && this._endRow !== undefined) {
+            this._terminal.handler(this._arrowSequences());
+        }
+    };
+    AltClickHandler.prototype._arrowSequences = function () {
+        if (!this._terminal.buffer.hasScrollback) {
+            return this._resetStartingRow() + this._moveToRequestedRow() + this._moveToRequestedCol();
+        }
+        return this._moveHorizontallyOnly();
+    };
+    AltClickHandler.prototype._resetStartingRow = function () {
+        if (this._moveToRequestedRow().length === 0) {
+            return '';
+        }
+        return repeat(this._bufferLine(this._startCol, this._startRow, this._startCol, this._startRow - this._wrappedRowsForRow(this._startRow), false).length, this._sequence("D"));
+    };
+    AltClickHandler.prototype._moveToRequestedRow = function () {
+        var startRow = this._startRow - this._wrappedRowsForRow(this._startRow);
+        var endRow = this._endRow - this._wrappedRowsForRow(this._endRow);
+        var rowsToMove = Math.abs(startRow - endRow) - this._wrappedRowsCount();
+        return repeat(rowsToMove, this._sequence(this._verticalDirection()));
+    };
+    AltClickHandler.prototype._moveToRequestedCol = function () {
+        var startRow;
+        if (this._moveToRequestedRow().length > 0) {
+            startRow = this._endRow - this._wrappedRowsForRow(this._endRow);
+        }
+        else {
+            startRow = this._startRow;
+        }
+        var endRow = this._endRow;
+        var direction = this._horizontalDirection();
+        return repeat(this._bufferLine(this._startCol, startRow, this._endCol, endRow, direction === "C").length, this._sequence(direction));
+    };
+    AltClickHandler.prototype._moveHorizontallyOnly = function () {
+        var direction = this._horizontalDirection();
+        return repeat(Math.abs(this._startCol - this._endCol), this._sequence(direction));
+    };
+    AltClickHandler.prototype._wrappedRowsCount = function () {
+        var wrappedRows = 0;
+        var startRow = this._startRow - this._wrappedRowsForRow(this._startRow);
+        var endRow = this._endRow - this._wrappedRowsForRow(this._endRow);
+        for (var i = 0; i < Math.abs(startRow - endRow); i++) {
+            var direction = this._verticalDirection() === "A" ? -1 : 1;
+            if (this._lines.get(startRow + (direction * i)).isWrapped) {
+                wrappedRows++;
+            }
+        }
+        return wrappedRows;
+    };
+    AltClickHandler.prototype._wrappedRowsForRow = function (currentRow) {
+        var rowCount = 0;
+        var lineWraps = this._lines.get(currentRow).isWrapped;
+        while (lineWraps && currentRow >= 0 && currentRow < this._terminal.rows) {
+            rowCount++;
+            currentRow--;
+            lineWraps = this._lines.get(currentRow).isWrapped;
+        }
+        return rowCount;
+    };
+    AltClickHandler.prototype._horizontalDirection = function () {
+        var startRow;
+        if (this._moveToRequestedRow().length > 0) {
+            startRow = this._endRow - this._wrappedRowsForRow(this._endRow);
+        }
+        else {
+            startRow = this._startRow;
+        }
+        if ((this._startCol < this._endCol &&
+            startRow <= this._endRow) ||
+            (this._startCol >= this._endCol &&
+                startRow < this._endRow)) {
+            return "C";
+        }
+        return "D";
+    };
+    AltClickHandler.prototype._verticalDirection = function () {
+        if (this._startRow > this._endRow) {
+            return "A";
+        }
+        return "B";
+    };
+    AltClickHandler.prototype._bufferLine = function (startCol, startRow, endCol, endRow, forward) {
+        var currentCol = startCol;
+        var currentRow = startRow;
+        var bufferStr = '';
+        while (currentCol !== endCol || currentRow !== endRow) {
+            currentCol += forward ? 1 : -1;
+            if (forward && currentCol > this._terminal.cols - 1) {
+                bufferStr += this._terminal.buffer.translateBufferLineToString(currentRow, false, startCol, currentCol);
+                currentCol = 0;
+                startCol = 0;
+                currentRow++;
+            }
+            else if (!forward && currentCol < 0) {
+                bufferStr += this._terminal.buffer.translateBufferLineToString(currentRow, false, 0, startCol + 1);
+                currentCol = this._terminal.cols - 1;
+                startCol = currentCol;
+                currentRow--;
+            }
+        }
+        return bufferStr + this._terminal.buffer.translateBufferLineToString(currentRow, false, startCol, currentCol);
+    };
+    AltClickHandler.prototype._sequence = function (direction) {
+        var mod = this._terminal.applicationCursor ? 'O' : '[';
+        return EscapeSequences_1.C0.ESC + mod + direction;
+    };
+    return AltClickHandler;
+}());
+exports.AltClickHandler = AltClickHandler;
+function repeat(count, str) {
+    count = Math.floor(count);
+    var rpt = '';
+    for (var i = 0; i < count; i++) {
+        rpt += str;
+    }
+    return rpt;
+}
+
+},{"../common/data/EscapeSequences":29}],34:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var Terminal_1 = require("../Terminal");
+var Strings = require("../Strings");
+var Terminal = (function () {
+    function Terminal(options) {
+        this._core = new Terminal_1.Terminal(options);
+    }
+    Object.defineProperty(Terminal.prototype, "onCursorMove", {
+        get: function () { return this._core.onCursorMove; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Terminal.prototype, "onLineFeed", {
+        get: function () { return this._core.onLineFeed; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Terminal.prototype, "onSelectionChange", {
+        get: function () { return this._core.onSelectionChange; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Terminal.prototype, "onData", {
+        get: function () { return this._core.onData; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Terminal.prototype, "onTitleChange", {
+        get: function () { return this._core.onTitleChange; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Terminal.prototype, "onScroll", {
+        get: function () { return this._core.onScroll; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Terminal.prototype, "onKey", {
+        get: function () { return this._core.onKey; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Terminal.prototype, "onRender", {
+        get: function () { return this._core.onRender; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Terminal.prototype, "onResize", {
+        get: function () { return this._core.onResize; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Terminal.prototype, "element", {
+        get: function () { return this._core.element; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Terminal.prototype, "textarea", {
+        get: function () { return this._core.textarea; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Terminal.prototype, "rows", {
+        get: function () { return this._core.rows; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Terminal.prototype, "cols", {
+        get: function () { return this._core.cols; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Terminal.prototype, "markers", {
+        get: function () { return this._core.markers; },
+        enumerable: true,
+        configurable: true
+    });
+    Terminal.prototype.blur = function () {
+        this._core.blur();
+    };
+    Terminal.prototype.focus = function () {
+        this._core.focus();
+    };
+    Terminal.prototype.on = function (type, listener) {
+        this._core.on(type, listener);
+    };
+    Terminal.prototype.off = function (type, listener) {
+        this._core.off(type, listener);
+    };
+    Terminal.prototype.emit = function (type, data) {
+        this._core.emit(type, data);
+    };
+    Terminal.prototype.addDisposableListener = function (type, handler) {
+        return this._core.addDisposableListener(type, handler);
+    };
+    Terminal.prototype.resize = function (columns, rows) {
+        this._core.resize(columns, rows);
+    };
+    Terminal.prototype.writeln = function (data) {
+        this._core.writeln(data);
+    };
+    Terminal.prototype.open = function (parent) {
+        this._core.open(parent);
+    };
+    Terminal.prototype.attachCustomKeyEventHandler = function (customKeyEventHandler) {
+        this._core.attachCustomKeyEventHandler(customKeyEventHandler);
+    };
+    Terminal.prototype.addCsiHandler = function (flag, callback) {
+        return this._core.addCsiHandler(flag, callback);
+    };
+    Terminal.prototype.addOscHandler = function (ident, callback) {
+        return this._core.addOscHandler(ident, callback);
+    };
+    Terminal.prototype.registerLinkMatcher = function (regex, handler, options) {
+        return this._core.registerLinkMatcher(regex, handler, options);
+    };
+    Terminal.prototype.deregisterLinkMatcher = function (matcherId) {
+        this._core.deregisterLinkMatcher(matcherId);
+    };
+    Terminal.prototype.registerCharacterJoiner = function (handler) {
+        return this._core.registerCharacterJoiner(handler);
+    };
+    Terminal.prototype.deregisterCharacterJoiner = function (joinerId) {
+        this._core.deregisterCharacterJoiner(joinerId);
+    };
+    Terminal.prototype.addMarker = function (cursorYOffset) {
+        return this._core.addMarker(cursorYOffset);
+    };
+    Terminal.prototype.hasSelection = function () {
+        return this._core.hasSelection();
+    };
+    Terminal.prototype.getSelection = function () {
+        return this._core.getSelection();
+    };
+    Terminal.prototype.clearSelection = function () {
+        this._core.clearSelection();
+    };
+    Terminal.prototype.selectAll = function () {
+        this._core.selectAll();
+    };
+    Terminal.prototype.selectLines = function (start, end) {
+        this._core.selectLines(start, end);
+    };
+    Terminal.prototype.dispose = function () {
+        this._core.dispose();
+    };
+    Terminal.prototype.destroy = function () {
+        this._core.destroy();
+    };
+    Terminal.prototype.scrollLines = function (amount) {
+        this._core.scrollLines(amount);
+    };
+    Terminal.prototype.scrollPages = function (pageCount) {
+        this._core.scrollPages(pageCount);
+    };
+    Terminal.prototype.scrollToTop = function () {
+        this._core.scrollToTop();
+    };
+    Terminal.prototype.scrollToBottom = function () {
+        this._core.scrollToBottom();
+    };
+    Terminal.prototype.scrollToLine = function (line) {
+        this._core.scrollToLine(line);
+    };
+    Terminal.prototype.clear = function () {
+        this._core.clear();
+    };
+    Terminal.prototype.write = function (data) {
+        this._core.write(data);
+    };
+    Terminal.prototype.getOption = function (key) {
+        return this._core.getOption(key);
+    };
+    Terminal.prototype.setOption = function (key, value) {
+        this._core.setOption(key, value);
+    };
+    Terminal.prototype.refresh = function (start, end) {
+        this._core.refresh(start, end);
+    };
+    Terminal.prototype.reset = function () {
+        this._core.reset();
+    };
+    Terminal.applyAddon = function (addon) {
+        addon.apply(Terminal);
+    };
+    Object.defineProperty(Terminal, "strings", {
+        get: function () {
+            return Strings;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    return Terminal;
+}());
+exports.Terminal = Terminal;
+
+},{"../Strings":18,"../Terminal":19}],35:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var Types_1 = require("./atlas/Types");
+var CharAtlasCache_1 = require("./atlas/CharAtlasCache");
+var BufferLine_1 = require("../BufferLine");
+var Buffer_1 = require("../Buffer");
+var CharacterJoinerRegistry_1 = require("./CharacterJoinerRegistry");
+var BaseRenderLayer = (function () {
+    function BaseRenderLayer(_container, id, zIndex, _alpha, _colors) {
+        this._container = _container;
+        this._alpha = _alpha;
+        this._colors = _colors;
+        this._scaledCharWidth = 0;
+        this._scaledCharHeight = 0;
+        this._scaledCellWidth = 0;
+        this._scaledCellHeight = 0;
+        this._scaledCharLeft = 0;
+        this._scaledCharTop = 0;
+        this._currentGlyphIdentifier = {
+            chars: '',
+            code: 0,
+            bg: 0,
+            fg: 0,
+            bold: false,
+            dim: false,
+            italic: false
+        };
+        this._canvas = document.createElement('canvas');
+        this._canvas.classList.add("xterm-" + id + "-layer");
+        this._canvas.style.zIndex = zIndex.toString();
+        this._initCanvas();
+        this._container.appendChild(this._canvas);
+    }
+    BaseRenderLayer.prototype.dispose = function () {
+        this._container.removeChild(this._canvas);
+        if (this._charAtlas) {
+            this._charAtlas.dispose();
+        }
+    };
+    BaseRenderLayer.prototype._initCanvas = function () {
+        this._ctx = this._canvas.getContext('2d', { alpha: this._alpha });
+        if (!this._alpha) {
+            this.clearAll();
+        }
+    };
+    BaseRenderLayer.prototype.onOptionsChanged = function (terminal) { };
+    BaseRenderLayer.prototype.onBlur = function (terminal) { };
+    BaseRenderLayer.prototype.onFocus = function (terminal) { };
+    BaseRenderLayer.prototype.onCursorMove = function (terminal) { };
+    BaseRenderLayer.prototype.onGridChanged = function (terminal, startRow, endRow) { };
+    BaseRenderLayer.prototype.onSelectionChanged = function (terminal, start, end, columnSelectMode) {
+        if (columnSelectMode === void 0) { columnSelectMode = false; }
+    };
+    BaseRenderLayer.prototype.onThemeChanged = function (terminal, colorSet) {
+        this._refreshCharAtlas(terminal, colorSet);
+    };
+    BaseRenderLayer.prototype.setTransparency = function (terminal, alpha) {
+        if (alpha === this._alpha) {
+            return;
+        }
+        var oldCanvas = this._canvas;
+        this._alpha = alpha;
+        this._canvas = this._canvas.cloneNode();
+        this._initCanvas();
+        this._container.replaceChild(this._canvas, oldCanvas);
+        this._refreshCharAtlas(terminal, this._colors);
+        this.onGridChanged(terminal, 0, terminal.rows - 1);
+    };
+    BaseRenderLayer.prototype._refreshCharAtlas = function (terminal, colorSet) {
+        if (this._scaledCharWidth <= 0 && this._scaledCharHeight <= 0) {
+            return;
+        }
+        this._charAtlas = CharAtlasCache_1.acquireCharAtlas(terminal, colorSet, this._scaledCharWidth, this._scaledCharHeight);
+        this._charAtlas.warmUp();
+    };
+    BaseRenderLayer.prototype.resize = function (terminal, dim) {
+        this._scaledCellWidth = dim.scaledCellWidth;
+        this._scaledCellHeight = dim.scaledCellHeight;
+        this._scaledCharWidth = dim.scaledCharWidth;
+        this._scaledCharHeight = dim.scaledCharHeight;
+        this._scaledCharLeft = dim.scaledCharLeft;
+        this._scaledCharTop = dim.scaledCharTop;
+        this._canvas.width = dim.scaledCanvasWidth;
+        this._canvas.height = dim.scaledCanvasHeight;
+        this._canvas.style.width = dim.canvasWidth + "px";
+        this._canvas.style.height = dim.canvasHeight + "px";
+        if (!this._alpha) {
+            this.clearAll();
+        }
+        this._refreshCharAtlas(terminal, this._colors);
+    };
+    BaseRenderLayer.prototype.fillCells = function (x, y, width, height) {
+        this._ctx.fillRect(x * this._scaledCellWidth, y * this._scaledCellHeight, width * this._scaledCellWidth, height * this._scaledCellHeight);
+    };
+    BaseRenderLayer.prototype.fillBottomLineAtCells = function (x, y, width) {
+        if (width === void 0) { width = 1; }
+        this._ctx.fillRect(x * this._scaledCellWidth, (y + 1) * this._scaledCellHeight - window.devicePixelRatio - 1, width * this._scaledCellWidth, window.devicePixelRatio);
+    };
+    BaseRenderLayer.prototype.fillLeftLineAtCell = function (x, y) {
+        this._ctx.fillRect(x * this._scaledCellWidth, y * this._scaledCellHeight, window.devicePixelRatio, this._scaledCellHeight);
+    };
+    BaseRenderLayer.prototype.strokeRectAtCell = function (x, y, width, height) {
+        this._ctx.lineWidth = window.devicePixelRatio;
+        this._ctx.strokeRect(x * this._scaledCellWidth + window.devicePixelRatio / 2, y * this._scaledCellHeight + (window.devicePixelRatio / 2), width * this._scaledCellWidth - window.devicePixelRatio, (height * this._scaledCellHeight) - window.devicePixelRatio);
+    };
+    BaseRenderLayer.prototype.clearAll = function () {
+        if (this._alpha) {
+            this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);
+        }
+        else {
+            this._ctx.fillStyle = this._colors.background.css;
+            this._ctx.fillRect(0, 0, this._canvas.width, this._canvas.height);
+        }
+    };
+    BaseRenderLayer.prototype.clearCells = function (x, y, width, height) {
+        if (this._alpha) {
+            this._ctx.clearRect(x * this._scaledCellWidth, y * this._scaledCellHeight, width * this._scaledCellWidth, height * this._scaledCellHeight);
+        }
+        else {
+            this._ctx.fillStyle = this._colors.background.css;
+            this._ctx.fillRect(x * this._scaledCellWidth, y * this._scaledCellHeight, width * this._scaledCellWidth, height * this._scaledCellHeight);
+        }
+    };
+    BaseRenderLayer.prototype.fillCharTrueColor = function (terminal, cell, x, y) {
+        this._ctx.font = this._getFont(terminal, false, false);
+        this._ctx.textBaseline = 'middle';
+        this._clipRow(terminal, y);
+        this._ctx.fillText(cell.getChars(), x * this._scaledCellWidth + this._scaledCharLeft, y * this._scaledCellHeight + this._scaledCharTop + this._scaledCharHeight / 2);
+    };
+    BaseRenderLayer.prototype.drawChars = function (terminal, cell, x, y) {
+        if (cell.isFgRGB() || cell.isBgRGB() || cell instanceof CharacterJoinerRegistry_1.JoinedCellData) {
+            this._drawUncachedChars(terminal, cell, x, y);
+            return;
+        }
+        var fg;
+        var bg;
+        if (cell.isInverse()) {
+            fg = (cell.isBgDefault()) ? Types_1.INVERTED_DEFAULT_COLOR : cell.getBgColor();
+            bg = (cell.isFgDefault()) ? Types_1.INVERTED_DEFAULT_COLOR : cell.getFgColor();
+        }
+        else {
+            bg = (cell.isBgDefault()) ? Types_1.DEFAULT_COLOR : cell.getBgColor();
+            fg = (cell.isFgDefault()) ? Types_1.DEFAULT_COLOR : cell.getFgColor();
+        }
+        var drawInBrightColor = terminal.options.drawBoldTextInBrightColors && cell.isBold() && fg < 8 && fg !== Types_1.INVERTED_DEFAULT_COLOR;
+        fg += drawInBrightColor ? 8 : 0;
+        this._currentGlyphIdentifier.chars = cell.getChars() || Buffer_1.WHITESPACE_CELL_CHAR;
+        this._currentGlyphIdentifier.code = cell.getCode() || Buffer_1.WHITESPACE_CELL_CODE;
+        this._currentGlyphIdentifier.bg = bg;
+        this._currentGlyphIdentifier.fg = fg;
+        this._currentGlyphIdentifier.bold = cell.isBold() && terminal.options.enableBold;
+        this._currentGlyphIdentifier.dim = !!cell.isDim();
+        this._currentGlyphIdentifier.italic = !!cell.isItalic();
+        var atlasDidDraw = this._charAtlas && this._charAtlas.draw(this._ctx, this._currentGlyphIdentifier, x * this._scaledCellWidth + this._scaledCharLeft, y * this._scaledCellHeight + this._scaledCharTop);
+        if (!atlasDidDraw) {
+            this._drawUncachedChars(terminal, cell, x, y);
+        }
+    };
+    BaseRenderLayer.prototype._drawUncachedChars = function (terminal, cell, x, y) {
+        this._ctx.save();
+        this._ctx.font = this._getFont(terminal, cell.isBold() && terminal.options.enableBold, !!cell.isItalic());
+        this._ctx.textBaseline = 'middle';
+        if (cell.isInverse()) {
+            if (cell.isBgDefault()) {
+                this._ctx.fillStyle = this._colors.background.css;
+            }
+            else if (cell.isBgRGB()) {
+                this._ctx.fillStyle = "rgb(" + BufferLine_1.AttributeData.toColorRGB(cell.getBgColor()).join(',') + ")";
+            }
+            else {
+                this._ctx.fillStyle = this._colors.ansi[cell.getBgColor()].css;
+            }
+        }
+        else {
+            if (cell.isFgDefault()) {
+                this._ctx.fillStyle = this._colors.foreground.css;
+            }
+            else if (cell.isFgRGB()) {
+                this._ctx.fillStyle = "rgb(" + BufferLine_1.AttributeData.toColorRGB(cell.getFgColor()).join(',') + ")";
+            }
+            else {
+                var fg = cell.getFgColor();
+                if (terminal.options.drawBoldTextInBrightColors && cell.isBold() && fg < 8) {
+                    fg += 8;
+                }
+                this._ctx.fillStyle = this._colors.ansi[fg].css;
+            }
+        }
+        this._clipRow(terminal, y);
+        if (cell.isDim()) {
+            this._ctx.globalAlpha = Types_1.DIM_OPACITY;
+        }
+        this._ctx.fillText(cell.getChars(), x * this._scaledCellWidth + this._scaledCharLeft, y * this._scaledCellHeight + this._scaledCharTop + this._scaledCharHeight / 2);
+        this._ctx.restore();
+    };
+    BaseRenderLayer.prototype._clipRow = function (terminal, y) {
+        this._ctx.beginPath();
+        this._ctx.rect(0, y * this._scaledCellHeight, terminal.cols * this._scaledCellWidth, this._scaledCellHeight);
+        this._ctx.clip();
+    };
+    BaseRenderLayer.prototype._getFont = function (terminal, isBold, isItalic) {
+        var fontWeight = isBold ? terminal.options.fontWeightBold : terminal.options.fontWeight;
+        var fontStyle = isItalic ? 'italic' : '';
+        return fontStyle + " " + fontWeight + " " + terminal.options.fontSize * window.devicePixelRatio + "px " + terminal.options.fontFamily;
+    };
+    return BaseRenderLayer;
+}());
+exports.BaseRenderLayer = BaseRenderLayer;
+
+},{"../Buffer":2,"../BufferLine":3,"./CharacterJoinerRegistry":36,"./atlas/CharAtlasCache":45,"./atlas/Types":52}],36:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = function (d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var BufferLine_1 = require("../BufferLine");
+var Buffer_1 = require("../Buffer");
+var JoinedCellData = (function (_super) {
+    __extends(JoinedCellData, _super);
+    function JoinedCellData(firstCell, chars, width) {
+        var _this = _super.call(this) || this;
+        _this.content = 0;
+        _this.combinedData = '';
+        _this.fg = firstCell.fg;
+        _this.bg = firstCell.bg;
+        _this.combinedData = chars;
+        _this._width = width;
+        return _this;
+    }
+    JoinedCellData.prototype.isCombined = function () {
+        return 2097152;
+    };
+    JoinedCellData.prototype.getWidth = function () {
+        return this._width;
+    };
+    JoinedCellData.prototype.getChars = function () {
+        return this.combinedData;
+    };
+    JoinedCellData.prototype.getCode = function () {
+        return 0x1FFFFF;
+    };
+    JoinedCellData.prototype.setFromCharData = function (value) {
+        throw new Error('not implemented');
+    };
+    JoinedCellData.prototype.getAsCharData = function () {
+        return [this.fg, this.getChars(), this.getWidth(), this.getCode()];
+    };
+    return JoinedCellData;
+}(BufferLine_1.AttributeData));
+exports.JoinedCellData = JoinedCellData;
+var CharacterJoinerRegistry = (function () {
+    function CharacterJoinerRegistry(_terminal) {
+        this._terminal = _terminal;
+        this._characterJoiners = [];
+        this._nextCharacterJoinerId = 0;
+        this._workCell = new BufferLine_1.CellData();
+    }
+    CharacterJoinerRegistry.prototype.registerCharacterJoiner = function (handler) {
+        var joiner = {
+            id: this._nextCharacterJoinerId++,
+            handler: handler
+        };
+        this._characterJoiners.push(joiner);
+        return joiner.id;
+    };
+    CharacterJoinerRegistry.prototype.deregisterCharacterJoiner = function (joinerId) {
+        for (var i = 0; i < this._characterJoiners.length; i++) {
+            if (this._characterJoiners[i].id === joinerId) {
+                this._characterJoiners.splice(i, 1);
+                return true;
+            }
+        }
+        return false;
+    };
+    CharacterJoinerRegistry.prototype.getJoinedCharacters = function (row) {
+        if (this._characterJoiners.length === 0) {
+            return [];
+        }
+        var line = this._terminal.buffer.lines.get(row);
+        if (line.length === 0) {
+            return [];
+        }
+        var ranges = [];
+        var lineStr = line.translateToString(true);
+        var rangeStartColumn = 0;
+        var currentStringIndex = 0;
+        var rangeStartStringIndex = 0;
+        var rangeAttrFG = line.getFg(0);
+        var rangeAttrBG = line.getBg(0);
+        for (var x = 0; x < line.getTrimmedLength(); x++) {
+            line.loadCell(x, this._workCell);
+            if (this._workCell.getWidth() === 0) {
+                continue;
+            }
+            if (this._workCell.fg !== rangeAttrFG || this._workCell.bg !== rangeAttrBG) {
+                if (x - rangeStartColumn > 1) {
+                    var joinedRanges = this._getJoinedRanges(lineStr, rangeStartStringIndex, currentStringIndex, line, rangeStartColumn);
+                    for (var i = 0; i < joinedRanges.length; i++) {
+                        ranges.push(joinedRanges[i]);
+                    }
+                }
+                rangeStartColumn = x;
+                rangeStartStringIndex = currentStringIndex;
+                rangeAttrFG = this._workCell.fg;
+                rangeAttrBG = this._workCell.bg;
+            }
+            currentStringIndex += this._workCell.getChars().length || Buffer_1.WHITESPACE_CELL_CHAR.length;
+        }
+        if (this._terminal.cols - rangeStartColumn > 1) {
+            var joinedRanges = this._getJoinedRanges(lineStr, rangeStartStringIndex, currentStringIndex, line, rangeStartColumn);
+            for (var i = 0; i < joinedRanges.length; i++) {
+                ranges.push(joinedRanges[i]);
+            }
+        }
+        return ranges;
+    };
+    CharacterJoinerRegistry.prototype._getJoinedRanges = function (line, startIndex, endIndex, lineData, startCol) {
+        var text = line.substring(startIndex, endIndex);
+        var joinedRanges = this._characterJoiners[0].handler(text);
+        for (var i = 1; i < this._characterJoiners.length; i++) {
+            var joinerRanges = this._characterJoiners[i].handler(text);
+            for (var j = 0; j < joinerRanges.length; j++) {
+                CharacterJoinerRegistry._mergeRanges(joinedRanges, joinerRanges[j]);
+            }
+        }
+        this._stringRangesToCellRanges(joinedRanges, lineData, startCol);
+        return joinedRanges;
+    };
+    CharacterJoinerRegistry.prototype._stringRangesToCellRanges = function (ranges, line, startCol) {
+        var currentRangeIndex = 0;
+        var currentRangeStarted = false;
+        var currentStringIndex = 0;
+        var currentRange = ranges[currentRangeIndex];
+        if (!currentRange) {
+            return;
+        }
+        for (var x = startCol; x < this._terminal.cols; x++) {
+            var width = line.getWidth(x);
+            var length_1 = line.getString(x).length || Buffer_1.WHITESPACE_CELL_CHAR.length;
+            if (width === 0) {
+                continue;
+            }
+            if (!currentRangeStarted && currentRange[0] <= currentStringIndex) {
+                currentRange[0] = x;
+                currentRangeStarted = true;
+            }
+            if (currentRange[1] <= currentStringIndex) {
+                currentRange[1] = x;
+                currentRange = ranges[++currentRangeIndex];
+                if (!currentRange) {
+                    break;
+                }
+                if (currentRange[0] <= currentStringIndex) {
+                    currentRange[0] = x;
+                    currentRangeStarted = true;
+                }
+                else {
+                    currentRangeStarted = false;
+                }
+            }
+            currentStringIndex += length_1;
+        }
+        if (currentRange) {
+            currentRange[1] = this._terminal.cols;
+        }
+    };
+    CharacterJoinerRegistry._mergeRanges = function (ranges, newRange) {
+        var inRange = false;
+        for (var i = 0; i < ranges.length; i++) {
+            var range = ranges[i];
+            if (!inRange) {
+                if (newRange[1] <= range[0]) {
+                    ranges.splice(i, 0, newRange);
+                    return ranges;
+                }
+                if (newRange[1] <= range[1]) {
+                    range[0] = Math.min(newRange[0], range[0]);
+                    return ranges;
+                }
+                if (newRange[0] < range[1]) {
+                    range[0] = Math.min(newRange[0], range[0]);
+                    inRange = true;
+                }
+                continue;
+            }
+            else {
+                if (newRange[1] <= range[0]) {
+                    ranges[i - 1][1] = newRange[1];
+                    return ranges;
+                }
+                if (newRange[1] <= range[1]) {
+                    ranges[i - 1][1] = Math.max(newRange[1], range[1]);
+                    ranges.splice(i, 1);
+                    inRange = false;
+                    return ranges;
+                }
+                ranges.splice(i, 1);
+                i--;
+            }
+        }
+        if (inRange) {
+            ranges[ranges.length - 1][1] = newRange[1];
+        }
+        else {
+            ranges.push(newRange);
+        }
+        return ranges;
+    };
+    return CharacterJoinerRegistry;
+}());
+exports.CharacterJoinerRegistry = CharacterJoinerRegistry;
+
+},{"../Buffer":2,"../BufferLine":3}],37:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var DEFAULT_FOREGROUND = fromHex('#ffffff');
+var DEFAULT_BACKGROUND = fromHex('#000000');
+var DEFAULT_CURSOR = fromHex('#ffffff');
+var DEFAULT_CURSOR_ACCENT = fromHex('#000000');
+var DEFAULT_SELECTION = {
+    css: 'rgba(255, 255, 255, 0.3)',
+    rgba: 0xFFFFFF77
+};
+exports.DEFAULT_ANSI_COLORS = (function () {
+    var colors = [
+        fromHex('#2e3436'),
+        fromHex('#cc0000'),
+        fromHex('#4e9a06'),
+        fromHex('#c4a000'),
+        fromHex('#3465a4'),
+        fromHex('#75507b'),
+        fromHex('#06989a'),
+        fromHex('#d3d7cf'),
+        fromHex('#555753'),
+        fromHex('#ef2929'),
+        fromHex('#8ae234'),
+        fromHex('#fce94f'),
+        fromHex('#729fcf'),
+        fromHex('#ad7fa8'),
+        fromHex('#34e2e2'),
+        fromHex('#eeeeec')
+    ];
+    var v = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff];
+    for (var i = 0; i < 216; i++) {
+        var r = v[(i / 36) % 6 | 0];
+        var g = v[(i / 6) % 6 | 0];
+        var b = v[i % 6];
+        colors.push({
+            css: "#" + toPaddedHex(r) + toPaddedHex(g) + toPaddedHex(b),
+            rgba: ((r << 24) | (g << 16) | (b << 8) | 0xFF) >>> 0
+        });
+    }
+    for (var i = 0; i < 24; i++) {
+        var c = 8 + i * 10;
+        var ch = toPaddedHex(c);
+        colors.push({
+            css: "#" + ch + ch + ch,
+            rgba: ((c << 24) | (c << 16) | (c << 8) | 0xFF) >>> 0
+        });
+    }
+    return colors;
+})();
+function fromHex(css) {
+    return {
+        css: css,
+        rgba: parseInt(css.slice(1), 16) << 8 | 0xFF
+    };
+}
+function toPaddedHex(c) {
+    var s = c.toString(16);
+    return s.length < 2 ? '0' + s : s;
+}
+var ColorManager = (function () {
+    function ColorManager(document, allowTransparency) {
+        this.allowTransparency = allowTransparency;
+        var canvas = document.createElement('canvas');
+        canvas.width = 1;
+        canvas.height = 1;
+        this._ctx = canvas.getContext('2d');
+        this._ctx.globalCompositeOperation = 'copy';
+        this._litmusColor = this._ctx.createLinearGradient(0, 0, 1, 1);
+        this.colors = {
+            foreground: DEFAULT_FOREGROUND,
+            background: DEFAULT_BACKGROUND,
+            cursor: DEFAULT_CURSOR,
+            cursorAccent: DEFAULT_CURSOR_ACCENT,
+            selection: DEFAULT_SELECTION,
+            ansi: exports.DEFAULT_ANSI_COLORS.slice()
+        };
+    }
+    ColorManager.prototype.setTheme = function (theme) {
+        this.colors.foreground = this._parseColor(theme.foreground, DEFAULT_FOREGROUND);
+        this.colors.background = this._parseColor(theme.background, DEFAULT_BACKGROUND);
+        this.colors.cursor = this._parseColor(theme.cursor, DEFAULT_CURSOR, true);
+        this.colors.cursorAccent = this._parseColor(theme.cursorAccent, DEFAULT_CURSOR_ACCENT, true);
+        this.colors.selection = this._parseColor(theme.selection, DEFAULT_SELECTION, true);
+        this.colors.ansi[0] = this._parseColor(theme.black, exports.DEFAULT_ANSI_COLORS[0]);
+        this.colors.ansi[1] = this._parseColor(theme.red, exports.DEFAULT_ANSI_COLORS[1]);
+        this.colors.ansi[2] = this._parseColor(theme.green, exports.DEFAULT_ANSI_COLORS[2]);
+        this.colors.ansi[3] = this._parseColor(theme.yellow, exports.DEFAULT_ANSI_COLORS[3]);
+        this.colors.ansi[4] = this._parseColor(theme.blue, exports.DEFAULT_ANSI_COLORS[4]);
+        this.colors.ansi[5] = this._parseColor(theme.magenta, exports.DEFAULT_ANSI_COLORS[5]);
+        this.colors.ansi[6] = this._parseColor(theme.cyan, exports.DEFAULT_ANSI_COLORS[6]);
+        this.colors.ansi[7] = this._parseColor(theme.white, exports.DEFAULT_ANSI_COLORS[7]);
+        this.colors.ansi[8] = this._parseColor(theme.brightBlack, exports.DEFAULT_ANSI_COLORS[8]);
+        this.colors.ansi[9] = this._parseColor(theme.brightRed, exports.DEFAULT_ANSI_COLORS[9]);
+        this.colors.ansi[10] = this._parseColor(theme.brightGreen, exports.DEFAULT_ANSI_COLORS[10]);
+        this.colors.ansi[11] = this._parseColor(theme.brightYellow, exports.DEFAULT_ANSI_COLORS[11]);
+        this.colors.ansi[12] = this._parseColor(theme.brightBlue, exports.DEFAULT_ANSI_COLORS[12]);
+        this.colors.ansi[13] = this._parseColor(theme.brightMagenta, exports.DEFAULT_ANSI_COLORS[13]);
+        this.colors.ansi[14] = this._parseColor(theme.brightCyan, exports.DEFAULT_ANSI_COLORS[14]);
+        this.colors.ansi[15] = this._parseColor(theme.brightWhite, exports.DEFAULT_ANSI_COLORS[15]);
+    };
+    ColorManager.prototype._parseColor = function (css, fallback, allowTransparency) {
+        if (allowTransparency === void 0) { allowTransparency = this.allowTransparency; }
+        if (!css) {
+            return fallback;
+        }
+        this._ctx.fillStyle = this._litmusColor;
+        this._ctx.fillStyle = css;
+        if (typeof this._ctx.fillStyle !== 'string') {
+            console.warn("Color: " + css + " is invalid using fallback " + fallback.css);
+            return fallback;
+        }
+        this._ctx.fillRect(0, 0, 1, 1);
+        var data = this._ctx.getImageData(0, 0, 1, 1).data;
+        if (!allowTransparency && data[3] !== 0xFF) {
+            console.warn("Color: " + css + " is using transparency, but allowTransparency is false. " +
+                ("Using fallback " + fallback.css + "."));
+            return fallback;
+        }
+        return {
+            css: css,
+            rgba: (data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]) >>> 0
+        };
+    };
+    return ColorManager;
+}());
+exports.ColorManager = ColorManager;
+
+},{}],38:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = function (d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var BaseRenderLayer_1 = require("./BaseRenderLayer");
+var BufferLine_1 = require("../BufferLine");
+var BLINK_INTERVAL = 600;
+var CursorRenderLayer = (function (_super) {
+    __extends(CursorRenderLayer, _super);
+    function CursorRenderLayer(container, zIndex, colors) {
+        var _this = _super.call(this, container, 'cursor', zIndex, true, colors) || this;
+        _this._cell = new BufferLine_1.CellData();
+        _this._state = {
+            x: null,
+            y: null,
+            isFocused: null,
+            style: null,
+            width: null
+        };
+        _this._cursorRenderers = {
+            'bar': _this._renderBarCursor.bind(_this),
+            'block': _this._renderBlockCursor.bind(_this),
+            'underline': _this._renderUnderlineCursor.bind(_this)
+        };
+        return _this;
+    }
+    CursorRenderLayer.prototype.resize = function (terminal, dim) {
+        _super.prototype.resize.call(this, terminal, dim);
+        this._state = {
+            x: null,
+            y: null,
+            isFocused: null,
+            style: null,
+            width: null
+        };
+    };
+    CursorRenderLayer.prototype.reset = function (terminal) {
+        this._clearCursor();
+        if (this._cursorBlinkStateManager) {
+            this._cursorBlinkStateManager.dispose();
+            this._cursorBlinkStateManager = null;
+            this.onOptionsChanged(terminal);
+        }
+    };
+    CursorRenderLayer.prototype.onBlur = function (terminal) {
+        if (this._cursorBlinkStateManager) {
+            this._cursorBlinkStateManager.pause();
+        }
+        terminal.refresh(terminal.buffer.y, terminal.buffer.y);
+    };
+    CursorRenderLayer.prototype.onFocus = function (terminal) {
+        if (this._cursorBlinkStateManager) {
+            this._cursorBlinkStateManager.resume(terminal);
+        }
+        else {
+            terminal.refresh(terminal.buffer.y, terminal.buffer.y);
+        }
+    };
+    CursorRenderLayer.prototype.onOptionsChanged = function (terminal) {
+        var _this = this;
+        if (terminal.options.cursorBlink) {
+            if (!this._cursorBlinkStateManager) {
+                this._cursorBlinkStateManager = new CursorBlinkStateManager(terminal, function () {
+                    _this._render(terminal, true);
+                });
+            }
+        }
+        else {
+            if (this._cursorBlinkStateManager) {
+                this._cursorBlinkStateManager.dispose();
+                this._cursorBlinkStateManager = null;
+            }
+            terminal.refresh(terminal.buffer.y, terminal.buffer.y);
+        }
+    };
+    CursorRenderLayer.prototype.onCursorMove = function (terminal) {
+        if (this._cursorBlinkStateManager) {
+            this._cursorBlinkStateManager.restartBlinkAnimation(terminal);
+        }
+    };
+    CursorRenderLayer.prototype.onGridChanged = function (terminal, startRow, endRow) {
+        if (!this._cursorBlinkStateManager || this._cursorBlinkStateManager.isPaused) {
+            this._render(terminal, false);
+        }
+        else {
+            this._cursorBlinkStateManager.restartBlinkAnimation(terminal);
+        }
+    };
+    CursorRenderLayer.prototype._render = function (terminal, triggeredByAnimationFrame) {
+        if (!terminal.cursorState || terminal.cursorHidden) {
+            this._clearCursor();
+            return;
+        }
+        var cursorY = terminal.buffer.ybase + terminal.buffer.y;
+        var viewportRelativeCursorY = cursorY - terminal.buffer.ydisp;
+        if (viewportRelativeCursorY < 0 || viewportRelativeCursorY >= terminal.rows) {
+            this._clearCursor();
+            return;
+        }
+        terminal.buffer.lines.get(cursorY).loadCell(terminal.buffer.x, this._cell);
+        if (this._cell.content === undefined) {
+            return;
+        }
+        if (!terminal.isFocused) {
+            this._clearCursor();
+            this._ctx.save();
+            this._ctx.fillStyle = this._colors.cursor.css;
+            this._renderBlurCursor(terminal, terminal.buffer.x, viewportRelativeCursorY, this._cell);
+            this._ctx.restore();
+            this._state.x = terminal.buffer.x;
+            this._state.y = viewportRelativeCursorY;
+            this._state.isFocused = false;
+            this._state.style = terminal.options.cursorStyle;
+            this._state.width = this._cell.getWidth();
+            return;
+        }
+        if (this._cursorBlinkStateManager && !this._cursorBlinkStateManager.isCursorVisible) {
+            this._clearCursor();
+            return;
+        }
+        if (this._state) {
+            if (this._state.x === terminal.buffer.x &&
+                this._state.y === viewportRelativeCursorY &&
+                this._state.isFocused === terminal.isFocused &&
+                this._state.style === terminal.options.cursorStyle &&
+                this._state.width === this._cell.getWidth()) {
+                return;
+            }
+            this._clearCursor();
+        }
+        this._ctx.save();
+        this._cursorRenderers[terminal.options.cursorStyle || 'block'](terminal, terminal.buffer.x, viewportRelativeCursorY, this._cell);
+        this._ctx.restore();
+        this._state.x = terminal.buffer.x;
+        this._state.y = viewportRelativeCursorY;
+        this._state.isFocused = false;
+        this._state.style = terminal.options.cursorStyle;
+        this._state.width = this._cell.getWidth();
+    };
+    CursorRenderLayer.prototype._clearCursor = function () {
+        if (this._state) {
+            this.clearCells(this._state.x, this._state.y, this._state.width, 1);
+            this._state = {
+                x: null,
+                y: null,
+                isFocused: null,
+                style: null,
+                width: null
+            };
+        }
+    };
+    CursorRenderLayer.prototype._renderBarCursor = function (terminal, x, y, cell) {
+        this._ctx.save();
+        this._ctx.fillStyle = this._colors.cursor.css;
+        this.fillLeftLineAtCell(x, y);
+        this._ctx.restore();
+    };
+    CursorRenderLayer.prototype._renderBlockCursor = function (terminal, x, y, cell) {
+        this._ctx.save();
+        this._ctx.fillStyle = this._colors.cursor.css;
+        this.fillCells(x, y, cell.getWidth(), 1);
+        this._ctx.fillStyle = this._colors.cursorAccent.css;
+        this.fillCharTrueColor(terminal, cell, x, y);
+        this._ctx.restore();
+    };
+    CursorRenderLayer.prototype._renderUnderlineCursor = function (terminal, x, y, cell) {
+        this._ctx.save();
+        this._ctx.fillStyle = this._colors.cursor.css;
+        this.fillBottomLineAtCells(x, y);
+        this._ctx.restore();
+    };
+    CursorRenderLayer.prototype._renderBlurCursor = function (terminal, x, y, cell) {
+        this._ctx.save();
+        this._ctx.strokeStyle = this._colors.cursor.css;
+        this.strokeRectAtCell(x, y, cell.getWidth(), 1);
+        this._ctx.restore();
+    };
+    return CursorRenderLayer;
+}(BaseRenderLayer_1.BaseRenderLayer));
+exports.CursorRenderLayer = CursorRenderLayer;
+var CursorBlinkStateManager = (function () {
+    function CursorBlinkStateManager(terminal, _renderCallback) {
+        this._renderCallback = _renderCallback;
+        this.isCursorVisible = true;
+        if (terminal.isFocused) {
+            this._restartInterval();
+        }
+    }
+    Object.defineProperty(CursorBlinkStateManager.prototype, "isPaused", {
+        get: function () { return !(this._blinkStartTimeout || this._blinkInterval); },
+        enumerable: true,
+        configurable: true
+    });
+    CursorBlinkStateManager.prototype.dispose = function () {
+        if (this._blinkInterval) {
+            window.clearInterval(this._blinkInterval);
+            this._blinkInterval = null;
+        }
+        if (this._blinkStartTimeout) {
+            window.clearTimeout(this._blinkStartTimeout);
+            this._blinkStartTimeout = null;
+        }
+        if (this._animationFrame) {
+            window.cancelAnimationFrame(this._animationFrame);
+            this._animationFrame = null;
+        }
+    };
+    CursorBlinkStateManager.prototype.restartBlinkAnimation = function (terminal) {
+        var _this = this;
+        if (this.isPaused) {
+            return;
+        }
+        this._animationTimeRestarted = Date.now();
+        this.isCursorVisible = true;
+        if (!this._animationFrame) {
+            this._animationFrame = window.requestAnimationFrame(function () {
+                _this._renderCallback();
+                _this._animationFrame = null;
+            });
+        }
+    };
+    CursorBlinkStateManager.prototype._restartInterval = function (timeToStart) {
+        var _this = this;
+        if (timeToStart === void 0) { timeToStart = BLINK_INTERVAL; }
+        if (this._blinkInterval) {
+            window.clearInterval(this._blinkInterval);
+        }
+        this._blinkStartTimeout = setTimeout(function () {
+            if (_this._animationTimeRestarted) {
+                var time = BLINK_INTERVAL - (Date.now() - _this._animationTimeRestarted);
+                _this._animationTimeRestarted = null;
+                if (time > 0) {
+                    _this._restartInterval(time);
+                    return;
+                }
+            }
+            _this.isCursorVisible = false;
+            _this._animationFrame = window.requestAnimationFrame(function () {
+                _this._renderCallback();
+                _this._animationFrame = null;
+            });
+            _this._blinkInterval = setInterval(function () {
+                if (_this._animationTimeRestarted) {
+                    var time = BLINK_INTERVAL - (Date.now() - _this._animationTimeRestarted);
+                    _this._animationTimeRestarted = null;
+                    _this._restartInterval(time);
+                    return;
+                }
+                _this.isCursorVisible = !_this.isCursorVisible;
+                _this._animationFrame = window.requestAnimationFrame(function () {
+                    _this._renderCallback();
+                    _this._animationFrame = null;
+                });
+            }, BLINK_INTERVAL);
+        }, timeToStart);
+    };
+    CursorBlinkStateManager.prototype.pause = function () {
+        this.isCursorVisible = true;
+        if (this._blinkInterval) {
+            window.clearInterval(this._blinkInterval);
+            this._blinkInterval = null;
+        }
+        if (this._blinkStartTimeout) {
+            window.clearTimeout(this._blinkStartTimeout);
+            this._blinkStartTimeout = null;
+        }
+        if (this._animationFrame) {
+            window.cancelAnimationFrame(this._animationFrame);
+            this._animationFrame = null;
+        }
+    };
+    CursorBlinkStateManager.prototype.resume = function (terminal) {
+        this._animationTimeRestarted = null;
+        this._restartInterval();
+        this.restartBlinkAnimation(terminal);
+    };
+    return CursorBlinkStateManager;
+}());
+
+},{"../BufferLine":3,"./BaseRenderLayer":35}],39:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var GridCache = (function () {
+    function GridCache() {
+        this.cache = [];
+    }
+    GridCache.prototype.resize = function (width, height) {
+        for (var x = 0; x < width; x++) {
+            if (this.cache.length <= x) {
+                this.cache.push([]);
+            }
+            for (var y = this.cache[x].length; y < height; y++) {
+                this.cache[x].push(null);
+            }
+            this.cache[x].length = height;
+        }
+        this.cache.length = width;
+    };
+    GridCache.prototype.clear = function () {
+        for (var x = 0; x < this.cache.length; x++) {
+            for (var y = 0; y < this.cache[x].length; y++) {
+                this.cache[x][y] = null;
+            }
+        }
+    };
+    return GridCache;
+}());
+exports.GridCache = GridCache;
+
+},{}],40:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = function (d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var BaseRenderLayer_1 = require("./BaseRenderLayer");
+var Types_1 = require("./atlas/Types");
+var CharAtlasUtils_1 = require("./atlas/CharAtlasUtils");
+var LinkRenderLayer = (function (_super) {
+    __extends(LinkRenderLayer, _super);
+    function LinkRenderLayer(container, zIndex, colors, terminal) {
+        var _this = _super.call(this, container, 'link', zIndex, true, colors) || this;
+        _this._state = null;
+        terminal.linkifier.onLinkHover(function (e) { return _this._onLinkHover(e); });
+        terminal.linkifier.onLinkLeave(function (e) { return _this._onLinkLeave(e); });
+        return _this;
+    }
+    LinkRenderLayer.prototype.resize = function (terminal, dim) {
+        _super.prototype.resize.call(this, terminal, dim);
+        this._state = null;
+    };
+    LinkRenderLayer.prototype.reset = function (terminal) {
+        this._clearCurrentLink();
+    };
+    LinkRenderLayer.prototype._clearCurrentLink = function () {
+        if (this._state) {
+            this.clearCells(this._state.x1, this._state.y1, this._state.cols - this._state.x1, 1);
+            var middleRowCount = this._state.y2 - this._state.y1 - 1;
+            if (middleRowCount > 0) {
+                this.clearCells(0, this._state.y1 + 1, this._state.cols, middleRowCount);
+            }
+            this.clearCells(0, this._state.y2, this._state.x2, 1);
+            this._state = null;
+        }
+    };
+    LinkRenderLayer.prototype._onLinkHover = function (e) {
+        if (e.fg === Types_1.INVERTED_DEFAULT_COLOR) {
+            this._ctx.fillStyle = this._colors.background.css;
+        }
+        else if (CharAtlasUtils_1.is256Color(e.fg)) {
+            this._ctx.fillStyle = this._colors.ansi[e.fg].css;
+        }
+        else {
+            this._ctx.fillStyle = this._colors.foreground.css;
+        }
+        if (e.y1 === e.y2) {
+            this.fillBottomLineAtCells(e.x1, e.y1, e.x2 - e.x1);
+        }
+        else {
+            this.fillBottomLineAtCells(e.x1, e.y1, e.cols - e.x1);
+            for (var y = e.y1 + 1; y < e.y2; y++) {
+                this.fillBottomLineAtCells(0, y, e.cols);
+            }
+            this.fillBottomLineAtCells(0, e.y2, e.x2);
+        }
+        this._state = e;
+    };
+    LinkRenderLayer.prototype._onLinkLeave = function (e) {
+        this._clearCurrentLink();
+    };
+    return LinkRenderLayer;
+}(BaseRenderLayer_1.BaseRenderLayer));
+exports.LinkRenderLayer = LinkRenderLayer;
+
+},{"./BaseRenderLayer":35,"./atlas/CharAtlasUtils":47,"./atlas/Types":52}],41:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = function (d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var TextRenderLayer_1 = require("./TextRenderLayer");
+var SelectionRenderLayer_1 = require("./SelectionRenderLayer");
+var CursorRenderLayer_1 = require("./CursorRenderLayer");
+var ColorManager_1 = require("./ColorManager");
+var LinkRenderLayer_1 = require("./LinkRenderLayer");
+var RenderDebouncer_1 = require("../ui/RenderDebouncer");
+var ScreenDprMonitor_1 = require("../ui/ScreenDprMonitor");
+var CharacterJoinerRegistry_1 = require("../renderer/CharacterJoinerRegistry");
+var EventEmitter2_1 = require("../common/EventEmitter2");
+var Lifecycle_1 = require("../common/Lifecycle");
+var Renderer = (function (_super) {
+    __extends(Renderer, _super);
+    function Renderer(_terminal, theme) {
+        var _this = _super.call(this) || this;
+        _this._terminal = _terminal;
+        _this._isPaused = false;
+        _this._needsFullRefresh = false;
+        _this._onCanvasResize = new EventEmitter2_1.EventEmitter2();
+        _this._onRender = new EventEmitter2_1.EventEmitter2();
+        var allowTransparency = _this._terminal.options.allowTransparency;
+        _this.colorManager = new ColorManager_1.ColorManager(document, allowTransparency);
+        _this._characterJoinerRegistry = new CharacterJoinerRegistry_1.CharacterJoinerRegistry(_terminal);
+        if (theme) {
+            _this.colorManager.setTheme(theme);
+        }
+        _this._renderLayers = [
+            new TextRenderLayer_1.TextRenderLayer(_this._terminal.screenElement, 0, _this.colorManager.colors, _this._characterJoinerRegistry, allowTransparency),
+            new SelectionRenderLayer_1.SelectionRenderLayer(_this._terminal.screenElement, 1, _this.colorManager.colors),
+            new LinkRenderLayer_1.LinkRenderLayer(_this._terminal.screenElement, 2, _this.colorManager.colors, _this._terminal),
+            new CursorRenderLayer_1.CursorRenderLayer(_this._terminal.screenElement, 3, _this.colorManager.colors)
+        ];
+        _this.dimensions = {
+            scaledCharWidth: null,
+            scaledCharHeight: null,
+            scaledCellWidth: null,
+            scaledCellHeight: null,
+            scaledCharLeft: null,
+            scaledCharTop: null,
+            scaledCanvasWidth: null,
+            scaledCanvasHeight: null,
+            canvasWidth: null,
+            canvasHeight: null,
+            actualCellWidth: null,
+            actualCellHeight: null
+        };
+        _this._devicePixelRatio = window.devicePixelRatio;
+        _this._updateDimensions();
+        _this.onOptionsChanged();
+        _this._renderDebouncer = new RenderDebouncer_1.RenderDebouncer(_this._renderRows.bind(_this));
+        _this._screenDprMonitor = new ScreenDprMonitor_1.ScreenDprMonitor();
+        _this._screenDprMonitor.setListener(function () { return _this.onWindowResize(window.devicePixelRatio); });
+        _this.register(_this._screenDprMonitor);
+        if ('IntersectionObserver' in window) {
+            var observer_1 = new IntersectionObserver(function (e) { return _this.onIntersectionChange(e[e.length - 1]); }, { threshold: 0 });
+            observer_1.observe(_this._terminal.element);
+            _this.register({ dispose: function () { return observer_1.disconnect(); } });
+        }
+        return _this;
+    }
+    Object.defineProperty(Renderer.prototype, "onCanvasResize", {
+        get: function () { return this._onCanvasResize.event; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Renderer.prototype, "onRender", {
+        get: function () { return this._onRender.event; },
+        enumerable: true,
+        configurable: true
+    });
+    Renderer.prototype.dispose = function () {
+        _super.prototype.dispose.call(this);
+        this._renderLayers.forEach(function (l) { return l.dispose(); });
+    };
+    Renderer.prototype.onIntersectionChange = function (entry) {
+        this._isPaused = entry.intersectionRatio === 0;
+        if (!this._isPaused && this._needsFullRefresh) {
+            this._terminal.refresh(0, this._terminal.rows - 1);
+            this._needsFullRefresh = false;
+        }
+    };
+    Renderer.prototype.onWindowResize = function (devicePixelRatio) {
+        if (this._devicePixelRatio !== devicePixelRatio) {
+            this._devicePixelRatio = devicePixelRatio;
+            this.onResize(this._terminal.cols, this._terminal.rows);
+        }
+    };
+    Renderer.prototype.setTheme = function (theme) {
+        var _this = this;
+        this.colorManager.setTheme(theme);
+        this._renderLayers.forEach(function (l) {
+            l.onThemeChanged(_this._terminal, _this.colorManager.colors);
+            l.reset(_this._terminal);
+        });
+        if (this._isPaused) {
+            this._needsFullRefresh = true;
+        }
+        else {
+            this._terminal.refresh(0, this._terminal.rows - 1);
+        }
+        return this.colorManager.colors;
+    };
+    Renderer.prototype.onResize = function (cols, rows) {
+        var _this = this;
+        this._updateDimensions();
+        this._renderLayers.forEach(function (l) { return l.resize(_this._terminal, _this.dimensions); });
+        if (this._isPaused) {
+            this._needsFullRefresh = true;
+        }
+        else {
+            this._terminal.refresh(0, this._terminal.rows - 1);
+        }
+        this._terminal.screenElement.style.width = this.dimensions.canvasWidth + "px";
+        this._terminal.screenElement.style.height = this.dimensions.canvasHeight + "px";
+        this._onCanvasResize.fire({
+            width: this.dimensions.canvasWidth,
+            height: this.dimensions.canvasHeight
+        });
+    };
+    Renderer.prototype.onCharSizeChanged = function () {
+        this.onResize(this._terminal.cols, this._terminal.rows);
+    };
+    Renderer.prototype.onBlur = function () {
+        var _this = this;
+        this._runOperation(function (l) { return l.onBlur(_this._terminal); });
+    };
+    Renderer.prototype.onFocus = function () {
+        var _this = this;
+        this._runOperation(function (l) { return l.onFocus(_this._terminal); });
+    };
+    Renderer.prototype.onSelectionChanged = function (start, end, columnSelectMode) {
+        var _this = this;
+        if (columnSelectMode === void 0) { columnSelectMode = false; }
+        this._runOperation(function (l) { return l.onSelectionChanged(_this._terminal, start, end, columnSelectMode); });
+    };
+    Renderer.prototype.onCursorMove = function () {
+        var _this = this;
+        this._runOperation(function (l) { return l.onCursorMove(_this._terminal); });
+    };
+    Renderer.prototype.onOptionsChanged = function () {
+        var _this = this;
+        this.colorManager.allowTransparency = this._terminal.options.allowTransparency;
+        this._runOperation(function (l) { return l.onOptionsChanged(_this._terminal); });
+    };
+    Renderer.prototype.clear = function () {
+        var _this = this;
+        this._runOperation(function (l) { return l.reset(_this._terminal); });
+    };
+    Renderer.prototype._runOperation = function (operation) {
+        if (this._isPaused) {
+            this._needsFullRefresh = true;
+        }
+        else {
+            this._renderLayers.forEach(function (l) { return operation(l); });
+        }
+    };
+    Renderer.prototype.refreshRows = function (start, end) {
+        if (this._isPaused) {
+            this._needsFullRefresh = true;
+            return;
+        }
+        this._renderDebouncer.refresh(start, end, this._terminal.rows);
+    };
+    Renderer.prototype._renderRows = function (start, end) {
+        var _this = this;
+        this._renderLayers.forEach(function (l) { return l.onGridChanged(_this._terminal, start, end); });
+        this._onRender.fire({ start: start, end: end });
+    };
+    Renderer.prototype._updateDimensions = function () {
+        if (!this._terminal.charMeasure.width || !this._terminal.charMeasure.height) {
+            return;
+        }
+        this.dimensions.scaledCharWidth = Math.floor(this._terminal.charMeasure.width * window.devicePixelRatio);
+        this.dimensions.scaledCharHeight = Math.ceil(this._terminal.charMeasure.height * window.devicePixelRatio);
+        this.dimensions.scaledCellHeight = Math.floor(this.dimensions.scaledCharHeight * this._terminal.options.lineHeight);
+        this.dimensions.scaledCharTop = this._terminal.options.lineHeight === 1 ? 0 : Math.round((this.dimensions.scaledCellHeight - this.dimensions.scaledCharHeight) / 2);
+        this.dimensions.scaledCellWidth = this.dimensions.scaledCharWidth + Math.round(this._terminal.options.letterSpacing);
+        this.dimensions.scaledCharLeft = Math.floor(this._terminal.options.letterSpacing / 2);
+        this.dimensions.scaledCanvasHeight = this._terminal.rows * this.dimensions.scaledCellHeight;
+        this.dimensions.scaledCanvasWidth = this._terminal.cols * this.dimensions.scaledCellWidth;
+        this.dimensions.canvasHeight = Math.round(this.dimensions.scaledCanvasHeight / window.devicePixelRatio);
+        this.dimensions.canvasWidth = Math.round(this.dimensions.scaledCanvasWidth / window.devicePixelRatio);
+        this.dimensions.actualCellHeight = this.dimensions.canvasHeight / this._terminal.rows;
+        this.dimensions.actualCellWidth = this.dimensions.canvasWidth / this._terminal.cols;
+    };
+    Renderer.prototype.registerCharacterJoiner = function (handler) {
+        return this._characterJoinerRegistry.registerCharacterJoiner(handler);
+    };
+    Renderer.prototype.deregisterCharacterJoiner = function (joinerId) {
+        return this._characterJoinerRegistry.deregisterCharacterJoiner(joinerId);
+    };
+    return Renderer;
+}(Lifecycle_1.Disposable));
+exports.Renderer = Renderer;
+
+},{"../common/EventEmitter2":25,"../common/Lifecycle":26,"../renderer/CharacterJoinerRegistry":36,"../ui/RenderDebouncer":56,"../ui/ScreenDprMonitor":57,"./ColorManager":37,"./CursorRenderLayer":38,"./LinkRenderLayer":40,"./SelectionRenderLayer":42,"./TextRenderLayer":43}],42:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = function (d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var BaseRenderLayer_1 = require("./BaseRenderLayer");
+var SelectionRenderLayer = (function (_super) {
+    __extends(SelectionRenderLayer, _super);
+    function SelectionRenderLayer(container, zIndex, colors) {
+        var _this = _super.call(this, container, 'selection', zIndex, true, colors) || this;
+        _this._clearState();
+        return _this;
+    }
+    SelectionRenderLayer.prototype._clearState = function () {
+        this._state = {
+            start: null,
+            end: null,
+            columnSelectMode: null,
+            ydisp: null
+        };
+    };
+    SelectionRenderLayer.prototype.resize = function (terminal, dim) {
+        _super.prototype.resize.call(this, terminal, dim);
+        this._clearState();
+    };
+    SelectionRenderLayer.prototype.reset = function (terminal) {
+        if (this._state.start && this._state.end) {
+            this._clearState();
+            this.clearAll();
+        }
+    };
+    SelectionRenderLayer.prototype.onSelectionChanged = function (terminal, start, end, columnSelectMode) {
+        if (!this._didStateChange(start, end, columnSelectMode, terminal.buffer.ydisp)) {
+            return;
+        }
+        this.clearAll();
+        if (!start || !end) {
+            this._clearState();
+            return;
+        }
+        var viewportStartRow = start[1] - terminal.buffer.ydisp;
+        var viewportEndRow = end[1] - terminal.buffer.ydisp;
+        var viewportCappedStartRow = Math.max(viewportStartRow, 0);
+        var viewportCappedEndRow = Math.min(viewportEndRow, terminal.rows - 1);
+        if (viewportCappedStartRow >= terminal.rows || viewportCappedEndRow < 0) {
+            return;
+        }
+        this._ctx.fillStyle = this._colors.selection.css;
+        if (columnSelectMode) {
+            var startCol = start[0];
+            var width = end[0] - startCol;
+            var height = viewportCappedEndRow - viewportCappedStartRow + 1;
+            this.fillCells(startCol, viewportCappedStartRow, width, height);
+        }
+        else {
+            var startCol = viewportStartRow === viewportCappedStartRow ? start[0] : 0;
+            var startRowEndCol = viewportCappedStartRow === viewportCappedEndRow ? end[0] : terminal.cols;
+            this.fillCells(startCol, viewportCappedStartRow, startRowEndCol - startCol, 1);
+            var middleRowsCount = Math.max(viewportCappedEndRow - viewportCappedStartRow - 1, 0);
+            this.fillCells(0, viewportCappedStartRow + 1, terminal.cols, middleRowsCount);
+            if (viewportCappedStartRow !== viewportCappedEndRow) {
+                var endCol = viewportEndRow === viewportCappedEndRow ? end[0] : terminal.cols;
+                this.fillCells(0, viewportCappedEndRow, endCol, 1);
+            }
+        }
+        this._state.start = [start[0], start[1]];
+        this._state.end = [end[0], end[1]];
+        this._state.columnSelectMode = columnSelectMode;
+        this._state.ydisp = terminal.buffer.ydisp;
+    };
+    SelectionRenderLayer.prototype._didStateChange = function (start, end, columnSelectMode, ydisp) {
+        return !this._areCoordinatesEqual(start, this._state.start) ||
+            !this._areCoordinatesEqual(end, this._state.end) ||
+            columnSelectMode !== this._state.columnSelectMode ||
+            ydisp !== this._state.ydisp;
+    };
+    SelectionRenderLayer.prototype._areCoordinatesEqual = function (coord1, coord2) {
+        if (!coord1 || !coord2) {
+            return false;
+        }
+        return coord1[0] === coord2[0] && coord1[1] === coord2[1];
+    };
+    return SelectionRenderLayer;
+}(BaseRenderLayer_1.BaseRenderLayer));
+exports.SelectionRenderLayer = SelectionRenderLayer;
+
+},{"./BaseRenderLayer":35}],43:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = function (d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var Buffer_1 = require("../Buffer");
+var GridCache_1 = require("./GridCache");
+var BaseRenderLayer_1 = require("./BaseRenderLayer");
+var BufferLine_1 = require("../BufferLine");
+var CharacterJoinerRegistry_1 = require("./CharacterJoinerRegistry");
+var TextRenderLayer = (function (_super) {
+    __extends(TextRenderLayer, _super);
+    function TextRenderLayer(container, zIndex, colors, characterJoinerRegistry, alpha) {
+        var _this = _super.call(this, container, 'text', zIndex, alpha, colors) || this;
+        _this._characterOverlapCache = {};
+        _this._workCell = new BufferLine_1.CellData();
+        _this._state = new GridCache_1.GridCache();
+        _this._characterJoinerRegistry = characterJoinerRegistry;
+        return _this;
+    }
+    TextRenderLayer.prototype.resize = function (terminal, dim) {
+        _super.prototype.resize.call(this, terminal, dim);
+        var terminalFont = this._getFont(terminal, false, false);
+        if (this._characterWidth !== dim.scaledCharWidth || this._characterFont !== terminalFont) {
+            this._characterWidth = dim.scaledCharWidth;
+            this._characterFont = terminalFont;
+            this._characterOverlapCache = {};
+        }
+        this._state.clear();
+        this._state.resize(terminal.cols, terminal.rows);
+    };
+    TextRenderLayer.prototype.reset = function (terminal) {
+        this._state.clear();
+        this.clearAll();
+    };
+    TextRenderLayer.prototype._forEachCell = function (terminal, firstRow, lastRow, joinerRegistry, callback) {
+        for (var y = firstRow; y <= lastRow; y++) {
+            var row = y + terminal.buffer.ydisp;
+            var line = terminal.buffer.lines.get(row);
+            var joinedRanges = joinerRegistry ? joinerRegistry.getJoinedCharacters(row) : [];
+            for (var x = 0; x < terminal.cols; x++) {
+                line.loadCell(x, this._workCell);
+                var cell = this._workCell;
+                var isJoined = false;
+                var lastCharX = x;
+                if (cell.getWidth() === 0) {
+                    continue;
+                }
+                if (joinedRanges.length > 0 && x === joinedRanges[0][0]) {
+                    isJoined = true;
+                    var range = joinedRanges.shift();
+                    cell = new CharacterJoinerRegistry_1.JoinedCellData(this._workCell, line.translateToString(true, range[0], range[1]), range[1] - range[0]);
+                    lastCharX = range[1] - 1;
+                }
+                if (!isJoined && this._isOverlapping(cell)) {
+                    if (lastCharX < line.length - 1 && line.getCodePoint(lastCharX + 1) === Buffer_1.NULL_CELL_CODE) {
+                        cell.content &= ~12582912;
+                        cell.content |= 2 << 22;
+                    }
+                }
+                callback(cell, x, y);
+                x = lastCharX;
+            }
+        }
+    };
+    TextRenderLayer.prototype._drawBackground = function (terminal, firstRow, lastRow) {
+        var _this = this;
+        var ctx = this._ctx;
+        var cols = terminal.cols;
+        var startX = 0;
+        var startY = 0;
+        var prevFillStyle = null;
+        ctx.save();
+        this._forEachCell(terminal, firstRow, lastRow, null, function (cell, x, y) {
+            var nextFillStyle = null;
+            if (cell.isInverse()) {
+                if (cell.isFgDefault()) {
+                    nextFillStyle = _this._colors.foreground.css;
+                }
+                else if (cell.isFgRGB()) {
+                    nextFillStyle = "rgb(" + BufferLine_1.AttributeData.toColorRGB(cell.getFgColor()).join(',') + ")";
+                }
+                else {
+                    nextFillStyle = _this._colors.ansi[cell.getFgColor()].css;
+                }
+            }
+            else if (cell.isBgRGB()) {
+                nextFillStyle = "rgb(" + BufferLine_1.AttributeData.toColorRGB(cell.getBgColor()).join(',') + ")";
+            }
+            else if (cell.isBgPalette()) {
+                nextFillStyle = _this._colors.ansi[cell.getBgColor()].css;
+            }
+            if (prevFillStyle === null) {
+                startX = x;
+                startY = y;
+            }
+            if (y !== startY) {
+                ctx.fillStyle = prevFillStyle;
+                _this.fillCells(startX, startY, cols - startX, 1);
+                startX = x;
+                startY = y;
+            }
+            else if (prevFillStyle !== nextFillStyle) {
+                ctx.fillStyle = prevFillStyle;
+                _this.fillCells(startX, startY, x - startX, 1);
+                startX = x;
+                startY = y;
+            }
+            prevFillStyle = nextFillStyle;
+        });
+        if (prevFillStyle !== null) {
+            ctx.fillStyle = prevFillStyle;
+            this.fillCells(startX, startY, cols - startX, 1);
+        }
+        ctx.restore();
+    };
+    TextRenderLayer.prototype._drawForeground = function (terminal, firstRow, lastRow) {
+        var _this = this;
+        this._forEachCell(terminal, firstRow, lastRow, this._characterJoinerRegistry, function (cell, x, y) {
+            if (cell.isInvisible()) {
+                return;
+            }
+            if (cell.isUnderline()) {
+                _this._ctx.save();
+                if (cell.isInverse()) {
+                    if (cell.isBgDefault()) {
+                        _this._ctx.fillStyle = _this._colors.background.css;
+                    }
+                    else if (cell.isBgRGB()) {
+                        _this._ctx.fillStyle = "rgb(" + BufferLine_1.AttributeData.toColorRGB(cell.getBgColor()).join(',') + ")";
+                    }
+                    else {
+                        _this._ctx.fillStyle = _this._colors.ansi[cell.getBgColor()].css;
+                    }
+                }
+                else {
+                    if (cell.isFgDefault()) {
+                        _this._ctx.fillStyle = _this._colors.foreground.css;
+                    }
+                    else if (cell.isFgRGB()) {
+                        _this._ctx.fillStyle = "rgb(" + BufferLine_1.AttributeData.toColorRGB(cell.getFgColor()).join(',') + ")";
+                    }
+                    else {
+                        var fg = cell.getFgColor();
+                        if (terminal.options.drawBoldTextInBrightColors && cell.isBold() && fg < 8) {
+                            fg += 8;
+                        }
+                        _this._ctx.fillStyle = _this._colors.ansi[fg].css;
+                    }
+                }
+                _this.fillBottomLineAtCells(x, y, cell.getWidth());
+                _this._ctx.restore();
+            }
+            _this.drawChars(terminal, cell, x, y);
+        });
+    };
+    TextRenderLayer.prototype.onGridChanged = function (terminal, firstRow, lastRow) {
+        if (this._state.cache.length === 0) {
+            return;
+        }
+        if (this._charAtlas) {
+            this._charAtlas.beginFrame();
+        }
+        this.clearCells(0, firstRow, terminal.cols, lastRow - firstRow + 1);
+        this._drawBackground(terminal, firstRow, lastRow);
+        this._drawForeground(terminal, firstRow, lastRow);
+    };
+    TextRenderLayer.prototype.onOptionsChanged = function (terminal) {
+        this.setTransparency(terminal, terminal.options.allowTransparency);
+    };
+    TextRenderLayer.prototype._isOverlapping = function (cell) {
+        if (cell.getWidth() !== 1) {
+            return false;
+        }
+        if (cell.getCode() < 256) {
+            return false;
+        }
+        var chars = cell.getChars();
+        if (this._characterOverlapCache.hasOwnProperty(chars)) {
+            return this._characterOverlapCache[chars];
+        }
+        this._ctx.save();
+        this._ctx.font = this._characterFont;
+        var overlaps = Math.floor(this._ctx.measureText(chars).width) > this._characterWidth;
+        this._ctx.restore();
+        this._characterOverlapCache[chars] = overlaps;
+        return overlaps;
+    };
+    return TextRenderLayer;
+}(BaseRenderLayer_1.BaseRenderLayer));
+exports.TextRenderLayer = TextRenderLayer;
+
+},{"../Buffer":2,"../BufferLine":3,"./BaseRenderLayer":35,"./CharacterJoinerRegistry":36,"./GridCache":39}],44:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var BaseCharAtlas = (function () {
+    function BaseCharAtlas() {
+        this._didWarmUp = false;
+    }
+    BaseCharAtlas.prototype.dispose = function () { };
+    BaseCharAtlas.prototype.warmUp = function () {
+        if (!this._didWarmUp) {
+            this._doWarmUp();
+            this._didWarmUp = true;
+        }
+    };
+    BaseCharAtlas.prototype._doWarmUp = function () { };
+    BaseCharAtlas.prototype.beginFrame = function () { };
+    return BaseCharAtlas;
+}());
+exports.default = BaseCharAtlas;
+
+},{}],45:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var CharAtlasUtils_1 = require("./CharAtlasUtils");
+var DynamicCharAtlas_1 = require("./DynamicCharAtlas");
+var NoneCharAtlas_1 = require("./NoneCharAtlas");
+var StaticCharAtlas_1 = require("./StaticCharAtlas");
+var charAtlasImplementations = {
+    'none': NoneCharAtlas_1.default,
+    'static': StaticCharAtlas_1.default,
+    'dynamic': DynamicCharAtlas_1.default
+};
+var charAtlasCache = [];
+function acquireCharAtlas(terminal, colors, scaledCharWidth, scaledCharHeight) {
+    var newConfig = CharAtlasUtils_1.generateConfig(scaledCharWidth, scaledCharHeight, terminal, colors);
+    for (var i = 0; i < charAtlasCache.length; i++) {
+        var entry = charAtlasCache[i];
+        var ownedByIndex = entry.ownedBy.indexOf(terminal);
+        if (ownedByIndex >= 0) {
+            if (CharAtlasUtils_1.configEquals(entry.config, newConfig)) {
+                return entry.atlas;
+            }
+            if (entry.ownedBy.length === 1) {
+                entry.atlas.dispose();
+                charAtlasCache.splice(i, 1);
+            }
+            else {
+                entry.ownedBy.splice(ownedByIndex, 1);
+            }
+            break;
+        }
+    }
+    for (var i = 0; i < charAtlasCache.length; i++) {
+        var entry = charAtlasCache[i];
+        if (CharAtlasUtils_1.configEquals(entry.config, newConfig)) {
+            entry.ownedBy.push(terminal);
+            return entry.atlas;
+        }
+    }
+    var newEntry = {
+        atlas: new charAtlasImplementations[terminal.options.experimentalCharAtlas](document, newConfig),
+        config: newConfig,
+        ownedBy: [terminal]
+    };
+    charAtlasCache.push(newEntry);
+    return newEntry.atlas;
+}
+exports.acquireCharAtlas = acquireCharAtlas;
+function removeTerminalFromCache(terminal) {
+    for (var i = 0; i < charAtlasCache.length; i++) {
+        var index = charAtlasCache[i].ownedBy.indexOf(terminal);
+        if (index !== -1) {
+            if (charAtlasCache[i].ownedBy.length === 1) {
+                charAtlasCache[i].atlas.dispose();
+                charAtlasCache.splice(i, 1);
+            }
+            else {
+                charAtlasCache[i].ownedBy.splice(index, 1);
+            }
+            break;
+        }
+    }
+}
+exports.removeTerminalFromCache = removeTerminalFromCache;
+
+},{"./CharAtlasUtils":47,"./DynamicCharAtlas":48,"./NoneCharAtlas":50,"./StaticCharAtlas":51}],46:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var Platform_1 = require("../../common/Platform");
+var Types_1 = require("./Types");
+function generateStaticCharAtlasTexture(context, canvasFactory, config) {
+    var cellWidth = config.scaledCharWidth + Types_1.CHAR_ATLAS_CELL_SPACING;
+    var cellHeight = config.scaledCharHeight + Types_1.CHAR_ATLAS_CELL_SPACING;
+    var canvas = canvasFactory(255 * cellWidth, (2 + 16 + 16) * cellHeight);
+    var ctx = canvas.getContext('2d', { alpha: config.allowTransparency });
+    ctx.fillStyle = config.colors.background.css;
+    ctx.fillRect(0, 0, canvas.width, canvas.height);
+    ctx.save();
+    ctx.fillStyle = config.colors.foreground.css;
+    ctx.font = getFont(config.fontWeight, config);
+    ctx.textBaseline = 'middle';
+    for (var i = 0; i < 256; i++) {
+        ctx.save();
+        ctx.beginPath();
+        ctx.rect(i * cellWidth, 0, cellWidth, cellHeight);
+        ctx.clip();
+        ctx.fillText(String.fromCharCode(i), i * cellWidth, cellHeight / 2);
+        ctx.restore();
+    }
+    ctx.save();
+    ctx.font = getFont(config.fontWeightBold, config);
+    for (var i = 0; i < 256; i++) {
+        ctx.save();
+        ctx.beginPath();
+        ctx.rect(i * cellWidth, cellHeight, cellWidth, cellHeight);
+        ctx.clip();
+        ctx.fillText(String.fromCharCode(i), i * cellWidth, cellHeight * 1.5);
+        ctx.restore();
+    }
+    ctx.restore();
+    ctx.font = getFont(config.fontWeight, config);
+    for (var colorIndex = 0; colorIndex < 16; colorIndex++) {
+        var y = (colorIndex + 2) * cellHeight;
+        for (var i = 0; i < 256; i++) {
+            ctx.save();
+            ctx.beginPath();
+            ctx.rect(i * cellWidth, y, cellWidth, cellHeight);
+            ctx.clip();
+            ctx.fillStyle = config.colors.ansi[colorIndex].css;
+            ctx.fillText(String.fromCharCode(i), i * cellWidth, y + cellHeight / 2);
+            ctx.restore();
+        }
+    }
+    ctx.font = getFont(config.fontWeightBold, config);
+    for (var colorIndex = 0; colorIndex < 16; colorIndex++) {
+        var y = (colorIndex + 2 + 16) * cellHeight;
+        for (var i = 0; i < 256; i++) {
+            ctx.save();
+            ctx.beginPath();
+            ctx.rect(i * cellWidth, y, cellWidth, cellHeight);
+            ctx.clip();
+            ctx.fillStyle = config.colors.ansi[colorIndex].css;
+            ctx.fillText(String.fromCharCode(i), i * cellWidth, y + cellHeight / 2);
+            ctx.restore();
+        }
+    }
+    ctx.restore();
+    if (!('createImageBitmap' in context) || Platform_1.isFirefox || Platform_1.isSafari) {
+        return canvas;
+    }
+    var charAtlasImageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
+    clearColor(charAtlasImageData, config.colors.background);
+    return context.createImageBitmap(charAtlasImageData);
+}
+exports.generateStaticCharAtlasTexture = generateStaticCharAtlasTexture;
+function clearColor(imageData, color) {
+    var isEmpty = true;
+    var r = color.rgba >>> 24;
+    var g = color.rgba >>> 16 & 0xFF;
+    var b = color.rgba >>> 8 & 0xFF;
+    for (var offset = 0; offset < imageData.data.length; offset += 4) {
+        if (imageData.data[offset] === r &&
+            imageData.data[offset + 1] === g &&
+            imageData.data[offset + 2] === b) {
+            imageData.data[offset + 3] = 0;
+        }
+        else {
+            isEmpty = false;
+        }
+    }
+    return isEmpty;
+}
+exports.clearColor = clearColor;
+function getFont(fontWeight, config) {
+    return fontWeight + " " + config.fontSize * config.devicePixelRatio + "px " + config.fontFamily;
+}
+
+},{"../../common/Platform":27,"./Types":52}],47:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var Types_1 = require("./Types");
+function generateConfig(scaledCharWidth, scaledCharHeight, terminal, colors) {
+    var clonedColors = {
+        foreground: colors.foreground,
+        background: colors.background,
+        cursor: null,
+        cursorAccent: null,
+        selection: null,
+        ansi: colors.ansi.slice(0, 16)
+    };
+    return {
+        type: terminal.options.experimentalCharAtlas,
+        devicePixelRatio: window.devicePixelRatio,
+        scaledCharWidth: scaledCharWidth,
+        scaledCharHeight: scaledCharHeight,
+        fontFamily: terminal.options.fontFamily,
+        fontSize: terminal.options.fontSize,
+        fontWeight: terminal.options.fontWeight,
+        fontWeightBold: terminal.options.fontWeightBold,
+        allowTransparency: terminal.options.allowTransparency,
+        colors: clonedColors
+    };
+}
+exports.generateConfig = generateConfig;
+function configEquals(a, b) {
+    for (var i = 0; i < a.colors.ansi.length; i++) {
+        if (a.colors.ansi[i].rgba !== b.colors.ansi[i].rgba) {
+            return false;
+        }
+    }
+    return a.type === b.type &&
+        a.devicePixelRatio === b.devicePixelRatio &&
+        a.fontFamily === b.fontFamily &&
+        a.fontSize === b.fontSize &&
+        a.fontWeight === b.fontWeight &&
+        a.fontWeightBold === b.fontWeightBold &&
+        a.allowTransparency === b.allowTransparency &&
+        a.scaledCharWidth === b.scaledCharWidth &&
+        a.scaledCharHeight === b.scaledCharHeight &&
+        a.colors.foreground === b.colors.foreground &&
+        a.colors.background === b.colors.background;
+}
+exports.configEquals = configEquals;
+function is256Color(colorCode) {
+    return colorCode < Types_1.DEFAULT_COLOR;
+}
+exports.is256Color = is256Color;
+
+},{"./Types":52}],48:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = function (d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var Types_1 = require("./Types");
+var BaseCharAtlas_1 = require("./BaseCharAtlas");
+var ColorManager_1 = require("../ColorManager");
+var CharAtlasGenerator_1 = require("./CharAtlasGenerator");
+var LRUMap_1 = require("./LRUMap");
+var Platform_1 = require("../../common/Platform");
+var TEXTURE_WIDTH = 1024;
+var TEXTURE_HEIGHT = 1024;
+var TRANSPARENT_COLOR = {
+    css: 'rgba(0, 0, 0, 0)',
+    rgba: 0
+};
+var FRAME_CACHE_DRAW_LIMIT = 100;
+var GLYPH_BITMAP_COMMIT_DELAY = 100;
+function getGlyphCacheKey(glyph) {
+    return glyph.code << 21 | glyph.bg << 12 | glyph.fg << 3 | (glyph.bold ? 0 : 4) + (glyph.dim ? 0 : 2) + (glyph.italic ? 0 : 1);
+}
+exports.getGlyphCacheKey = getGlyphCacheKey;
+var DynamicCharAtlas = (function (_super) {
+    __extends(DynamicCharAtlas, _super);
+    function DynamicCharAtlas(document, _config) {
+        var _this = _super.call(this) || this;
+        _this._config = _config;
+        _this._drawToCacheCount = 0;
+        _this._glyphsWaitingOnBitmap = [];
+        _this._bitmapCommitTimeout = null;
+        _this._bitmap = null;
+        _this._cacheCanvas = document.createElement('canvas');
+        _this._cacheCanvas.width = TEXTURE_WIDTH;
+        _this._cacheCanvas.height = TEXTURE_HEIGHT;
+        _this._cacheCtx = _this._cacheCanvas.getContext('2d', { alpha: true });
+        var tmpCanvas = document.createElement('canvas');
+        tmpCanvas.width = _this._config.scaledCharWidth;
+        tmpCanvas.height = _this._config.scaledCharHeight;
+        _this._tmpCtx = tmpCanvas.getContext('2d', { alpha: _this._config.allowTransparency });
+        _this._width = Math.floor(TEXTURE_WIDTH / _this._config.scaledCharWidth);
+        _this._height = Math.floor(TEXTURE_HEIGHT / _this._config.scaledCharHeight);
+        var capacity = _this._width * _this._height;
+        _this._cacheMap = new LRUMap_1.default(capacity);
+        _this._cacheMap.prealloc(capacity);
+        return _this;
+    }
+    DynamicCharAtlas.prototype.dispose = function () {
+        if (this._bitmapCommitTimeout !== null) {
+            window.clearTimeout(this._bitmapCommitTimeout);
+            this._bitmapCommitTimeout = null;
+        }
+    };
+    DynamicCharAtlas.prototype.beginFrame = function () {
+        this._drawToCacheCount = 0;
+    };
+    DynamicCharAtlas.prototype.draw = function (ctx, glyph, x, y) {
+        if (glyph.code === 32) {
+            return true;
+        }
+        if (!this._canCache(glyph)) {
+            return false;
+        }
+        var glyphKey = getGlyphCacheKey(glyph);
+        var cacheValue = this._cacheMap.get(glyphKey);
+        if (cacheValue !== null && cacheValue !== undefined) {
+            this._drawFromCache(ctx, cacheValue, x, y);
+            return true;
+        }
+        else if (this._drawToCacheCount < FRAME_CACHE_DRAW_LIMIT) {
+            var index = void 0;
+            if (this._cacheMap.size < this._cacheMap.capacity) {
+                index = this._cacheMap.size;
+            }
+            else {
+                index = this._cacheMap.peek().index;
+            }
+            var cacheValue_1 = this._drawToCache(glyph, index);
+            this._cacheMap.set(glyphKey, cacheValue_1);
+            this._drawFromCache(ctx, cacheValue_1, x, y);
+            return true;
+        }
+        return false;
+    };
+    DynamicCharAtlas.prototype._canCache = function (glyph) {
+        return glyph.code < 256;
+    };
+    DynamicCharAtlas.prototype._toCoordinateX = function (index) {
+        return (index % this._width) * this._config.scaledCharWidth;
+    };
+    DynamicCharAtlas.prototype._toCoordinateY = function (index) {
+        return Math.floor(index / this._width) * this._config.scaledCharHeight;
+    };
+    DynamicCharAtlas.prototype._drawFromCache = function (ctx, cacheValue, x, y) {
+        if (cacheValue.isEmpty) {
+            return;
+        }
+        var cacheX = this._toCoordinateX(cacheValue.index);
+        var cacheY = this._toCoordinateY(cacheValue.index);
+        ctx.drawImage(cacheValue.inBitmap ? this._bitmap : this._cacheCanvas, cacheX, cacheY, this._config.scaledCharWidth, this._config.scaledCharHeight, x, y, this._config.scaledCharWidth, this._config.scaledCharHeight);
+    };
+    DynamicCharAtlas.prototype._getColorFromAnsiIndex = function (idx) {
+        if (idx < this._config.colors.ansi.length) {
+            return this._config.colors.ansi[idx];
+        }
+        return ColorManager_1.DEFAULT_ANSI_COLORS[idx];
+    };
+    DynamicCharAtlas.prototype._getBackgroundColor = function (glyph) {
+        if (this._config.allowTransparency) {
+            return TRANSPARENT_COLOR;
+        }
+        else if (glyph.bg === Types_1.INVERTED_DEFAULT_COLOR) {
+            return this._config.colors.foreground;
+        }
+        else if (glyph.bg < 256) {
+            return this._getColorFromAnsiIndex(glyph.bg);
+        }
+        return this._config.colors.background;
+    };
+    DynamicCharAtlas.prototype._getForegroundColor = function (glyph) {
+        if (glyph.fg === Types_1.INVERTED_DEFAULT_COLOR) {
+            return this._config.colors.background;
+        }
+        else if (glyph.fg < 256) {
+            return this._getColorFromAnsiIndex(glyph.fg);
+        }
+        return this._config.colors.foreground;
+    };
+    DynamicCharAtlas.prototype._drawToCache = function (glyph, index) {
+        this._drawToCacheCount++;
+        this._tmpCtx.save();
+        var backgroundColor = this._getBackgroundColor(glyph);
+        this._tmpCtx.globalCompositeOperation = 'copy';
+        this._tmpCtx.fillStyle = backgroundColor.css;
+        this._tmpCtx.fillRect(0, 0, this._config.scaledCharWidth, this._config.scaledCharHeight);
+        this._tmpCtx.globalCompositeOperation = 'source-over';
+        var fontWeight = glyph.bold ? this._config.fontWeightBold : this._config.fontWeight;
+        var fontStyle = glyph.italic ? 'italic' : '';
+        this._tmpCtx.font =
+            fontStyle + " " + fontWeight + " " + this._config.fontSize * this._config.devicePixelRatio + "px " + this._config.fontFamily;
+        this._tmpCtx.textBaseline = 'middle';
+        this._tmpCtx.fillStyle = this._getForegroundColor(glyph).css;
+        if (glyph.dim) {
+            this._tmpCtx.globalAlpha = Types_1.DIM_OPACITY;
+        }
+        this._tmpCtx.fillText(glyph.chars, 0, this._config.scaledCharHeight / 2);
+        this._tmpCtx.restore();
+        var imageData = this._tmpCtx.getImageData(0, 0, this._config.scaledCharWidth, this._config.scaledCharHeight);
+        var isEmpty = false;
+        if (!this._config.allowTransparency) {
+            isEmpty = CharAtlasGenerator_1.clearColor(imageData, backgroundColor);
+        }
+        var x = this._toCoordinateX(index);
+        var y = this._toCoordinateY(index);
+        this._cacheCtx.putImageData(imageData, x, y);
+        var cacheValue = {
+            index: index,
+            isEmpty: isEmpty,
+            inBitmap: false
+        };
+        this._addGlyphToBitmap(cacheValue);
+        return cacheValue;
+    };
+    DynamicCharAtlas.prototype._addGlyphToBitmap = function (cacheValue) {
+        var _this = this;
+        if (!('createImageBitmap' in window) || Platform_1.isFirefox || Platform_1.isSafari) {
+            return;
+        }
+        this._glyphsWaitingOnBitmap.push(cacheValue);
+        if (this._bitmapCommitTimeout !== null) {
+            return;
+        }
+        this._bitmapCommitTimeout = window.setTimeout(function () { return _this._generateBitmap(); }, GLYPH_BITMAP_COMMIT_DELAY);
+    };
+    DynamicCharAtlas.prototype._generateBitmap = function () {
+        var _this = this;
+        var glyphsMovingToBitmap = this._glyphsWaitingOnBitmap;
+        this._glyphsWaitingOnBitmap = [];
+        window.createImageBitmap(this._cacheCanvas).then(function (bitmap) {
+            _this._bitmap = bitmap;
+            for (var i = 0; i < glyphsMovingToBitmap.length; i++) {
+                var value = glyphsMovingToBitmap[i];
+                value.inBitmap = true;
+            }
+        });
+        this._bitmapCommitTimeout = null;
+    };
+    return DynamicCharAtlas;
+}(BaseCharAtlas_1.default));
+exports.default = DynamicCharAtlas;
+
+},{"../../common/Platform":27,"../ColorManager":37,"./BaseCharAtlas":44,"./CharAtlasGenerator":46,"./LRUMap":49,"./Types":52}],49:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var LRUMap = (function () {
+    function LRUMap(capacity) {
+        this.capacity = capacity;
+        this._map = {};
+        this._head = null;
+        this._tail = null;
+        this._nodePool = [];
+        this.size = 0;
+    }
+    LRUMap.prototype._unlinkNode = function (node) {
+        var prev = node.prev;
+        var next = node.next;
+        if (node === this._head) {
+            this._head = next;
+        }
+        if (node === this._tail) {
+            this._tail = prev;
+        }
+        if (prev !== null) {
+            prev.next = next;
+        }
+        if (next !== null) {
+            next.prev = prev;
+        }
+    };
+    LRUMap.prototype._appendNode = function (node) {
+        var tail = this._tail;
+        if (tail !== null) {
+            tail.next = node;
+        }
+        node.prev = tail;
+        node.next = null;
+        this._tail = node;
+        if (this._head === null) {
+            this._head = node;
+        }
+    };
+    LRUMap.prototype.prealloc = function (count) {
+        var nodePool = this._nodePool;
+        for (var i = 0; i < count; i++) {
+            nodePool.push({
+                prev: null,
+                next: null,
+                key: null,
+                value: null
+            });
+        }
+    };
+    LRUMap.prototype.get = function (key) {
+        var node = this._map[key];
+        if (node !== undefined) {
+            this._unlinkNode(node);
+            this._appendNode(node);
+            return node.value;
+        }
+        return null;
+    };
+    LRUMap.prototype.peekValue = function (key) {
+        var node = this._map[key];
+        if (node !== undefined) {
+            return node.value;
+        }
+        return null;
+    };
+    LRUMap.prototype.peek = function () {
+        var head = this._head;
+        return head === null ? null : head.value;
+    };
+    LRUMap.prototype.set = function (key, value) {
+        var node = this._map[key];
+        if (node !== undefined) {
+            node = this._map[key];
+            this._unlinkNode(node);
+            node.value = value;
+        }
+        else if (this.size >= this.capacity) {
+            node = this._head;
+            this._unlinkNode(node);
+            delete this._map[node.key];
+            node.key = key;
+            node.value = value;
+            this._map[key] = node;
+        }
+        else {
+            var nodePool = this._nodePool;
+            if (nodePool.length > 0) {
+                node = nodePool.pop();
+                node.key = key;
+                node.value = value;
+            }
+            else {
+                node = {
+                    prev: null,
+                    next: null,
+                    key: key,
+                    value: value
+                };
+            }
+            this._map[key] = node;
+            this.size++;
+        }
+        this._appendNode(node);
+    };
+    return LRUMap;
+}());
+exports.default = LRUMap;
+
+},{}],50:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = function (d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var BaseCharAtlas_1 = require("./BaseCharAtlas");
+var NoneCharAtlas = (function (_super) {
+    __extends(NoneCharAtlas, _super);
+    function NoneCharAtlas(document, config) {
+        return _super.call(this) || this;
+    }
+    NoneCharAtlas.prototype.draw = function (ctx, glyph, x, y) {
+        return false;
+    };
+    return NoneCharAtlas;
+}(BaseCharAtlas_1.default));
+exports.default = NoneCharAtlas;
+
+},{"./BaseCharAtlas":44}],51:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = function (d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var Types_1 = require("./Types");
+var CharAtlasGenerator_1 = require("./CharAtlasGenerator");
+var BaseCharAtlas_1 = require("./BaseCharAtlas");
+var CharAtlasUtils_1 = require("./CharAtlasUtils");
+var StaticCharAtlas = (function (_super) {
+    __extends(StaticCharAtlas, _super);
+    function StaticCharAtlas(_document, _config) {
+        var _this = _super.call(this) || this;
+        _this._document = _document;
+        _this._config = _config;
+        _this._canvasFactory = function (width, height) {
+            var canvas = _this._document.createElement('canvas');
+            canvas.width = width;
+            canvas.height = height;
+            return canvas;
+        };
+        return _this;
+    }
+    StaticCharAtlas.prototype._doWarmUp = function () {
+        var _this = this;
+        var result = CharAtlasGenerator_1.generateStaticCharAtlasTexture(window, this._canvasFactory, this._config);
+        if (result instanceof HTMLCanvasElement) {
+            this._texture = result;
+        }
+        else {
+            result.then(function (texture) {
+                _this._texture = texture;
+            });
+        }
+    };
+    StaticCharAtlas.prototype._isCached = function (glyph, colorIndex) {
+        var isAscii = glyph.code < 256;
+        var isBasicColor = glyph.fg < 16;
+        var isDefaultColor = glyph.fg === Types_1.DEFAULT_COLOR;
+        var isDefaultBackground = glyph.bg === Types_1.DEFAULT_COLOR;
+        return isAscii && (isBasicColor || isDefaultColor) && isDefaultBackground && !glyph.italic;
+    };
+    StaticCharAtlas.prototype.draw = function (ctx, glyph, x, y) {
+        if (this._texture === null || this._texture === undefined) {
+            return false;
+        }
+        var colorIndex = 0;
+        if (CharAtlasUtils_1.is256Color(glyph.fg)) {
+            colorIndex = 2 + glyph.fg + (glyph.bold ? 16 : 0);
+        }
+        else if (glyph.fg === Types_1.DEFAULT_COLOR) {
+            if (glyph.bold) {
+                colorIndex = 1;
+            }
+        }
+        if (!this._isCached(glyph, colorIndex)) {
+            return false;
+        }
+        ctx.save();
+        var charAtlasCellWidth = this._config.scaledCharWidth + Types_1.CHAR_ATLAS_CELL_SPACING;
+        var charAtlasCellHeight = this._config.scaledCharHeight + Types_1.CHAR_ATLAS_CELL_SPACING;
+        if (glyph.dim) {
+            ctx.globalAlpha = Types_1.DIM_OPACITY;
+        }
+        ctx.drawImage(this._texture, glyph.code * charAtlasCellWidth, colorIndex * charAtlasCellHeight, charAtlasCellWidth, this._config.scaledCharHeight, x, y, charAtlasCellWidth, this._config.scaledCharHeight);
+        ctx.restore();
+        return true;
+    };
+    return StaticCharAtlas;
+}(BaseCharAtlas_1.default));
+exports.default = StaticCharAtlas;
+
+},{"./BaseCharAtlas":44,"./CharAtlasGenerator":46,"./CharAtlasUtils":47,"./Types":52}],52:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.DEFAULT_COLOR = 256;
+exports.INVERTED_DEFAULT_COLOR = 257;
+exports.DIM_OPACITY = 0.5;
+exports.CHAR_ATLAS_CELL_SPACING = 1;
+
+},{}],53:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = function (d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var ColorManager_1 = require("../ColorManager");
+var RenderDebouncer_1 = require("../../ui/RenderDebouncer");
+var DomRendererRowFactory_1 = require("./DomRendererRowFactory");
+var Types_1 = require("../atlas/Types");
+var EventEmitter2_1 = require("../../common/EventEmitter2");
+var Lifecycle_1 = require("../../common/Lifecycle");
+var TERMINAL_CLASS_PREFIX = 'xterm-dom-renderer-owner-';
+var ROW_CONTAINER_CLASS = 'xterm-rows';
+var FG_CLASS_PREFIX = 'xterm-fg-';
+var BG_CLASS_PREFIX = 'xterm-bg-';
+var FOCUS_CLASS = 'xterm-focus';
+var SELECTION_CLASS = 'xterm-selection';
+var nextTerminalId = 1;
+var DomRenderer = (function (_super) {
+    __extends(DomRenderer, _super);
+    function DomRenderer(_terminal, theme) {
+        var _this = _super.call(this) || this;
+        _this._terminal = _terminal;
+        _this._terminalClass = nextTerminalId++;
+        _this._rowElements = [];
+        _this._onCanvasResize = new EventEmitter2_1.EventEmitter2();
+        _this._onRender = new EventEmitter2_1.EventEmitter2();
+        var allowTransparency = _this._terminal.options.allowTransparency;
+        _this.colorManager = new ColorManager_1.ColorManager(document, allowTransparency);
+        _this.setTheme(theme);
+        _this._rowContainer = document.createElement('div');
+        _this._rowContainer.classList.add(ROW_CONTAINER_CLASS);
+        _this._rowContainer.style.lineHeight = 'normal';
+        _this._rowContainer.setAttribute('aria-hidden', 'true');
+        _this._refreshRowElements(_this._terminal.cols, _this._terminal.rows);
+        _this._selectionContainer = document.createElement('div');
+        _this._selectionContainer.classList.add(SELECTION_CLASS);
+        _this._selectionContainer.setAttribute('aria-hidden', 'true');
+        _this.dimensions = {
+            scaledCharWidth: null,
+            scaledCharHeight: null,
+            scaledCellWidth: null,
+            scaledCellHeight: null,
+            scaledCharLeft: null,
+            scaledCharTop: null,
+            scaledCanvasWidth: null,
+            scaledCanvasHeight: null,
+            canvasWidth: null,
+            canvasHeight: null,
+            actualCellWidth: null,
+            actualCellHeight: null
+        };
+        _this._updateDimensions();
+        _this._renderDebouncer = new RenderDebouncer_1.RenderDebouncer(_this._renderRows.bind(_this));
+        _this._rowFactory = new DomRendererRowFactory_1.DomRendererRowFactory(_terminal.options, document);
+        _this._terminal.element.classList.add(TERMINAL_CLASS_PREFIX + _this._terminalClass);
+        _this._terminal.screenElement.appendChild(_this._rowContainer);
+        _this._terminal.screenElement.appendChild(_this._selectionContainer);
+        _this._terminal.linkifier.onLinkHover(function (e) { return _this._onLinkHover(e); });
+        _this._terminal.linkifier.onLinkLeave(function (e) { return _this._onLinkLeave(e); });
+        return _this;
+    }
+    Object.defineProperty(DomRenderer.prototype, "onCanvasResize", {
+        get: function () { return this._onCanvasResize.event; },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(DomRenderer.prototype, "onRender", {
+        get: function () { return this._onRender.event; },
+        enumerable: true,
+        configurable: true
+    });
+    DomRenderer.prototype.dispose = function () {
+        this._terminal.element.classList.remove(TERMINAL_CLASS_PREFIX + this._terminalClass);
+        this._terminal.screenElement.removeChild(this._rowContainer);
+        this._terminal.screenElement.removeChild(this._selectionContainer);
+        this._terminal.screenElement.removeChild(this._themeStyleElement);
+        this._terminal.screenElement.removeChild(this._dimensionsStyleElement);
+        _super.prototype.dispose.call(this);
+    };
+    DomRenderer.prototype._updateDimensions = function () {
+        var _this = this;
+        this.dimensions.scaledCharWidth = Math.floor(this._terminal.charMeasure.width * window.devicePixelRatio);
+        this.dimensions.scaledCharHeight = Math.ceil(this._terminal.charMeasure.height * window.devicePixelRatio);
+        this.dimensions.scaledCellWidth = this.dimensions.scaledCharWidth + Math.round(this._terminal.options.letterSpacing);
+        this.dimensions.scaledCellHeight = Math.floor(this.dimensions.scaledCharHeight * this._terminal.options.lineHeight);
+        this.dimensions.scaledCharLeft = 0;
+        this.dimensions.scaledCharTop = 0;
+        this.dimensions.scaledCanvasWidth = this.dimensions.scaledCellWidth * this._terminal.cols;
+        this.dimensions.scaledCanvasHeight = this.dimensions.scaledCellHeight * this._terminal.rows;
+        this.dimensions.canvasWidth = Math.round(this.dimensions.scaledCanvasWidth / window.devicePixelRatio);
+        this.dimensions.canvasHeight = Math.round(this.dimensions.scaledCanvasHeight / window.devicePixelRatio);
+        this.dimensions.actualCellWidth = this.dimensions.canvasWidth / this._terminal.cols;
+        this.dimensions.actualCellHeight = this.dimensions.canvasHeight / this._terminal.rows;
+        this._rowElements.forEach(function (element) {
+            element.style.width = _this.dimensions.canvasWidth + "px";
+            element.style.height = _this.dimensions.actualCellHeight + "px";
+            element.style.lineHeight = _this.dimensions.actualCellHeight + "px";
+            element.style.overflow = 'hidden';
+        });
+        if (!this._dimensionsStyleElement) {
+            this._dimensionsStyleElement = document.createElement('style');
+            this._terminal.screenElement.appendChild(this._dimensionsStyleElement);
+        }
+        var styles = this._terminalSelector + " ." + ROW_CONTAINER_CLASS + " span {" +
+            " display: inline-block;" +
+            " height: 100%;" +
+            " vertical-align: top;" +
+            (" width: " + this.dimensions.actualCellWidth + "px") +
+            "}";
+        this._dimensionsStyleElement.innerHTML = styles;
+        this._selectionContainer.style.height = this._terminal._viewportElement.style.height;
+        this._terminal.screenElement.style.width = this.dimensions.canvasWidth + "px";
+        this._terminal.screenElement.style.height = this.dimensions.canvasHeight + "px";
+    };
+    DomRenderer.prototype.setTheme = function (theme) {
+        var _this = this;
+        if (theme) {
+            this.colorManager.setTheme(theme);
+        }
+        if (!this._themeStyleElement) {
+            this._themeStyleElement = document.createElement('style');
+            this._terminal.screenElement.appendChild(this._themeStyleElement);
+        }
+        var styles = this._terminalSelector + " ." + ROW_CONTAINER_CLASS + " {" +
+            (" color: " + this.colorManager.colors.foreground.css + ";") +
+            (" background-color: " + this.colorManager.colors.background.css + ";") +
+            (" font-family: " + this._terminal.getOption('fontFamily') + ";") +
+            (" font-size: " + this._terminal.getOption('fontSize') + "px;") +
+            "}";
+        styles +=
+            this._terminalSelector + " span:not(." + DomRendererRowFactory_1.BOLD_CLASS + ") {" +
+                (" font-weight: " + this._terminal.options.fontWeight + ";") +
+                "}" +
+                (this._terminalSelector + " span." + DomRendererRowFactory_1.BOLD_CLASS + " {") +
+                (" font-weight: " + this._terminal.options.fontWeightBold + ";") +
+                "}" +
+                (this._terminalSelector + " span." + DomRendererRowFactory_1.ITALIC_CLASS + " {") +
+                " font-style: italic;" +
+                "}";
+        styles +=
+            "@keyframes blink {" +
+                " 0% { opacity: 1.0; }" +
+                " 50% { opacity: 0.0; }" +
+                " 100% { opacity: 1.0; }" +
+                "}";
+        styles +=
+            this._terminalSelector + " ." + ROW_CONTAINER_CLASS + ":not(." + FOCUS_CLASS + ") ." + DomRendererRowFactory_1.CURSOR_CLASS + " {" +
+                (" outline: 1px solid " + this.colorManager.colors.cursor.css + ";") +
+                " outline-offset: -1px;" +
+                "}" +
+                (this._terminalSelector + " ." + ROW_CONTAINER_CLASS + "." + FOCUS_CLASS + " ." + DomRendererRowFactory_1.CURSOR_CLASS + "." + DomRendererRowFactory_1.CURSOR_BLINK_CLASS + " {") +
+                " animation: blink 1s step-end infinite;" +
+                "}" +
+                (this._terminalSelector + " ." + ROW_CONTAINER_CLASS + "." + FOCUS_CLASS + " ." + DomRendererRowFactory_1.CURSOR_CLASS + "." + DomRendererRowFactory_1.CURSOR_STYLE_BLOCK_CLASS + " {") +
+                (" background-color: " + this.colorManager.colors.cursor.css + ";") +
+                (" color: " + this.colorManager.colors.cursorAccent.css + ";") +
+                "}" +
+                (this._terminalSelector + " ." + ROW_CONTAINER_CLASS + "." + FOCUS_CLASS + " ." + DomRendererRowFactory_1.CURSOR_CLASS + "." + DomRendererRowFactory_1.CURSOR_STYLE_BAR_CLASS + " {") +
+                (" box-shadow: 1px 0 0 " + this.colorManager.colors.cursor.css + " inset;") +
+                "}" +
+                (this._terminalSelector + " ." + ROW_CONTAINER_CLASS + "." + FOCUS_CLASS + " ." + DomRendererRowFactory_1.CURSOR_CLASS + "." + DomRendererRowFactory_1.CURSOR_STYLE_UNDERLINE_CLASS + " {") +
+                (" box-shadow: 0 -1px 0 " + this.colorManager.colors.cursor.css + " inset;") +
+                "}";
+        styles +=
+            this._terminalSelector + " ." + SELECTION_CLASS + " {" +
+                " position: absolute;" +
+                " top: 0;" +
+                " left: 0;" +
+                " z-index: 1;" +
+                " pointer-events: none;" +
+                "}" +
+                (this._terminalSelector + " ." + SELECTION_CLASS + " div {") +
+                " position: absolute;" +
+                (" background-color: " + this.colorManager.colors.selection.css + ";") +
+                "}";
+        this.colorManager.colors.ansi.forEach(function (c, i) {
+            styles +=
+                _this._terminalSelector + " ." + FG_CLASS_PREFIX + i + " { color: " + c.css + "; }" +
+                    (_this._terminalSelector + " ." + BG_CLASS_PREFIX + i + " { background-color: " + c.css + "; }");
+        });
+        styles +=
+            this._terminalSelector + " ." + FG_CLASS_PREFIX + Types_1.INVERTED_DEFAULT_COLOR + " { color: " + this.colorManager.colors.background.css + "; }" +
+                (this._terminalSelector + " ." + BG_CLASS_PREFIX + Types_1.INVERTED_DEFAULT_COLOR + " { background-color: " + this.colorManager.colors.foreground.css + "; }");
+        this._themeStyleElement.innerHTML = styles;
+        return this.colorManager.colors;
+    };
+    DomRenderer.prototype.onWindowResize = function (devicePixelRatio) {
+        this._updateDimensions();
+    };
+    DomRenderer.prototype._refreshRowElements = function (cols, rows) {
+        for (var i = this._rowElements.length; i <= rows; i++) {
+            var row = document.createElement('div');
+            this._rowContainer.appendChild(row);
+            this._rowElements.push(row);
+        }
+        while (this._rowElements.length > rows) {
+            this._rowContainer.removeChild(this._rowElements.pop());
+        }
+    };
+    DomRenderer.prototype.onResize = function (cols, rows) {
+        this._refreshRowElements(cols, rows);
+        this._updateDimensions();
+        this._onCanvasResize.fire({
+            width: this.dimensions.canvasWidth,
+            height: this.dimensions.canvasHeight
+        });
+    };
+    DomRenderer.prototype.onCharSizeChanged = function () {
+        this._updateDimensions();
+    };
+    DomRenderer.prototype.onBlur = function () {
+        this._rowContainer.classList.remove(FOCUS_CLASS);
+    };
+    DomRenderer.prototype.onFocus = function () {
+        this._rowContainer.classList.add(FOCUS_CLASS);
+    };
+    DomRenderer.prototype.onSelectionChanged = function (start, end, columnSelectMode) {
+        while (this._selectionContainer.children.length) {
+            this._selectionContainer.removeChild(this._selectionContainer.children[0]);
+        }
+        if (!start || !end) {
+            return;
+        }
+        var viewportStartRow = start[1] - this._terminal.buffer.ydisp;
+        var viewportEndRow = end[1] - this._terminal.buffer.ydisp;
+        var viewportCappedStartRow = Math.max(viewportStartRow, 0);
+        var viewportCappedEndRow = Math.min(viewportEndRow, this._terminal.rows - 1);
+        if (viewportCappedStartRow >= this._terminal.rows || viewportCappedEndRow < 0) {
+            return;
+        }
+        var documentFragment = document.createDocumentFragment();
+        if (columnSelectMode) {
+            documentFragment.appendChild(this._createSelectionElement(viewportCappedStartRow, start[0], end[0], viewportCappedEndRow - viewportCappedStartRow + 1));
+        }
+        else {
+            var startCol = viewportStartRow === viewportCappedStartRow ? start[0] : 0;
+            var endCol = viewportCappedStartRow === viewportCappedEndRow ? end[0] : this._terminal.cols;
+            documentFragment.appendChild(this._createSelectionElement(viewportCappedStartRow, startCol, endCol));
+            var middleRowsCount = viewportCappedEndRow - viewportCappedStartRow - 1;
+            documentFragment.appendChild(this._createSelectionElement(viewportCappedStartRow + 1, 0, this._terminal.cols, middleRowsCount));
+            if (viewportCappedStartRow !== viewportCappedEndRow) {
+                var endCol_1 = viewportEndRow === viewportCappedEndRow ? end[0] : this._terminal.cols;
+                documentFragment.appendChild(this._createSelectionElement(viewportCappedEndRow, 0, endCol_1));
+            }
+        }
+        this._selectionContainer.appendChild(documentFragment);
+    };
+    DomRenderer.prototype._createSelectionElement = function (row, colStart, colEnd, rowCount) {
+        if (rowCount === void 0) { rowCount = 1; }
+        var element = document.createElement('div');
+        element.style.height = rowCount * this.dimensions.actualCellHeight + "px";
+        element.style.top = row * this.dimensions.actualCellHeight + "px";
+        element.style.left = colStart * this.dimensions.actualCellWidth + "px";
+        element.style.width = this.dimensions.actualCellWidth * (colEnd - colStart) + "px";
+        return element;
+    };
+    DomRenderer.prototype.onCursorMove = function () {
+    };
+    DomRenderer.prototype.onOptionsChanged = function () {
+        this._updateDimensions();
+        this.setTheme(undefined);
+        this._terminal.refresh(0, this._terminal.rows - 1);
+    };
+    DomRenderer.prototype.clear = function () {
+        this._rowElements.forEach(function (e) { return e.innerHTML = ''; });
+    };
+    DomRenderer.prototype.refreshRows = function (start, end) {
+        this._renderDebouncer.refresh(start, end, this._terminal.rows);
+    };
+    DomRenderer.prototype._renderRows = function (start, end) {
+        var terminal = this._terminal;
+        var cursorAbsoluteY = terminal.buffer.ybase + terminal.buffer.y;
+        var cursorX = this._terminal.buffer.x;
+        var cursorBlink = this._terminal.options.cursorBlink;
+        for (var y = start; y <= end; y++) {
+            var rowElement = this._rowElements[y];
+            rowElement.innerHTML = '';
+            var row = y + terminal.buffer.ydisp;
+            var lineData = terminal.buffer.lines.get(row);
+            var cursorStyle = terminal.options.cursorStyle;
+            rowElement.appendChild(this._rowFactory.createRow(lineData, row === cursorAbsoluteY, cursorStyle, cursorX, cursorBlink, this.dimensions.actualCellWidth, terminal.cols));
+        }
+        this._onRender.fire({ start: start, end: end });
+    };
+    Object.defineProperty(DomRenderer.prototype, "_terminalSelector", {
+        get: function () {
+            return "." + TERMINAL_CLASS_PREFIX + this._terminalClass;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    DomRenderer.prototype.registerCharacterJoiner = function (handler) { return -1; };
+    DomRenderer.prototype.deregisterCharacterJoiner = function (joinerId) { return false; };
+    DomRenderer.prototype._onLinkHover = function (e) {
+        this._setCellUnderline(e.x1, e.x2, e.y1, e.y2, e.cols, true);
+    };
+    DomRenderer.prototype._onLinkLeave = function (e) {
+        this._setCellUnderline(e.x1, e.x2, e.y1, e.y2, e.cols, false);
+    };
+    DomRenderer.prototype._setCellUnderline = function (x, x2, y, y2, cols, enabled) {
+        while (x !== x2 || y !== y2) {
+            var row = this._rowElements[y];
+            if (!row) {
+                return;
+            }
+            var span = row.children[x];
+            if (span) {
+                span.style.textDecoration = enabled ? 'underline' : 'none';
+            }
+            if (++x >= cols) {
+                x = 0;
+                y++;
+            }
+        }
+    };
+    return DomRenderer;
+}(Lifecycle_1.Disposable));
+exports.DomRenderer = DomRenderer;
+
+},{"../../common/EventEmitter2":25,"../../common/Lifecycle":26,"../../ui/RenderDebouncer":56,"../ColorManager":37,"../atlas/Types":52,"./DomRendererRowFactory":54}],54:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var Buffer_1 = require("../../Buffer");
+var Types_1 = require("../atlas/Types");
+var BufferLine_1 = require("../../BufferLine");
+exports.BOLD_CLASS = 'xterm-bold';
+exports.DIM_CLASS = 'xterm-dim';
+exports.ITALIC_CLASS = 'xterm-italic';
+exports.UNDERLINE_CLASS = 'xterm-underline';
+exports.CURSOR_CLASS = 'xterm-cursor';
+exports.CURSOR_BLINK_CLASS = 'xterm-cursor-blink';
+exports.CURSOR_STYLE_BLOCK_CLASS = 'xterm-cursor-block';
+exports.CURSOR_STYLE_BAR_CLASS = 'xterm-cursor-bar';
+exports.CURSOR_STYLE_UNDERLINE_CLASS = 'xterm-cursor-underline';
+var DomRendererRowFactory = (function () {
+    function DomRendererRowFactory(_terminalOptions, _document) {
+        this._terminalOptions = _terminalOptions;
+        this._document = _document;
+        this._workCell = new BufferLine_1.CellData();
+    }
+    DomRendererRowFactory.prototype.createRow = function (lineData, isCursorRow, cursorStyle, cursorX, cursorBlink, cellWidth, cols) {
+        var fragment = this._document.createDocumentFragment();
+        var lineLength = 0;
+        for (var x = Math.min(lineData.length, cols) - 1; x >= 0; x--) {
+            if (lineData.loadCell(x, this._workCell).getCode() !== Buffer_1.NULL_CELL_CODE || (isCursorRow && x === cursorX)) {
+                lineLength = x + 1;
+                break;
+            }
+        }
+        for (var x = 0; x < lineLength; x++) {
+            lineData.loadCell(x, this._workCell);
+            var width = this._workCell.getWidth();
+            if (width === 0) {
+                continue;
+            }
+            var charElement = this._document.createElement('span');
+            if (width > 1) {
+                charElement.style.width = cellWidth * width + "px";
+            }
+            if (isCursorRow && x === cursorX) {
+                charElement.classList.add(exports.CURSOR_CLASS);
+                if (cursorBlink) {
+                    charElement.classList.add(exports.CURSOR_BLINK_CLASS);
+                }
+                switch (cursorStyle) {
+                    case 'bar':
+                        charElement.classList.add(exports.CURSOR_STYLE_BAR_CLASS);
+                        break;
+                    case 'underline':
+                        charElement.classList.add(exports.CURSOR_STYLE_UNDERLINE_CLASS);
+                        break;
+                    default:
+                        charElement.classList.add(exports.CURSOR_STYLE_BLOCK_CLASS);
+                        break;
+                }
+            }
+            if (this._workCell.isBold() && this._terminalOptions.enableBold) {
+                charElement.classList.add(exports.BOLD_CLASS);
+            }
+            if (this._workCell.isItalic()) {
+                charElement.classList.add(exports.ITALIC_CLASS);
+            }
+            if (this._workCell.isDim()) {
+                charElement.classList.add(exports.DIM_CLASS);
+            }
+            if (this._workCell.isUnderline()) {
+                charElement.classList.add(exports.UNDERLINE_CLASS);
+            }
+            charElement.textContent = this._workCell.getChars() || Buffer_1.WHITESPACE_CELL_CHAR;
+            var swapColor = this._workCell.isInverse();
+            if (this._workCell.isFgRGB()) {
+                var style = charElement.getAttribute('style') || '';
+                style += (swapColor ? 'background-' : '') + "color:rgb(" + (BufferLine_1.AttributeData.toColorRGB(this._workCell.getFgColor())).join(',') + ");";
+                charElement.setAttribute('style', style);
+            }
+            else if (this._workCell.isFgPalette()) {
+                var fg = this._workCell.getFgColor();
+                if (this._workCell.isBold() && fg < 8 && !swapColor &&
+                    this._terminalOptions.enableBold && this._terminalOptions.drawBoldTextInBrightColors) {
+                    fg += 8;
+                }
+                charElement.classList.add("xterm-" + (swapColor ? 'b' : 'f') + "g-" + fg);
+            }
+            else if (swapColor) {
+                charElement.classList.add("xterm-bg-" + Types_1.INVERTED_DEFAULT_COLOR);
+            }
+            if (this._workCell.isBgRGB()) {
+                var style = charElement.getAttribute('style') || '';
+                style += (swapColor ? '' : 'background-') + "color:rgb(" + (BufferLine_1.AttributeData.toColorRGB(this._workCell.getBgColor())).join(',') + ");";
+                charElement.setAttribute('style', style);
+            }
+            else if (this._workCell.isBgPalette()) {
+                charElement.classList.add("xterm-" + (swapColor ? 'f' : 'b') + "g-" + this._workCell.getBgColor());
+            }
+            else if (swapColor) {
+                charElement.classList.add("xterm-fg-" + Types_1.INVERTED_DEFAULT_COLOR);
+            }
+            fragment.appendChild(charElement);
+        }
+        return fragment;
+    };
+    return DomRendererRowFactory;
+}());
+exports.DomRendererRowFactory = DomRendererRowFactory;
+
+},{"../../Buffer":2,"../../BufferLine":3,"../atlas/Types":52}],55:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+function addDisposableDomListener(node, type, handler, useCapture) {
+    node.addEventListener(type, handler, useCapture);
+    return {
+        dispose: function () {
+            if (!handler) {
+                return;
+            }
+            node.removeEventListener(type, handler, useCapture);
+        }
+    };
+}
+exports.addDisposableDomListener = addDisposableDomListener;
+
+},{}],56:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var RenderDebouncer = (function () {
+    function RenderDebouncer(_renderCallback) {
+        this._renderCallback = _renderCallback;
+    }
+    RenderDebouncer.prototype.dispose = function () {
+        if (this._animationFrame) {
+            window.cancelAnimationFrame(this._animationFrame);
+            this._animationFrame = undefined;
+        }
+    };
+    RenderDebouncer.prototype.refresh = function (rowStart, rowEnd, rowCount) {
+        var _this = this;
+        this._rowCount = rowCount;
+        rowStart = rowStart !== undefined ? rowStart : 0;
+        rowEnd = rowEnd !== undefined ? rowEnd : this._rowCount - 1;
+        this._rowStart = this._rowStart !== undefined ? Math.min(this._rowStart, rowStart) : rowStart;
+        this._rowEnd = this._rowEnd !== undefined ? Math.max(this._rowEnd, rowEnd) : rowEnd;
+        if (this._animationFrame) {
+            return;
+        }
+        this._animationFrame = window.requestAnimationFrame(function () { return _this._innerRefresh(); });
+    };
+    RenderDebouncer.prototype._innerRefresh = function () {
+        if (this._rowStart === undefined || this._rowEnd === undefined || this._rowCount === undefined) {
+            return;
+        }
+        this._rowStart = Math.max(this._rowStart, 0);
+        this._rowEnd = Math.min(this._rowEnd, this._rowCount - 1);
+        this._renderCallback(this._rowStart, this._rowEnd);
+        this._rowStart = undefined;
+        this._rowEnd = undefined;
+        this._animationFrame = undefined;
+    };
+    return RenderDebouncer;
+}());
+exports.RenderDebouncer = RenderDebouncer;
+
+},{}],57:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = function (d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var Lifecycle_1 = require("../common/Lifecycle");
+var ScreenDprMonitor = (function (_super) {
+    __extends(ScreenDprMonitor, _super);
+    function ScreenDprMonitor() {
+        var _this = _super !== null && _super.apply(this, arguments) || this;
+        _this._currentDevicePixelRatio = window.devicePixelRatio;
+        return _this;
+    }
+    ScreenDprMonitor.prototype.setListener = function (listener) {
+        var _this = this;
+        if (this._listener) {
+            this.clearListener();
+        }
+        this._listener = listener;
+        this._outerListener = function () {
+            if (!_this._listener) {
+                return;
+            }
+            _this._listener(window.devicePixelRatio, _this._currentDevicePixelRatio);
+            _this._updateDpr();
+        };
+        this._updateDpr();
+    };
+    ScreenDprMonitor.prototype.dispose = function () {
+        _super.prototype.dispose.call(this);
+        this.clearListener();
+    };
+    ScreenDprMonitor.prototype._updateDpr = function () {
+        if (!this._resolutionMediaMatchList || !this._outerListener) {
+            return;
+        }
+        this._resolutionMediaMatchList.removeListener(this._outerListener);
+        this._currentDevicePixelRatio = window.devicePixelRatio;
+        this._resolutionMediaMatchList = window.matchMedia("screen and (resolution: " + window.devicePixelRatio + "dppx)");
+        this._resolutionMediaMatchList.addListener(this._outerListener);
+    };
+    ScreenDprMonitor.prototype.clearListener = function () {
+        if (!this._resolutionMediaMatchList || !this._listener || !this._outerListener) {
+            return;
+        }
+        this._resolutionMediaMatchList.removeListener(this._outerListener);
+        this._resolutionMediaMatchList = undefined;
+        this._listener = undefined;
+        this._outerListener = undefined;
+    };
+    return ScreenDprMonitor;
+}(Lifecycle_1.Disposable));
+exports.ScreenDprMonitor = ScreenDprMonitor;
+
+},{"../common/Lifecycle":26}],58:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var Terminal_1 = require("./public/Terminal");
+module.exports = Terminal_1.Terminal;
+
+},{"./public/Terminal":34}]},{},[58])(58)
+});
+//# sourceMappingURL=xterm.js.map
diff --git a/src/www/xterm.js.map b/src/www/xterm.js.map
new file mode 100644 (file)
index 0000000..cf96ecb
--- /dev/null
@@ -0,0 +1 @@
+{"version":3,"file":"xterm.js","sources":["../src/xterm.ts","../src/ui/ScreenDprMonitor.ts","../src/ui/RenderDebouncer.ts","../src/ui/Lifecycle.ts","../src/renderer/dom/DomRendererRowFactory.ts","../src/renderer/dom/DomRenderer.ts","../src/renderer/atlas/Types.ts","../src/renderer/atlas/StaticCharAtlas.ts","../src/renderer/atlas/NoneCharAtlas.ts","../src/renderer/atlas/LRUMap.ts","../src/renderer/atlas/DynamicCharAtlas.ts","../src/renderer/atlas/CharAtlasUtils.ts","../src/renderer/atlas/CharAtlasGenerator.ts","../src/renderer/atlas/CharAtlasCache.ts","../src/renderer/atlas/BaseCharAtlas.ts","../src/renderer/TextRenderLayer.ts","../src/renderer/SelectionRenderLayer.ts","../src/renderer/Renderer.ts","../src/renderer/LinkRenderLayer.ts","../src/renderer/GridCache.ts","../src/renderer/CursorRenderLayer.ts","../src/renderer/ColorManager.ts","../src/renderer/CharacterJoinerRegistry.ts","../src/renderer/BaseRenderLayer.ts","../src/public/Terminal.ts","../src/handlers/AltClickHandler.ts","../src/core/input/TextDecoder.ts","../src/core/input/Keyboard.ts","../src/core/data/Charsets.ts","../src/common/data/EscapeSequences.ts","../src/common/TypedArrayUtils.ts","../src/common/Platform.ts","../src/common/Lifecycle.ts","../src/common/EventEmitter2.ts","../src/common/EventEmitter.ts","../src/common/Clone.ts","../src/common/CircularList.ts","../src/WindowsMode.ts","../src/Viewport.ts","../src/Terminal.ts","../src/Strings.ts","../src/SoundManager.ts","../src/SelectionModel.ts","../src/SelectionManager.ts","../src/MouseZoneManager.ts","../src/MouseHelper.ts","../src/Linkifier.ts","../src/InputHandler.ts","../src/EscapeSequenceParser.ts","../src/CompositionHelper.ts","../src/Clipboard.ts","../src/CharWidth.ts","../src/CharMeasure.ts","../src/BufferSet.ts","../src/BufferReflow.ts","../src/BufferLine.ts","../src/Buffer.ts","../src/AccessibilityManager.ts","../node_modules/browser-pack/_prelude.js"],"sourcesContent":["/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * This file is the entry point for browserify.\n */\n\nimport { Terminal } from './public/Terminal';\n\nmodule.exports = Terminal;\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Disposable } from '../common/Lifecycle';\n\nexport type ScreenDprListener = (newDevicePixelRatio?: number, oldDevicePixelRatio?: number) => void;\n\n/**\n * The screen device pixel ratio monitor allows listening for when the\n * window.devicePixelRatio value changes. This is done not with polling but with\n * the use of window.matchMedia to watch media queries. When the event fires,\n * the listener will be reattached using a different media query to ensure that\n * any further changes will register.\n *\n * The listener should fire on both window zoom changes and switching to a\n * monitor with a different DPI.\n */\nexport class ScreenDprMonitor extends Disposable {\n  private _currentDevicePixelRatio: number = window.devicePixelRatio;\n  private _outerListener: ((this: MediaQueryList, ev: MediaQueryListEvent) => any) | undefined;\n  private _listener: ScreenDprListener | undefined;\n  private _resolutionMediaMatchList: MediaQueryList | undefined;\n\n  public setListener(listener: ScreenDprListener): void {\n    if (this._listener) {\n      this.clearListener();\n    }\n    this._listener = listener;\n    this._outerListener = () => {\n      if (!this._listener) {\n        return;\n      }\n      this._listener(window.devicePixelRatio, this._currentDevicePixelRatio);\n      this._updateDpr();\n    };\n    this._updateDpr();\n  }\n\n  public dispose(): void {\n    super.dispose();\n    this.clearListener();\n  }\n\n  private _updateDpr(): void {\n    if (!this._resolutionMediaMatchList || !this._outerListener) {\n      return;\n    }\n\n    // Clear listeners for old DPR\n    this._resolutionMediaMatchList.removeListener(this._outerListener);\n\n    // Add listeners for new DPR\n    this._currentDevicePixelRatio = window.devicePixelRatio;\n    this._resolutionMediaMatchList = window.matchMedia(`screen and (resolution: ${window.devicePixelRatio}dppx)`);\n    this._resolutionMediaMatchList.addListener(this._outerListener);\n  }\n\n  public clearListener(): void {\n    if (!this._resolutionMediaMatchList || !this._listener || !this._outerListener) {\n      return;\n    }\n    this._resolutionMediaMatchList.removeListener(this._outerListener);\n    this._resolutionMediaMatchList = undefined;\n    this._listener = undefined;\n    this._outerListener = undefined;\n  }\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IDisposable } from '../common/Types';\n\n/**\n * Debounces calls to render terminal rows using animation frames.\n */\nexport class RenderDebouncer implements IDisposable {\n  private _rowStart: number | undefined;\n  private _rowEnd: number | undefined;\n  private _rowCount: number | undefined;\n  private _animationFrame: number | undefined;\n\n  constructor(\n    private _renderCallback: (start: number, end: number) => void\n  ) {\n  }\n\n  public dispose(): void {\n    if (this._animationFrame) {\n      window.cancelAnimationFrame(this._animationFrame);\n      this._animationFrame = undefined;\n    }\n  }\n\n  public refresh(rowStart: number, rowEnd: number, rowCount: number): void {\n    this._rowCount = rowCount;\n    // Get the min/max row start/end for the arg values\n    rowStart = rowStart !== undefined ? rowStart : 0;\n    rowEnd = rowEnd !== undefined ? rowEnd : this._rowCount - 1;\n    // Set the properties to the updated values\n    this._rowStart = this._rowStart !== undefined ? Math.min(this._rowStart, rowStart) : rowStart;\n    this._rowEnd = this._rowEnd !== undefined ? Math.max(this._rowEnd, rowEnd) : rowEnd;\n\n    if (this._animationFrame) {\n      return;\n    }\n\n    this._animationFrame = window.requestAnimationFrame(() => this._innerRefresh());\n  }\n\n  private _innerRefresh(): void {\n    // Make sure values are set\n    if (this._rowStart === undefined || this._rowEnd === undefined || this._rowCount === undefined) {\n      return;\n    }\n\n    // Clamp values\n    this._rowStart = Math.max(this._rowStart, 0);\n    this._rowEnd = Math.min(this._rowEnd, this._rowCount - 1);\n\n    // Run render callback\n    this._renderCallback(this._rowStart, this._rowEnd);\n\n    // Reset debouncer\n    this._rowStart = undefined;\n    this._rowEnd = undefined;\n    this._animationFrame = undefined;\n  }\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IDisposable } from '../common/Types';\n\n/**\n * Adds a disposable listener to a node in the DOM, returning the disposable.\n * @param type The event type.\n * @param handler The handler for the listener.\n */\nexport function addDisposableDomListener(\n  node: Element | Window | Document,\n  type: string,\n  handler: (e: any) => void,\n  useCapture?: boolean\n): IDisposable {\n  node.addEventListener(type, handler, useCapture);\n  return {\n    dispose: () => {\n      if (!handler) {\n        // Already disposed\n        return;\n      }\n      node.removeEventListener(type, handler, useCapture);\n    }\n  };\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport {  NULL_CELL_CODE, WHITESPACE_CELL_CHAR } from '../../Buffer';\nimport { IBufferLine, ITerminalOptions } from '../../Types';\nimport { INVERTED_DEFAULT_COLOR } from '../atlas/Types';\nimport { CellData, AttributeData } from '../../BufferLine';\n\nexport const BOLD_CLASS = 'xterm-bold';\nexport const DIM_CLASS = 'xterm-dim';\nexport const ITALIC_CLASS = 'xterm-italic';\nexport const UNDERLINE_CLASS = 'xterm-underline';\nexport const CURSOR_CLASS = 'xterm-cursor';\nexport const CURSOR_BLINK_CLASS = 'xterm-cursor-blink';\nexport const CURSOR_STYLE_BLOCK_CLASS = 'xterm-cursor-block';\nexport const CURSOR_STYLE_BAR_CLASS = 'xterm-cursor-bar';\nexport const CURSOR_STYLE_UNDERLINE_CLASS = 'xterm-cursor-underline';\n\nexport class DomRendererRowFactory {\n  private _workCell: CellData = new CellData();\n\n  constructor(\n    private _terminalOptions: ITerminalOptions,\n    private _document: Document\n  ) {\n  }\n\n  public createRow(lineData: IBufferLine, isCursorRow: boolean, cursorStyle: string | undefined, cursorX: number, cursorBlink: boolean, cellWidth: number, cols: number): DocumentFragment {\n    const fragment = this._document.createDocumentFragment();\n\n    // Find the line length first, this prevents the need to output a bunch of\n    // empty cells at the end. This cannot easily be integrated into the main\n    // loop below because of the colCount feature (which can be removed after we\n    // properly support reflow and disallow data to go beyond the right-side of\n    // the viewport).\n    let lineLength = 0;\n    for (let x = Math.min(lineData.length, cols) - 1; x >= 0; x--) {\n      if (lineData.loadCell(x, this._workCell).getCode() !== NULL_CELL_CODE || (isCursorRow && x === cursorX)) {\n        lineLength = x + 1;\n        break;\n      }\n    }\n\n    for (let x = 0; x < lineLength; x++) {\n      lineData.loadCell(x, this._workCell);\n      const width = this._workCell.getWidth();\n\n      // The character to the left is a wide character, drawing is owned by the char at x-1\n      if (width === 0) {\n        continue;\n      }\n\n      const charElement = this._document.createElement('span');\n      if (width > 1) {\n        charElement.style.width = `${cellWidth * width}px`;\n      }\n\n      if (isCursorRow && x === cursorX) {\n        charElement.classList.add(CURSOR_CLASS);\n\n        if (cursorBlink) {\n          charElement.classList.add(CURSOR_BLINK_CLASS);\n        }\n\n        switch (cursorStyle) {\n          case 'bar':\n            charElement.classList.add(CURSOR_STYLE_BAR_CLASS);\n            break;\n          case 'underline':\n            charElement.classList.add(CURSOR_STYLE_UNDERLINE_CLASS);\n            break;\n          default:\n            charElement.classList.add(CURSOR_STYLE_BLOCK_CLASS);\n            break;\n        }\n      }\n\n      if (this._workCell.isBold() && this._terminalOptions.enableBold) {\n        charElement.classList.add(BOLD_CLASS);\n      }\n\n      if (this._workCell.isItalic()) {\n        charElement.classList.add(ITALIC_CLASS);\n      }\n\n      if (this._workCell.isDim()) {\n        charElement.classList.add(DIM_CLASS);\n      }\n\n      if (this._workCell.isUnderline()) {\n        charElement.classList.add(UNDERLINE_CLASS);\n      }\n\n      charElement.textContent = this._workCell.getChars() || WHITESPACE_CELL_CHAR;\n\n      const swapColor = this._workCell.isInverse();\n\n      // fg\n      if (this._workCell.isFgRGB()) {\n        let style = charElement.getAttribute('style') || '';\n        style += `${swapColor ? 'background-' : ''}color:rgb(${(AttributeData.toColorRGB(this._workCell.getFgColor())).join(',')});`;\n        charElement.setAttribute('style', style);\n      } else if (this._workCell.isFgPalette()) {\n        let fg = this._workCell.getFgColor();\n        if (this._workCell.isBold() && fg < 8 && !swapColor &&\n            this._terminalOptions.enableBold && this._terminalOptions.drawBoldTextInBrightColors) {\n          fg += 8;\n        }\n        charElement.classList.add(`xterm-${swapColor ? 'b' : 'f'}g-${fg}`);\n      } else if (swapColor) {\n        charElement.classList.add(`xterm-bg-${INVERTED_DEFAULT_COLOR}`);\n      }\n\n      // bg\n      if (this._workCell.isBgRGB()) {\n        let style = charElement.getAttribute('style') || '';\n        style += `${swapColor ? '' : 'background-'}color:rgb(${(AttributeData.toColorRGB(this._workCell.getBgColor())).join(',')});`;\n        charElement.setAttribute('style', style);\n      } else if (this._workCell.isBgPalette()) {\n        charElement.classList.add(`xterm-${swapColor ? 'f' : 'b'}g-${this._workCell.getBgColor()}`);\n      } else if (swapColor) {\n        charElement.classList.add(`xterm-fg-${INVERTED_DEFAULT_COLOR}`);\n      }\n\n      fragment.appendChild(charElement);\n    }\n    return fragment;\n  }\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IRenderer, IRenderDimensions, IColorSet } from '../Types';\nimport { ILinkifierEvent, ITerminal, CharacterJoinerHandler } from '../../Types';\nimport { ITheme } from 'xterm';\nimport { ColorManager } from '../ColorManager';\nimport { RenderDebouncer } from '../../ui/RenderDebouncer';\nimport { BOLD_CLASS, ITALIC_CLASS, CURSOR_CLASS, CURSOR_STYLE_BLOCK_CLASS, CURSOR_BLINK_CLASS, CURSOR_STYLE_BAR_CLASS, CURSOR_STYLE_UNDERLINE_CLASS, DomRendererRowFactory } from './DomRendererRowFactory';\nimport { INVERTED_DEFAULT_COLOR } from '../atlas/Types';\nimport { EventEmitter2, IEvent } from '../../common/EventEmitter2';\nimport { Disposable } from '../../common/Lifecycle';\n\nconst TERMINAL_CLASS_PREFIX = 'xterm-dom-renderer-owner-';\nconst ROW_CONTAINER_CLASS = 'xterm-rows';\nconst FG_CLASS_PREFIX = 'xterm-fg-';\nconst BG_CLASS_PREFIX = 'xterm-bg-';\nconst FOCUS_CLASS = 'xterm-focus';\nconst SELECTION_CLASS = 'xterm-selection';\n\nlet nextTerminalId = 1;\n\n// TODO: Pull into an addon when TS composite projects allow easier sharing of code (not just\n// interfaces) between core and addons\n\n/**\n * A fallback renderer for when canvas is slow. This is not meant to be\n * particularly fast or feature complete, more just stable and usable for when\n * canvas is not an option.\n */\nexport class DomRenderer extends Disposable implements IRenderer {\n  private _renderDebouncer: RenderDebouncer;\n  private _rowFactory: DomRendererRowFactory;\n  private _terminalClass: number = nextTerminalId++;\n\n  private _themeStyleElement: HTMLStyleElement;\n  private _dimensionsStyleElement: HTMLStyleElement;\n  private _rowContainer: HTMLElement;\n  private _rowElements: HTMLElement[] = [];\n  private _selectionContainer: HTMLElement;\n\n  public dimensions: IRenderDimensions;\n  public colorManager: ColorManager;\n\n  private _onCanvasResize = new EventEmitter2<{ width: number, height: number }>();\n  public get onCanvasResize(): IEvent<{ width: number, height: number }> { return this._onCanvasResize.event; }\n  private _onRender = new EventEmitter2<{ start: number, end: number }>();\n  public get onRender(): IEvent<{ start: number, end: number }> { return this._onRender.event; }\n\n  constructor(private _terminal: ITerminal, theme: ITheme | undefined) {\n    super();\n    const allowTransparency = this._terminal.options.allowTransparency;\n    this.colorManager = new ColorManager(document, allowTransparency);\n    this.setTheme(theme);\n\n    this._rowContainer = document.createElement('div');\n    this._rowContainer.classList.add(ROW_CONTAINER_CLASS);\n    this._rowContainer.style.lineHeight = 'normal';\n    this._rowContainer.setAttribute('aria-hidden', 'true');\n    this._refreshRowElements(this._terminal.cols, this._terminal.rows);\n    this._selectionContainer = document.createElement('div');\n    this._selectionContainer.classList.add(SELECTION_CLASS);\n    this._selectionContainer.setAttribute('aria-hidden', 'true');\n\n    this.dimensions = {\n      scaledCharWidth: null,\n      scaledCharHeight: null,\n      scaledCellWidth: null,\n      scaledCellHeight: null,\n      scaledCharLeft: null,\n      scaledCharTop: null,\n      scaledCanvasWidth: null,\n      scaledCanvasHeight: null,\n      canvasWidth: null,\n      canvasHeight: null,\n      actualCellWidth: null,\n      actualCellHeight: null\n    };\n    this._updateDimensions();\n\n    this._renderDebouncer = new RenderDebouncer(this._renderRows.bind(this));\n    this._rowFactory = new DomRendererRowFactory(_terminal.options, document);\n\n    this._terminal.element.classList.add(TERMINAL_CLASS_PREFIX + this._terminalClass);\n    this._terminal.screenElement.appendChild(this._rowContainer);\n    this._terminal.screenElement.appendChild(this._selectionContainer);\n\n    this._terminal.linkifier.onLinkHover(e => this._onLinkHover(e));\n    this._terminal.linkifier.onLinkLeave(e => this._onLinkLeave(e));\n  }\n\n  public dispose(): void {\n    this._terminal.element.classList.remove(TERMINAL_CLASS_PREFIX + this._terminalClass);\n    this._terminal.screenElement.removeChild(this._rowContainer);\n    this._terminal.screenElement.removeChild(this._selectionContainer);\n    this._terminal.screenElement.removeChild(this._themeStyleElement);\n    this._terminal.screenElement.removeChild(this._dimensionsStyleElement);\n    super.dispose();\n  }\n\n  private _updateDimensions(): void {\n    this.dimensions.scaledCharWidth = Math.floor(this._terminal.charMeasure.width * window.devicePixelRatio);\n    this.dimensions.scaledCharHeight = Math.ceil(this._terminal.charMeasure.height * window.devicePixelRatio);\n    this.dimensions.scaledCellWidth = this.dimensions.scaledCharWidth + Math.round(this._terminal.options.letterSpacing);\n    this.dimensions.scaledCellHeight = Math.floor(this.dimensions.scaledCharHeight * this._terminal.options.lineHeight);\n    this.dimensions.scaledCharLeft = 0;\n    this.dimensions.scaledCharTop = 0;\n    this.dimensions.scaledCanvasWidth = this.dimensions.scaledCellWidth * this._terminal.cols;\n    this.dimensions.scaledCanvasHeight = this.dimensions.scaledCellHeight * this._terminal.rows;\n    this.dimensions.canvasWidth = Math.round(this.dimensions.scaledCanvasWidth / window.devicePixelRatio);\n    this.dimensions.canvasHeight = Math.round(this.dimensions.scaledCanvasHeight / window.devicePixelRatio);\n    this.dimensions.actualCellWidth = this.dimensions.canvasWidth / this._terminal.cols;\n    this.dimensions.actualCellHeight = this.dimensions.canvasHeight / this._terminal.rows;\n\n    this._rowElements.forEach(element => {\n      element.style.width = `${this.dimensions.canvasWidth}px`;\n      element.style.height = `${this.dimensions.actualCellHeight}px`;\n      element.style.lineHeight = `${this.dimensions.actualCellHeight}px`;\n      // Make sure rows don't overflow onto following row\n      element.style.overflow = 'hidden';\n    });\n\n    if (!this._dimensionsStyleElement) {\n      this._dimensionsStyleElement = document.createElement('style');\n      this._terminal.screenElement.appendChild(this._dimensionsStyleElement);\n    }\n\n    const styles =\n        `${this._terminalSelector} .${ROW_CONTAINER_CLASS} span {` +\n        ` display: inline-block;` +\n        ` height: 100%;` +\n        ` vertical-align: top;` +\n        ` width: ${this.dimensions.actualCellWidth}px` +\n        `}`;\n\n    this._dimensionsStyleElement.innerHTML = styles;\n\n    this._selectionContainer.style.height = (<any>this._terminal)._viewportElement.style.height;\n    this._terminal.screenElement.style.width = `${this.dimensions.canvasWidth}px`;\n    this._terminal.screenElement.style.height = `${this.dimensions.canvasHeight}px`;\n  }\n\n  public setTheme(theme: ITheme | undefined): IColorSet {\n    if (theme) {\n      this.colorManager.setTheme(theme);\n    }\n\n    if (!this._themeStyleElement) {\n      this._themeStyleElement = document.createElement('style');\n      this._terminal.screenElement.appendChild(this._themeStyleElement);\n    }\n\n    // Base CSS\n    let styles =\n        `${this._terminalSelector} .${ROW_CONTAINER_CLASS} {` +\n        ` color: ${this.colorManager.colors.foreground.css};` +\n        ` background-color: ${this.colorManager.colors.background.css};` +\n        ` font-family: ${this._terminal.getOption('fontFamily')};` +\n        ` font-size: ${this._terminal.getOption('fontSize')}px;` +\n        `}`;\n    // Text styles\n    styles +=\n        `${this._terminalSelector} span:not(.${BOLD_CLASS}) {` +\n        ` font-weight: ${this._terminal.options.fontWeight};` +\n        `}` +\n        `${this._terminalSelector} span.${BOLD_CLASS} {` +\n        ` font-weight: ${this._terminal.options.fontWeightBold};` +\n        `}` +\n        `${this._terminalSelector} span.${ITALIC_CLASS} {` +\n        ` font-style: italic;` +\n        `}`;\n    // Blink animation\n    styles +=\n        `@keyframes blink {` +\n        ` 0% { opacity: 1.0; }` +\n        ` 50% { opacity: 0.0; }` +\n        ` 100% { opacity: 1.0; }` +\n        `}`;\n    // Cursor\n    styles +=\n        `${this._terminalSelector} .${ROW_CONTAINER_CLASS}:not(.${FOCUS_CLASS}) .${CURSOR_CLASS} {` +\n        ` outline: 1px solid ${this.colorManager.colors.cursor.css};` +\n        ` outline-offset: -1px;` +\n        `}` +\n        `${this._terminalSelector} .${ROW_CONTAINER_CLASS}.${FOCUS_CLASS} .${CURSOR_CLASS}.${CURSOR_BLINK_CLASS} {` +\n        ` animation: blink 1s step-end infinite;` +\n        `}` +\n        `${this._terminalSelector} .${ROW_CONTAINER_CLASS}.${FOCUS_CLASS} .${CURSOR_CLASS}.${CURSOR_STYLE_BLOCK_CLASS} {` +\n        ` background-color: ${this.colorManager.colors.cursor.css};` +\n        ` color: ${this.colorManager.colors.cursorAccent.css};` +\n        `}` +\n        `${this._terminalSelector} .${ROW_CONTAINER_CLASS}.${FOCUS_CLASS} .${CURSOR_CLASS}.${CURSOR_STYLE_BAR_CLASS} {` +\n        ` box-shadow: 1px 0 0 ${this.colorManager.colors.cursor.css} inset;` +\n        `}` +\n        `${this._terminalSelector} .${ROW_CONTAINER_CLASS}.${FOCUS_CLASS} .${CURSOR_CLASS}.${CURSOR_STYLE_UNDERLINE_CLASS} {` +\n        ` box-shadow: 0 -1px 0 ${this.colorManager.colors.cursor.css} inset;` +\n        `}`;\n    // Selection\n    styles +=\n        `${this._terminalSelector} .${SELECTION_CLASS} {` +\n        ` position: absolute;` +\n        ` top: 0;` +\n        ` left: 0;` +\n        ` z-index: 1;` +\n        ` pointer-events: none;` +\n        `}` +\n        `${this._terminalSelector} .${SELECTION_CLASS} div {` +\n        ` position: absolute;` +\n        ` background-color: ${this.colorManager.colors.selection.css};` +\n        `}`;\n    // Colors\n    this.colorManager.colors.ansi.forEach((c, i) => {\n      styles +=\n          `${this._terminalSelector} .${FG_CLASS_PREFIX}${i} { color: ${c.css}; }` +\n          `${this._terminalSelector} .${BG_CLASS_PREFIX}${i} { background-color: ${c.css}; }`;\n    });\n    styles +=\n        `${this._terminalSelector} .${FG_CLASS_PREFIX}${INVERTED_DEFAULT_COLOR} { color: ${this.colorManager.colors.background.css}; }` +\n        `${this._terminalSelector} .${BG_CLASS_PREFIX}${INVERTED_DEFAULT_COLOR} { background-color: ${this.colorManager.colors.foreground.css}; }`;\n\n    this._themeStyleElement.innerHTML = styles;\n    return this.colorManager.colors;\n  }\n\n  public onWindowResize(devicePixelRatio: number): void {\n    this._updateDimensions();\n  }\n\n  private _refreshRowElements(cols: number, rows: number): void {\n    // Add missing elements\n    for (let i = this._rowElements.length; i <= rows; i++) {\n      const row = document.createElement('div');\n      this._rowContainer.appendChild(row);\n      this._rowElements.push(row);\n    }\n    // Remove excess elements\n    while (this._rowElements.length > rows) {\n      this._rowContainer.removeChild(this._rowElements.pop());\n    }\n  }\n\n  public onResize(cols: number, rows: number): void {\n    this._refreshRowElements(cols, rows);\n    this._updateDimensions();\n    this._onCanvasResize.fire({\n      width: this.dimensions.canvasWidth,\n      height: this.dimensions.canvasHeight\n    });\n  }\n\n  public onCharSizeChanged(): void {\n    this._updateDimensions();\n  }\n\n  public onBlur(): void {\n    this._rowContainer.classList.remove(FOCUS_CLASS);\n  }\n\n  public onFocus(): void {\n    this._rowContainer.classList.add(FOCUS_CLASS);\n  }\n\n  public onSelectionChanged(start: [number, number], end: [number, number], columnSelectMode: boolean): void {\n    // Remove all selections\n    while (this._selectionContainer.children.length) {\n      this._selectionContainer.removeChild(this._selectionContainer.children[0]);\n    }\n\n    // Selection does not exist\n    if (!start || !end) {\n      return;\n    }\n\n    // Translate from buffer position to viewport position\n    const viewportStartRow = start[1] - this._terminal.buffer.ydisp;\n    const viewportEndRow = end[1] - this._terminal.buffer.ydisp;\n    const viewportCappedStartRow = Math.max(viewportStartRow, 0);\n    const viewportCappedEndRow = Math.min(viewportEndRow, this._terminal.rows - 1);\n\n    // No need to draw the selection\n    if (viewportCappedStartRow >= this._terminal.rows || viewportCappedEndRow < 0) {\n      return;\n    }\n\n    // Create the selections\n    const documentFragment = document.createDocumentFragment();\n\n    if (columnSelectMode) {\n      documentFragment.appendChild(\n        this._createSelectionElement(viewportCappedStartRow, start[0], end[0], viewportCappedEndRow - viewportCappedStartRow + 1)\n      );\n    } else {\n      // Draw first row\n      const startCol = viewportStartRow === viewportCappedStartRow ? start[0] : 0;\n      const endCol = viewportCappedStartRow === viewportCappedEndRow ? end[0] : this._terminal.cols;\n      documentFragment.appendChild(this._createSelectionElement(viewportCappedStartRow, startCol, endCol));\n      // Draw middle rows\n      const middleRowsCount = viewportCappedEndRow - viewportCappedStartRow - 1;\n      documentFragment.appendChild(this._createSelectionElement(viewportCappedStartRow + 1, 0, this._terminal.cols, middleRowsCount));\n      // Draw final row\n      if (viewportCappedStartRow !== viewportCappedEndRow) {\n        // Only draw viewportEndRow if it's not the same as viewporttartRow\n        const endCol = viewportEndRow === viewportCappedEndRow ? end[0] : this._terminal.cols;\n        documentFragment.appendChild(this._createSelectionElement(viewportCappedEndRow, 0, endCol));\n      }\n    }\n    this._selectionContainer.appendChild(documentFragment);\n  }\n\n  /**\n   * Creates a selection element at the specified position.\n   * @param row The row of the selection.\n   * @param colStart The start column.\n   * @param colEnd The end columns.\n   */\n  private _createSelectionElement(row: number, colStart: number, colEnd: number, rowCount: number = 1): HTMLElement {\n    const element = document.createElement('div');\n    element.style.height = `${rowCount * this.dimensions.actualCellHeight}px`;\n    element.style.top = `${row * this.dimensions.actualCellHeight}px`;\n    element.style.left = `${colStart * this.dimensions.actualCellWidth}px`;\n    element.style.width = `${this.dimensions.actualCellWidth * (colEnd - colStart)}px`;\n    return element;\n  }\n\n  public onCursorMove(): void {\n    // No-op, the cursor is drawn when rows are drawn\n  }\n\n  public onOptionsChanged(): void {\n    // Force a refresh\n    this._updateDimensions();\n    this.setTheme(undefined);\n    this._terminal.refresh(0, this._terminal.rows - 1);\n  }\n\n  public clear(): void {\n    this._rowElements.forEach(e => e.innerHTML = '');\n  }\n\n  public refreshRows(start: number, end: number): void {\n    this._renderDebouncer.refresh(start, end, this._terminal.rows);\n  }\n\n  private _renderRows(start: number, end: number): void {\n    const terminal = this._terminal;\n\n    const cursorAbsoluteY = terminal.buffer.ybase + terminal.buffer.y;\n    const cursorX = this._terminal.buffer.x;\n    const cursorBlink = this._terminal.options.cursorBlink;\n\n    for (let y = start; y <= end; y++) {\n      const rowElement = this._rowElements[y];\n      rowElement.innerHTML = '';\n\n      const row = y + terminal.buffer.ydisp;\n      const lineData = terminal.buffer.lines.get(row);\n      const cursorStyle = terminal.options.cursorStyle;\n      rowElement.appendChild(this._rowFactory.createRow(lineData, row === cursorAbsoluteY, cursorStyle, cursorX, cursorBlink, this.dimensions.actualCellWidth, terminal.cols));\n    }\n\n    this._onRender.fire({ start, end });\n  }\n\n  private get _terminalSelector(): string {\n    return `.${TERMINAL_CLASS_PREFIX}${this._terminalClass}`;\n  }\n\n  public registerCharacterJoiner(handler: CharacterJoinerHandler): number { return -1; }\n  public deregisterCharacterJoiner(joinerId: number): boolean { return false; }\n\n  private _onLinkHover(e: ILinkifierEvent): void {\n    this._setCellUnderline(e.x1, e.x2, e.y1, e.y2, e.cols, true);\n  }\n\n  private _onLinkLeave(e: ILinkifierEvent): void {\n    this._setCellUnderline(e.x1, e.x2, e.y1, e.y2, e.cols, false);\n  }\n\n  private _setCellUnderline(x: number, x2: number, y: number, y2: number, cols: number, enabled: boolean): void {\n    while (x !== x2 || y !== y2) {\n      const row = this._rowElements[y];\n      if (!row) {\n        return;\n      }\n      const span = <HTMLElement>row.children[x];\n      if (span) {\n        span.style.textDecoration = enabled ? 'underline' : 'none';\n      }\n      if (++x >= cols) {\n        x = 0;\n        y++;\n      }\n    }\n  }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { FontWeight } from 'xterm';\nimport { IColorSet } from '../Types';\n\nexport const DEFAULT_COLOR = 256;\nexport const INVERTED_DEFAULT_COLOR = 257;\nexport const DIM_OPACITY = 0.5;\n\nexport const CHAR_ATLAS_CELL_SPACING = 1;\n\nexport interface IGlyphIdentifier {\n  chars: string;\n  code: number;\n  bg: number;\n  fg: number;\n  bold: boolean;\n  dim: boolean;\n  italic: boolean;\n}\n\nexport interface ICharAtlasConfig {\n  type: 'none' | 'static' | 'dynamic';\n  devicePixelRatio: number;\n  fontSize: number;\n  fontFamily: string;\n  fontWeight: FontWeight;\n  fontWeightBold: FontWeight;\n  scaledCharWidth: number;\n  scaledCharHeight: number;\n  allowTransparency: boolean;\n  colors: IColorSet;\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { DIM_OPACITY, IGlyphIdentifier, DEFAULT_COLOR, ICharAtlasConfig, CHAR_ATLAS_CELL_SPACING } from './Types';\nimport { generateStaticCharAtlasTexture } from './CharAtlasGenerator';\nimport BaseCharAtlas from './BaseCharAtlas';\nimport { is256Color } from './CharAtlasUtils';\n\nexport default class StaticCharAtlas extends BaseCharAtlas {\n  private _texture: HTMLCanvasElement | ImageBitmap;\n\n  constructor(private _document: Document, private _config: ICharAtlasConfig) {\n    super();\n  }\n\n  private _canvasFactory = (width: number, height: number) => {\n    const canvas = this._document.createElement('canvas');\n    canvas.width = width;\n    canvas.height = height;\n\n    // This is useful for debugging\n    // document.body.appendChild(canvas);\n\n    return canvas;\n  }\n\n  protected _doWarmUp(): void {\n    const result = generateStaticCharAtlasTexture(window, this._canvasFactory, this._config);\n    if (result instanceof HTMLCanvasElement) {\n      this._texture = result;\n    } else {\n      result.then(texture => {\n        this._texture = texture;\n      });\n    }\n  }\n\n  private _isCached(glyph: IGlyphIdentifier, colorIndex: number): boolean {\n    const isAscii = glyph.code < 256;\n    // A color is basic if it is one of the 4 bit ANSI colors.\n    const isBasicColor = glyph.fg < 16;\n    const isDefaultColor = glyph.fg === DEFAULT_COLOR;\n    const isDefaultBackground = glyph.bg === DEFAULT_COLOR;\n    return isAscii && (isBasicColor || isDefaultColor) && isDefaultBackground && !glyph.italic;\n  }\n\n  public draw(\n    ctx: CanvasRenderingContext2D,\n    glyph: IGlyphIdentifier,\n    x: number,\n    y: number\n  ): boolean {\n    // we're not warmed up yet\n    if (this._texture === null || this._texture === undefined) {\n      return false;\n    }\n\n    let colorIndex = 0;\n    if (is256Color(glyph.fg)) {\n      colorIndex = 2 + glyph.fg + (glyph.bold ? 16 : 0);\n    } else if (glyph.fg === DEFAULT_COLOR) {\n      // If default color and bold\n      if (glyph.bold) {\n        colorIndex = 1;\n      }\n    }\n    if (!this._isCached(glyph, colorIndex)) {\n      return false;\n    }\n\n    ctx.save();\n\n    // ImageBitmap's draw about twice as fast as from a canvas\n    const charAtlasCellWidth = this._config.scaledCharWidth + CHAR_ATLAS_CELL_SPACING;\n    const charAtlasCellHeight = this._config.scaledCharHeight + CHAR_ATLAS_CELL_SPACING;\n\n    // Apply alpha to dim the character\n    if (glyph.dim) {\n      ctx.globalAlpha = DIM_OPACITY;\n    }\n\n    ctx.drawImage(\n      this._texture,\n      glyph.code * charAtlasCellWidth,\n      colorIndex * charAtlasCellHeight,\n      charAtlasCellWidth,\n      this._config.scaledCharHeight,\n      x,\n      y,\n      charAtlasCellWidth,\n      this._config.scaledCharHeight\n    );\n\n    ctx.restore();\n\n    return true;\n  }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * A dummy CharAtlas implementation that always fails to draw characters.\n */\n\nimport { IGlyphIdentifier, ICharAtlasConfig } from './Types';\nimport BaseCharAtlas from './BaseCharAtlas';\n\nexport default class NoneCharAtlas extends BaseCharAtlas {\n  constructor(document: Document, config: ICharAtlasConfig) {\n    super();\n  }\n\n  public draw(\n    ctx: CanvasRenderingContext2D,\n    glyph: IGlyphIdentifier,\n    x: number,\n    y: number\n  ): boolean {\n    return false;\n  }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\ninterface ILinkedListNode<T> {\n  prev: ILinkedListNode<T>;\n  next: ILinkedListNode<T>;\n  key: number;\n  value: T;\n}\n\nexport default class LRUMap<T> {\n  private _map: { [key: number]: ILinkedListNode<T> } = {};\n  private _head: ILinkedListNode<T> = null;\n  private _tail: ILinkedListNode<T> = null;\n  private _nodePool: ILinkedListNode<T>[] = [];\n  public size: number = 0;\n\n  constructor(public capacity: number) { }\n\n  private _unlinkNode(node: ILinkedListNode<T>): void {\n    const prev = node.prev;\n    const next = node.next;\n    if (node === this._head) {\n      this._head = next;\n    }\n    if (node === this._tail) {\n      this._tail = prev;\n    }\n    if (prev !== null) {\n      prev.next = next;\n    }\n    if (next !== null) {\n      next.prev = prev;\n    }\n  }\n\n  private _appendNode(node: ILinkedListNode<T>): void {\n    const tail = this._tail;\n    if (tail !== null) {\n      tail.next = node;\n    }\n    node.prev = tail;\n    node.next = null;\n    this._tail = node;\n    if (this._head === null) {\n      this._head = node;\n    }\n  }\n\n  /**\n   * Preallocate a bunch of linked-list nodes. Allocating these nodes ahead of time means that\n   * they're more likely to live next to each other in memory, which seems to improve performance.\n   *\n   * Each empty object only consumes about 60 bytes of memory, so this is pretty cheap, even for\n   * large maps.\n   */\n  public prealloc(count: number): void {\n    const nodePool = this._nodePool;\n    for (let i = 0; i < count; i++) {\n      nodePool.push({\n        prev: null,\n        next: null,\n        key: null,\n        value: null\n      });\n    }\n  }\n\n  public get(key: number): T | null {\n    // This is unsafe: We're assuming our keyspace doesn't overlap with Object.prototype. However,\n    // it's faster than calling hasOwnProperty, and in our case, it would never overlap.\n    const node = this._map[key];\n    if (node !== undefined) {\n      this._unlinkNode(node);\n      this._appendNode(node);\n      return node.value;\n    }\n    return null;\n  }\n\n  /**\n   * Gets a value from a key without marking it as the most recently used item.\n   */\n  public peekValue(key: number): T | null {\n    const node = this._map[key];\n    if (node !== undefined) {\n      return node.value;\n    }\n    return null;\n  }\n\n  public peek(): T | null {\n    const head = this._head;\n    return head === null ? null : head.value;\n  }\n\n  public set(key: number, value: T): void {\n    // This is unsafe: See note above.\n    let node = this._map[key];\n    if (node !== undefined) {\n      // already exists, we just need to mutate it and move it to the end of the list\n      node = this._map[key];\n      this._unlinkNode(node);\n      node.value = value;\n    } else if (this.size >= this.capacity) {\n      // we're out of space: recycle the head node, move it to the tail\n      node = this._head;\n      this._unlinkNode(node);\n      delete this._map[node.key];\n      node.key = key;\n      node.value = value;\n      this._map[key] = node;\n    } else {\n      // make a new element\n      const nodePool = this._nodePool;\n      if (nodePool.length > 0) {\n        // use a preallocated node if we can\n        node = nodePool.pop();\n        node.key = key;\n        node.value = value;\n      } else {\n        node = {\n          prev: null,\n          next: null,\n          key,\n          value\n        };\n      }\n      this._map[key] = node;\n      this.size++;\n    }\n    this._appendNode(node);\n  }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { DIM_OPACITY, IGlyphIdentifier, INVERTED_DEFAULT_COLOR, ICharAtlasConfig } from './Types';\nimport BaseCharAtlas from './BaseCharAtlas';\nimport { DEFAULT_ANSI_COLORS } from '../ColorManager';\nimport { clearColor } from './CharAtlasGenerator';\nimport LRUMap from './LRUMap';\nimport { isFirefox, isSafari } from '../../common/Platform';\nimport { IColor } from '../Types';\n\n// In practice we're probably never going to exhaust a texture this large. For debugging purposes,\n// however, it can be useful to set this to a really tiny value, to verify that LRU eviction works.\nconst TEXTURE_WIDTH = 1024;\nconst TEXTURE_HEIGHT = 1024;\n\nconst TRANSPARENT_COLOR = {\n  css: 'rgba(0, 0, 0, 0)',\n  rgba: 0\n};\n\n// Drawing to the cache is expensive: If we have to draw more than this number of glyphs to the\n// cache in a single frame, give up on trying to cache anything else, and try to finish the current\n// frame ASAP.\n//\n// This helps to limit the amount of damage a program can do when it would otherwise thrash the\n// cache.\nconst FRAME_CACHE_DRAW_LIMIT = 100;\n\n/**\n * The number of milliseconds to wait before generating the ImageBitmap, this is to debounce/batch\n * the operation as window.createImageBitmap is asynchronous.\n */\nconst GLYPH_BITMAP_COMMIT_DELAY = 100;\n\ninterface IGlyphCacheValue {\n  index: number;\n  isEmpty: boolean;\n  inBitmap: boolean;\n}\n\nexport function getGlyphCacheKey(glyph: IGlyphIdentifier): number {\n  // Note that this only returns a valid key when code < 256\n  // Layout:\n  // 0b00000000000000000000000000000001: italic (1)\n  // 0b00000000000000000000000000000010: dim (1)\n  // 0b00000000000000000000000000000100: bold (1)\n  // 0b00000000000000000000111111111000: fg (9)\n  // 0b00000000000111111111000000000000: bg (9)\n  // 0b00011111111000000000000000000000: code (8)\n  // 0b11100000000000000000000000000000: unused (3)\n  return glyph.code << 21 | glyph.bg << 12 | glyph.fg << 3 | (glyph.bold ? 0 : 4) + (glyph.dim ? 0 : 2) + (glyph.italic ? 0 : 1);\n}\n\nexport default class DynamicCharAtlas extends BaseCharAtlas {\n  // An ordered map that we're using to keep track of where each glyph is in the atlas texture.\n  // It's ordered so that we can determine when to remove the old entries.\n  private _cacheMap: LRUMap<IGlyphCacheValue>;\n\n  // The texture that the atlas is drawn to\n  private _cacheCanvas: HTMLCanvasElement;\n  private _cacheCtx: CanvasRenderingContext2D;\n\n  // A temporary context that glyphs are drawn to before being transfered to the atlas.\n  private _tmpCtx: CanvasRenderingContext2D;\n\n  // The number of characters stored in the atlas by width/height\n  private _width: number;\n  private _height: number;\n\n  private _drawToCacheCount: number = 0;\n\n  // An array of glyph keys that are waiting on the bitmap to be generated.\n  private _glyphsWaitingOnBitmap: IGlyphCacheValue[] = [];\n\n  // The timeout that is used to batch bitmap generation so it's not requested for every new glyph.\n  private _bitmapCommitTimeout: number | null = null;\n\n  // The bitmap to draw from, this is much faster on other browsers than others.\n  private _bitmap: ImageBitmap | null = null;\n\n  constructor(document: Document, private _config: ICharAtlasConfig) {\n    super();\n    this._cacheCanvas = document.createElement('canvas');\n    this._cacheCanvas.width = TEXTURE_WIDTH;\n    this._cacheCanvas.height = TEXTURE_HEIGHT;\n    // The canvas needs alpha because we use clearColor to convert the background color to alpha.\n    // It might also contain some characters with transparent backgrounds if allowTransparency is\n    // set.\n    this._cacheCtx = this._cacheCanvas.getContext('2d', {alpha: true});\n\n    const tmpCanvas = document.createElement('canvas');\n    tmpCanvas.width = this._config.scaledCharWidth;\n    tmpCanvas.height = this._config.scaledCharHeight;\n    this._tmpCtx = tmpCanvas.getContext('2d', {alpha: this._config.allowTransparency});\n\n    this._width = Math.floor(TEXTURE_WIDTH / this._config.scaledCharWidth);\n    this._height = Math.floor(TEXTURE_HEIGHT / this._config.scaledCharHeight);\n    const capacity = this._width * this._height;\n    this._cacheMap = new LRUMap(capacity);\n    this._cacheMap.prealloc(capacity);\n\n    // This is useful for debugging\n    // document.body.appendChild(this._cacheCanvas);\n  }\n\n  public dispose(): void {\n    if (this._bitmapCommitTimeout !== null) {\n      window.clearTimeout(this._bitmapCommitTimeout);\n      this._bitmapCommitTimeout = null;\n    }\n  }\n\n  public beginFrame(): void {\n    this._drawToCacheCount = 0;\n  }\n\n  public draw(\n    ctx: CanvasRenderingContext2D,\n    glyph: IGlyphIdentifier,\n    x: number,\n    y: number\n  ): boolean {\n    // Space is always an empty cell, special case this as it's so common\n    if (glyph.code === 32) {\n      return true;\n    }\n\n    // Exit early for uncachable glyphs\n    if (!this._canCache(glyph)) {\n      return false;\n    }\n\n    const glyphKey = getGlyphCacheKey(glyph);\n    const cacheValue = this._cacheMap.get(glyphKey);\n    if (cacheValue !== null && cacheValue !== undefined) {\n      this._drawFromCache(ctx, cacheValue, x, y);\n      return true;\n    } else if (this._drawToCacheCount < FRAME_CACHE_DRAW_LIMIT) {\n      let index;\n      if (this._cacheMap.size < this._cacheMap.capacity) {\n        index = this._cacheMap.size;\n      } else {\n        // we're out of space, so our call to set will delete this item\n        index = this._cacheMap.peek().index;\n      }\n      const cacheValue = this._drawToCache(glyph, index);\n      this._cacheMap.set(glyphKey, cacheValue);\n      this._drawFromCache(ctx, cacheValue, x, y);\n      return true;\n    }\n    return false;\n  }\n\n  private _canCache(glyph: IGlyphIdentifier): boolean {\n    // Only cache ascii and extended characters for now, to be safe. In the future, we could do\n    // something more complicated to determine the expected width of a character.\n    //\n    // If we switch the renderer over to webgl at some point, we may be able to use blending modes\n    // to draw overlapping glyphs from the atlas:\n    // https://github.com/servo/webrender/issues/464#issuecomment-255632875\n    // https://webglfundamentals.org/webgl/lessons/webgl-text-texture.html\n    return glyph.code < 256;\n  }\n\n  private _toCoordinateX(index: number): number {\n    return (index % this._width) * this._config.scaledCharWidth;\n  }\n\n  private _toCoordinateY(index: number): number {\n    return Math.floor(index / this._width) * this._config.scaledCharHeight;\n  }\n\n  private _drawFromCache(\n    ctx: CanvasRenderingContext2D,\n    cacheValue: IGlyphCacheValue,\n    x: number,\n    y: number\n  ): void {\n    // We don't actually need to do anything if this is whitespace.\n    if (cacheValue.isEmpty) {\n      return;\n    }\n    const cacheX = this._toCoordinateX(cacheValue.index);\n    const cacheY = this._toCoordinateY(cacheValue.index);\n    ctx.drawImage(\n      cacheValue.inBitmap ? this._bitmap : this._cacheCanvas,\n      cacheX,\n      cacheY,\n      this._config.scaledCharWidth,\n      this._config.scaledCharHeight,\n      x,\n      y,\n      this._config.scaledCharWidth,\n      this._config.scaledCharHeight\n    );\n  }\n\n  private _getColorFromAnsiIndex(idx: number): IColor {\n    if (idx < this._config.colors.ansi.length) {\n      return this._config.colors.ansi[idx];\n    }\n    return DEFAULT_ANSI_COLORS[idx];\n  }\n\n  private _getBackgroundColor(glyph: IGlyphIdentifier): IColor {\n    if (this._config.allowTransparency) {\n      // The background color might have some transparency, so we need to render it as fully\n      // transparent in the atlas. Otherwise we'd end up drawing the transparent background twice\n      // around the anti-aliased edges of the glyph, and it would look too dark.\n      return TRANSPARENT_COLOR;\n    } else if (glyph.bg === INVERTED_DEFAULT_COLOR) {\n      return this._config.colors.foreground;\n    } else if (glyph.bg < 256) {\n      return this._getColorFromAnsiIndex(glyph.bg);\n    }\n    return this._config.colors.background;\n  }\n\n  private _getForegroundColor(glyph: IGlyphIdentifier): IColor {\n    if (glyph.fg === INVERTED_DEFAULT_COLOR) {\n      return this._config.colors.background;\n    } else if (glyph.fg < 256) {\n      // 256 color support\n      return this._getColorFromAnsiIndex(glyph.fg);\n    }\n    return this._config.colors.foreground;\n  }\n\n  // TODO: We do this (or something similar) in multiple places. We should split this off\n  // into a shared function.\n  private _drawToCache(glyph: IGlyphIdentifier, index: number): IGlyphCacheValue {\n    this._drawToCacheCount++;\n\n    this._tmpCtx.save();\n\n    // draw the background\n    const backgroundColor = this._getBackgroundColor(glyph);\n    // Use a 'copy' composite operation to clear any existing glyph out of _tmpCtxWithAlpha, regardless of\n    // transparency in backgroundColor\n    this._tmpCtx.globalCompositeOperation = 'copy';\n    this._tmpCtx.fillStyle = backgroundColor.css;\n    this._tmpCtx.fillRect(0, 0, this._config.scaledCharWidth, this._config.scaledCharHeight);\n    this._tmpCtx.globalCompositeOperation = 'source-over';\n\n    // draw the foreground/glyph\n    const fontWeight = glyph.bold ? this._config.fontWeightBold : this._config.fontWeight;\n    const fontStyle = glyph.italic ? 'italic' : '';\n    this._tmpCtx.font =\n      `${fontStyle} ${fontWeight} ${this._config.fontSize * this._config.devicePixelRatio}px ${this._config.fontFamily}`;\n    this._tmpCtx.textBaseline = 'middle';\n\n    this._tmpCtx.fillStyle = this._getForegroundColor(glyph).css;\n\n    // Apply alpha to dim the character\n    if (glyph.dim) {\n      this._tmpCtx.globalAlpha = DIM_OPACITY;\n    }\n    // Draw the character\n    this._tmpCtx.fillText(glyph.chars, 0, this._config.scaledCharHeight / 2);\n    this._tmpCtx.restore();\n\n    // clear the background from the character to avoid issues with drawing over the previous\n    // character if it extends past it's bounds\n    const imageData = this._tmpCtx.getImageData(\n      0, 0, this._config.scaledCharWidth, this._config.scaledCharHeight\n    );\n    let isEmpty = false;\n    if (!this._config.allowTransparency) {\n      isEmpty = clearColor(imageData, backgroundColor);\n    }\n\n    // copy the data from imageData to _cacheCanvas\n    const x = this._toCoordinateX(index);\n    const y = this._toCoordinateY(index);\n    // putImageData doesn't do any blending, so it will overwrite any existing cache entry for us\n    this._cacheCtx.putImageData(imageData, x, y);\n\n    // Add the glyph and queue it to the bitmap (if the browser supports it)\n    const cacheValue = {\n      index,\n      isEmpty,\n      inBitmap: false\n    };\n    this._addGlyphToBitmap(cacheValue);\n\n    return cacheValue;\n  }\n\n  private _addGlyphToBitmap(cacheValue: IGlyphCacheValue): void {\n    // Support is patchy for createImageBitmap at the moment, pass a canvas back\n    // if support is lacking as drawImage works there too. Firefox is also\n    // included here as ImageBitmap appears both buggy and has horrible\n    // performance (tested on v55).\n    if (!('createImageBitmap' in window) || isFirefox || isSafari) {\n      return;\n    }\n\n    // Add the glyph to the queue\n    this._glyphsWaitingOnBitmap.push(cacheValue);\n\n    // Check if bitmap generation timeout already exists\n    if (this._bitmapCommitTimeout !== null) {\n      return;\n    }\n\n    this._bitmapCommitTimeout = window.setTimeout(() => this._generateBitmap(), GLYPH_BITMAP_COMMIT_DELAY);\n  }\n\n  private _generateBitmap(): void {\n    const glyphsMovingToBitmap = this._glyphsWaitingOnBitmap;\n    this._glyphsWaitingOnBitmap = [];\n    window.createImageBitmap(this._cacheCanvas).then(bitmap => {\n      // Set bitmap\n      this._bitmap = bitmap;\n\n      // Mark all new glyphs as in bitmap, excluding glyphs that came in after\n      // the bitmap was requested\n      for (let i = 0; i < glyphsMovingToBitmap.length; i++) {\n        const value = glyphsMovingToBitmap[i];\n        // It doesn't matter if the value was already evicted, it will be\n        // released from memory after this block if so.\n        value.inBitmap = true;\n      }\n    });\n    this._bitmapCommitTimeout = null;\n  }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ITerminal } from '../../Types';\nimport { IColorSet } from '../Types';\nimport { DEFAULT_COLOR, ICharAtlasConfig } from './Types';\n\nexport function generateConfig(scaledCharWidth: number, scaledCharHeight: number, terminal: ITerminal, colors: IColorSet): ICharAtlasConfig {\n  // null out some fields that don't matter\n  const clonedColors = <IColorSet>{\n    foreground: colors.foreground,\n    background: colors.background,\n    cursor: null,\n    cursorAccent: null,\n    selection: null,\n    // For the static char atlas, we only use the first 16 colors, but we need all 256 for the\n    // dynamic character atlas.\n    ansi: colors.ansi.slice(0, 16)\n  };\n  return {\n    type: terminal.options.experimentalCharAtlas,\n    devicePixelRatio: window.devicePixelRatio,\n    scaledCharWidth,\n    scaledCharHeight,\n    fontFamily: terminal.options.fontFamily,\n    fontSize: terminal.options.fontSize,\n    fontWeight: terminal.options.fontWeight,\n    fontWeightBold: terminal.options.fontWeightBold,\n    allowTransparency: terminal.options.allowTransparency,\n    colors: clonedColors\n  };\n}\n\nexport function configEquals(a: ICharAtlasConfig, b: ICharAtlasConfig): boolean {\n  for (let i = 0; i < a.colors.ansi.length; i++) {\n    if (a.colors.ansi[i].rgba !== b.colors.ansi[i].rgba) {\n      return false;\n    }\n  }\n  return a.type === b.type &&\n      a.devicePixelRatio === b.devicePixelRatio &&\n      a.fontFamily === b.fontFamily &&\n      a.fontSize === b.fontSize &&\n      a.fontWeight === b.fontWeight &&\n      a.fontWeightBold === b.fontWeightBold &&\n      a.allowTransparency === b.allowTransparency &&\n      a.scaledCharWidth === b.scaledCharWidth &&\n      a.scaledCharHeight === b.scaledCharHeight &&\n      a.colors.foreground === b.colors.foreground &&\n      a.colors.background === b.colors.background;\n}\n\nexport function is256Color(colorCode: number): boolean {\n  return colorCode < DEFAULT_COLOR;\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { FontWeight } from 'xterm';\nimport { isFirefox, isSafari } from '../../common/Platform';\nimport { IColor } from '../Types';\nimport { ICharAtlasConfig, CHAR_ATLAS_CELL_SPACING } from './Types';\n\n/**\n * Generates a char atlas.\n * @param context The window or worker context.\n * @param canvasFactory A function to generate a canvas with a width or height.\n * @param config The config for the new char atlas.\n */\nexport function generateStaticCharAtlasTexture(context: Window, canvasFactory: (width: number, height: number) => HTMLCanvasElement, config: ICharAtlasConfig): HTMLCanvasElement | Promise<ImageBitmap> {\n  const cellWidth = config.scaledCharWidth + CHAR_ATLAS_CELL_SPACING;\n  const cellHeight = config.scaledCharHeight + CHAR_ATLAS_CELL_SPACING;\n  const canvas = canvasFactory(\n    /*255 ascii chars*/255 * cellWidth,\n    (/*default+default bold*/2 + /*0-15*/16 + /*0-15 bold*/16) * cellHeight\n  );\n  const ctx = canvas.getContext('2d', {alpha: config.allowTransparency});\n\n  ctx.fillStyle = config.colors.background.css;\n  ctx.fillRect(0, 0, canvas.width, canvas.height);\n\n  ctx.save();\n  ctx.fillStyle = config.colors.foreground.css;\n  ctx.font = getFont(config.fontWeight, config);\n  ctx.textBaseline = 'middle';\n\n  // Default color\n  for (let i = 0; i < 256; i++) {\n    ctx.save();\n    ctx.beginPath();\n    ctx.rect(i * cellWidth, 0, cellWidth, cellHeight);\n    ctx.clip();\n    ctx.fillText(String.fromCharCode(i), i * cellWidth, cellHeight / 2);\n    ctx.restore();\n  }\n  // Default color bold\n  ctx.save();\n  ctx.font = getFont(config.fontWeightBold, config);\n  for (let i = 0; i < 256; i++) {\n    ctx.save();\n    ctx.beginPath();\n    ctx.rect(i * cellWidth, cellHeight, cellWidth, cellHeight);\n    ctx.clip();\n    ctx.fillText(String.fromCharCode(i), i * cellWidth, cellHeight * 1.5);\n    ctx.restore();\n  }\n  ctx.restore();\n\n  // Colors 0-15\n  ctx.font = getFont(config.fontWeight, config);\n  for (let colorIndex = 0; colorIndex < 16; colorIndex++) {\n    const y = (colorIndex + 2) * cellHeight;\n    // Draw ascii characters\n    for (let i = 0; i < 256; i++) {\n      ctx.save();\n      ctx.beginPath();\n      ctx.rect(i * cellWidth, y, cellWidth, cellHeight);\n      ctx.clip();\n      ctx.fillStyle = config.colors.ansi[colorIndex].css;\n      ctx.fillText(String.fromCharCode(i), i * cellWidth, y + cellHeight / 2);\n      ctx.restore();\n    }\n  }\n\n  // Colors 0-15 bold\n  ctx.font = getFont(config.fontWeightBold, config);\n  for (let colorIndex = 0; colorIndex < 16; colorIndex++) {\n    const y = (colorIndex + 2 + 16) * cellHeight;\n    // Draw ascii characters\n    for (let i = 0; i < 256; i++) {\n      ctx.save();\n      ctx.beginPath();\n      ctx.rect(i * cellWidth, y, cellWidth, cellHeight);\n      ctx.clip();\n      ctx.fillStyle = config.colors.ansi[colorIndex].css;\n      ctx.fillText(String.fromCharCode(i), i * cellWidth, y + cellHeight / 2);\n      ctx.restore();\n    }\n  }\n  ctx.restore();\n\n  // Support is patchy for createImageBitmap at the moment, pass a canvas back\n  // if support is lacking as drawImage works there too. Firefox is also\n  // included here as ImageBitmap appears both buggy and has horrible\n  // performance (tested on v55).\n  if (!('createImageBitmap' in context) || isFirefox || isSafari) {\n    // Don't attempt to clear background colors if createImageBitmap is not supported\n    return canvas;\n  }\n\n  const charAtlasImageData = ctx.getImageData(0, 0, canvas.width, canvas.height);\n\n  // Remove the background color from the image so characters may overlap\n  clearColor(charAtlasImageData, config.colors.background);\n\n  return context.createImageBitmap(charAtlasImageData);\n}\n\n/**\n * Makes a partiicular rgb color in an ImageData completely transparent.\n * @returns True if the result is \"empty\", meaning all pixels are fully transparent.\n */\nexport function clearColor(imageData: ImageData, color: IColor): boolean {\n  let isEmpty = true;\n  const r = color.rgba >>> 24;\n  const g = color.rgba >>> 16 & 0xFF;\n  const b = color.rgba >>> 8 & 0xFF;\n  for (let offset = 0; offset < imageData.data.length; offset += 4) {\n    if (imageData.data[offset] === r &&\n        imageData.data[offset + 1] === g &&\n        imageData.data[offset + 2] === b) {\n      imageData.data[offset + 3] = 0;\n    } else {\n      isEmpty = false;\n    }\n  }\n  return isEmpty;\n}\n\nfunction getFont(fontWeight: FontWeight, config: ICharAtlasConfig): string {\n  return `${fontWeight} ${config.fontSize * config.devicePixelRatio}px ${config.fontFamily}`;\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ITerminal } from '../../Types';\nimport { IColorSet } from '../Types';\nimport { generateConfig, configEquals } from './CharAtlasUtils';\nimport BaseCharAtlas from './BaseCharAtlas';\nimport DynamicCharAtlas from './DynamicCharAtlas';\nimport NoneCharAtlas from './NoneCharAtlas';\nimport StaticCharAtlas from './StaticCharAtlas';\nimport { ICharAtlasConfig } from './Types';\n\nconst charAtlasImplementations = {\n  'none': NoneCharAtlas,\n  'static': StaticCharAtlas,\n  'dynamic': DynamicCharAtlas\n};\n\ninterface ICharAtlasCacheEntry {\n  atlas: BaseCharAtlas;\n  config: ICharAtlasConfig;\n  // N.B. This implementation potentially holds onto copies of the terminal forever, so\n  // this may cause memory leaks.\n  ownedBy: ITerminal[];\n}\n\nconst charAtlasCache: ICharAtlasCacheEntry[] = [];\n\n/**\n * Acquires a char atlas, either generating a new one or returning an existing\n * one that is in use by another terminal.\n * @param terminal The terminal.\n * @param colors The colors to use.\n */\nexport function acquireCharAtlas(\n  terminal: ITerminal,\n  colors: IColorSet,\n  scaledCharWidth: number,\n  scaledCharHeight: number\n): BaseCharAtlas {\n  const newConfig = generateConfig(scaledCharWidth, scaledCharHeight, terminal, colors);\n\n  // Check to see if the terminal already owns this config\n  for (let i = 0; i < charAtlasCache.length; i++) {\n    const entry = charAtlasCache[i];\n    const ownedByIndex = entry.ownedBy.indexOf(terminal);\n    if (ownedByIndex >= 0) {\n      if (configEquals(entry.config, newConfig)) {\n        return entry.atlas;\n      }\n      // The configs differ, release the terminal from the entry\n      if (entry.ownedBy.length === 1) {\n        entry.atlas.dispose();\n        charAtlasCache.splice(i, 1);\n      } else {\n        entry.ownedBy.splice(ownedByIndex, 1);\n      }\n      break;\n    }\n  }\n\n  // Try match a char atlas from the cache\n  for (let i = 0; i < charAtlasCache.length; i++) {\n    const entry = charAtlasCache[i];\n    if (configEquals(entry.config, newConfig)) {\n      // Add the terminal to the cache entry and return\n      entry.ownedBy.push(terminal);\n      return entry.atlas;\n    }\n  }\n\n  const newEntry: ICharAtlasCacheEntry = {\n    atlas: new charAtlasImplementations[terminal.options.experimentalCharAtlas](\n      document,\n      newConfig\n    ),\n    config: newConfig,\n    ownedBy: [terminal]\n  };\n  charAtlasCache.push(newEntry);\n  return newEntry.atlas;\n}\n\n/**\n * Removes a terminal reference from the cache, allowing its memory to be freed.\n * @param terminal The terminal to remove.\n */\nexport function removeTerminalFromCache(terminal: ITerminal): void {\n  for (let i = 0; i < charAtlasCache.length; i++) {\n    const index = charAtlasCache[i].ownedBy.indexOf(terminal);\n    if (index !== -1) {\n      if (charAtlasCache[i].ownedBy.length === 1) {\n        // Remove the cache entry if it's the only terminal\n        charAtlasCache[i].atlas.dispose();\n        charAtlasCache.splice(i, 1);\n      } else {\n        // Remove the reference from the cache entry\n        charAtlasCache[i].ownedBy.splice(index, 1);\n      }\n      break;\n    }\n  }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IGlyphIdentifier } from './Types';\nimport { IDisposable } from 'xterm';\n\nexport default abstract class BaseCharAtlas implements IDisposable {\n  private _didWarmUp: boolean = false;\n\n  public dispose(): void { }\n\n  /**\n   * Perform any work needed to warm the cache before it can be used. May be called multiple times.\n   * Implement _doWarmUp instead if you only want to get called once.\n   */\n  public warmUp(): void {\n    if (!this._didWarmUp) {\n      this._doWarmUp();\n      this._didWarmUp = true;\n    }\n  }\n\n  /**\n   * Perform any work needed to warm the cache before it can be used. Used by the default\n   * implementation of warmUp(), and will only be called once.\n   */\n  protected _doWarmUp(): void { }\n\n  /**\n   * Called when we start drawing a new frame.\n   *\n   * TODO: We rely on this getting called by TextRenderLayer. This should really be called by\n   * Renderer instead, but we need to make Renderer the source-of-truth for the char atlas, instead\n   * of BaseRenderLayer.\n   */\n  public beginFrame(): void { }\n\n  /**\n   * May be called before warmUp finishes, however it is okay for the implementation to\n   * do nothing and return false in that case.\n   *\n   * @param ctx Where to draw the character onto.\n   * @param glyph Information about what to draw\n   * @param x The position on the context to start drawing at\n   * @param y The position on the context to start drawing at\n   * @returns The success state. True if we drew the character.\n   */\n  public abstract draw(\n    ctx: CanvasRenderingContext2D,\n    glyph: IGlyphIdentifier,\n    x: number,\n    y: number\n  ): boolean;\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { NULL_CELL_CODE } from '../Buffer';\nimport { IColorSet, IRenderDimensions, ICharacterJoinerRegistry } from './Types';\nimport { CharData, ITerminal, ICellData } from '../Types';\nimport { GridCache } from './GridCache';\nimport { BaseRenderLayer } from './BaseRenderLayer';\nimport { CellData, AttributeData, Content } from '../BufferLine';\nimport { JoinedCellData } from './CharacterJoinerRegistry';\n\n/**\n * This CharData looks like a null character, which will forc a clear and render\n * when the character changes (a regular space ' ' character may not as it's\n * drawn state is a cleared cell).\n */\n// const OVERLAP_OWNED_CHAR_DATA: CharData = [null, '', 0, -1];\n\nexport class TextRenderLayer extends BaseRenderLayer {\n  private _state: GridCache<CharData>;\n  private _characterWidth: number;\n  private _characterFont: string;\n  private _characterOverlapCache: { [key: string]: boolean } = {};\n  private _characterJoinerRegistry: ICharacterJoinerRegistry;\n  private _workCell = new CellData();\n\n  constructor(container: HTMLElement, zIndex: number, colors: IColorSet, characterJoinerRegistry: ICharacterJoinerRegistry, alpha: boolean) {\n    super(container, 'text', zIndex, alpha, colors);\n    this._state = new GridCache<CharData>();\n    this._characterJoinerRegistry = characterJoinerRegistry;\n  }\n\n  public resize(terminal: ITerminal, dim: IRenderDimensions): void {\n    super.resize(terminal, dim);\n\n    // Clear the character width cache if the font or width has changed\n    const terminalFont = this._getFont(terminal, false, false);\n    if (this._characterWidth !== dim.scaledCharWidth || this._characterFont !== terminalFont) {\n      this._characterWidth = dim.scaledCharWidth;\n      this._characterFont = terminalFont;\n      this._characterOverlapCache = {};\n    }\n    // Resizing the canvas discards the contents of the canvas so clear state\n    this._state.clear();\n    this._state.resize(terminal.cols, terminal.rows);\n  }\n\n  public reset(terminal: ITerminal): void {\n    this._state.clear();\n    this.clearAll();\n  }\n\n  private _forEachCell(\n    terminal: ITerminal,\n    firstRow: number,\n    lastRow: number,\n    joinerRegistry: ICharacterJoinerRegistry | null,\n    callback: (\n      cell: ICellData,\n      x: number,\n      y: number\n    ) => void\n  ): void {\n    for (let y = firstRow; y <= lastRow; y++) {\n      const row = y + terminal.buffer.ydisp;\n      const line = terminal.buffer.lines.get(row);\n      const joinedRanges = joinerRegistry ? joinerRegistry.getJoinedCharacters(row) : [];\n      for (let x = 0; x < terminal.cols; x++) {\n        line.loadCell(x, this._workCell);\n        let cell = this._workCell;\n\n        // If true, indicates that the current character(s) to draw were joined.\n        let isJoined = false;\n        let lastCharX = x;\n\n        // The character to the left is a wide character, drawing is owned by\n        // the char at x-1\n        if (cell.getWidth() === 0) {\n          continue;\n        }\n\n        // Process any joined character ranges as needed. Because of how the\n        // ranges are produced, we know that they are valid for the characters\n        // and attributes of our input.\n        if (joinedRanges.length > 0 && x === joinedRanges[0][0]) {\n          isJoined = true;\n          const range = joinedRanges.shift();\n\n          // We already know the exact start and end column of the joined range,\n          // so we get the string and width representing it directly\n\n          cell = new JoinedCellData(\n            this._workCell,\n            line.translateToString(true, range[0], range[1]),\n            range[1] - range[0]\n          );\n\n          // Skip over the cells occupied by this range in the loop\n          lastCharX = range[1] - 1;\n        }\n\n        // If the character is an overlapping char and the character to the\n        // right is a space, take ownership of the cell to the right. We skip\n        // this check for joined characters because their rendering likely won't\n        // yield the same result as rendering the last character individually.\n        if (!isJoined && this._isOverlapping(cell)) {\n          // If the character is overlapping, we want to force a re-render on every\n          // frame. This is specifically to work around the case where two\n          // overlaping chars `a` and `b` are adjacent, the cursor is moved to b and a\n          // space is added. Without this, the first half of `b` would never\n          // get removed, and `a` would not re-render because it thinks it's\n          // already in the correct state.\n          // this._state.cache[x][y] = OVERLAP_OWNED_CHAR_DATA;\n          if (lastCharX < line.length - 1 && line.getCodePoint(lastCharX + 1) === NULL_CELL_CODE) {\n            // patch width to 2\n            cell.content &= ~Content.WIDTH_MASK;\n            cell.content |= 2 << Content.WIDTH_SHIFT;\n            // this._clearChar(x + 1, y);\n            // The overlapping char's char data will force a clear and render when the\n            // overlapping char is no longer to the left of the character and also when\n            // the space changes to another character.\n            // this._state.cache[x + 1][y] = OVERLAP_OWNED_CHAR_DATA;\n          }\n        }\n\n        callback(\n          cell,\n          x,\n          y\n        );\n\n        x = lastCharX;\n      }\n    }\n  }\n\n  /**\n   * Draws the background for a specified range of columns. Tries to batch adjacent cells of the\n   * same color together to reduce draw calls.\n   */\n  private _drawBackground(terminal: ITerminal, firstRow: number, lastRow: number): void {\n    const ctx = this._ctx;\n    const cols = terminal.cols;\n    let startX: number = 0;\n    let startY: number = 0;\n    let prevFillStyle: string | null = null;\n\n    ctx.save();\n\n    this._forEachCell(terminal, firstRow, lastRow, null, (cell, x, y) => {\n      // libvte and xterm both draw the background (but not foreground) of invisible characters,\n      // so we should too.\n      let nextFillStyle = null; // null represents default background color\n\n      if (cell.isInverse()) {\n        if (cell.isFgDefault()) {\n          nextFillStyle = this._colors.foreground.css;\n        } else if (cell.isFgRGB()) {\n          nextFillStyle = `rgb(${AttributeData.toColorRGB(cell.getFgColor()).join(',')})`;\n        } else {\n          nextFillStyle = this._colors.ansi[cell.getFgColor()].css;\n        }\n      } else if (cell.isBgRGB()) {\n        nextFillStyle = `rgb(${AttributeData.toColorRGB(cell.getBgColor()).join(',')})`;\n      } else if (cell.isBgPalette()) {\n        nextFillStyle = this._colors.ansi[cell.getBgColor()].css;\n      }\n\n      if (prevFillStyle === null) {\n        // This is either the first iteration, or the default background was set. Either way, we\n        // don't need to draw anything.\n        startX = x;\n        startY = y;\n      } if (y !== startY) {\n        // our row changed, draw the previous row\n        ctx.fillStyle = prevFillStyle;\n        this.fillCells(startX, startY, cols - startX, 1);\n        startX = x;\n        startY = y;\n      } else if (prevFillStyle !== nextFillStyle) {\n        // our color changed, draw the previous characters in this row\n        ctx.fillStyle = prevFillStyle;\n        this.fillCells(startX, startY, x - startX, 1);\n        startX = x;\n        startY = y;\n      }\n\n      prevFillStyle = nextFillStyle;\n    });\n\n    // flush the last color we encountered\n    if (prevFillStyle !== null) {\n      ctx.fillStyle = prevFillStyle;\n      this.fillCells(startX, startY, cols - startX, 1);\n    }\n\n    ctx.restore();\n  }\n\n  private _drawForeground(terminal: ITerminal, firstRow: number, lastRow: number): void {\n    this._forEachCell(terminal, firstRow, lastRow, this._characterJoinerRegistry, (cell, x, y) => {\n      if (cell.isInvisible()) {\n        return;\n      }\n      if (cell.isUnderline()) {\n        this._ctx.save();\n\n        if (cell.isInverse()) {\n          if (cell.isBgDefault()) {\n            this._ctx.fillStyle = this._colors.background.css;\n          } else if (cell.isBgRGB()) {\n            this._ctx.fillStyle = `rgb(${AttributeData.toColorRGB(cell.getBgColor()).join(',')})`;\n          } else {\n            this._ctx.fillStyle = this._colors.ansi[cell.getBgColor()].css;\n          }\n        } else {\n          if (cell.isFgDefault()) {\n            this._ctx.fillStyle = this._colors.foreground.css;\n          } else if (cell.isFgRGB()) {\n            this._ctx.fillStyle = `rgb(${AttributeData.toColorRGB(cell.getFgColor()).join(',')})`;\n          } else {\n            let fg = cell.getFgColor();\n            if (terminal.options.drawBoldTextInBrightColors && cell.isBold() && fg < 8) {\n              fg += 8;\n            }\n            this._ctx.fillStyle = this._colors.ansi[fg].css;\n          }\n        }\n\n        this.fillBottomLineAtCells(x, y, cell.getWidth());\n        this._ctx.restore();\n      }\n      this.drawChars(terminal, cell, x, y);\n    });\n  }\n\n  public onGridChanged(terminal: ITerminal, firstRow: number, lastRow: number): void {\n    // Resize has not been called yet\n    if (this._state.cache.length === 0) {\n      return;\n    }\n\n    if (this._charAtlas) {\n      this._charAtlas.beginFrame();\n    }\n\n    this.clearCells(0, firstRow, terminal.cols, lastRow - firstRow + 1);\n    this._drawBackground(terminal, firstRow, lastRow);\n    this._drawForeground(terminal, firstRow, lastRow);\n  }\n\n  public onOptionsChanged(terminal: ITerminal): void {\n    this.setTransparency(terminal, terminal.options.allowTransparency);\n  }\n\n  /**\n   * Whether a character is overlapping to the next cell.\n   */\n  private _isOverlapping(cell: ICellData): boolean {\n    // Only single cell characters can be overlapping, rendering issues can\n    // occur without this check\n    if (cell.getWidth() !== 1) {\n      return false;\n    }\n\n    // We assume that any ascii character will not overlap\n    if (cell.getCode() < 256) {\n      return false;\n    }\n\n    const chars = cell.getChars();\n\n    // Deliver from cache if available\n    if (this._characterOverlapCache.hasOwnProperty(chars)) {\n      return this._characterOverlapCache[chars];\n    }\n\n    // Setup the font\n    this._ctx.save();\n    this._ctx.font = this._characterFont;\n\n    // Measure the width of the character, but Math.floor it\n    // because that is what the renderer does when it calculates\n    // the character dimensions we are comparing against\n    const overlaps = Math.floor(this._ctx.measureText(chars).width) > this._characterWidth;\n\n    // Restore the original context\n    this._ctx.restore();\n\n    // Cache and return\n    this._characterOverlapCache[chars] = overlaps;\n    return overlaps;\n  }\n\n  /**\n   * Clear the charcater at the cell specified.\n   * @param x The column of the char.\n   * @param y The row of the char.\n   */\n  // private _clearChar(x: number, y: number): void {\n  //   let colsToClear = 1;\n  //   // Clear the adjacent character if it was wide\n  //   const state = this._state.cache[x][y];\n  //   if (state && state[CHAR_DATA_WIDTH_INDEX] === 2) {\n  //     colsToClear = 2;\n  //   }\n  //   this.clearCells(x, y, colsToClear, 1);\n  // }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ITerminal } from '../Types';\nimport { IColorSet, IRenderDimensions } from './Types';\nimport { BaseRenderLayer } from './BaseRenderLayer';\n\ninterface ISelectionState {\n  start: [number, number];\n  end: [number, number];\n  columnSelectMode: boolean;\n  ydisp: number;\n}\n\nexport class SelectionRenderLayer extends BaseRenderLayer {\n  private _state: ISelectionState;\n\n  constructor(container: HTMLElement, zIndex: number, colors: IColorSet) {\n    super(container, 'selection', zIndex, true, colors);\n    this._clearState();\n  }\n\n  private _clearState(): void {\n    this._state = {\n      start: null,\n      end: null,\n      columnSelectMode: null,\n      ydisp: null\n    };\n  }\n\n  public resize(terminal: ITerminal, dim: IRenderDimensions): void {\n    super.resize(terminal, dim);\n    // Resizing the canvas discards the contents of the canvas so clear state\n    this._clearState();\n  }\n\n  public reset(terminal: ITerminal): void {\n    if (this._state.start && this._state.end) {\n      this._clearState();\n      this.clearAll();\n    }\n  }\n\n  public onSelectionChanged(terminal: ITerminal, start: [number, number], end: [number, number], columnSelectMode: boolean): void {\n    // Selection has not changed\n    if (!this._didStateChange(start, end, columnSelectMode, terminal.buffer.ydisp)) {\n      return;\n    }\n\n    // Remove all selections\n    this.clearAll();\n\n    // Selection does not exist\n    if (!start || !end) {\n      this._clearState();\n      return;\n    }\n\n    // Translate from buffer position to viewport position\n    const viewportStartRow = start[1] - terminal.buffer.ydisp;\n    const viewportEndRow = end[1] - terminal.buffer.ydisp;\n    const viewportCappedStartRow = Math.max(viewportStartRow, 0);\n    const viewportCappedEndRow = Math.min(viewportEndRow, terminal.rows - 1);\n\n    // No need to draw the selection\n    if (viewportCappedStartRow >= terminal.rows || viewportCappedEndRow < 0) {\n      return;\n    }\n\n    this._ctx.fillStyle = this._colors.selection.css;\n\n    if (columnSelectMode) {\n      const startCol = start[0];\n      const width = end[0] - startCol;\n      const height = viewportCappedEndRow - viewportCappedStartRow + 1;\n      this.fillCells(startCol, viewportCappedStartRow, width, height);\n    } else {\n      // Draw first row\n      const startCol = viewportStartRow === viewportCappedStartRow ? start[0] : 0;\n      const startRowEndCol = viewportCappedStartRow === viewportCappedEndRow ? end[0] : terminal.cols;\n      this.fillCells(startCol, viewportCappedStartRow, startRowEndCol - startCol, 1);\n\n      // Draw middle rows\n      const middleRowsCount = Math.max(viewportCappedEndRow - viewportCappedStartRow - 1, 0);\n      this.fillCells(0, viewportCappedStartRow + 1, terminal.cols, middleRowsCount);\n\n      // Draw final row\n      if (viewportCappedStartRow !== viewportCappedEndRow) {\n        // Only draw viewportEndRow if it's not the same as viewportStartRow\n        const endCol = viewportEndRow === viewportCappedEndRow ? end[0] : terminal.cols;\n        this.fillCells(0, viewportCappedEndRow, endCol, 1);\n      }\n    }\n\n    // Save state for next render\n    this._state.start = [start[0], start[1]];\n    this._state.end = [end[0], end[1]];\n    this._state.columnSelectMode = columnSelectMode;\n    this._state.ydisp = terminal.buffer.ydisp;\n  }\n\n  private _didStateChange(start: [number, number], end: [number, number], columnSelectMode: boolean, ydisp: number): boolean {\n    return !this._areCoordinatesEqual(start, this._state.start) ||\n      !this._areCoordinatesEqual(end, this._state.end) ||\n      columnSelectMode !== this._state.columnSelectMode ||\n      ydisp !== this._state.ydisp;\n  }\n\n  private _areCoordinatesEqual(coord1: [number, number], coord2: [number, number]): boolean {\n    if (!coord1 || !coord2) {\n      return false;\n    }\n\n    return coord1[0] === coord2[0] && coord1[1] === coord2[1];\n  }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { TextRenderLayer } from './TextRenderLayer';\nimport { SelectionRenderLayer } from './SelectionRenderLayer';\nimport { CursorRenderLayer } from './CursorRenderLayer';\nimport { ColorManager } from './ColorManager';\nimport { IRenderLayer, IColorSet, IRenderer, IRenderDimensions, ICharacterJoinerRegistry } from './Types';\nimport { ITerminal, CharacterJoinerHandler } from '../Types';\nimport { LinkRenderLayer } from './LinkRenderLayer';\nimport { RenderDebouncer } from '../ui/RenderDebouncer';\nimport { ScreenDprMonitor } from '../ui/ScreenDprMonitor';\nimport { ITheme } from 'xterm';\nimport { CharacterJoinerRegistry } from '../renderer/CharacterJoinerRegistry';\nimport { EventEmitter2, IEvent } from '../common/EventEmitter2';\nimport { Disposable } from '../common/Lifecycle';\n\nexport class Renderer extends Disposable implements IRenderer {\n  private _renderDebouncer: RenderDebouncer;\n\n  private _renderLayers: IRenderLayer[];\n  private _devicePixelRatio: number;\n  private _screenDprMonitor: ScreenDprMonitor;\n  private _isPaused: boolean = false;\n  private _needsFullRefresh: boolean = false;\n  private _characterJoinerRegistry: ICharacterJoinerRegistry;\n\n  public colorManager: ColorManager;\n  public dimensions: IRenderDimensions;\n\n  private _onCanvasResize = new EventEmitter2<{ width: number, height: number }>();\n  public get onCanvasResize(): IEvent<{ width: number, height: number }> { return this._onCanvasResize.event; }\n  private _onRender = new EventEmitter2<{ start: number, end: number }>();\n  public get onRender(): IEvent<{ start: number, end: number }> { return this._onRender.event; }\n\n  constructor(private _terminal: ITerminal, theme: ITheme) {\n    super();\n    const allowTransparency = this._terminal.options.allowTransparency;\n    this.colorManager = new ColorManager(document, allowTransparency);\n    this._characterJoinerRegistry = new CharacterJoinerRegistry(_terminal);\n    if (theme) {\n      this.colorManager.setTheme(theme);\n    }\n\n    this._renderLayers = [\n      new TextRenderLayer(this._terminal.screenElement, 0, this.colorManager.colors, this._characterJoinerRegistry, allowTransparency),\n      new SelectionRenderLayer(this._terminal.screenElement, 1, this.colorManager.colors),\n      new LinkRenderLayer(this._terminal.screenElement, 2, this.colorManager.colors, this._terminal),\n      new CursorRenderLayer(this._terminal.screenElement, 3, this.colorManager.colors)\n    ];\n    this.dimensions = {\n      scaledCharWidth: null,\n      scaledCharHeight: null,\n      scaledCellWidth: null,\n      scaledCellHeight: null,\n      scaledCharLeft: null,\n      scaledCharTop: null,\n      scaledCanvasWidth: null,\n      scaledCanvasHeight: null,\n      canvasWidth: null,\n      canvasHeight: null,\n      actualCellWidth: null,\n      actualCellHeight: null\n    };\n    this._devicePixelRatio = window.devicePixelRatio;\n    this._updateDimensions();\n    this.onOptionsChanged();\n\n    this._renderDebouncer = new RenderDebouncer(this._renderRows.bind(this));\n    this._screenDprMonitor = new ScreenDprMonitor();\n    this._screenDprMonitor.setListener(() => this.onWindowResize(window.devicePixelRatio));\n    this.register(this._screenDprMonitor);\n\n    // Detect whether IntersectionObserver is detected and enable renderer pause\n    // and resume based on terminal visibility if so\n    if ('IntersectionObserver' in window) {\n      const observer = new IntersectionObserver(e => this.onIntersectionChange(e[e.length - 1]), { threshold: 0 });\n      observer.observe(this._terminal.element);\n      this.register({ dispose: () => observer.disconnect() });\n    }\n  }\n\n  public dispose(): void {\n    super.dispose();\n    this._renderLayers.forEach(l => l.dispose());\n  }\n\n  public onIntersectionChange(entry: IntersectionObserverEntry): void {\n    this._isPaused = entry.intersectionRatio === 0;\n    if (!this._isPaused && this._needsFullRefresh) {\n      this._terminal.refresh(0, this._terminal.rows - 1);\n      this._needsFullRefresh = false;\n    }\n  }\n\n  public onWindowResize(devicePixelRatio: number): void {\n    // If the device pixel ratio changed, the char atlas needs to be regenerated\n    // and the terminal needs to refreshed\n    if (this._devicePixelRatio !== devicePixelRatio) {\n      this._devicePixelRatio = devicePixelRatio;\n      this.onResize(this._terminal.cols, this._terminal.rows);\n    }\n  }\n\n  public setTheme(theme: ITheme): IColorSet {\n    this.colorManager.setTheme(theme);\n\n    // Clear layers and force a full render\n    this._renderLayers.forEach(l => {\n      l.onThemeChanged(this._terminal, this.colorManager.colors);\n      l.reset(this._terminal);\n    });\n\n    if (this._isPaused) {\n      this._needsFullRefresh = true;\n    } else {\n      this._terminal.refresh(0, this._terminal.rows - 1);\n    }\n\n    return this.colorManager.colors;\n  }\n\n  public onResize(cols: number, rows: number): void {\n    // Update character and canvas dimensions\n    this._updateDimensions();\n\n    // Resize all render layers\n    this._renderLayers.forEach(l => l.resize(this._terminal, this.dimensions));\n\n    // Force a refresh\n    if (this._isPaused) {\n      this._needsFullRefresh = true;\n    } else {\n      this._terminal.refresh(0, this._terminal.rows - 1);\n    }\n\n    // Resize the screen\n    this._terminal.screenElement.style.width = `${this.dimensions.canvasWidth}px`;\n    this._terminal.screenElement.style.height = `${this.dimensions.canvasHeight}px`;\n\n    this._onCanvasResize.fire({\n      width: this.dimensions.canvasWidth,\n      height: this.dimensions.canvasHeight\n    });\n  }\n\n  public onCharSizeChanged(): void {\n    this.onResize(this._terminal.cols, this._terminal.rows);\n  }\n\n  public onBlur(): void {\n    this._runOperation(l => l.onBlur(this._terminal));\n  }\n\n  public onFocus(): void {\n    this._runOperation(l => l.onFocus(this._terminal));\n  }\n\n  public onSelectionChanged(start: [number, number], end: [number, number], columnSelectMode: boolean = false): void {\n    this._runOperation(l => l.onSelectionChanged(this._terminal, start, end, columnSelectMode));\n  }\n\n  public onCursorMove(): void {\n    this._runOperation(l => l.onCursorMove(this._terminal));\n  }\n\n  public onOptionsChanged(): void {\n    this.colorManager.allowTransparency = this._terminal.options.allowTransparency;\n    this._runOperation(l => l.onOptionsChanged(this._terminal));\n  }\n\n  public clear(): void {\n    this._runOperation(l => l.reset(this._terminal));\n  }\n\n  private _runOperation(operation: (layer: IRenderLayer) => void): void {\n    if (this._isPaused) {\n      this._needsFullRefresh = true;\n    } else {\n      this._renderLayers.forEach(l => operation(l));\n    }\n  }\n\n  /**\n   * Queues a refresh between two rows (inclusive), to be done on next animation\n   * frame.\n   * @param start The start row.\n   * @param end The end row.\n   */\n  public refreshRows(start: number, end: number): void {\n    if (this._isPaused) {\n      this._needsFullRefresh = true;\n      return;\n    }\n    this._renderDebouncer.refresh(start, end, this._terminal.rows);\n  }\n\n  /**\n   * Performs the refresh loop callback, calling refresh only if a refresh is\n   * necessary before queueing up the next one.\n   */\n  private _renderRows(start: number, end: number): void {\n    this._renderLayers.forEach(l => l.onGridChanged(this._terminal, start, end));\n    this._onRender.fire({ start, end });\n  }\n\n  /**\n   * Recalculates the character and canvas dimensions.\n   */\n  private _updateDimensions(): void {\n    // Perform a new measure if the CharMeasure dimensions are not yet available\n    if (!this._terminal.charMeasure.width || !this._terminal.charMeasure.height) {\n      return;\n    }\n\n    // Calculate the scaled character width. Width is floored as it must be\n    // drawn to an integer grid in order for the CharAtlas \"stamps\" to not be\n    // blurry. When text is drawn to the grid not using the CharAtlas, it is\n    // clipped to ensure there is no overlap with the next cell.\n    this.dimensions.scaledCharWidth = Math.floor(this._terminal.charMeasure.width * window.devicePixelRatio);\n\n    // Calculate the scaled character height. Height is ceiled in case\n    // devicePixelRatio is a floating point number in order to ensure there is\n    // enough space to draw the character to the cell.\n    this.dimensions.scaledCharHeight = Math.ceil(this._terminal.charMeasure.height * window.devicePixelRatio);\n\n    // Calculate the scaled cell height, if lineHeight is not 1 then the value\n    // will be floored because since lineHeight can never be lower then 1, there\n    // is a guarentee that the scaled line height will always be larger than\n    // scaled char height.\n    this.dimensions.scaledCellHeight = Math.floor(this.dimensions.scaledCharHeight * this._terminal.options.lineHeight);\n\n    // Calculate the y coordinate within a cell that text should draw from in\n    // order to draw in the center of a cell.\n    this.dimensions.scaledCharTop = this._terminal.options.lineHeight === 1 ? 0 : Math.round((this.dimensions.scaledCellHeight - this.dimensions.scaledCharHeight) / 2);\n\n    // Calculate the scaled cell width, taking the letterSpacing into account.\n    this.dimensions.scaledCellWidth = this.dimensions.scaledCharWidth + Math.round(this._terminal.options.letterSpacing);\n\n    // Calculate the x coordinate with a cell that text should draw from in\n    // order to draw in the center of a cell.\n    this.dimensions.scaledCharLeft = Math.floor(this._terminal.options.letterSpacing / 2);\n\n    // Recalculate the canvas dimensions; scaled* define the actual number of\n    // pixel in the canvas\n    this.dimensions.scaledCanvasHeight = this._terminal.rows * this.dimensions.scaledCellHeight;\n    this.dimensions.scaledCanvasWidth = this._terminal.cols * this.dimensions.scaledCellWidth;\n\n    // The the size of the canvas on the page. It's very important that this\n    // rounds to nearest integer and not ceils as browsers often set\n    // window.devicePixelRatio as something like 1.100000023841858, when it's\n    // actually 1.1. Ceiling causes blurriness as the backing canvas image is 1\n    // pixel too large for the canvas element size.\n    this.dimensions.canvasHeight = Math.round(this.dimensions.scaledCanvasHeight / window.devicePixelRatio);\n    this.dimensions.canvasWidth = Math.round(this.dimensions.scaledCanvasWidth / window.devicePixelRatio);\n\n    // Get the _actual_ dimensions of an individual cell. This needs to be\n    // derived from the canvasWidth/Height calculated above which takes into\n    // account window.devicePixelRatio. CharMeasure.width/height by itself is\n    // insufficient when the page is not at 100% zoom level as CharMeasure is\n    // measured in CSS pixels, but the actual char size on the canvas can\n    // differ.\n    this.dimensions.actualCellHeight = this.dimensions.canvasHeight / this._terminal.rows;\n    this.dimensions.actualCellWidth = this.dimensions.canvasWidth / this._terminal.cols;\n  }\n\n  public registerCharacterJoiner(handler: CharacterJoinerHandler): number {\n    return this._characterJoinerRegistry.registerCharacterJoiner(handler);\n  }\n\n  public deregisterCharacterJoiner(joinerId: number): boolean {\n    return this._characterJoinerRegistry.deregisterCharacterJoiner(joinerId);\n  }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ILinkifierEvent, ITerminal, ILinkifierAccessor } from '../Types';\nimport { IColorSet, IRenderDimensions } from './Types';\nimport { BaseRenderLayer } from './BaseRenderLayer';\nimport { INVERTED_DEFAULT_COLOR } from './atlas/Types';\nimport { is256Color } from './atlas/CharAtlasUtils';\n\nexport class LinkRenderLayer extends BaseRenderLayer {\n  private _state: ILinkifierEvent = null;\n\n  constructor(container: HTMLElement, zIndex: number, colors: IColorSet, terminal: ILinkifierAccessor) {\n    super(container, 'link', zIndex, true, colors);\n    terminal.linkifier.onLinkHover(e => this._onLinkHover(e));\n    terminal.linkifier.onLinkLeave(e => this._onLinkLeave(e));\n  }\n\n  public resize(terminal: ITerminal, dim: IRenderDimensions): void {\n    super.resize(terminal, dim);\n    // Resizing the canvas discards the contents of the canvas so clear state\n    this._state = null;\n  }\n\n  public reset(terminal: ITerminal): void {\n    this._clearCurrentLink();\n  }\n\n  private _clearCurrentLink(): void {\n    if (this._state) {\n      this.clearCells(this._state.x1, this._state.y1, this._state.cols - this._state.x1, 1);\n      const middleRowCount = this._state.y2 - this._state.y1 - 1;\n      if (middleRowCount > 0) {\n        this.clearCells(0, this._state.y1 + 1, this._state.cols, middleRowCount);\n      }\n      this.clearCells(0, this._state.y2, this._state.x2, 1);\n      this._state = null;\n    }\n  }\n\n  private _onLinkHover(e: ILinkifierEvent): void {\n    if (e.fg === INVERTED_DEFAULT_COLOR) {\n      this._ctx.fillStyle = this._colors.background.css;\n    } else if (is256Color(e.fg)) {\n      // 256 color support\n      this._ctx.fillStyle = this._colors.ansi[e.fg].css;\n    } else {\n      this._ctx.fillStyle = this._colors.foreground.css;\n    }\n\n    if (e.y1 === e.y2) {\n      // Single line link\n      this.fillBottomLineAtCells(e.x1, e.y1, e.x2 - e.x1);\n    } else {\n      // Multi-line link\n      this.fillBottomLineAtCells(e.x1, e.y1, e.cols - e.x1);\n      for (let y = e.y1 + 1; y < e.y2; y++) {\n        this.fillBottomLineAtCells(0, y, e.cols);\n      }\n      this.fillBottomLineAtCells(0, e.y2, e.x2);\n    }\n    this._state = e;\n  }\n\n  private _onLinkLeave(e: ILinkifierEvent): void {\n    this._clearCurrentLink();\n  }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nexport class GridCache<T> {\n  public cache: T[][];\n\n  public constructor() {\n    this.cache = [];\n  }\n\n  public resize(width: number, height: number): void {\n    for (let x = 0; x < width; x++) {\n      if (this.cache.length <= x) {\n        this.cache.push([]);\n      }\n      for (let y = this.cache[x].length; y < height; y++) {\n        this.cache[x].push(null);\n      }\n      this.cache[x].length = height;\n    }\n    this.cache.length = width;\n  }\n\n  public clear(): void {\n    for (let x = 0; x < this.cache.length; x++) {\n      for (let y = 0; y < this.cache[x].length; y++) {\n        this.cache[x][y] = null;\n      }\n    }\n  }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColorSet, IRenderDimensions } from './Types';\nimport { BaseRenderLayer } from './BaseRenderLayer';\nimport { ITerminal, ICellData } from '../Types';\nimport { CellData } from '../BufferLine';\n\ninterface ICursorState {\n  x: number;\n  y: number;\n  isFocused: boolean;\n  style: string;\n  width: number;\n}\n\n/**\n * The time between cursor blinks.\n */\nconst BLINK_INTERVAL = 600;\n\nexport class CursorRenderLayer extends BaseRenderLayer {\n  private _state: ICursorState;\n  private _cursorRenderers: {[key: string]: (terminal: ITerminal, x: number, y: number, cell: ICellData) => void};\n  private _cursorBlinkStateManager: CursorBlinkStateManager;\n  private _cell: ICellData = new CellData();\n\n  constructor(container: HTMLElement, zIndex: number, colors: IColorSet) {\n    super(container, 'cursor', zIndex, true, colors);\n    this._state = {\n      x: null,\n      y: null,\n      isFocused: null,\n      style: null,\n      width: null\n    };\n    this._cursorRenderers = {\n      'bar': this._renderBarCursor.bind(this),\n      'block': this._renderBlockCursor.bind(this),\n      'underline': this._renderUnderlineCursor.bind(this)\n    };\n    // TODO: Consider initial options? Maybe onOptionsChanged should be called at the end of open?\n  }\n\n  public resize(terminal: ITerminal, dim: IRenderDimensions): void {\n    super.resize(terminal, dim);\n    // Resizing the canvas discards the contents of the canvas so clear state\n    this._state = {\n      x: null,\n      y: null,\n      isFocused: null,\n      style: null,\n      width: null\n    };\n  }\n\n  public reset(terminal: ITerminal): void {\n    this._clearCursor();\n    if (this._cursorBlinkStateManager) {\n      this._cursorBlinkStateManager.dispose();\n      this._cursorBlinkStateManager = null;\n      this.onOptionsChanged(terminal);\n    }\n  }\n\n  public onBlur(terminal: ITerminal): void {\n    if (this._cursorBlinkStateManager) {\n      this._cursorBlinkStateManager.pause();\n    }\n    terminal.refresh(terminal.buffer.y, terminal.buffer.y);\n  }\n\n  public onFocus(terminal: ITerminal): void {\n    if (this._cursorBlinkStateManager) {\n      this._cursorBlinkStateManager.resume(terminal);\n    } else {\n      terminal.refresh(terminal.buffer.y, terminal.buffer.y);\n    }\n  }\n\n  public onOptionsChanged(terminal: ITerminal): void {\n    if (terminal.options.cursorBlink) {\n      if (!this._cursorBlinkStateManager) {\n        this._cursorBlinkStateManager = new CursorBlinkStateManager(terminal, () => {\n          this._render(terminal, true);\n        });\n      }\n    } else {\n      if (this._cursorBlinkStateManager) {\n        this._cursorBlinkStateManager.dispose();\n        this._cursorBlinkStateManager = null;\n      }\n      // Request a refresh from the terminal as management of rendering is being\n      // moved back to the terminal\n      terminal.refresh(terminal.buffer.y, terminal.buffer.y);\n    }\n  }\n\n  public onCursorMove(terminal: ITerminal): void {\n    if (this._cursorBlinkStateManager) {\n      this._cursorBlinkStateManager.restartBlinkAnimation(terminal);\n    }\n  }\n\n  public onGridChanged(terminal: ITerminal, startRow: number, endRow: number): void {\n    if (!this._cursorBlinkStateManager || this._cursorBlinkStateManager.isPaused) {\n      this._render(terminal, false);\n    } else {\n      this._cursorBlinkStateManager.restartBlinkAnimation(terminal);\n    }\n  }\n\n  private _render(terminal: ITerminal, triggeredByAnimationFrame: boolean): void {\n    // Don't draw the cursor if it's hidden\n    if (!terminal.cursorState || terminal.cursorHidden) {\n      this._clearCursor();\n      return;\n    }\n\n    const cursorY = terminal.buffer.ybase + terminal.buffer.y;\n    const viewportRelativeCursorY = cursorY - terminal.buffer.ydisp;\n\n    // Don't draw the cursor if it's off-screen\n    if (viewportRelativeCursorY < 0 || viewportRelativeCursorY >= terminal.rows) {\n      this._clearCursor();\n      return;\n    }\n\n    terminal.buffer.lines.get(cursorY).loadCell(terminal.buffer.x, this._cell);\n    if (this._cell.content === undefined) {\n      return;\n    }\n\n    if (!terminal.isFocused) {\n      this._clearCursor();\n      this._ctx.save();\n      this._ctx.fillStyle = this._colors.cursor.css;\n      this._renderBlurCursor(terminal, terminal.buffer.x, viewportRelativeCursorY, this._cell);\n      this._ctx.restore();\n      this._state.x = terminal.buffer.x;\n      this._state.y = viewportRelativeCursorY;\n      this._state.isFocused = false;\n      this._state.style = terminal.options.cursorStyle;\n      this._state.width = this._cell.getWidth();\n      return;\n    }\n\n    // Don't draw the cursor if it's blinking\n    if (this._cursorBlinkStateManager && !this._cursorBlinkStateManager.isCursorVisible) {\n      this._clearCursor();\n      return;\n    }\n\n    if (this._state) {\n      // The cursor is already in the correct spot, don't redraw\n      if (this._state.x === terminal.buffer.x &&\n          this._state.y === viewportRelativeCursorY &&\n          this._state.isFocused === terminal.isFocused &&\n          this._state.style === terminal.options.cursorStyle &&\n          this._state.width === this._cell.getWidth()) {\n        return;\n      }\n      this._clearCursor();\n    }\n\n    this._ctx.save();\n    this._cursorRenderers[terminal.options.cursorStyle || 'block'](terminal, terminal.buffer.x, viewportRelativeCursorY, this._cell);\n    this._ctx.restore();\n\n    this._state.x = terminal.buffer.x;\n    this._state.y = viewportRelativeCursorY;\n    this._state.isFocused = false;\n    this._state.style = terminal.options.cursorStyle;\n    this._state.width = this._cell.getWidth();\n  }\n\n  private _clearCursor(): void {\n    if (this._state) {\n      this.clearCells(this._state.x, this._state.y, this._state.width, 1);\n      this._state = {\n        x: null,\n        y: null,\n        isFocused: null,\n        style: null,\n        width: null\n      };\n    }\n  }\n\n  private _renderBarCursor(terminal: ITerminal, x: number, y: number, cell: ICellData): void {\n    this._ctx.save();\n    this._ctx.fillStyle = this._colors.cursor.css;\n    this.fillLeftLineAtCell(x, y);\n    this._ctx.restore();\n  }\n\n  private _renderBlockCursor(terminal: ITerminal, x: number, y: number, cell: ICellData): void {\n    this._ctx.save();\n    this._ctx.fillStyle = this._colors.cursor.css;\n    this.fillCells(x, y, cell.getWidth(), 1);\n    this._ctx.fillStyle = this._colors.cursorAccent.css;\n    this.fillCharTrueColor(terminal, cell, x, y);\n    this._ctx.restore();\n  }\n\n  private _renderUnderlineCursor(terminal: ITerminal, x: number, y: number, cell: ICellData): void {\n    this._ctx.save();\n    this._ctx.fillStyle = this._colors.cursor.css;\n    this.fillBottomLineAtCells(x, y);\n    this._ctx.restore();\n  }\n\n  private _renderBlurCursor(terminal: ITerminal, x: number, y: number, cell: ICellData): void {\n    this._ctx.save();\n    this._ctx.strokeStyle = this._colors.cursor.css;\n    this.strokeRectAtCell(x, y, cell.getWidth(), 1);\n    this._ctx.restore();\n  }\n}\n\nclass CursorBlinkStateManager {\n  public isCursorVisible: boolean;\n\n  private _animationFrame: number;\n  private _blinkStartTimeout: number;\n  private _blinkInterval: number;\n\n  /**\n   * The time at which the animation frame was restarted, this is used on the\n   * next render to restart the timers so they don't need to restart the timers\n   * multiple times over a short period.\n   */\n  private _animationTimeRestarted: number;\n\n  constructor(\n    terminal: ITerminal,\n    private _renderCallback: () => void\n  ) {\n    this.isCursorVisible = true;\n    if (terminal.isFocused) {\n      this._restartInterval();\n    }\n  }\n\n  public get isPaused(): boolean { return !(this._blinkStartTimeout || this._blinkInterval); }\n\n  public dispose(): void {\n    if (this._blinkInterval) {\n      window.clearInterval(this._blinkInterval);\n      this._blinkInterval = null;\n    }\n    if (this._blinkStartTimeout) {\n      window.clearTimeout(this._blinkStartTimeout);\n      this._blinkStartTimeout = null;\n    }\n    if (this._animationFrame) {\n      window.cancelAnimationFrame(this._animationFrame);\n      this._animationFrame = null;\n    }\n  }\n\n  public restartBlinkAnimation(terminal: ITerminal): void {\n    if (this.isPaused) {\n      return;\n    }\n    // Save a timestamp so that the restart can be done on the next interval\n    this._animationTimeRestarted = Date.now();\n    // Force a cursor render to ensure it's visible and in the correct position\n    this.isCursorVisible = true;\n    if (!this._animationFrame) {\n      this._animationFrame = window.requestAnimationFrame(() => {\n        this._renderCallback();\n        this._animationFrame = null;\n      });\n    }\n  }\n\n  private _restartInterval(timeToStart: number = BLINK_INTERVAL): void {\n    // Clear any existing interval\n    if (this._blinkInterval) {\n      window.clearInterval(this._blinkInterval);\n    }\n\n    // Setup the initial timeout which will hide the cursor, this is done before\n    // the regular interval is setup in order to support restarting the blink\n    // animation in a lightweight way (without thrashing clearInterval and\n    // setInterval).\n    this._blinkStartTimeout = <number><any>setTimeout(() => {\n      // Check if another animation restart was requested while this was being\n      // started\n      if (this._animationTimeRestarted) {\n        const time = BLINK_INTERVAL - (Date.now() - this._animationTimeRestarted);\n        this._animationTimeRestarted = null;\n        if (time > 0) {\n          this._restartInterval(time);\n          return;\n        }\n      }\n\n      // Hide the cursor\n      this.isCursorVisible = false;\n      this._animationFrame = window.requestAnimationFrame(() => {\n        this._renderCallback();\n        this._animationFrame = null;\n      });\n\n      // Setup the blink interval\n      this._blinkInterval = <number><any>setInterval(() => {\n        // Adjust the animation time if it was restarted\n        if (this._animationTimeRestarted) {\n          // calc time diff\n          // Make restart interval do a setTimeout initially?\n          const time = BLINK_INTERVAL - (Date.now() - this._animationTimeRestarted);\n          this._animationTimeRestarted = null;\n          this._restartInterval(time);\n          return;\n        }\n\n        // Invert visibility and render\n        this.isCursorVisible = !this.isCursorVisible;\n        this._animationFrame = window.requestAnimationFrame(() => {\n          this._renderCallback();\n          this._animationFrame = null;\n        });\n      }, BLINK_INTERVAL);\n    }, timeToStart);\n  }\n\n  public pause(): void {\n    this.isCursorVisible = true;\n    if (this._blinkInterval) {\n      window.clearInterval(this._blinkInterval);\n      this._blinkInterval = null;\n    }\n    if (this._blinkStartTimeout) {\n      window.clearTimeout(this._blinkStartTimeout);\n      this._blinkStartTimeout = null;\n    }\n    if (this._animationFrame) {\n      window.cancelAnimationFrame(this._animationFrame);\n      this._animationFrame = null;\n    }\n  }\n\n  public resume(terminal: ITerminal): void {\n    this._animationTimeRestarted = null;\n    this._restartInterval();\n    this.restartBlinkAnimation(terminal);\n  }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColorManager, IColor, IColorSet } from './Types';\nimport { ITheme } from 'xterm';\n\nconst DEFAULT_FOREGROUND = fromHex('#ffffff');\nconst DEFAULT_BACKGROUND = fromHex('#000000');\nconst DEFAULT_CURSOR = fromHex('#ffffff');\nconst DEFAULT_CURSOR_ACCENT = fromHex('#000000');\nconst DEFAULT_SELECTION = {\n  css: 'rgba(255, 255, 255, 0.3)',\n  rgba: 0xFFFFFF77\n};\n\n// An IIFE to generate DEFAULT_ANSI_COLORS. Do not mutate DEFAULT_ANSI_COLORS, instead make a copy\n// and mutate that.\nexport const DEFAULT_ANSI_COLORS = (() => {\n  const colors = [\n    // dark:\n    fromHex('#2e3436'),\n    fromHex('#cc0000'),\n    fromHex('#4e9a06'),\n    fromHex('#c4a000'),\n    fromHex('#3465a4'),\n    fromHex('#75507b'),\n    fromHex('#06989a'),\n    fromHex('#d3d7cf'),\n    // bright:\n    fromHex('#555753'),\n    fromHex('#ef2929'),\n    fromHex('#8ae234'),\n    fromHex('#fce94f'),\n    fromHex('#729fcf'),\n    fromHex('#ad7fa8'),\n    fromHex('#34e2e2'),\n    fromHex('#eeeeec')\n  ];\n\n  // Fill in the remaining 240 ANSI colors.\n  // Generate colors (16-231)\n  const v = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff];\n  for (let i = 0; i < 216; i++) {\n    const r = v[(i / 36) % 6 | 0];\n    const g = v[(i / 6) % 6 | 0];\n    const b = v[i % 6];\n    colors.push({\n      css: `#${toPaddedHex(r)}${toPaddedHex(g)}${toPaddedHex(b)}`,\n      // Use >>> 0 to force a conversion to an unsigned int\n      rgba: ((r << 24) | (g << 16) | (b << 8) | 0xFF) >>> 0\n    });\n  }\n\n  // Generate greys (232-255)\n  for (let i = 0; i < 24; i++) {\n    const c = 8 + i * 10;\n    const ch = toPaddedHex(c);\n    colors.push({\n      css: `#${ch}${ch}${ch}`,\n      rgba: ((c << 24) | (c << 16) | (c << 8) | 0xFF) >>> 0\n    });\n  }\n\n  return colors;\n})();\n\nfunction fromHex(css: string): IColor {\n  return {\n    css,\n    rgba: parseInt(css.slice(1), 16) << 8 | 0xFF\n  };\n}\n\nfunction toPaddedHex(c: number): string {\n  const s = c.toString(16);\n  return s.length < 2 ? '0' + s : s;\n}\n\n/**\n * Manages the source of truth for a terminal's colors.\n */\nexport class ColorManager implements IColorManager {\n  public colors: IColorSet;\n  private _ctx: CanvasRenderingContext2D;\n  private _litmusColor: CanvasGradient;\n\n  constructor(document: Document, public allowTransparency: boolean) {\n    const canvas = document.createElement('canvas');\n    canvas.width = 1;\n    canvas.height = 1;\n    this._ctx = canvas.getContext('2d');\n    this._ctx.globalCompositeOperation = 'copy';\n    this._litmusColor = this._ctx.createLinearGradient(0, 0, 1, 1);\n    this.colors = {\n      foreground: DEFAULT_FOREGROUND,\n      background: DEFAULT_BACKGROUND,\n      cursor: DEFAULT_CURSOR,\n      cursorAccent: DEFAULT_CURSOR_ACCENT,\n      selection: DEFAULT_SELECTION,\n      ansi: DEFAULT_ANSI_COLORS.slice()\n    };\n  }\n\n  /**\n   * Sets the terminal's theme.\n   * @param theme The  theme to use. If a partial theme is provided then default\n   * colors will be used where colors are not defined.\n   */\n  public setTheme(theme: ITheme): void {\n    this.colors.foreground = this._parseColor(theme.foreground, DEFAULT_FOREGROUND);\n    this.colors.background = this._parseColor(theme.background, DEFAULT_BACKGROUND);\n    this.colors.cursor = this._parseColor(theme.cursor, DEFAULT_CURSOR, true);\n    this.colors.cursorAccent = this._parseColor(theme.cursorAccent, DEFAULT_CURSOR_ACCENT, true);\n    this.colors.selection = this._parseColor(theme.selection, DEFAULT_SELECTION, true);\n    this.colors.ansi[0] = this._parseColor(theme.black, DEFAULT_ANSI_COLORS[0]);\n    this.colors.ansi[1] = this._parseColor(theme.red, DEFAULT_ANSI_COLORS[1]);\n    this.colors.ansi[2] = this._parseColor(theme.green, DEFAULT_ANSI_COLORS[2]);\n    this.colors.ansi[3] = this._parseColor(theme.yellow, DEFAULT_ANSI_COLORS[3]);\n    this.colors.ansi[4] = this._parseColor(theme.blue, DEFAULT_ANSI_COLORS[4]);\n    this.colors.ansi[5] = this._parseColor(theme.magenta, DEFAULT_ANSI_COLORS[5]);\n    this.colors.ansi[6] = this._parseColor(theme.cyan, DEFAULT_ANSI_COLORS[6]);\n    this.colors.ansi[7] = this._parseColor(theme.white, DEFAULT_ANSI_COLORS[7]);\n    this.colors.ansi[8] = this._parseColor(theme.brightBlack, DEFAULT_ANSI_COLORS[8]);\n    this.colors.ansi[9] = this._parseColor(theme.brightRed, DEFAULT_ANSI_COLORS[9]);\n    this.colors.ansi[10] = this._parseColor(theme.brightGreen, DEFAULT_ANSI_COLORS[10]);\n    this.colors.ansi[11] = this._parseColor(theme.brightYellow, DEFAULT_ANSI_COLORS[11]);\n    this.colors.ansi[12] = this._parseColor(theme.brightBlue, DEFAULT_ANSI_COLORS[12]);\n    this.colors.ansi[13] = this._parseColor(theme.brightMagenta, DEFAULT_ANSI_COLORS[13]);\n    this.colors.ansi[14] = this._parseColor(theme.brightCyan, DEFAULT_ANSI_COLORS[14]);\n    this.colors.ansi[15] = this._parseColor(theme.brightWhite, DEFAULT_ANSI_COLORS[15]);\n  }\n\n  private _parseColor(\n    css: string,\n    fallback: IColor,\n    allowTransparency: boolean = this.allowTransparency\n  ): IColor {\n    if (!css) {\n      return fallback;\n    }\n\n    // If parsing the value results in failure, then it must be ignored, and the attribute must\n    // retain its previous value.\n    // -- https://html.spec.whatwg.org/multipage/canvas.html#fill-and-stroke-styles\n    this._ctx.fillStyle = this._litmusColor;\n    this._ctx.fillStyle = css;\n    if (typeof this._ctx.fillStyle !== 'string') {\n      console.warn(`Color: ${css} is invalid using fallback ${fallback.css}`);\n      return fallback;\n    }\n\n    this._ctx.fillRect(0, 0, 1, 1);\n    const data = this._ctx.getImageData(0, 0, 1, 1).data;\n\n    if (!allowTransparency && data[3] !== 0xFF) {\n      // Ideally we'd just ignore the alpha channel, but...\n      //\n      // Browsers may not give back exactly the same RGB values we put in, because most/all\n      // convert the color to a pre-multiplied representation. getImageData converts that back to\n      // a un-premultipled representation, but the precision loss may make the RGB channels unuable\n      // on their own.\n      //\n      // E.g. In Chrome #12345610 turns into #10305010, and in the extreme case, 0xFFFFFF00 turns\n      // into 0x00000000.\n      //\n      // \"Note: Due to the lossy nature of converting to and from premultiplied alpha color values,\n      // pixels that have just been set using putImageData() might be returned to an equivalent\n      // getImageData() as different values.\"\n      // -- https://html.spec.whatwg.org/multipage/canvas.html#pixel-manipulation\n      //\n      // So let's just use the fallback color in this case instead.\n      console.warn(\n        `Color: ${css} is using transparency, but allowTransparency is false. ` +\n        `Using fallback ${fallback.css}.`\n      );\n      return fallback;\n    }\n\n    return {\n      css,\n      rgba: (data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]) >>> 0\n    };\n  }\n}\n","import { ITerminal, IBufferLine, ICellData, CharData } from '../Types';\nimport { ICharacterJoinerRegistry, ICharacterJoiner } from './Types';\nimport { CellData, Content, AttributeData } from '../BufferLine';\nimport { WHITESPACE_CELL_CHAR } from '../Buffer';\n\nexport class JoinedCellData extends AttributeData implements ICellData {\n  private _width: number;\n  // .content carries no meaning for joined CellData, simply nullify it\n  // thus we have to overload all other .content accessors\n  public content: number = 0;\n  public fg: number;\n  public bg: number;\n  public combinedData: string = '';\n\n  constructor(firstCell: ICellData, chars: string, width: number) {\n    super();\n    this.fg = firstCell.fg;\n    this.bg = firstCell.bg;\n    this.combinedData = chars;\n    this._width = width;\n  }\n\n  public isCombined(): number {\n    // always mark joined cell data as combined\n    return Content.IS_COMBINED_MASK;\n  }\n\n  public getWidth(): number {\n    return this._width;\n  }\n\n  public getChars(): string {\n    return this.combinedData;\n  }\n\n  public getCode(): number {\n    // code always gets the highest possible fake codepoint (read as -1)\n    // this is needed as code is used by caches as identifier\n    return 0x1FFFFF;\n  }\n\n  public setFromCharData(value: CharData): void {\n    throw new Error('not implemented');\n  }\n\n  public getAsCharData(): CharData {\n    return [this.fg, this.getChars(), this.getWidth(), this.getCode()];\n  }\n}\n\nexport class CharacterJoinerRegistry implements ICharacterJoinerRegistry {\n\n  private _characterJoiners: ICharacterJoiner[] = [];\n  private _nextCharacterJoinerId: number = 0;\n  private _workCell: CellData = new CellData();\n\n  constructor(private _terminal: ITerminal) {\n  }\n\n  public registerCharacterJoiner(handler: (text: string) => [number, number][]): number {\n    const joiner: ICharacterJoiner = {\n      id: this._nextCharacterJoinerId++,\n      handler\n    };\n\n    this._characterJoiners.push(joiner);\n    return joiner.id;\n  }\n\n  public deregisterCharacterJoiner(joinerId: number): boolean {\n    for (let i = 0; i < this._characterJoiners.length; i++) {\n      if (this._characterJoiners[i].id === joinerId) {\n        this._characterJoiners.splice(i, 1);\n        return true;\n      }\n    }\n\n    return false;\n  }\n\n  public getJoinedCharacters(row: number): [number, number][] {\n    if (this._characterJoiners.length === 0) {\n      return [];\n    }\n\n    const line = this._terminal.buffer.lines.get(row);\n    if (line.length === 0) {\n      return [];\n    }\n\n    const ranges: [number, number][] = [];\n    const lineStr = line.translateToString(true);\n\n    // Because some cells can be represented by multiple javascript characters,\n    // we track the cell and the string indexes separately. This allows us to\n    // translate the string ranges we get from the joiners back into cell ranges\n    // for use when rendering\n    let rangeStartColumn = 0;\n    let currentStringIndex = 0;\n    let rangeStartStringIndex = 0;\n    let rangeAttrFG = line.getFg(0);\n    let rangeAttrBG = line.getBg(0);\n\n    for (let x = 0; x < line.getTrimmedLength(); x++) {\n      line.loadCell(x, this._workCell);\n\n      if (this._workCell.getWidth() === 0) {\n        // If this character is of width 0, skip it.\n        continue;\n      }\n\n      // End of range\n      if (this._workCell.fg !== rangeAttrFG || this._workCell.bg !== rangeAttrBG) {\n        // If we ended up with a sequence of more than one character,\n        // look for ranges to join.\n        if (x - rangeStartColumn > 1) {\n          const joinedRanges = this._getJoinedRanges(\n            lineStr,\n            rangeStartStringIndex,\n            currentStringIndex,\n            line,\n            rangeStartColumn\n          );\n          for (let i = 0; i < joinedRanges.length; i++) {\n            ranges.push(joinedRanges[i]);\n          }\n        }\n\n        // Reset our markers for a new range.\n        rangeStartColumn = x;\n        rangeStartStringIndex = currentStringIndex;\n        rangeAttrFG = this._workCell.fg;\n        rangeAttrBG = this._workCell.bg;\n      }\n\n      currentStringIndex += this._workCell.getChars().length || WHITESPACE_CELL_CHAR.length;\n    }\n\n    // Process any trailing ranges.\n    if (this._terminal.cols - rangeStartColumn > 1) {\n      const joinedRanges = this._getJoinedRanges(\n        lineStr,\n        rangeStartStringIndex,\n        currentStringIndex,\n        line,\n        rangeStartColumn\n      );\n      for (let i = 0; i < joinedRanges.length; i++) {\n        ranges.push(joinedRanges[i]);\n      }\n    }\n\n    return ranges;\n  }\n\n  /**\n   * Given a segment of a line of text, find all ranges of text that should be\n   * joined in a single rendering unit. Ranges are internally converted to\n   * column ranges, rather than string ranges.\n   * @param line String representation of the full line of text\n   * @param startIndex Start position of the range to search in the string (inclusive)\n   * @param endIndex End position of the range to search in the string (exclusive)\n   */\n  private _getJoinedRanges(line: string, startIndex: number, endIndex: number, lineData: IBufferLine, startCol: number): [number, number][] {\n    const text = line.substring(startIndex, endIndex);\n    // At this point we already know that there is at least one joiner so\n    // we can just pull its value and assign it directly rather than\n    // merging it into an empty array, which incurs unnecessary writes.\n    const joinedRanges: [number, number][] = this._characterJoiners[0].handler(text);\n    for (let i = 1; i < this._characterJoiners.length; i++) {\n      // We merge any overlapping ranges across the different joiners\n      const joinerRanges = this._characterJoiners[i].handler(text);\n      for (let j = 0; j < joinerRanges.length; j++) {\n        CharacterJoinerRegistry._mergeRanges(joinedRanges, joinerRanges[j]);\n      }\n    }\n    this._stringRangesToCellRanges(joinedRanges, lineData, startCol);\n    return joinedRanges;\n  }\n\n  /**\n   * Modifies the provided ranges in-place to adjust for variations between\n   * string length and cell width so that the range represents a cell range,\n   * rather than the string range the joiner provides.\n   * @param ranges String ranges containing start (inclusive) and end (exclusive) index\n   * @param line Cell data for the relevant line in the terminal\n   * @param startCol Offset within the line to start from\n   */\n  private _stringRangesToCellRanges(ranges: [number, number][], line: IBufferLine, startCol: number): void {\n    let currentRangeIndex = 0;\n    let currentRangeStarted = false;\n    let currentStringIndex = 0;\n    let currentRange = ranges[currentRangeIndex];\n\n    // If we got through all of the ranges, stop searching\n    if (!currentRange) {\n      return;\n    }\n\n    for (let x = startCol; x < this._terminal.cols; x++) {\n      const width = line.getWidth(x);\n      const length = line.getString(x).length || WHITESPACE_CELL_CHAR.length;\n\n      // We skip zero-width characters when creating the string to join the text\n      // so we do the same here\n      if (width === 0) {\n        continue;\n      }\n\n      // Adjust the start of the range\n      if (!currentRangeStarted && currentRange[0] <= currentStringIndex) {\n        currentRange[0] = x;\n        currentRangeStarted = true;\n      }\n\n      // Adjust the end of the range\n      if (currentRange[1] <= currentStringIndex) {\n        currentRange[1] = x;\n\n        // We're finished with this range, so we move to the next one\n        currentRange = ranges[++currentRangeIndex];\n\n        // If there are no more ranges left, stop searching\n        if (!currentRange) {\n          break;\n        }\n\n        // Ranges can be on adjacent characters. Because the end index of the\n        // ranges are exclusive, this means that the index for the start of a\n        // range can be the same as the end index of the previous range. To\n        // account for the start of the next range, we check here just in case.\n        if (currentRange[0] <= currentStringIndex) {\n          currentRange[0] = x;\n          currentRangeStarted = true;\n        } else {\n          currentRangeStarted = false;\n        }\n      }\n\n      // Adjust the string index based on the character length to line up with\n      // the column adjustment\n      currentStringIndex += length;\n    }\n\n    // If there is still a range left at the end, it must extend all the way to\n    // the end of the line.\n    if (currentRange) {\n      currentRange[1] = this._terminal.cols;\n    }\n  }\n\n  /**\n   * Merges the range defined by the provided start and end into the list of\n   * existing ranges. The merge is done in place on the existing range for\n   * performance and is also returned.\n   * @param ranges Existing range list\n   * @param newRange Tuple of two numbers representing the new range to merge in.\n   * @returns The ranges input with the new range merged in place\n   */\n  private static _mergeRanges(ranges: [number, number][], newRange: [number, number]): [number, number][] {\n    let inRange = false;\n    for (let i = 0; i < ranges.length; i++) {\n      const range = ranges[i];\n      if (!inRange) {\n        if (newRange[1] <= range[0]) {\n          // Case 1: New range is before the search range\n          ranges.splice(i, 0, newRange);\n          return ranges;\n        }\n\n        if (newRange[1] <= range[1]) {\n          // Case 2: New range is either wholly contained within the\n          // search range or overlaps with the front of it\n          range[0] = Math.min(newRange[0], range[0]);\n          return ranges;\n        }\n\n        if (newRange[0] < range[1]) {\n          // Case 3: New range either wholly contains the search range\n          // or overlaps with the end of it\n          range[0] = Math.min(newRange[0], range[0]);\n          inRange = true;\n        }\n\n        // Case 4: New range starts after the search range\n        continue;\n      } else {\n        if (newRange[1] <= range[0]) {\n          // Case 5: New range extends from previous range but doesn't\n          // reach the current one\n          ranges[i - 1][1] = newRange[1];\n          return ranges;\n        }\n\n        if (newRange[1] <= range[1]) {\n          // Case 6: New range extends from prvious range into the\n          // current range\n          ranges[i - 1][1] = Math.max(newRange[1], range[1]);\n          ranges.splice(i, 1);\n          inRange = false;\n          return ranges;\n        }\n\n        // Case 7: New range extends from previous range past the\n        // end of the current range\n        ranges.splice(i, 1);\n        i--;\n      }\n    }\n\n    if (inRange) {\n      // Case 8: New range extends past the last existing range\n      ranges[ranges.length - 1][1] = newRange[1];\n    } else {\n      // Case 9: New range starts after the last existing range\n      ranges.push(newRange);\n    }\n\n    return ranges;\n  }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IRenderLayer, IColorSet, IRenderDimensions } from './Types';\nimport { ITerminal, ICellData } from '../Types';\nimport { DIM_OPACITY, INVERTED_DEFAULT_COLOR, IGlyphIdentifier, DEFAULT_COLOR } from './atlas/Types';\nimport BaseCharAtlas from './atlas/BaseCharAtlas';\nimport { acquireCharAtlas } from './atlas/CharAtlasCache';\nimport { CellData, AttributeData } from '../BufferLine';\nimport { WHITESPACE_CELL_CHAR, WHITESPACE_CELL_CODE } from '../Buffer';\nimport { JoinedCellData } from './CharacterJoinerRegistry';\n\nexport abstract class BaseRenderLayer implements IRenderLayer {\n  private _canvas: HTMLCanvasElement;\n  protected _ctx: CanvasRenderingContext2D;\n  private _scaledCharWidth: number = 0;\n  private _scaledCharHeight: number = 0;\n  private _scaledCellWidth: number = 0;\n  private _scaledCellHeight: number = 0;\n  private _scaledCharLeft: number = 0;\n  private _scaledCharTop: number = 0;\n\n  protected _charAtlas: BaseCharAtlas;\n\n  /**\n   * An object that's reused when drawing glyphs in order to reduce GC.\n   */\n  private _currentGlyphIdentifier: IGlyphIdentifier = {\n    chars: '',\n    code: 0,\n    bg: 0,\n    fg: 0,\n    bold: false,\n    dim: false,\n    italic: false\n  };\n\n  constructor(\n    private _container: HTMLElement,\n    id: string,\n    zIndex: number,\n    private _alpha: boolean,\n    protected _colors: IColorSet\n  ) {\n    this._canvas = document.createElement('canvas');\n    this._canvas.classList.add(`xterm-${id}-layer`);\n    this._canvas.style.zIndex = zIndex.toString();\n    this._initCanvas();\n    this._container.appendChild(this._canvas);\n  }\n\n  public dispose(): void {\n    this._container.removeChild(this._canvas);\n    if (this._charAtlas) {\n      this._charAtlas.dispose();\n    }\n  }\n\n  private _initCanvas(): void {\n    this._ctx = this._canvas.getContext('2d', {alpha: this._alpha});\n    // Draw the background if this is an opaque layer\n    if (!this._alpha) {\n      this.clearAll();\n    }\n  }\n\n  public onOptionsChanged(terminal: ITerminal): void {}\n  public onBlur(terminal: ITerminal): void {}\n  public onFocus(terminal: ITerminal): void {}\n  public onCursorMove(terminal: ITerminal): void {}\n  public onGridChanged(terminal: ITerminal, startRow: number, endRow: number): void {}\n  public onSelectionChanged(terminal: ITerminal, start: [number, number], end: [number, number], columnSelectMode: boolean = false): void {}\n\n  public onThemeChanged(terminal: ITerminal, colorSet: IColorSet): void {\n    this._refreshCharAtlas(terminal, colorSet);\n  }\n\n  protected setTransparency(terminal: ITerminal, alpha: boolean): void {\n    // Do nothing when alpha doesn't change\n    if (alpha === this._alpha) {\n      return;\n    }\n\n    // Create new canvas and replace old one\n    const oldCanvas = this._canvas;\n    this._alpha = alpha;\n    // Cloning preserves properties\n    this._canvas = <HTMLCanvasElement>this._canvas.cloneNode();\n    this._initCanvas();\n    this._container.replaceChild(this._canvas, oldCanvas);\n\n    // Regenerate char atlas and force a full redraw\n    this._refreshCharAtlas(terminal, this._colors);\n    this.onGridChanged(terminal, 0, terminal.rows - 1);\n  }\n\n  /**\n   * Refreshes the char atlas, aquiring a new one if necessary.\n   * @param terminal The terminal.\n   * @param colorSet The color set to use for the char atlas.\n   */\n  private _refreshCharAtlas(terminal: ITerminal, colorSet: IColorSet): void {\n    if (this._scaledCharWidth <= 0 && this._scaledCharHeight <= 0) {\n      return;\n    }\n    this._charAtlas = acquireCharAtlas(terminal, colorSet, this._scaledCharWidth, this._scaledCharHeight);\n    this._charAtlas.warmUp();\n  }\n\n  public resize(terminal: ITerminal, dim: IRenderDimensions): void {\n    this._scaledCellWidth = dim.scaledCellWidth;\n    this._scaledCellHeight = dim.scaledCellHeight;\n    this._scaledCharWidth = dim.scaledCharWidth;\n    this._scaledCharHeight = dim.scaledCharHeight;\n    this._scaledCharLeft = dim.scaledCharLeft;\n    this._scaledCharTop = dim.scaledCharTop;\n    this._canvas.width = dim.scaledCanvasWidth;\n    this._canvas.height = dim.scaledCanvasHeight;\n    this._canvas.style.width = `${dim.canvasWidth}px`;\n    this._canvas.style.height = `${dim.canvasHeight}px`;\n\n    // Draw the background if this is an opaque layer\n    if (!this._alpha) {\n      this.clearAll();\n    }\n\n    this._refreshCharAtlas(terminal, this._colors);\n  }\n\n  public abstract reset(terminal: ITerminal): void;\n\n  /**\n   * Fills 1+ cells completely. This uses the existing fillStyle on the context.\n   * @param x The column to start at.\n   * @param y The row to start at\n   * @param width The number of columns to fill.\n   * @param height The number of rows to fill.\n   */\n  protected fillCells(x: number, y: number, width: number, height: number): void {\n    this._ctx.fillRect(\n        x * this._scaledCellWidth,\n        y * this._scaledCellHeight,\n        width * this._scaledCellWidth,\n        height * this._scaledCellHeight);\n  }\n\n  /**\n   * Fills a 1px line (2px on HDPI) at the bottom of the cell. This uses the\n   * existing fillStyle on the context.\n   * @param x The column to fill.\n   * @param y The row to fill.\n   */\n  protected fillBottomLineAtCells(x: number, y: number, width: number = 1): void {\n    this._ctx.fillRect(\n        x * this._scaledCellWidth,\n        (y + 1) * this._scaledCellHeight - window.devicePixelRatio - 1 /* Ensure it's drawn within the cell */,\n        width * this._scaledCellWidth,\n        window.devicePixelRatio);\n  }\n\n  /**\n   * Fills a 1px line (2px on HDPI) at the left of the cell. This uses the\n   * existing fillStyle on the context.\n   * @param x The column to fill.\n   * @param y The row to fill.\n   */\n  protected fillLeftLineAtCell(x: number, y: number): void {\n    this._ctx.fillRect(\n        x * this._scaledCellWidth,\n        y * this._scaledCellHeight,\n        window.devicePixelRatio,\n        this._scaledCellHeight);\n  }\n\n  /**\n   * Strokes a 1px rectangle (2px on HDPI) around a cell. This uses the existing\n   * strokeStyle on the context.\n   * @param x The column to fill.\n   * @param y The row to fill.\n   */\n  protected strokeRectAtCell(x: number, y: number, width: number, height: number): void {\n    this._ctx.lineWidth = window.devicePixelRatio;\n    this._ctx.strokeRect(\n        x * this._scaledCellWidth + window.devicePixelRatio / 2,\n        y * this._scaledCellHeight + (window.devicePixelRatio / 2),\n        width * this._scaledCellWidth - window.devicePixelRatio,\n        (height * this._scaledCellHeight) - window.devicePixelRatio);\n  }\n\n  /**\n   * Clears the entire canvas.\n   */\n  protected clearAll(): void {\n    if (this._alpha) {\n      this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);\n    } else {\n      this._ctx.fillStyle = this._colors.background.css;\n      this._ctx.fillRect(0, 0, this._canvas.width, this._canvas.height);\n    }\n  }\n\n  /**\n   * Clears 1+ cells completely.\n   * @param x The column to start at.\n   * @param y The row to start at.\n   * @param width The number of columns to clear.\n   * @param height The number of rows to clear.\n   */\n  protected clearCells(x: number, y: number, width: number, height: number): void {\n    if (this._alpha) {\n      this._ctx.clearRect(\n          x * this._scaledCellWidth,\n          y * this._scaledCellHeight,\n          width * this._scaledCellWidth,\n          height * this._scaledCellHeight);\n    } else {\n      this._ctx.fillStyle = this._colors.background.css;\n      this._ctx.fillRect(\n          x * this._scaledCellWidth,\n          y * this._scaledCellHeight,\n          width * this._scaledCellWidth,\n          height * this._scaledCellHeight);\n    }\n  }\n\n  /**\n   * Draws a truecolor character at the cell. The character will be clipped to\n   * ensure that it fits with the cell, including the cell to the right if it's\n   * a wide character. This uses the existing fillStyle on the context.\n   * @param terminal The terminal.\n   * @param cell The cell data for the character to draw.\n   * @param x The column to draw at.\n   * @param y The row to draw at.\n   * @param color The color of the character.\n   */\n  protected fillCharTrueColor(terminal: ITerminal, cell: CellData, x: number, y: number): void {\n    this._ctx.font = this._getFont(terminal, false, false);\n    this._ctx.textBaseline = 'middle';\n    this._clipRow(terminal, y);\n    this._ctx.fillText(\n        cell.getChars(),\n        x * this._scaledCellWidth + this._scaledCharLeft,\n        y * this._scaledCellHeight + this._scaledCharTop + this._scaledCharHeight / 2);\n  }\n\n  /**\n   * Draws one or more characters at a cell. If possible this will draw using\n   * the character atlas to reduce draw time.\n   * @param terminal The terminal.\n   * @param chars The character or characters.\n   * @param code The character code.\n   * @param width The width of the characters.\n   * @param x The column to draw at.\n   * @param y The row to draw at.\n   * @param fg The foreground color, in the format stored within the attributes.\n   * @param bg The background color, in the format stored within the attributes.\n   * This is used to validate whether a cached image can be used.\n   * @param bold Whether the text is bold.\n   */\n  protected drawChars(terminal: ITerminal, cell: ICellData, x: number, y: number): void {\n\n    // skip cache right away if we draw in RGB\n    // Note: to avoid bad runtime JoinedCellData will be skipped\n    //       in the cache handler (atlasDidDraw == false) itself and\n    //       fall through to uncached later down below\n    if (cell.isFgRGB() || cell.isBgRGB() || cell instanceof JoinedCellData) {\n      this._drawUncachedChars(terminal, cell, x, y);\n      return;\n    }\n\n    let fg;\n    let bg;\n    if (cell.isInverse()) {\n      fg = (cell.isBgDefault()) ? INVERTED_DEFAULT_COLOR : cell.getBgColor();\n      bg = (cell.isFgDefault()) ? INVERTED_DEFAULT_COLOR : cell.getFgColor();\n    } else {\n      bg = (cell.isBgDefault()) ? DEFAULT_COLOR : cell.getBgColor();\n      fg = (cell.isFgDefault()) ? DEFAULT_COLOR : cell.getFgColor();\n    }\n\n    const drawInBrightColor = terminal.options.drawBoldTextInBrightColors && cell.isBold() && fg < 8 && fg !== INVERTED_DEFAULT_COLOR;\n\n    fg += drawInBrightColor ? 8 : 0;\n    this._currentGlyphIdentifier.chars = cell.getChars() || WHITESPACE_CELL_CHAR;\n    this._currentGlyphIdentifier.code = cell.getCode() || WHITESPACE_CELL_CODE;\n    this._currentGlyphIdentifier.bg = bg;\n    this._currentGlyphIdentifier.fg = fg;\n    this._currentGlyphIdentifier.bold = cell.isBold() && terminal.options.enableBold;\n    this._currentGlyphIdentifier.dim = !!cell.isDim();\n    this._currentGlyphIdentifier.italic = !!cell.isItalic();\n    const atlasDidDraw = this._charAtlas && this._charAtlas.draw(\n      this._ctx,\n      this._currentGlyphIdentifier,\n      x * this._scaledCellWidth + this._scaledCharLeft,\n      y * this._scaledCellHeight + this._scaledCharTop\n    );\n\n    if (!atlasDidDraw) {\n      this._drawUncachedChars(terminal, cell, x, y);\n    }\n  }\n\n  /**\n   * Draws one or more characters at one or more cells. The character(s) will be\n   * clipped to ensure that they fit with the cell(s), including the cell to the\n   * right if the last character is a wide character.\n   * @param terminal The terminal.\n   * @param chars The character.\n   * @param width The width of the character.\n   * @param fg The foreground color, in the format stored within the attributes.\n   * @param x The column to draw at.\n   * @param y The row to draw at.\n   */\n  private _drawUncachedChars(terminal: ITerminal, cell: ICellData, x: number, y: number): void {\n    this._ctx.save();\n    this._ctx.font = this._getFont(terminal, cell.isBold() && terminal.options.enableBold, !!cell.isItalic());\n    this._ctx.textBaseline = 'middle';\n\n    if (cell.isInverse()) {\n      if (cell.isBgDefault()) {\n        this._ctx.fillStyle = this._colors.background.css;\n      } else if (cell.isBgRGB()) {\n        this._ctx.fillStyle = `rgb(${AttributeData.toColorRGB(cell.getBgColor()).join(',')})`;\n      } else {\n        this._ctx.fillStyle = this._colors.ansi[cell.getBgColor()].css;\n      }\n    } else {\n      if (cell.isFgDefault()) {\n        this._ctx.fillStyle = this._colors.foreground.css;\n      } else if (cell.isFgRGB()) {\n        this._ctx.fillStyle = `rgb(${AttributeData.toColorRGB(cell.getFgColor()).join(',')})`;\n      } else {\n        let fg = cell.getFgColor();\n        if (terminal.options.drawBoldTextInBrightColors && cell.isBold() && fg < 8) {\n          fg += 8;\n        }\n        this._ctx.fillStyle = this._colors.ansi[fg].css;\n      }\n    }\n\n    this._clipRow(terminal, y);\n\n    // Apply alpha to dim the character\n    if (cell.isDim()) {\n      this._ctx.globalAlpha = DIM_OPACITY;\n    }\n    // Draw the character\n    this._ctx.fillText(\n        cell.getChars(),\n        x * this._scaledCellWidth + this._scaledCharLeft,\n        y * this._scaledCellHeight + this._scaledCharTop + this._scaledCharHeight / 2);\n    this._ctx.restore();\n  }\n\n  /**\n   * Clips a row to ensure no pixels will be drawn outside the cells in the row.\n   * @param terminal The terminal.\n   * @param y The row to clip.\n   */\n  private _clipRow(terminal: ITerminal, y: number): void {\n    this._ctx.beginPath();\n    this._ctx.rect(\n        0,\n        y * this._scaledCellHeight,\n        terminal.cols * this._scaledCellWidth,\n        this._scaledCellHeight);\n    this._ctx.clip();\n  }\n\n  /**\n   * Gets the current font.\n   * @param terminal The terminal.\n   * @param isBold If we should use the bold fontWeight.\n   */\n  protected _getFont(terminal: ITerminal, isBold: boolean, isItalic: boolean): string {\n    const fontWeight = isBold ? terminal.options.fontWeightBold : terminal.options.fontWeight;\n    const fontStyle = isItalic ? 'italic' : '';\n\n    return `${fontStyle} ${fontWeight} ${terminal.options.fontSize * window.devicePixelRatio}px ${terminal.options.fontFamily}`;\n  }\n}\n\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Terminal as ITerminalApi, ITerminalOptions, IMarker, IDisposable, ILinkMatcherOptions, ITheme, ILocalizableStrings } from 'xterm';\nimport { ITerminal } from '../Types';\nimport { Terminal as TerminalCore } from '../Terminal';\nimport * as Strings from '../Strings';\nimport { IEvent } from '../common/EventEmitter2';\n\nexport class Terminal implements ITerminalApi {\n  private _core: ITerminal;\n\n  constructor(options?: ITerminalOptions) {\n    this._core = new TerminalCore(options);\n  }\n\n  public get onCursorMove(): IEvent<void> { return this._core.onCursorMove; }\n  public get onLineFeed(): IEvent<void> { return this._core.onLineFeed; }\n  public get onSelectionChange(): IEvent<void> { return this._core.onSelectionChange; }\n  public get onData(): IEvent<string> { return this._core.onData; }\n  public get onTitleChange(): IEvent<string> { return this._core.onTitleChange; }\n  public get onScroll(): IEvent<number> { return this._core.onScroll; }\n  public get onKey(): IEvent<{ key: string, domEvent: KeyboardEvent }> { return this._core.onKey; }\n  public get onRender(): IEvent<{ start: number, end: number }> { return this._core.onRender; }\n  public get onResize(): IEvent<{ cols: number, rows: number }> { return this._core.onResize; }\n\n  public get element(): HTMLElement { return this._core.element; }\n  public get textarea(): HTMLTextAreaElement { return this._core.textarea; }\n  public get rows(): number { return this._core.rows; }\n  public get cols(): number { return this._core.cols; }\n  public get markers(): ReadonlyArray<IMarker> { return this._core.markers; }\n  public blur(): void {\n    this._core.blur();\n  }\n  public focus(): void {\n    this._core.focus();\n  }\n  public on(type: 'blur' | 'focus' | 'linefeed' | 'selection', listener: () => void): void;\n  public on(type: 'data', listener: (...args: any[]) => void): void;\n  public on(type: 'key', listener: (key?: string, event?: KeyboardEvent) => void): void;\n  public on(type: 'keypress' | 'keydown', listener: (event?: KeyboardEvent) => void): void;\n  public on(type: 'refresh', listener: (data?: { start: number; end: number; }) => void): void;\n  public on(type: 'resize', listener: (data?: { cols: number; rows: number; }) => void): void;\n  public on(type: 'scroll', listener: (ydisp?: number) => void): void;\n  public on(type: 'title', listener: (title?: string) => void): void;\n  public on(type: string, listener: (...args: any[]) => void): void;\n  public on(type: any, listener: any): void {\n    this._core.on(type, listener);\n  }\n  public off(type: string, listener: (...args: any[]) => void): void {\n    this._core.off(type, listener);\n  }\n  public emit(type: string, data?: any): void {\n    this._core.emit(type, data);\n  }\n  public addDisposableListener(type: string, handler: (...args: any[]) => void): IDisposable {\n    return this._core.addDisposableListener(type, handler);\n  }\n  public resize(columns: number, rows: number): void {\n    this._core.resize(columns, rows);\n  }\n  public writeln(data: string): void {\n    this._core.writeln(data);\n  }\n  public open(parent: HTMLElement): void {\n    this._core.open(parent);\n  }\n  public attachCustomKeyEventHandler(customKeyEventHandler: (event: KeyboardEvent) => boolean): void {\n    this._core.attachCustomKeyEventHandler(customKeyEventHandler);\n  }\n  public addCsiHandler(flag: string, callback: (params: number[], collect: string) => boolean): IDisposable {\n    return this._core.addCsiHandler(flag, callback);\n  }\n  public addOscHandler(ident: number, callback: (data: string) => boolean): IDisposable {\n    return this._core.addOscHandler(ident, callback);\n  }\n  public registerLinkMatcher(regex: RegExp, handler: (event: MouseEvent, uri: string) => void, options?: ILinkMatcherOptions): number {\n    return this._core.registerLinkMatcher(regex, handler, options);\n  }\n  public deregisterLinkMatcher(matcherId: number): void {\n    this._core.deregisterLinkMatcher(matcherId);\n  }\n  public registerCharacterJoiner(handler: (text: string) => [number, number][]): number {\n    return this._core.registerCharacterJoiner(handler);\n  }\n  public deregisterCharacterJoiner(joinerId: number): void {\n    this._core.deregisterCharacterJoiner(joinerId);\n  }\n  public addMarker(cursorYOffset: number): IMarker {\n    return this._core.addMarker(cursorYOffset);\n  }\n  public hasSelection(): boolean {\n    return this._core.hasSelection();\n  }\n  public getSelection(): string {\n    return this._core.getSelection();\n  }\n  public clearSelection(): void {\n    this._core.clearSelection();\n  }\n  public selectAll(): void {\n    this._core.selectAll();\n  }\n  public selectLines(start: number, end: number): void {\n    this._core.selectLines(start, end);\n  }\n  public dispose(): void {\n    this._core.dispose();\n  }\n  public destroy(): void {\n    this._core.destroy();\n  }\n  public scrollLines(amount: number): void {\n    this._core.scrollLines(amount);\n  }\n  public scrollPages(pageCount: number): void {\n    this._core.scrollPages(pageCount);\n  }\n  public scrollToTop(): void {\n    this._core.scrollToTop();\n  }\n  public scrollToBottom(): void {\n    this._core.scrollToBottom();\n  }\n  public scrollToLine(line: number): void {\n    this._core.scrollToLine(line);\n  }\n  public clear(): void {\n    this._core.clear();\n  }\n  public write(data: string): void {\n    this._core.write(data);\n  }\n  public getOption(key: 'bellSound' | 'bellStyle' | 'cursorStyle' | 'fontFamily' | 'fontWeight' | 'fontWeightBold' | 'rendererType' | 'termName'): string;\n  public getOption(key: 'allowTransparency' | 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'debug' | 'disableStdin' | 'enableBold' | 'macOptionIsMeta' | 'rightClickSelectsWord' | 'popOnBell' | 'screenKeys' | 'useFlowControl' | 'visualBell'): boolean;\n  public getOption(key: 'colors'): string[];\n  public getOption(key: 'cols' | 'fontSize' | 'letterSpacing' | 'lineHeight' | 'rows' | 'tabStopWidth' | 'scrollback'): number;\n  public getOption(key: 'handler'): (data: string) => void;\n  public getOption(key: string): any;\n  public getOption(key: any): any {\n    return this._core.getOption(key);\n  }\n  public setOption(key: 'bellSound' | 'fontFamily' | 'termName', value: string): void;\n  public setOption(key: 'fontWeight' | 'fontWeightBold', value: 'normal' | 'bold' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900'): void;\n  public setOption(key: 'bellStyle', value: 'none' | 'visual' | 'sound' | 'both'): void;\n  public setOption(key: 'cursorStyle', value: 'block' | 'underline' | 'bar'): void;\n  public setOption(key: 'allowTransparency' | 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'debug' | 'disableStdin' | 'enableBold' | 'macOptionIsMeta' | 'rightClickSelectsWord' | 'popOnBell' | 'screenKeys' | 'useFlowControl' | 'visualBell', value: boolean): void;\n  public setOption(key: 'colors', value: string[]): void;\n  public setOption(key: 'fontSize' | 'letterSpacing' | 'lineHeight' | 'tabStopWidth' | 'scrollback', value: number): void;\n  public setOption(key: 'handler', value: (data: string) => void): void;\n  public setOption(key: 'theme', value: ITheme): void;\n  public setOption(key: 'cols' | 'rows', value: number): void;\n  public setOption(key: string, value: any): void;\n  public setOption(key: any, value: any): void {\n    this._core.setOption(key, value);\n  }\n  public refresh(start: number, end: number): void {\n    this._core.refresh(start, end);\n  }\n  public reset(): void {\n    this._core.reset();\n  }\n  public static applyAddon(addon: any): void {\n    addon.apply(Terminal);\n  }\n  public static get strings(): ILocalizableStrings {\n    return Strings;\n  }\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ITerminal, IBufferLine } from '../Types';\nimport { ICircularList } from '../common/Types';\nimport { C0 } from '../common/data/EscapeSequences';\n\nconst enum Direction {\n  UP = 'A',\n  DOWN = 'B',\n  RIGHT = 'C',\n  LEFT = 'D'\n}\n\nexport class AltClickHandler {\n  private _startRow: number;\n  private _startCol: number;\n  private _endRow: number;\n  private _endCol: number;\n  private _lines: ICircularList<IBufferLine>;\n\n  constructor(\n    private _mouseEvent: MouseEvent,\n    private _terminal: ITerminal\n  ) {\n    this._lines = this._terminal.buffer.lines;\n    this._startCol = this._terminal.buffer.x;\n    this._startRow = this._terminal.buffer.y;\n\n    const coordinates = this._terminal.mouseHelper.getCoords(\n      this._mouseEvent,\n      this._terminal.element,\n      this._terminal.charMeasure,\n      this._terminal.cols,\n      this._terminal.rows,\n      false\n    );\n\n    if (coordinates) {\n      [this._endCol, this._endRow] = coordinates.map((coordinate: number) => {\n        return coordinate - 1;\n      });\n    }\n  }\n\n  /**\n   * Writes the escape sequences of arrows to the terminal\n   */\n  public move(): void {\n    if (this._mouseEvent.altKey && this._endCol !== undefined && this._endRow !== undefined) {\n      this._terminal.handler(this._arrowSequences());\n    }\n  }\n\n  /**\n   * Concatenates all the arrow sequences together.\n   * Resets the starting row to an unwrapped row, moves to the requested row,\n   * then moves to requested col.\n   */\n  private _arrowSequences(): string {\n    // The alt buffer should try to navigate between rows\n    if (!this._terminal.buffer.hasScrollback) {\n      return this._resetStartingRow() + this._moveToRequestedRow() + this._moveToRequestedCol();\n    }\n\n    // Only move horizontally for the normal buffer\n    return this._moveHorizontallyOnly();\n  }\n\n  /**\n   * If the initial position of the cursor is on a row that is wrapped, move the\n   * cursor up to the first row that is not wrapped to have accurate vertical\n   * positioning.\n   */\n  private _resetStartingRow(): string {\n    if (this._moveToRequestedRow().length === 0) {\n      return '';\n    }\n    return repeat(this._bufferLine(\n      this._startCol, this._startRow, this._startCol,\n      this._startRow - this._wrappedRowsForRow(this._startRow), false\n    ).length, this._sequence(Direction.LEFT));\n  }\n\n  /**\n   * Using the reset starting and ending row, move to the requested row,\n   * ignoring wrapped rows\n   */\n  private _moveToRequestedRow(): string {\n    const startRow = this._startRow - this._wrappedRowsForRow(this._startRow);\n    const endRow = this._endRow - this._wrappedRowsForRow(this._endRow);\n\n    const rowsToMove = Math.abs(startRow - endRow) - this._wrappedRowsCount();\n\n    return repeat(rowsToMove, this._sequence(this._verticalDirection()));\n  }\n\n  /**\n   * Move to the requested col on the ending row\n   */\n  private _moveToRequestedCol(): string {\n    let startRow;\n    if (this._moveToRequestedRow().length > 0) {\n      startRow = this._endRow - this._wrappedRowsForRow(this._endRow);\n    } else {\n      startRow = this._startRow;\n    }\n\n    const endRow = this._endRow;\n    const direction = this._horizontalDirection();\n\n    return repeat(this._bufferLine(\n      this._startCol, startRow, this._endCol, endRow,\n      direction === Direction.RIGHT\n    ).length, this._sequence(direction));\n  }\n\n  private _moveHorizontallyOnly(): string {\n    const direction = this._horizontalDirection();\n    return repeat(Math.abs(this._startCol - this._endCol), this._sequence(direction));\n  }\n\n  /**\n   * Utility functions\n   */\n\n  /**\n   * Calculates the number of wrapped rows between the unwrapped starting and\n   * ending rows. These rows need to ignored since the cursor skips over them.\n   */\n  private _wrappedRowsCount(): number {\n    let wrappedRows = 0;\n    const startRow = this._startRow - this._wrappedRowsForRow(this._startRow);\n    const endRow = this._endRow - this._wrappedRowsForRow(this._endRow);\n\n    for (let i = 0; i < Math.abs(startRow - endRow); i++) {\n      const direction = this._verticalDirection() === Direction.UP ? -1 : 1;\n\n      if (this._lines.get(startRow + (direction * i)).isWrapped) {\n        wrappedRows++;\n      }\n    }\n\n    return wrappedRows;\n  }\n\n  /**\n   * Calculates the number of wrapped rows that make up a given row.\n   * @param currentRow The row to determine how many wrapped rows make it up\n   */\n  private _wrappedRowsForRow(currentRow: number): number {\n    let rowCount = 0;\n    let lineWraps = this._lines.get(currentRow).isWrapped;\n\n    while (lineWraps && currentRow >= 0 && currentRow < this._terminal.rows) {\n      rowCount++;\n      currentRow--;\n      lineWraps = this._lines.get(currentRow).isWrapped;\n    }\n\n    return rowCount;\n  }\n\n  /**\n   * Direction determiners\n   */\n\n  /**\n   * Determines if the right or left arrow is needed\n   */\n  private _horizontalDirection(): Direction {\n    let startRow;\n    if (this._moveToRequestedRow().length > 0) {\n      startRow = this._endRow - this._wrappedRowsForRow(this._endRow);\n    } else {\n      startRow = this._startRow;\n    }\n\n    if ((this._startCol < this._endCol &&\n      startRow <= this._endRow) || // down/right or same y/right\n      (this._startCol >= this._endCol &&\n      startRow < this._endRow)) {  // down/left or same y/left\n      return Direction.RIGHT;\n    }\n    return Direction.LEFT;\n  }\n\n  /**\n   * Determines if the up or down arrow is needed\n   */\n  private _verticalDirection(): Direction {\n    if (this._startRow > this._endRow) {\n      return Direction.UP;\n    }\n    return Direction.DOWN;\n  }\n\n  /**\n   * Constructs the string of chars in the buffer from a starting row and col\n   * to an ending row and col\n   * @param startCol The starting column position\n   * @param startRow The starting row position\n   * @param endCol The ending column position\n   * @param endRow The ending row position\n   * @param forward Direction to move\n   */\n  private _bufferLine(\n    startCol: number,\n    startRow: number,\n    endCol: number,\n    endRow: number,\n    forward: boolean\n  ): string {\n    let currentCol = startCol;\n    let currentRow = startRow;\n    let bufferStr = '';\n\n    while (currentCol !== endCol || currentRow !== endRow) {\n      currentCol += forward ? 1 : -1;\n\n      if (forward && currentCol > this._terminal.cols - 1) {\n        bufferStr += this._terminal.buffer.translateBufferLineToString(\n          currentRow, false, startCol, currentCol\n        );\n        currentCol = 0;\n        startCol = 0;\n        currentRow++;\n      } else if (!forward && currentCol < 0) {\n        bufferStr += this._terminal.buffer.translateBufferLineToString(\n          currentRow, false, 0, startCol + 1\n        );\n        currentCol = this._terminal.cols - 1;\n        startCol = currentCol;\n        currentRow--;\n      }\n    }\n\n    return bufferStr + this._terminal.buffer.translateBufferLineToString(\n      currentRow, false, startCol, currentCol\n    );\n  }\n\n  /**\n   * Constructs the escape sequence for clicking an arrow\n   * @param direction The direction to move\n   */\n  private _sequence(direction: Direction): string {\n    const mod = this._terminal.applicationCursor ? 'O' : '[';\n    return C0.ESC + mod + direction;\n  }\n}\n\n/**\n * Returns a string repeated a given number of times\n * Polyfill from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat\n * @param count The number of times to repeat the string\n * @param string The string that is to be repeated\n */\nfunction repeat(count: number, str: string): string {\n  count = Math.floor(count);\n  let rpt = '';\n  for (let i = 0; i < count; i++) {\n    rpt += str;\n  }\n  return rpt;\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n/**\n * StringToUtf32 - decodes UTF16 sequences into UTF32 codepoints.\n * To keep the decoder in line with JS strings it handles single surrogates as UCS2.\n */\nexport class StringToUtf32 {\n  private _interim: number = 0;\n\n  /**\n   * Clears interim and resets decoder to clean state.\n   */\n  public clear(): void {\n    this._interim = 0;\n  }\n\n  /**\n   * Decode JS string to UTF32 codepoints.\n   * The methods assumes stream input and will store partly transmitted\n   * surrogate pairs and decode them with the next data chunk.\n   * Note: The method does no bound checks for target, therefore make sure\n   * the provided input data does not exceed the size of `target`.\n   * Returns the number of written codepoints in `target`.\n   */\n  decode(input: string, target: Uint32Array): number {\n    const length = input.length;\n\n    if (!length) {\n      return 0;\n    }\n\n    let size = 0;\n    let startPos = 0;\n\n    // handle leftover surrogate high\n    if (this._interim) {\n      const second = input.charCodeAt(startPos++);\n      if (0xDC00 <= second && second <= 0xDFFF) {\n        target[size++] = (this._interim - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;\n      } else {\n        // illegal codepoint (USC2 handling)\n        target[size++] = this._interim;\n        target[size++] = second;\n      }\n      this._interim = 0;\n    }\n\n    for (let i = startPos; i < length; ++i) {\n      const code = input.charCodeAt(i);\n      // surrogate pair first\n      if (0xD800 <= code && code <= 0xDBFF) {\n        if (++i >= length) {\n          this._interim = code;\n          return size;\n        }\n        const second = input.charCodeAt(i);\n        if (0xDC00 <= second && second <= 0xDFFF) {\n          target[size++] = (code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;\n        } else {\n          // illegal codepoint (USC2 handling)\n          target[size++] = code;\n          target[size++] = second;\n        }\n        continue;\n      }\n      target[size++] = code;\n    }\n    return size;\n  }\n}\n\n/**\n * Convert UTF32 codepoint into JS string.\n */\nexport function stringFromCodePoint(codePoint: number): string {\n  if (codePoint > 0xFFFF) {\n    // UTF32 to UTF16 conversion (see comments in utf32ToString)\n    codePoint -= 0x10000;\n    return String.fromCharCode((codePoint >> 10) + 0xD800) + String.fromCharCode((codePoint % 0x400) + 0xDC00);\n  }\n  return String.fromCharCode(codePoint);\n}\n\n/**\n * Convert UTF32 char codes into JS string.\n * Basically the same as `stringFromCodePoint` but for multiple codepoints\n * in a loop (which is a lot faster).\n */\nexport function utf32ToString(data: Uint32Array, start: number = 0, end: number = data.length): string {\n  let result = '';\n  for (let i = start; i < end; ++i) {\n    let codepoint = data[i];\n    if (codepoint > 0xFFFF) {\n      // JS string are encoded as UTF16, thus a non BMP codepoint gets converted into a surrogate pair\n      // conversion rules:\n      //  - subtract 0x10000 from code point, leaving a 20 bit number\n      //  - add high 10 bits to 0xD800  --> first surrogate\n      //  - add low 10 bits to 0xDC00   --> second surrogate\n      codepoint -= 0x10000;\n      result += String.fromCharCode((codepoint >> 10) + 0xD800) + String.fromCharCode((codepoint % 0x400) + 0xDC00);\n    } else {\n      result += String.fromCharCode(codepoint);\n    }\n  }\n  return result;\n}\n","/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * @license MIT\n */\n\nimport { IKeyboardEvent } from '../../common/Types';\nimport { IKeyboardResult, KeyboardResultType } from '../Types';\nimport { C0 } from '../../common/data/EscapeSequences';\n\n// reg + shift key mappings for digits and special chars\nconst KEYCODE_KEY_MAPPINGS: { [key: number]: [string, string]} = {\n  // digits 0-9\n  48: ['0', ')'],\n  49: ['1', '!'],\n  50: ['2', '@'],\n  51: ['3', '#'],\n  52: ['4', '$'],\n  53: ['5', '%'],\n  54: ['6', '^'],\n  55: ['7', '&'],\n  56: ['8', '*'],\n  57: ['9', '('],\n\n  // special chars\n  186: [';', ':'],\n  187: ['=', '+'],\n  188: [',', '<'],\n  189: ['-', '_'],\n  190: ['.', '>'],\n  191: ['/', '?'],\n  192: ['`', '~'],\n  219: ['[', '{'],\n  220: ['\\\\', '|'],\n  221: [']', '}'],\n  222: ['\\'', '\"']\n};\n\nexport function evaluateKeyboardEvent(\n  ev: IKeyboardEvent,\n  applicationCursorMode: boolean,\n  isMac: boolean,\n  macOptionIsMeta: boolean\n): IKeyboardResult {\n  const result: IKeyboardResult = {\n    type: KeyboardResultType.SEND_KEY,\n    // Whether to cancel event propagation (NOTE: this may not be needed since the event is\n    // canceled at the end of keyDown\n    cancel: false,\n    // The new key even to emit\n    key: undefined\n  };\n  const modifiers = (ev.shiftKey ? 1 : 0) | (ev.altKey ? 2 : 0) | (ev.ctrlKey ? 4 : 0) | (ev.metaKey ? 8 : 0);\n  switch (ev.keyCode) {\n    case 0:\n      if (ev.key === 'UIKeyInputUpArrow') {\n        if (applicationCursorMode) {\n          result.key = C0.ESC + 'OA';\n        } else {\n          result.key = C0.ESC + '[A';\n        }\n      }\n      else if (ev.key === 'UIKeyInputLeftArrow') {\n        if (applicationCursorMode) {\n          result.key = C0.ESC + 'OD';\n        } else {\n          result.key = C0.ESC + '[D';\n        }\n      }\n      else if (ev.key === 'UIKeyInputRightArrow') {\n        if (applicationCursorMode) {\n          result.key = C0.ESC + 'OC';\n        } else {\n          result.key = C0.ESC + '[C';\n        }\n      }\n      else if (ev.key === 'UIKeyInputDownArrow') {\n        if (applicationCursorMode) {\n          result.key = C0.ESC + 'OB';\n        } else {\n          result.key = C0.ESC + '[B';\n        }\n      }\n      break;\n    case 8:\n      // backspace\n      if (ev.shiftKey) {\n        result.key = C0.BS; // ^H\n        break;\n      } else if (ev.altKey) {\n        result.key = C0.ESC + C0.DEL; // \\e ^?\n        break;\n      }\n      result.key = C0.DEL; // ^?\n      break;\n    case 9:\n      // tab\n      if (ev.shiftKey) {\n        result.key = C0.ESC + '[Z';\n        break;\n      }\n      result.key = C0.HT;\n      result.cancel = true;\n      break;\n    case 13:\n      // return/enter\n      result.key = C0.CR;\n      result.cancel = true;\n      break;\n    case 27:\n      // escape\n      result.key = C0.ESC;\n      result.cancel = true;\n      break;\n    case 37:\n      // left-arrow\n      if (modifiers) {\n        result.key = C0.ESC + '[1;' + (modifiers + 1) + 'D';\n        // HACK: Make Alt + left-arrow behave like Ctrl + left-arrow: move one word backwards\n        // http://unix.stackexchange.com/a/108106\n        // macOS uses different escape sequences than linux\n        if (result.key === C0.ESC + '[1;3D') {\n          result.key = isMac ? C0.ESC + 'b' : C0.ESC + '[1;5D';\n        }\n      } else if (applicationCursorMode) {\n        result.key = C0.ESC + 'OD';\n      } else {\n        result.key = C0.ESC + '[D';\n      }\n      break;\n    case 39:\n      // right-arrow\n      if (modifiers) {\n        result.key = C0.ESC + '[1;' + (modifiers + 1) + 'C';\n        // HACK: Make Alt + right-arrow behave like Ctrl + right-arrow: move one word forward\n        // http://unix.stackexchange.com/a/108106\n        // macOS uses different escape sequences than linux\n        if (result.key === C0.ESC + '[1;3C') {\n          result.key = isMac ? C0.ESC + 'f' : C0.ESC + '[1;5C';\n        }\n      } else if (applicationCursorMode) {\n        result.key = C0.ESC + 'OC';\n      } else {\n        result.key = C0.ESC + '[C';\n      }\n      break;\n    case 38:\n      // up-arrow\n      if (modifiers) {\n        result.key = C0.ESC + '[1;' + (modifiers + 1) + 'A';\n        // HACK: Make Alt + up-arrow behave like Ctrl + up-arrow\n        // http://unix.stackexchange.com/a/108106\n        if (result.key === C0.ESC + '[1;3A') {\n          result.key = C0.ESC + '[1;5A';\n        }\n      } else if (applicationCursorMode) {\n        result.key = C0.ESC + 'OA';\n      } else {\n        result.key = C0.ESC + '[A';\n      }\n      break;\n    case 40:\n      // down-arrow\n      if (modifiers) {\n        result.key = C0.ESC + '[1;' + (modifiers + 1) + 'B';\n        // HACK: Make Alt + down-arrow behave like Ctrl + down-arrow\n        // http://unix.stackexchange.com/a/108106\n        if (result.key === C0.ESC + '[1;3B') {\n          result.key = C0.ESC + '[1;5B';\n        }\n      } else if (applicationCursorMode) {\n        result.key = C0.ESC + 'OB';\n      } else {\n        result.key = C0.ESC + '[B';\n      }\n      break;\n    case 45:\n      // insert\n      if (!ev.shiftKey && !ev.ctrlKey) {\n        // <Ctrl> or <Shift> + <Insert> are used to\n        // copy-paste on some systems.\n        result.key = C0.ESC + '[2~';\n      }\n      break;\n    case 46:\n      // delete\n      if (modifiers) {\n        result.key = C0.ESC + '[3;' + (modifiers + 1) + '~';\n      } else {\n        result.key = C0.ESC + '[3~';\n      }\n      break;\n    case 36:\n      // home\n      if (modifiers) {\n        result.key = C0.ESC + '[1;' + (modifiers + 1) + 'H';\n      } else if (applicationCursorMode) {\n        result.key = C0.ESC + 'OH';\n      } else {\n        result.key = C0.ESC + '[H';\n      }\n      break;\n    case 35:\n      // end\n      if (modifiers) {\n        result.key = C0.ESC + '[1;' + (modifiers + 1) + 'F';\n      } else if (applicationCursorMode) {\n        result.key = C0.ESC + 'OF';\n      } else {\n        result.key = C0.ESC + '[F';\n      }\n      break;\n    case 33:\n      // page up\n      if (ev.shiftKey) {\n        result.type = KeyboardResultType.PAGE_UP;\n      } else {\n        result.key = C0.ESC + '[5~';\n      }\n      break;\n    case 34:\n      // page down\n      if (ev.shiftKey) {\n        result.type = KeyboardResultType.PAGE_DOWN;\n      } else {\n        result.key = C0.ESC + '[6~';\n      }\n      break;\n    case 112:\n      // F1-F12\n      if (modifiers) {\n        result.key = C0.ESC + '[1;' + (modifiers + 1) + 'P';\n      } else {\n        result.key = C0.ESC + 'OP';\n      }\n      break;\n    case 113:\n      if (modifiers) {\n        result.key = C0.ESC + '[1;' + (modifiers + 1) + 'Q';\n      } else {\n        result.key = C0.ESC + 'OQ';\n      }\n      break;\n    case 114:\n      if (modifiers) {\n        result.key = C0.ESC + '[1;' + (modifiers + 1) + 'R';\n      } else {\n        result.key = C0.ESC + 'OR';\n      }\n      break;\n    case 115:\n      if (modifiers) {\n        result.key = C0.ESC + '[1;' + (modifiers + 1) + 'S';\n      } else {\n        result.key = C0.ESC + 'OS';\n      }\n      break;\n    case 116:\n      if (modifiers) {\n        result.key = C0.ESC + '[15;' + (modifiers + 1) + '~';\n      } else {\n        result.key = C0.ESC + '[15~';\n      }\n      break;\n    case 117:\n      if (modifiers) {\n        result.key = C0.ESC + '[17;' + (modifiers + 1) + '~';\n      } else {\n        result.key = C0.ESC + '[17~';\n      }\n      break;\n    case 118:\n      if (modifiers) {\n        result.key = C0.ESC + '[18;' + (modifiers + 1) + '~';\n      } else {\n        result.key = C0.ESC + '[18~';\n      }\n      break;\n    case 119:\n      if (modifiers) {\n        result.key = C0.ESC + '[19;' + (modifiers + 1) + '~';\n      } else {\n        result.key = C0.ESC + '[19~';\n      }\n      break;\n    case 120:\n      if (modifiers) {\n        result.key = C0.ESC + '[20;' + (modifiers + 1) + '~';\n      } else {\n        result.key = C0.ESC + '[20~';\n      }\n      break;\n    case 121:\n      if (modifiers) {\n        result.key = C0.ESC + '[21;' + (modifiers + 1) + '~';\n      } else {\n        result.key = C0.ESC + '[21~';\n      }\n      break;\n    case 122:\n      if (modifiers) {\n        result.key = C0.ESC + '[23;' + (modifiers + 1) + '~';\n      } else {\n        result.key = C0.ESC + '[23~';\n      }\n      break;\n    case 123:\n      if (modifiers) {\n        result.key = C0.ESC + '[24;' + (modifiers + 1) + '~';\n      } else {\n        result.key = C0.ESC + '[24~';\n      }\n      break;\n    default:\n      // a-z and space\n      if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey) {\n        if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n          result.key = String.fromCharCode(ev.keyCode - 64);\n        } else if (ev.keyCode === 32) {\n          // NUL\n          result.key = String.fromCharCode(0);\n        } else if (ev.keyCode >= 51 && ev.keyCode <= 55) {\n          // escape, file sep, group sep, record sep, unit sep\n          result.key = String.fromCharCode(ev.keyCode - 51 + 27);\n        } else if (ev.keyCode === 56) {\n          // delete\n          result.key = String.fromCharCode(127);\n        } else if (ev.keyCode === 219) {\n          // ^[ - Control Sequence Introducer (CSI)\n          result.key = String.fromCharCode(27);\n        } else if (ev.keyCode === 220) {\n          // ^\\ - String Terminator (ST)\n          result.key = String.fromCharCode(28);\n        } else if (ev.keyCode === 221) {\n          // ^] - Operating System Command (OSC)\n          result.key = String.fromCharCode(29);\n        }\n      } else if ((!isMac || macOptionIsMeta) && ev.altKey && !ev.metaKey) {\n        // On macOS this is a third level shift when !macOptionIsMeta. Use <Esc> instead.\n        const keyMapping = KEYCODE_KEY_MAPPINGS[ev.keyCode];\n        const key = keyMapping && keyMapping[!ev.shiftKey ? 0 : 1];\n        if (key) {\n          result.key = C0.ESC + key;\n        } else if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n          const keyCode = ev.ctrlKey ? ev.keyCode - 64 : ev.keyCode + 32;\n          result.key = C0.ESC + String.fromCharCode(keyCode);\n        }\n      } else if (isMac && !ev.altKey && !ev.ctrlKey && ev.metaKey) {\n        if (ev.keyCode === 65) { // cmd + a\n          result.type = KeyboardResultType.SELECT_ALL;\n        }\n      } else if (ev.key && !ev.ctrlKey && !ev.altKey && !ev.metaKey && ev.keyCode >= 48 && ev.key.length === 1) {\n        // Include only keys that that result in a _single_ character; don't include num lock, volume up, etc.\n        result.key = ev.key;\n      } else if (ev.key && ev.ctrlKey) {\n        if (ev.key === '_') { // ^_\n          result.key = C0.US;\n        }\n      }\n      break;\n  }\n\n  return result;\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICharset } from '../Types';\n\n/**\n * The character sets supported by the terminal. These enable several languages\n * to be represented within the terminal with only 8-bit encoding. See ISO 2022\n * for a discussion on character sets. Only VT100 character sets are supported.\n */\nexport const CHARSETS: { [key: string]: ICharset | null } = {};\n\n/**\n * The default character set, US.\n */\nexport const DEFAULT_CHARSET: ICharset | null = CHARSETS['B'];\n\n/**\n * DEC Special Character and Line Drawing Set.\n * Reference: http://vt100.net/docs/vt102-ug/table5-13.html\n * A lot of curses apps use this if they see TERM=xterm.\n * testing: echo -e '\\e(0a\\e(B'\n * The xterm output sometimes seems to conflict with the\n * reference above. xterm seems in line with the reference\n * when running vttest however.\n * The table below now uses xterm's output from vttest.\n */\nCHARSETS['0'] = {\n  '`': '\\u25c6', // '◆'\n  'a': '\\u2592', // '▒'\n  'b': '\\u0009', // '\\t'\n  'c': '\\u000c', // '\\f'\n  'd': '\\u000d', // '\\r'\n  'e': '\\u000a', // '\\n'\n  'f': '\\u00b0', // '°'\n  'g': '\\u00b1', // '±'\n  'h': '\\u2424', // '\\u2424' (NL)\n  'i': '\\u000b', // '\\v'\n  'j': '\\u2518', // '┘'\n  'k': '\\u2510', // '┐'\n  'l': '\\u250c', // '┌'\n  'm': '\\u2514', // '└'\n  'n': '\\u253c', // '┼'\n  'o': '\\u23ba', // '⎺'\n  'p': '\\u23bb', // '⎻'\n  'q': '\\u2500', // '─'\n  'r': '\\u23bc', // '⎼'\n  's': '\\u23bd', // '⎽'\n  't': '\\u251c', // '├'\n  'u': '\\u2524', // '┤'\n  'v': '\\u2534', // '┴'\n  'w': '\\u252c', // '┬'\n  'x': '\\u2502', // '│'\n  'y': '\\u2264', // '≤'\n  'z': '\\u2265', // '≥'\n  '{': '\\u03c0', // 'π'\n  '|': '\\u2260', // '≠'\n  '}': '\\u00a3', // '£'\n  '~': '\\u00b7'  // '·'\n};\n\n/**\n * British character set\n * ESC (A\n * Reference: http://vt100.net/docs/vt220-rm/table2-5.html\n */\nCHARSETS['A'] = {\n  '#': '£'\n};\n\n/**\n * United States character set\n * ESC (B\n */\nCHARSETS['B'] = null;\n\n/**\n * Dutch character set\n * ESC (4\n * Reference: http://vt100.net/docs/vt220-rm/table2-6.html\n */\nCHARSETS['4'] = {\n  '#': '£',\n  '@': '¾',\n  '[': 'ij',\n  '\\\\': '½',\n  ']': '|',\n  '{': '¨',\n  '|': 'f',\n  '}': '¼',\n  '~': '´'\n};\n\n/**\n * Finnish character set\n * ESC (C or ESC (5\n * Reference: http://vt100.net/docs/vt220-rm/table2-7.html\n */\nCHARSETS['C'] =\nCHARSETS['5'] = {\n  '[': 'Ä',\n  '\\\\': 'Ö',\n  ']': 'Å',\n  '^': 'Ü',\n  '`': 'é',\n  '{': 'ä',\n  '|': 'ö',\n  '}': 'å',\n  '~': 'ü'\n};\n\n/**\n * French character set\n * ESC (R\n * Reference: http://vt100.net/docs/vt220-rm/table2-8.html\n */\nCHARSETS['R'] = {\n  '#': '£',\n  '@': 'à',\n  '[': '°',\n  '\\\\': 'ç',\n  ']': '§',\n  '{': 'é',\n  '|': 'ù',\n  '}': 'è',\n  '~': '¨'\n};\n\n/**\n * French Canadian character set\n * ESC (Q\n * Reference: http://vt100.net/docs/vt220-rm/table2-9.html\n */\nCHARSETS['Q'] = {\n  '@': 'à',\n  '[': 'â',\n  '\\\\': 'ç',\n  ']': 'ê',\n  '^': 'î',\n  '`': 'ô',\n  '{': 'é',\n  '|': 'ù',\n  '}': 'è',\n  '~': 'û'\n};\n\n/**\n * German character set\n * ESC (K\n * Reference: http://vt100.net/docs/vt220-rm/table2-10.html\n */\nCHARSETS['K'] = {\n  '@': '§',\n  '[': 'Ä',\n  '\\\\': 'Ö',\n  ']': 'Ü',\n  '{': 'ä',\n  '|': 'ö',\n  '}': 'ü',\n  '~': 'ß'\n};\n\n/**\n * Italian character set\n * ESC (Y\n * Reference: http://vt100.net/docs/vt220-rm/table2-11.html\n */\nCHARSETS['Y'] = {\n  '#': '£',\n  '@': '§',\n  '[': '°',\n  '\\\\': 'ç',\n  ']': 'é',\n  '`': 'ù',\n  '{': 'à',\n  '|': 'ò',\n  '}': 'è',\n  '~': 'ì'\n};\n\n/**\n * Norwegian/Danish character set\n * ESC (E or ESC (6\n * Reference: http://vt100.net/docs/vt220-rm/table2-12.html\n */\nCHARSETS['E'] =\nCHARSETS['6'] = {\n  '@': 'Ä',\n  '[': 'Æ',\n  '\\\\': 'Ø',\n  ']': 'Å',\n  '^': 'Ü',\n  '`': 'ä',\n  '{': 'æ',\n  '|': 'ø',\n  '}': 'å',\n  '~': 'ü'\n};\n\n/**\n * Spanish character set\n * ESC (Z\n * Reference: http://vt100.net/docs/vt220-rm/table2-13.html\n */\nCHARSETS['Z'] = {\n  '#': '£',\n  '@': '§',\n  '[': '¡',\n  '\\\\': 'Ñ',\n  ']': '¿',\n  '{': '°',\n  '|': 'ñ',\n  '}': 'ç'\n};\n\n/**\n * Swedish character set\n * ESC (H or ESC (7\n * Reference: http://vt100.net/docs/vt220-rm/table2-14.html\n */\nCHARSETS['H'] =\nCHARSETS['7'] = {\n  '@': 'É',\n  '[': 'Ä',\n  '\\\\': 'Ö',\n  ']': 'Å',\n  '^': 'Ü',\n  '`': 'é',\n  '{': 'ä',\n  '|': 'ö',\n  '}': 'å',\n  '~': 'ü'\n};\n\n/**\n * Swiss character set\n * ESC (=\n * Reference: http://vt100.net/docs/vt220-rm/table2-15.html\n */\nCHARSETS['='] = {\n  '#': 'ù',\n  '@': 'à',\n  '[': 'é',\n  '\\\\': 'ç',\n  ']': 'ê',\n  '^': 'î',\n  '_': 'è',\n  '`': 'ô',\n  '{': 'ä',\n  '|': 'ö',\n  '}': 'ü',\n  '~': 'û'\n};\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n/**\n * C0 control codes\n * See = https://en.wikipedia.org/wiki/C0_and_C1_control_codes\n */\nexport namespace C0 {\n  /** Null (Caret = ^@, C = \\0) */\n  export const NUL = '\\x00';\n  /** Start of Heading (Caret = ^A) */\n  export const SOH = '\\x01';\n  /** Start of Text (Caret = ^B) */\n  export const STX = '\\x02';\n  /** End of Text (Caret = ^C) */\n  export const ETX = '\\x03';\n  /** End of Transmission (Caret = ^D) */\n  export const EOT = '\\x04';\n  /** Enquiry (Caret = ^E) */\n  export const ENQ = '\\x05';\n  /** Acknowledge (Caret = ^F) */\n  export const ACK = '\\x06';\n  /** Bell (Caret = ^G, C = \\a) */\n  export const BEL = '\\x07';\n  /** Backspace (Caret = ^H, C = \\b) */\n  export const BS  = '\\x08';\n  /** Character Tabulation, Horizontal Tabulation (Caret = ^I, C = \\t) */\n  export const HT  = '\\x09';\n  /** Line Feed (Caret = ^J, C = \\n) */\n  export const LF  = '\\x0a';\n  /** Line Tabulation, Vertical Tabulation (Caret = ^K, C = \\v) */\n  export const VT  = '\\x0b';\n  /** Form Feed (Caret = ^L, C = \\f) */\n  export const FF  = '\\x0c';\n  /** Carriage Return (Caret = ^M, C = \\r) */\n  export const CR  = '\\x0d';\n  /** Shift Out (Caret = ^N) */\n  export const SO  = '\\x0e';\n  /** Shift In (Caret = ^O) */\n  export const SI  = '\\x0f';\n  /** Data Link Escape (Caret = ^P) */\n  export const DLE = '\\x10';\n  /** Device Control One (XON) (Caret = ^Q) */\n  export const DC1 = '\\x11';\n  /** Device Control Two (Caret = ^R) */\n  export const DC2 = '\\x12';\n  /** Device Control Three (XOFF) (Caret = ^S) */\n  export const DC3 = '\\x13';\n  /** Device Control Four (Caret = ^T) */\n  export const DC4 = '\\x14';\n  /** Negative Acknowledge (Caret = ^U) */\n  export const NAK = '\\x15';\n  /** Synchronous Idle (Caret = ^V) */\n  export const SYN = '\\x16';\n  /** End of Transmission Block (Caret = ^W) */\n  export const ETB = '\\x17';\n  /** Cancel (Caret = ^X) */\n  export const CAN = '\\x18';\n  /** End of Medium (Caret = ^Y) */\n  export const EM  = '\\x19';\n  /** Substitute (Caret = ^Z) */\n  export const SUB = '\\x1a';\n  /** Escape (Caret = ^[, C = \\e) */\n  export const ESC = '\\x1b';\n  /** File Separator (Caret = ^\\) */\n  export const FS  = '\\x1c';\n  /** Group Separator (Caret = ^]) */\n  export const GS  = '\\x1d';\n  /** Record Separator (Caret = ^^) */\n  export const RS  = '\\x1e';\n  /** Unit Separator (Caret = ^_) */\n  export const US  = '\\x1f';\n  /** Space */\n  export const SP  = '\\x20';\n  /** Delete (Caret = ^?) */\n  export const DEL = '\\x7f';\n}\n\n/**\n * C1 control codes\n * See = https://en.wikipedia.org/wiki/C0_and_C1_control_codes\n */\nexport namespace C1 {\n  /** padding character */\n  export const PAD = '\\x80';\n  /** High Octet Preset */\n  export const HOP = '\\x81';\n  /** Break Permitted Here */\n  export const BPH = '\\x82';\n  /** No Break Here */\n  export const NBH = '\\x83';\n  /** Index */\n  export const IND = '\\x84';\n  /** Next Line */\n  export const NEL = '\\x85';\n  /** Start of Selected Area */\n  export const SSA = '\\x86';\n  /** End of Selected Area */\n  export const ESA = '\\x87';\n  /** Horizontal Tabulation Set */\n  export const HTS = '\\x88';\n  /** Horizontal Tabulation With Justification */\n  export const HTJ = '\\x89';\n  /** Vertical Tabulation Set */\n  export const VTS = '\\x8a';\n  /** Partial Line Down */\n  export const PLD = '\\x8b';\n  /** Partial Line Up */\n  export const PLU = '\\x8c';\n  /** Reverse Index */\n  export const RI = '\\x8d';\n  /** Single-Shift 2 */\n  export const SS2 = '\\x8e';\n  /** Single-Shift 3 */\n  export const SS3 = '\\x8f';\n  /** Device Control String */\n  export const DCS = '\\x90';\n  /** Private Use 1 */\n  export const PU1 = '\\x91';\n  /** Private Use 2 */\n  export const PU2 = '\\x92';\n  /** Set Transmit State */\n  export const STS = '\\x93';\n  /** Destructive backspace, intended to eliminate ambiguity about meaning of BS. */\n  export const CCH = '\\x94';\n  /** Message Waiting */\n  export const MW = '\\x95';\n  /** Start of Protected Area */\n  export const SPA = '\\x96';\n  /** End of Protected Area */\n  export const EPA = '\\x97';\n  /** Start of String */\n  export const SOS = '\\x98';\n  /** Single Graphic Character Introducer */\n  export const SGCI = '\\x99';\n  /** Single Character Introducer */\n  export const SCI = '\\x9a';\n  /** Control Sequence Introducer */\n  export const CSI = '\\x9b';\n  /** String Terminator */\n  export const ST = '\\x9c';\n  /** Operating System Command */\n  export const OSC = '\\x9d';\n  /** Privacy Message */\n  export const PM = '\\x9e';\n  /** Application Program Command */\n  export const APC = '\\x9f';\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nexport type TypedArray = Uint8Array | Uint16Array | Uint32Array | Uint8ClampedArray\n  | Int8Array | Int16Array | Int32Array\n  | Float32Array | Float64Array;\n\n\n/**\n * polyfill for TypedArray.fill\n * This is needed to support .fill in all safari versions and IE 11.\n */\nexport function fill<T extends TypedArray>(array: T, value: number, start?: number, end?: number): T {\n  // all modern engines that support .fill\n  if (array.fill) {\n    return array.fill(value, start, end) as T;\n  }\n  return fillFallback(array, value, start, end);\n}\n\nexport function fillFallback<T extends TypedArray>(array: T, value: number, start: number = 0, end: number = array.length): T {\n  // safari and IE 11\n  // since IE 11 does not support Array.prototype.fill either\n  // we cannot use the suggested polyfill from MDN\n  // instead we simply fall back to looping\n  if (start >= array.length) {\n    return array;\n  }\n  start = (array.length + start) % array.length;\n  if (end >= array.length) {\n    end = array.length;\n  } else {\n    end = (array.length + end) % array.length;\n  }\n  for (let i = start; i < end; ++i) {\n    array[i] = value;\n  }\n  return array;\n}\n\n/**\n * Concat two typed arrays `a` and `b`.\n * Returns a new typed array.\n */\nexport function concat<T extends TypedArray>(a: T, b: T): T {\n  const result = new (a.constructor as any)(a.length + b.length);\n  result.set(a);\n  result.set(b, a.length);\n  return result;\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\ninterface INavigator {\n  userAgent: string;\n  language: string;\n  platform: string;\n}\n\n// We're declaring a navigator global here as we expect it in all runtimes (node and browser), but\n// we want this module to live in common.\ndeclare const navigator: INavigator;\n\nconst isNode = (typeof navigator === 'undefined') ? true : false;\nconst userAgent = (isNode) ? 'node' : navigator.userAgent;\nconst platform = (isNode) ? 'node' : navigator.platform;\n\nexport const isFirefox = !!~userAgent.indexOf('Firefox');\nexport const isSafari = /^((?!chrome|android).)*safari/i.test(userAgent);\nexport const isMSIE = !!~userAgent.indexOf('MSIE') || !!~userAgent.indexOf('Trident');\n\n// Find the users platform. We use this to interpret the meta key\n// and ISO third level shifts.\n// http://stackoverflow.com/q/19877924/577598\nexport const isMac = contains(['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'], platform);\nexport const isIpad = platform === 'iPad';\nexport const isIphone = platform === 'iPhone';\nexport const isMSWindows = contains(['Windows', 'Win16', 'Win32', 'WinCE'], platform);\nexport const isLinux = platform.indexOf('Linux') >= 0;\n\n/**\n * Return if the given array contains the given element\n * @param arr The array to search for the given element.\n * @param el The element to look for into the array\n */\nfunction contains(arr: any[], el: any): boolean {\n  return arr.indexOf(el) >= 0;\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IDisposable } from './Types';\n\n/**\n * A base class that can be extended to provide convenience methods for managing the lifecycle of an\n * object and its components.\n */\nexport abstract class Disposable implements IDisposable {\n  protected _disposables: IDisposable[] = [];\n  protected _isDisposed: boolean = false;\n\n  constructor() {\n  }\n\n  /**\n   * Disposes the object, triggering the `dispose` method on all registered IDisposables.\n   */\n  public dispose(): void {\n    this._isDisposed = true;\n    this._disposables.forEach(d => d.dispose());\n    this._disposables.length = 0;\n  }\n\n  /**\n   * Registers a disposable object.\n   * @param d The disposable to register.\n   */\n  public register<T extends IDisposable>(d: T): void {\n    this._disposables.push(d);\n  }\n\n  /**\n   * Unregisters a disposable object if it has been registered, if not do\n   * nothing.\n   * @param d The disposable to unregister.\n   */\n  public unregister<T extends IDisposable>(d: T): void {\n    const index = this._disposables.indexOf(d);\n    if (index !== -1) {\n      this._disposables.splice(index, 1);\n    }\n  }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IDisposable } from './Types';\n\ninterface IListener<T> {\n  (e: T): void;\n}\n\nexport interface IEvent<T> {\n  (listener: (e: T) => any): IDisposable;\n}\n\nexport class EventEmitter2<T> {\n  private _listeners: IListener<T>[] = [];\n  private _event?: IEvent<T>;\n\n  public get event(): IEvent<T> {\n    if (!this._event) {\n      this._event = (listener: (e: T) => any) => {\n        this._listeners.push(listener);\n        const disposable = {\n          dispose: () => {\n            for (let i = 0; i < this._listeners.length; i++) {\n              if (this._listeners[i] === listener) {\n                this._listeners.splice(i, 1);\n                return;\n              }\n            }\n          }\n        };\n        return disposable;\n      };\n    }\n    return this._event;\n  }\n\n  public fire(data: T): void {\n    const queue: IListener<T>[] = [];\n    for (let i = 0; i < this._listeners.length; i++) {\n      queue.push(this._listeners[i]);\n    }\n    for (let i = 0; i < queue.length; i++) {\n      queue[i].call(undefined, data);\n    }\n  }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IDisposable, IEventEmitter, XtermListener } from './Types';\nimport { Disposable } from './Lifecycle';\n\nexport class EventEmitter extends Disposable implements IEventEmitter, IDisposable {\n  private _events: {[type: string]: XtermListener[]};\n\n  constructor() {\n    super();\n    // Restore the previous events if available, this will happen if the\n    // constructor is called multiple times on the same object (terminal reset).\n    this._events = (<any>this)._events || {};\n  }\n\n  public on(type: string, listener: XtermListener): void {\n    this._events[type] = this._events[type] || [];\n    this._events[type].push(listener);\n  }\n\n  /**\n   * Adds a disposable listener to the EventEmitter, returning the disposable.\n   * @param type The event type.\n   * @param handler The handler for the listener.\n   */\n  public addDisposableListener(type: string, handler: XtermListener): IDisposable {\n    // TODO: Rename addDisposableEventListener to more easily disambiguate from Dom listener\n    this.on(type, handler);\n    let disposed = false;\n    return {\n      dispose: () => {\n        if (disposed) {\n          // Already disposed\n          return;\n        }\n        this.off(type, handler);\n        disposed = true;\n      }\n    };\n  }\n\n  public off(type: string, listener: XtermListener): void {\n    if (!this._events[type]) {\n      return;\n    }\n\n    const obj = this._events[type];\n    let i = obj.length;\n\n    while (i--) {\n      if (obj[i] === listener) {\n        obj.splice(i, 1);\n        return;\n      }\n    }\n  }\n\n  public removeAllListeners(type: string): void {\n    if (this._events[type]) {\n       delete this._events[type];\n    }\n  }\n\n  public emit(type: string, ...args: any[]): void {\n    if (!this._events[type]) {\n      return;\n    }\n    const obj = this._events[type];\n    for (let i = 0; i < obj.length; i++) {\n      obj[i].apply(this, args);\n    }\n  }\n\n  public emitMayRemoveListeners(type: string, ...args: any[]): void {\n    if (!this._events[type]) {\n      return;\n    }\n    const obj = this._events[type];\n    let length = obj.length;\n    for (let i = 0; i < obj.length; i++) {\n      obj[i].apply(this, args);\n      i -= length - obj.length;\n      length = obj.length;\n    }\n  }\n\n  public listeners(type: string): XtermListener[] {\n    return this._events[type] || [];\n  }\n\n  public dispose(): void {\n    super.dispose();\n    this._events = {};\n  }\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n/*\n * A simple utility for cloning values\n */\nexport function clone<T>(val: T, depth: number = 5): T | null {\n  if (typeof val !== 'object') {\n    return val;\n  }\n\n  // cloning null always returns null\n  if (val === null) {\n    return null;\n  }\n\n  // If we're cloning an array, use an array as the base, otherwise use an object\n  const clonedObject: any = Array.isArray(val) ? [] : {};\n\n  for (const key in val) {\n    // Recursively clone eack item unless we're at the maximum depth\n    clonedObject[key] = depth <= 1 ? val[key] : clone(val[key], depth - 1);\n  }\n\n  return clonedObject as T;\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICircularList } from './Types';\nimport { EventEmitter2, IEvent } from './EventEmitter2';\n\nexport interface IInsertEvent {\n  index: number;\n  amount: number;\n}\n\nexport interface IDeleteEvent {\n  index: number;\n  amount: number;\n}\n\n/**\n * Represents a circular list; a list with a maximum size that wraps around when push is called,\n * overriding values at the start of the list.\n */\nexport class CircularList<T> implements ICircularList<T> {\n  protected _array: (T | undefined)[];\n  private _startIndex: number;\n  private _length: number;\n\n  public onDeleteEmitter = new EventEmitter2<IDeleteEvent>();\n  public get onDelete(): IEvent<IDeleteEvent> { return this.onDeleteEmitter.event; }\n  public onInsertEmitter = new EventEmitter2<IInsertEvent>();\n  public get onInsert(): IEvent<IInsertEvent> { return this.onInsertEmitter.event; }\n  public onTrimEmitter = new EventEmitter2<number>();\n  public get onTrim(): IEvent<number> { return this.onTrimEmitter.event; }\n\n  constructor(\n    private _maxLength: number\n  ) {\n    this._array = new Array<T>(this._maxLength);\n    this._startIndex = 0;\n    this._length = 0;\n  }\n\n  public get maxLength(): number {\n    return this._maxLength;\n  }\n\n  public set maxLength(newMaxLength: number) {\n    // There was no change in maxLength, return early.\n    if (this._maxLength === newMaxLength) {\n      return;\n    }\n\n    // Reconstruct array, starting at index 0. Only transfer values from the\n    // indexes 0 to length.\n    const newArray = new Array<T | undefined>(newMaxLength);\n    for (let i = 0; i < Math.min(newMaxLength, this.length); i++) {\n      newArray[i] = this._array[this._getCyclicIndex(i)];\n    }\n    this._array = newArray;\n    this._maxLength = newMaxLength;\n    this._startIndex = 0;\n  }\n\n  public get length(): number {\n    return this._length;\n  }\n\n  public set length(newLength: number) {\n    if (newLength > this._length) {\n      for (let i = this._length; i < newLength; i++) {\n        this._array[i] = undefined;\n      }\n    }\n    this._length = newLength;\n  }\n\n  /**\n   * Gets the value at an index.\n   *\n   * Note that for performance reasons there is no bounds checking here, the index reference is\n   * circular so this should always return a value and never throw.\n   * @param index The index of the value to get.\n   * @return The value corresponding to the index.\n   */\n  public get(index: number): T | undefined {\n    return this._array[this._getCyclicIndex(index)];\n  }\n\n  /**\n   * Sets the value at an index.\n   *\n   * Note that for performance reasons there is no bounds checking here, the index reference is\n   * circular so this should always return a value and never throw.\n   * @param index The index to set.\n   * @param value The value to set.\n   */\n  public set(index: number, value: T | undefined): void {\n    this._array[this._getCyclicIndex(index)] = value;\n  }\n\n  /**\n   * Pushes a new value onto the list, wrapping around to the start of the array, overriding index 0\n   * if the maximum length is reached.\n   * @param value The value to push onto the list.\n   */\n  public push(value: T): void {\n    this._array[this._getCyclicIndex(this._length)] = value;\n    if (this._length === this._maxLength) {\n      this._startIndex = ++this._startIndex % this._maxLength;\n      this.onTrimEmitter.fire(1);\n    } else {\n      this._length++;\n    }\n  }\n\n  /**\n   * Advance ringbuffer index and return current element for recycling.\n   * Note: The buffer must be full for this method to work.\n   * @throws When the buffer is not full.\n   */\n  public recycle(): T {\n    if (this._length !== this._maxLength) {\n      throw new Error('Can only recycle when the buffer is full');\n    }\n    this._startIndex = ++this._startIndex % this._maxLength;\n    this.onTrimEmitter.fire(1);\n    return this._array[this._getCyclicIndex(this._length - 1)]!;\n  }\n\n  /**\n   * Ringbuffer is at max length.\n   */\n  public get isFull(): boolean {\n    return this._length === this._maxLength;\n  }\n\n  /**\n   * Removes and returns the last value on the list.\n   * @return The popped value.\n   */\n  public pop(): T | undefined {\n    return this._array[this._getCyclicIndex(this._length-- - 1)];\n  }\n\n  /**\n   * Deletes and/or inserts items at a particular index (in that order). Unlike\n   * Array.prototype.splice, this operation does not return the deleted items as a new array in\n   * order to save creating a new array. Note that this operation may shift all values in the list\n   * in the worst case.\n   * @param start The index to delete and/or insert.\n   * @param deleteCount The number of elements to delete.\n   * @param items The items to insert.\n   */\n  public splice(start: number, deleteCount: number, ...items: T[]): void {\n    // Delete items\n    if (deleteCount) {\n      for (let i = start; i < this._length - deleteCount; i++) {\n        this._array[this._getCyclicIndex(i)] = this._array[this._getCyclicIndex(i + deleteCount)];\n      }\n      this._length -= deleteCount;\n    }\n\n    // Add items\n    for (let i = this._length - 1; i >= start; i--) {\n      this._array[this._getCyclicIndex(i + items.length)] = this._array[this._getCyclicIndex(i)];\n    }\n    for (let i = 0; i < items.length; i++) {\n      this._array[this._getCyclicIndex(start + i)] = items[i];\n    }\n\n    // Adjust length as needed\n    if (this._length + items.length > this._maxLength) {\n      const countToTrim = (this._length + items.length) - this._maxLength;\n      this._startIndex += countToTrim;\n      this._length = this._maxLength;\n      this.onTrimEmitter.fire(countToTrim);\n    } else {\n      this._length += items.length;\n    }\n  }\n\n  /**\n   * Trims a number of items from the start of the list.\n   * @param count The number of items to remove.\n   */\n  public trimStart(count: number): void {\n    if (count > this._length) {\n      count = this._length;\n    }\n    this._startIndex += count;\n    this._length -= count;\n    this.onTrimEmitter.fire(count);\n  }\n\n  public shiftElements(start: number, count: number, offset: number): void {\n    if (count <= 0) {\n      return;\n    }\n    if (start < 0 || start >= this._length) {\n      throw new Error('start argument out of range');\n    }\n    if (start + offset < 0) {\n      throw new Error('Cannot shift elements in list beyond index 0');\n    }\n\n    if (offset > 0) {\n      for (let i = count - 1; i >= 0; i--) {\n        this.set(start + i + offset, this.get(start + i));\n      }\n      const expandListBy = (start + count + offset) - this._length;\n      if (expandListBy > 0) {\n        this._length += expandListBy;\n        while (this._length > this._maxLength) {\n          this._length--;\n          this._startIndex++;\n          this.onTrimEmitter.fire(1);\n        }\n      }\n    } else {\n      for (let i = 0; i < count; i++) {\n        this.set(start + i + offset, this.get(start + i));\n      }\n    }\n  }\n\n  /**\n   * Gets the cyclic index for the specified regular index. The cyclic index can then be used on the\n   * backing array to get the element associated with the regular index.\n   * @param index The regular index.\n   * @returns The cyclic index.\n   */\n  private _getCyclicIndex(index: number): number {\n    return (this._startIndex + index) % this._maxLength;\n  }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IDisposable } from 'xterm';\nimport { ITerminal } from './Types';\nimport { CHAR_DATA_CODE_INDEX, NULL_CELL_CODE, WHITESPACE_CELL_CODE } from './Buffer';\n\nexport function applyWindowsMode(terminal: ITerminal): IDisposable {\n  // Winpty does not support wraparound mode which means that lines will never\n  // be marked as wrapped. This causes issues for things like copying a line\n  // retaining the wrapped new line characters or if consumers are listening\n  // in on the data stream.\n  //\n  // The workaround for this is to listen to every incoming line feed and mark\n  // the line as wrapped if the last character in the previous line is not a\n  // space. This is certainly not without its problems, but generally on\n  // Windows when text reaches the end of the terminal it's likely going to be\n  // wrapped.\n  return terminal.onLineFeed(() => {\n    const line = terminal.buffer.lines.get(terminal.buffer.ybase + terminal.buffer.y - 1);\n    const lastChar = line.get(terminal.cols - 1);\n\n    if (lastChar[CHAR_DATA_CODE_INDEX] !== NULL_CELL_CODE && lastChar[CHAR_DATA_CODE_INDEX] !== WHITESPACE_CELL_CODE) {\n      const nextLine = terminal.buffer.lines.get(terminal.buffer.ybase + terminal.buffer.y);\n      nextLine.isWrapped = true;\n    }\n  });\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColorSet } from './renderer/Types';\nimport { ITerminal, IViewport } from './Types';\nimport { CharMeasure } from './CharMeasure';\nimport { Disposable } from './common/Lifecycle';\nimport { addDisposableDomListener } from './ui/Lifecycle';\n\nconst FALLBACK_SCROLL_BAR_WIDTH = 15;\n\n/**\n * Represents the viewport of a terminal, the visible area within the larger buffer of output.\n * Logic for the virtual scroll bar is included in this object.\n */\nexport class Viewport extends Disposable implements IViewport {\n  public scrollBarWidth: number = 0;\n  private _currentRowHeight: number = 0;\n  private _lastRecordedBufferLength: number = 0;\n  private _lastRecordedViewportHeight: number = 0;\n  private _lastRecordedBufferHeight: number = 0;\n  private _lastTouchY: number;\n  private _lastScrollTop: number = 0;\n\n  // Stores a partial line amount when scrolling, this is used to keep track of how much of a line\n  // is scrolled so we can \"scroll\" over partial lines and feel natural on touchpads. This is a\n  // quick fix and could have a more robust solution in place that reset the value when needed.\n  private _wheelPartialScroll: number = 0;\n\n  private _refreshAnimationFrame: number | null = null;\n  private _ignoreNextScrollEvent: boolean = false;\n\n  /**\n   * Creates a new Viewport.\n   * @param _terminal The terminal this viewport belongs to.\n   * @param _viewportElement The DOM element acting as the viewport.\n   * @param _scrollArea The DOM element acting as the scroll area.\n   * @param _charMeasure A DOM element used to measure the character size of. the terminal.\n   */\n  constructor(\n    private _terminal: ITerminal,\n    private _viewportElement: HTMLElement,\n    private _scrollArea: HTMLElement,\n    private _charMeasure: CharMeasure\n  ) {\n    super();\n\n    // Measure the width of the scrollbar. If it is 0 we can assume it's an OSX overlay scrollbar.\n    // Unfortunately the overlay scrollbar would be hidden underneath the screen element in that case,\n    // therefore we account for a standard amount to make it visible\n    this.scrollBarWidth = (this._viewportElement.offsetWidth - this._scrollArea.offsetWidth) || FALLBACK_SCROLL_BAR_WIDTH;\n    this.register(addDisposableDomListener(this._viewportElement, 'scroll', this._onScroll.bind(this)));\n\n    // Perform this async to ensure the CharMeasure is ready.\n    setTimeout(() => this.syncScrollArea(), 0);\n  }\n\n  public onThemeChanged(colors: IColorSet): void {\n    this._viewportElement.style.backgroundColor = colors.background.css;\n  }\n\n  /**\n   * Refreshes row height, setting line-height, viewport height and scroll area height if\n   * necessary.\n   */\n  private _refresh(): void {\n    if (this._refreshAnimationFrame === null) {\n      this._refreshAnimationFrame = requestAnimationFrame(() => this._innerRefresh());\n    }\n  }\n\n  private _innerRefresh(): void {\n    if (this._charMeasure.height > 0) {\n      this._currentRowHeight = this._terminal.renderer.dimensions.scaledCellHeight / window.devicePixelRatio;\n      this._lastRecordedViewportHeight = this._viewportElement.offsetHeight;\n      const newBufferHeight = Math.round(this._currentRowHeight * this._lastRecordedBufferLength) + (this._lastRecordedViewportHeight - this._terminal.renderer.dimensions.canvasHeight);\n      if (this._lastRecordedBufferHeight !== newBufferHeight) {\n        this._lastRecordedBufferHeight = newBufferHeight;\n        this._scrollArea.style.height = this._lastRecordedBufferHeight + 'px';\n      }\n    }\n\n    // Sync scrollTop\n    const scrollTop = this._terminal.buffer.ydisp * this._currentRowHeight;\n    if (this._viewportElement.scrollTop !== scrollTop) {\n      // Ignore the next scroll event which will be triggered by setting the scrollTop as we do not\n      // want this event to scroll the terminal\n      this._ignoreNextScrollEvent = true;\n      this._viewportElement.scrollTop = scrollTop;\n    }\n\n    this._refreshAnimationFrame = null;\n  }\n\n  /**\n   * Updates dimensions and synchronizes the scroll area if necessary.\n   */\n  public syncScrollArea(): void {\n    // If buffer height changed\n    if (this._lastRecordedBufferLength !== this._terminal.buffer.lines.length) {\n      this._lastRecordedBufferLength = this._terminal.buffer.lines.length;\n      this._refresh();\n      return;\n    }\n\n    // If viewport height changed\n    if (this._lastRecordedViewportHeight !== (<any>this._terminal).renderer.dimensions.canvasHeight) {\n      this._refresh();\n      return;\n    }\n\n    // If the buffer position doesn't match last scroll top\n    const newScrollTop = this._terminal.buffer.ydisp * this._currentRowHeight;\n    if (this._lastScrollTop !== newScrollTop) {\n      this._refresh();\n      return;\n    }\n\n    // If element's scroll top changed, this can happen when hiding the element\n    if (this._lastScrollTop !== this._viewportElement.scrollTop) {\n      this._refresh();\n      return;\n    }\n\n    // If row height changed\n    if (this._terminal.renderer.dimensions.scaledCellHeight / window.devicePixelRatio !== this._currentRowHeight) {\n      this._refresh();\n      return;\n    }\n  }\n\n  /**\n   * Handles scroll events on the viewport, calculating the new viewport and requesting the\n   * terminal to scroll to it.\n   * @param ev The scroll event.\n   */\n  private _onScroll(ev: Event): void {\n    // Record current scroll top position\n    this._lastScrollTop = this._viewportElement.scrollTop;\n\n    // Don't attempt to scroll if the element is not visible, otherwise scrollTop will be corrupt\n    // which causes the terminal to scroll the buffer to the top\n    if (!this._viewportElement.offsetParent) {\n      return;\n    }\n\n    // Ignore the event if it was flagged to ignore (when the source of the event is from Viewport)\n    if (this._ignoreNextScrollEvent) {\n      this._ignoreNextScrollEvent = false;\n      return;\n    }\n\n    const newRow = Math.round(this._lastScrollTop / this._currentRowHeight);\n    const diff = newRow - this._terminal.buffer.ydisp;\n    this._terminal.scrollLines(diff, true);\n  }\n\n  /**\n   * Handles mouse wheel events by adjusting the viewport's scrollTop and delegating the actual\n   * scrolling to `onScroll`, this event needs to be attached manually by the consumer of\n   * `Viewport`.\n   * @param ev The mouse wheel event.\n   */\n  public onWheel(ev: WheelEvent): void {\n    const amount = this._getPixelsScrolled(ev);\n    if (amount === 0) {\n      return;\n    }\n    this._viewportElement.scrollTop += amount;\n    // Prevent the page from scrolling when the terminal scrolls\n    ev.preventDefault();\n  }\n\n  private _getPixelsScrolled(ev: WheelEvent): number {\n    // Do nothing if it's not a vertical scroll event\n    if (ev.deltaY === 0) {\n      return 0;\n    }\n\n    // Fallback to WheelEvent.DOM_DELTA_PIXEL\n    let amount = ev.deltaY;\n    if (ev.deltaMode === WheelEvent.DOM_DELTA_LINE) {\n      amount *= this._currentRowHeight;\n    } else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) {\n      amount *= this._currentRowHeight * this._terminal.rows;\n    }\n    return amount;\n  }\n\n  /**\n   * Gets the number of pixels scrolled by the mouse event taking into account what type of delta\n   * is being used.\n   * @param ev The mouse wheel event.\n   */\n  public getLinesScrolled(ev: WheelEvent): number {\n    // Do nothing if it's not a vertical scroll event\n    if (ev.deltaY === 0) {\n      return 0;\n    }\n\n    // Fallback to WheelEvent.DOM_DELTA_LINE\n    let amount = ev.deltaY;\n    if (ev.deltaMode === WheelEvent.DOM_DELTA_PIXEL) {\n      amount /= this._currentRowHeight + 0.0; // Prevent integer division\n      this._wheelPartialScroll += amount;\n      amount = Math.floor(Math.abs(this._wheelPartialScroll)) * (this._wheelPartialScroll > 0 ? 1 : -1);\n      this._wheelPartialScroll %= 1;\n    } else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) {\n      amount *= this._terminal.rows;\n    }\n    return amount;\n  }\n\n  /**\n   * Handles the touchstart event, recording the touch occurred.\n   * @param ev The touch event.\n   */\n  public onTouchStart(ev: TouchEvent): void {\n    this._lastTouchY = ev.touches[0].pageY;\n  }\n\n  /**\n   * Handles the touchmove event, scrolling the viewport if the position shifted.\n   * @param ev The touch event.\n   */\n  public onTouchMove(ev: TouchEvent): void {\n    const deltaY = this._lastTouchY - ev.touches[0].pageY;\n    this._lastTouchY = ev.touches[0].pageY;\n    if (deltaY === 0) {\n      return;\n    }\n    this._viewportElement.scrollTop += deltaY;\n    ev.preventDefault();\n  }\n}\n","/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * @license MIT\n *\n * Originally forked from (with the author's permission):\n *   Fabrice Bellard's javascript vt100 for jslinux:\n *   http://bellard.org/jslinux/\n *   Copyright (c) 2011 Fabrice Bellard\n *   The original design remains. The terminal itself\n *   has been extended to include xterm CSI codes, among\n *   other features.\n *\n * Terminal Emulation References:\n *   http://vt100.net/\n *   http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt\n *   http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n *   http://invisible-island.net/vttest/\n *   http://www.inwap.com/pdp10/ansicode.txt\n *   http://linux.die.net/man/4/console_codes\n *   http://linux.die.net/man/7/urxvt\n */\n\nimport { IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminalOptions, ITerminal, IBrowser, ILinkifier, ILinkMatcherOptions, CustomKeyEventHandler, LinkMatcherHandler, CharacterJoinerHandler, IBufferLine, IAttributeData, IMouseZoneManager } from './Types';\nimport { IRenderer } from './renderer/Types';\nimport { BufferSet } from './BufferSet';\nimport { Buffer, MAX_BUFFER_SIZE, DEFAULT_ATTR_DATA } from './Buffer';\nimport { CompositionHelper } from './CompositionHelper';\nimport { EventEmitter } from './common/EventEmitter';\nimport { Viewport } from './Viewport';\nimport { rightClickHandler, moveTextAreaUnderMouseCursor, pasteHandler, copyHandler } from './Clipboard';\nimport { C0 } from './common/data/EscapeSequences';\nimport { InputHandler } from './InputHandler';\nimport { Renderer } from './renderer/Renderer';\nimport { Linkifier } from './Linkifier';\nimport { SelectionManager } from './SelectionManager';\nimport { CharMeasure } from './CharMeasure';\nimport * as Browser from './common/Platform';\nimport { addDisposableDomListener } from './ui/Lifecycle';\nimport * as Strings from './Strings';\nimport { MouseHelper } from './MouseHelper';\nimport { DEFAULT_BELL_SOUND, SoundManager } from './SoundManager';\nimport { MouseZoneManager } from './MouseZoneManager';\nimport { AccessibilityManager } from './AccessibilityManager';\nimport { ScreenDprMonitor } from './ui/ScreenDprMonitor';\nimport { ITheme, IMarker, IDisposable } from 'xterm';\nimport { removeTerminalFromCache } from './renderer/atlas/CharAtlasCache';\nimport { DomRenderer } from './renderer/dom/DomRenderer';\nimport { IKeyboardEvent } from './common/Types';\nimport { evaluateKeyboardEvent } from './core/input/Keyboard';\nimport { KeyboardResultType, ICharset } from './core/Types';\nimport { clone } from './common/Clone';\nimport { EventEmitter2, IEvent } from './common/EventEmitter2';\nimport { Attributes } from './BufferLine';\nimport { applyWindowsMode } from './WindowsMode';\n\n// Let it work inside Node.js for automated testing purposes.\nconst document = (typeof window !== 'undefined') ? window.document : null;\n\n/**\n * The amount of write requests to queue before sending an XOFF signal to the\n * pty process. This number must be small in order for ^C and similar sequences\n * to be responsive.\n */\nconst WRITE_BUFFER_PAUSE_THRESHOLD = 5;\n\n/**\n * The max number of ms to spend on writes before allowing the renderer to\n * catch up with a 0ms setTimeout. A value of < 33 to keep us close to\n * 30fps, and a value of < 16 to try to run at 60fps. Of course, the real FPS\n * depends on the time it takes for the renderer to draw the frame.\n */\nconst WRITE_TIMEOUT_MS = 12;\n\nconst MINIMUM_COLS = 2; // Less than 2 can mess with wide chars\nconst MINIMUM_ROWS = 1;\n\n/**\n * The set of options that only have an effect when set in the Terminal constructor.\n */\nconst CONSTRUCTOR_ONLY_OPTIONS = ['cols', 'rows'];\n\nconst DEFAULT_OPTIONS: ITerminalOptions = {\n  cols: 80,\n  rows: 24,\n  convertEol: false,\n  termName: 'xterm',\n  cursorBlink: false,\n  cursorStyle: 'block',\n  bellSound: DEFAULT_BELL_SOUND,\n  bellStyle: 'none',\n  drawBoldTextInBrightColors: true,\n  enableBold: true,\n  experimentalCharAtlas: 'static',\n  fontFamily: 'courier-new, courier, monospace',\n  fontSize: 15,\n  fontWeight: 'normal',\n  fontWeightBold: 'bold',\n  lineHeight: 1.0,\n  letterSpacing: 0,\n  scrollback: 1000,\n  screenKeys: false,\n  screenReaderMode: false,\n  debug: false,\n  macOptionIsMeta: false,\n  macOptionClickForcesSelection: false,\n  cancelEvents: false,\n  disableStdin: false,\n  useFlowControl: false,\n  allowTransparency: false,\n  tabStopWidth: 8,\n  theme: null,\n  rightClickSelectsWord: Browser.isMac,\n  rendererType: 'canvas',\n  windowsMode: false\n};\n\nexport class Terminal extends EventEmitter implements ITerminal, IDisposable, IInputHandlingTerminal {\n  public textarea: HTMLTextAreaElement;\n  public element: HTMLElement;\n  public screenElement: HTMLElement;\n\n  /**\n   * The HTMLElement that the terminal is created in, set by Terminal.open.\n   */\n  private _parent: HTMLElement;\n  private _context: Window;\n  private _document: Document;\n  private _viewportScrollArea: HTMLElement;\n  private _viewportElement: HTMLElement;\n  private _helperContainer: HTMLElement;\n  private _compositionView: HTMLElement;\n\n  private _visualBellTimer: number;\n\n  public browser: IBrowser = <any>Browser;\n\n  public options: ITerminalOptions;\n\n  // TODO: This can be changed to an enum or boolean, 0 and 1 seem to be the only options\n  public cursorState: number;\n  public cursorHidden: boolean;\n\n  private _customKeyEventHandler: CustomKeyEventHandler;\n\n  // modes\n  public applicationKeypad: boolean;\n  public applicationCursor: boolean;\n  public originMode: boolean;\n  public insertMode: boolean;\n  public wraparoundMode: boolean; // defaults: xterm - true, vt100 - false\n  public bracketedPasteMode: boolean;\n\n  // charset\n  // The current charset\n  public charset: ICharset;\n  public gcharset: number;\n  public glevel: number;\n  public charsets: ICharset[];\n\n  // mouse properties\n  private _decLocator: boolean; // This is unstable and never set\n  public x10Mouse: boolean;\n  public vt200Mouse: boolean;\n  private _vt300Mouse: boolean; // This is unstable and never set\n  public normalMouse: boolean;\n  public mouseEvents: boolean;\n  public sendFocus: boolean;\n  public utfMouse: boolean;\n  public sgrMouse: boolean;\n  public urxvtMouse: boolean;\n\n  // misc\n  private _refreshStart: number;\n  private _refreshEnd: number;\n  public savedCols: number;\n\n  public curAttrData: IAttributeData;\n  private _eraseAttrData: IAttributeData;\n\n  public params: (string | number)[];\n  public currentParam: string | number;\n\n  // user input states\n  public writeBuffer: string[];\n  private _writeInProgress: boolean;\n\n  /**\n   * Whether _xterm.js_ sent XOFF in order to catch up with the pty process.\n   * This is a distinct state from writeStopped so that if the user requested\n   * XOFF via ^S that it will not automatically resume when the writeBuffer goes\n   * below threshold.\n   */\n  private _xoffSentToCatchUp: boolean;\n\n  /** Whether writing has been stopped as a result of XOFF */\n  // private _writeStopped: boolean;\n\n  // Store if user went browsing history in scrollback\n  private _userScrolling: boolean;\n\n  private _inputHandler: InputHandler;\n  public soundManager: SoundManager;\n  public renderer: IRenderer;\n  public selectionManager: SelectionManager;\n  public linkifier: ILinkifier;\n  public buffers: BufferSet;\n  public viewport: IViewport;\n  private _compositionHelper: ICompositionHelper;\n  public charMeasure: CharMeasure;\n  private _mouseZoneManager: IMouseZoneManager;\n  public mouseHelper: MouseHelper;\n  private _accessibilityManager: AccessibilityManager;\n  private _screenDprMonitor: ScreenDprMonitor;\n  private _theme: ITheme;\n  private _windowsMode: IDisposable | undefined;\n\n  // bufferline to clone/copy from for new blank lines\n  private _blankLine: IBufferLine = null;\n\n  public cols: number;\n  public rows: number;\n\n  private _onCursorMove = new EventEmitter2<void>();\n  public get onCursorMove(): IEvent<void> { return this._onCursorMove.event; }\n  private _onData = new EventEmitter2<string>();\n  public get onData(): IEvent<string> { return this._onData.event; }\n  private _onKey = new EventEmitter2<{ key: string, domEvent: KeyboardEvent }>();\n  public get onKey(): IEvent<{ key: string, domEvent: KeyboardEvent }> { return this._onKey.event; }\n  private _onLineFeed = new EventEmitter2<void>();\n  public get onLineFeed(): IEvent<void> { return this._onLineFeed.event; }\n  private _onRender = new EventEmitter2<{ start: number, end: number }>();\n  public get onRender(): IEvent<{ start: number, end: number }> { return this._onRender.event; }\n  private _onResize = new EventEmitter2<{ cols: number, rows: number }>();\n  public get onResize(): IEvent<{ cols: number, rows: number }> { return this._onResize.event; }\n  private _onScroll = new EventEmitter2<number>();\n  public get onScroll(): IEvent<number> { return this._onScroll.event; }\n  private _onSelectionChange = new EventEmitter2<void>();\n  public get onSelectionChange(): IEvent<void> { return this._onSelectionChange.event; }\n  private _onTitleChange = new EventEmitter2<string>();\n  public get onTitleChange(): IEvent<string> { return this._onTitleChange.event; }\n\n  /**\n   * Creates a new `Terminal` object.\n   *\n   * @param options An object containing a set of options, the available options are:\n   *   - `cursorBlink` (boolean): Whether the terminal cursor blinks\n   *   - `cols` (number): The number of columns of the terminal (horizontal size)\n   *   - `rows` (number): The number of rows of the terminal (vertical size)\n   *\n   * @public\n   * @class Xterm Xterm\n   * @alias module:xterm/src/xterm\n   */\n  constructor(\n    options: ITerminalOptions = {}\n  ) {\n    super();\n    this.options = clone(options);\n    this._setup();\n\n    // TODO: Remove these in v4\n    // Fire old style events from new emitters\n    this.onCursorMove(() => this.emit('cursormove'));\n    this.onData(e => this.emit('data', e));\n    this.onKey(e => this.emit('key', e.key, e.domEvent));\n    this.onLineFeed(() => this.emit('linefeed'));\n    this.onRender(e => this.emit('refresh', e));\n    this.onResize(e => this.emit('resize', e));\n    this.onSelectionChange(() => this.emit('selection'));\n    this.onScroll(e => this.emit('scroll', e));\n    this.onTitleChange(e => this.emit('title', e));\n  }\n\n  public dispose(): void {\n    super.dispose();\n    if (this._windowsMode) {\n      this._windowsMode.dispose();\n      this._windowsMode = undefined;\n    }\n    this._customKeyEventHandler = null;\n    removeTerminalFromCache(this);\n    this.handler = () => {};\n    this.write = () => {};\n    if (this.element && this.element.parentNode) {\n      this.element.parentNode.removeChild(this.element);\n    }\n  }\n\n  /**\n   * @deprecated Use dispose instead.\n   */\n  public destroy(): void {\n    this.dispose();\n  }\n\n  private _setup(): void {\n    Object.keys(DEFAULT_OPTIONS).forEach((key) => {\n      if (this.options[key] === null || this.options[key] === undefined) {\n        this.options[key] = DEFAULT_OPTIONS[key];\n      }\n    });\n\n    // this.context = options.context || window;\n    // this.document = options.document || document;\n    // TODO: WHy not document.body?\n    this._parent = document ? document.body : null;\n\n    this.cols = Math.max(this.options.cols, MINIMUM_COLS);\n    this.rows = Math.max(this.options.rows, MINIMUM_ROWS);\n\n    if (this.options.handler) {\n      this.onData(this.options.handler);\n    }\n\n    this.cursorState = 0;\n    this.cursorHidden = false;\n    this._customKeyEventHandler = null;\n\n    // modes\n    this.applicationKeypad = false;\n    this.applicationCursor = false;\n    this.originMode = false;\n    this.insertMode = false;\n    this.wraparoundMode = true; // defaults: xterm - true, vt100 - false\n    this.bracketedPasteMode = false;\n\n    // charset\n    this.charset = null;\n    this.gcharset = null;\n    this.glevel = 0;\n    // TODO: Can this be just []?\n    this.charsets = [null];\n\n    this.curAttrData = DEFAULT_ATTR_DATA.clone();\n    this._eraseAttrData = DEFAULT_ATTR_DATA.clone();\n\n    this.params = [];\n    this.currentParam = 0;\n\n    // user input states\n    this.writeBuffer = [];\n    this._writeInProgress = false;\n\n    this._xoffSentToCatchUp = false;\n    // this._writeStopped = false;\n    this._userScrolling = false;\n\n    // Register input handler and refire/handle events\n    this._inputHandler = new InputHandler(this);\n    this._inputHandler.onCursorMove(() => this._onCursorMove.fire());\n    this._inputHandler.onLineFeed(() => this._onLineFeed.fire());\n    this._inputHandler.onData(e => this._onData.fire(e));\n    this.register(this._inputHandler);\n\n    // Reuse renderer if the Terminal is being recreated via a reset call.\n    this.renderer = this.renderer || null;\n    this.selectionManager = this.selectionManager || null;\n    this.linkifier = this.linkifier || new Linkifier(this);\n    this._mouseZoneManager = this._mouseZoneManager || null;\n    this.soundManager = this.soundManager || new SoundManager(this);\n\n    // Create the terminal's buffers and set the current buffer\n    this.buffers = new BufferSet(this);\n    if (this.selectionManager) {\n      this.selectionManager.clearSelection();\n      this.selectionManager.initBuffersListeners();\n    }\n\n    if (this.options.windowsMode) {\n      this._windowsMode = applyWindowsMode(this);\n    }\n  }\n\n  /**\n   * Convenience property to active buffer.\n   */\n  public get buffer(): Buffer {\n    return this.buffers.active;\n  }\n\n  /**\n   * back_color_erase feature for xterm.\n   */\n  public eraseAttrData(): IAttributeData {\n    this._eraseAttrData.bg &= ~(Attributes.CM_MASK | 0xFFFFFF);\n    this._eraseAttrData.bg |= this.curAttrData.bg & ~0xFC000000;\n    return this._eraseAttrData;\n  }\n\n  /**\n   * Focus the terminal. Delegates focus handling to the terminal's DOM element.\n   */\n  public focus(): void {\n    if (this.textarea) {\n      this.textarea.focus({ preventScroll: true });\n    }\n  }\n\n  public get isFocused(): boolean {\n    return document.activeElement === this.textarea && document.hasFocus();\n  }\n\n  /**\n   * Retrieves an option's value from the terminal.\n   * @param key The option key.\n   */\n  public getOption(key: string): any {\n    if (!(key in DEFAULT_OPTIONS)) {\n      throw new Error('No option with key \"' + key + '\"');\n    }\n\n    return this.options[key];\n  }\n\n  /**\n   * Sets an option on the terminal.\n   * @param key The option key.\n   * @param value The option value.\n   */\n  public setOption(key: string, value: any): void {\n    if (!(key in DEFAULT_OPTIONS)) {\n      throw new Error('No option with key \"' + key + '\"');\n    }\n    if (CONSTRUCTOR_ONLY_OPTIONS.indexOf(key) !== -1) {\n      console.error(`Option \"${key}\" can only be set in the constructor`);\n    }\n    if (this.options[key] === value) {\n      return;\n    }\n    switch (key) {\n      case 'bellStyle':\n        if (!value) {\n          value = 'none';\n        }\n        break;\n      case 'cursorStyle':\n        if (!value) {\n          value = 'block';\n        }\n        break;\n      case 'fontWeight':\n        if (!value) {\n          value = 'normal';\n        }\n        break;\n      case 'fontWeightBold':\n        if (!value) {\n          value = 'bold';\n        }\n        break;\n      case 'lineHeight':\n        if (value < 1) {\n          console.warn(`${key} cannot be less than 1, value: ${value}`);\n          return;\n        }\n      case 'rendererType':\n        if (!value) {\n          value = 'canvas';\n        }\n        break;\n      case 'tabStopWidth':\n        if (value < 1) {\n          console.warn(`${key} cannot be less than 1, value: ${value}`);\n          return;\n        }\n        break;\n      case 'theme':\n        // If open has been called we do not want to set options.theme as the\n        // source of truth is owned by the renderer.\n        if (this.renderer) {\n          this._setTheme(<ITheme>value);\n          return;\n        }\n        break;\n      case 'scrollback':\n        value = Math.min(value, MAX_BUFFER_SIZE);\n\n        if (value < 0) {\n          console.warn(`${key} cannot be less than 0, value: ${value}`);\n          return;\n        }\n        if (this.options[key] !== value) {\n          const newBufferLength = this.rows + value;\n          if (this.buffer.lines.length > newBufferLength) {\n            const amountToTrim = this.buffer.lines.length - newBufferLength;\n            const needsRefresh = (this.buffer.ydisp - amountToTrim < 0);\n            this.buffer.lines.trimStart(amountToTrim);\n            this.buffer.ybase = Math.max(this.buffer.ybase - amountToTrim, 0);\n            this.buffer.ydisp = Math.max(this.buffer.ydisp - amountToTrim, 0);\n            if (needsRefresh) {\n              this.refresh(0, this.rows - 1);\n            }\n          }\n        }\n        break;\n    }\n    this.options[key] = value;\n    switch (key) {\n      case 'fontFamily':\n      case 'fontSize':\n        // When the font changes the size of the cells may change which requires a renderer clear\n        if (this.renderer) {\n          this.renderer.clear();\n          this.charMeasure.measure(this.options);\n        }\n        break;\n      case 'drawBoldTextInBrightColors':\n      case 'experimentalCharAtlas':\n      case 'enableBold':\n      case 'letterSpacing':\n      case 'lineHeight':\n      case 'fontWeight':\n      case 'fontWeightBold':\n        // When the font changes the size of the cells may change which requires a renderer clear\n        if (this.renderer) {\n          this.renderer.clear();\n          this.renderer.onResize(this.cols, this.rows);\n          this.refresh(0, this.rows - 1);\n        }\n        break;\n      case 'rendererType':\n        if (this.renderer) {\n          this.unregister(this.renderer);\n          this.renderer.dispose();\n          this.renderer = null;\n        }\n        this._setupRenderer();\n        this.renderer.onCharSizeChanged();\n        if (this._theme) {\n          this.renderer.setTheme(this._theme);\n        }\n        this.mouseHelper.setRenderer(this.renderer);\n        break;\n      case 'scrollback':\n        this.buffers.resize(this.cols, this.rows);\n        if (this.viewport) {\n          this.viewport.syncScrollArea();\n        }\n        break;\n      case 'screenReaderMode':\n        if (value) {\n          if (!this._accessibilityManager) {\n            this._accessibilityManager = new AccessibilityManager(this);\n          }\n        } else {\n          if (this._accessibilityManager) {\n            this._accessibilityManager.dispose();\n            this._accessibilityManager = null;\n          }\n        }\n        break;\n      case 'tabStopWidth': this.buffers.setupTabStops(); break;\n      case 'windowsMode':\n        if (value) {\n          if (!this._windowsMode) {\n            this._windowsMode = applyWindowsMode(this);\n          }\n        } else {\n          if (this._windowsMode) {\n            this._windowsMode.dispose();\n            this._windowsMode = undefined;\n          }\n        }\n        break;\n    }\n    // Inform renderer of changes\n    if (this.renderer) {\n      this.renderer.onOptionsChanged();\n    }\n  }\n\n  /**\n   * Binds the desired focus behavior on a given terminal object.\n   */\n  private _onTextAreaFocus(ev: KeyboardEvent): void {\n    if (this.sendFocus) {\n      this.handler(C0.ESC + '[I');\n    }\n    this.updateCursorStyle(ev);\n    this.element.classList.add('focus');\n    this.showCursor();\n    this.emit('focus');\n  }\n\n  /**\n   * Blur the terminal, calling the blur function on the terminal's underlying\n   * textarea.\n   */\n  public blur(): void {\n    return this.textarea.blur();\n  }\n\n  /**\n   * Binds the desired blur behavior on a given terminal object.\n   */\n  private _onTextAreaBlur(): void {\n    // Text can safely be removed on blur. Doing it earlier could interfere with\n    // screen readers reading it out.\n    this.textarea.value = '';\n    this.refresh(this.buffer.y, this.buffer.y);\n    if (this.sendFocus) {\n      this.handler(C0.ESC + '[O');\n    }\n    this.element.classList.remove('focus');\n    this.emit('blur');\n  }\n\n  /**\n   * Initialize default behavior\n   */\n  private _initGlobal(): void {\n    this._bindKeys();\n\n    // Bind clipboard functionality\n    this.register(addDisposableDomListener(this.element, 'copy', (event: ClipboardEvent) => {\n      // If mouse events are active it means the selection manager is disabled and\n      // copy should be handled by the host program.\n      if (!this.hasSelection()) {\n        return;\n      }\n      copyHandler(event, this, this.selectionManager);\n    }));\n    const pasteHandlerWrapper = (event: ClipboardEvent) => pasteHandler(event, this);\n    this.register(addDisposableDomListener(this.textarea, 'paste', pasteHandlerWrapper));\n    this.register(addDisposableDomListener(this.element, 'paste', pasteHandlerWrapper));\n\n    // Handle right click context menus\n    if (Browser.isFirefox) {\n      // Firefox doesn't appear to fire the contextmenu event on right click\n      this.register(addDisposableDomListener(this.element, 'mousedown', (event: MouseEvent) => {\n        if (event.button === 2) {\n          rightClickHandler(event, this, this.selectionManager, this.options.rightClickSelectsWord);\n        }\n      }));\n    } else {\n      this.register(addDisposableDomListener(this.element, 'contextmenu', (event: MouseEvent) => {\n        rightClickHandler(event, this, this.selectionManager, this.options.rightClickSelectsWord);\n      }));\n    }\n\n    // Move the textarea under the cursor when middle clicking on Linux to ensure\n    // middle click to paste selection works. This only appears to work in Chrome\n    // at the time is writing.\n    if (Browser.isLinux) {\n      // Use auxclick event over mousedown the latter doesn't seem to work. Note\n      // that the regular click event doesn't fire for the middle mouse button.\n      this.register(addDisposableDomListener(this.element, 'auxclick', (event: MouseEvent) => {\n        if (event.button === 1) {\n          moveTextAreaUnderMouseCursor(event, this);\n        }\n      }));\n    }\n  }\n\n  /**\n   * Apply key handling to the terminal\n   */\n  private _bindKeys(): void {\n    const self = this;\n    this.register(addDisposableDomListener(this.element, 'keydown', function (ev: KeyboardEvent): void {\n      if (document.activeElement !== this) {\n        return;\n      }\n      self._keyDown(ev);\n    }, true));\n\n    this.register(addDisposableDomListener(this.element, 'keypress', function (ev: KeyboardEvent): void {\n      if (document.activeElement !== this) {\n        return;\n      }\n      self._keyPress(ev);\n    }, true));\n\n    this.register(addDisposableDomListener(this.element, 'keyup', (ev: KeyboardEvent) => {\n      if (!wasModifierKeyOnlyEvent(ev)) {\n        this.focus();\n      }\n\n      self._keyUp(ev);\n    }, true));\n\n    this.register(addDisposableDomListener(this.textarea, 'keydown', (ev: KeyboardEvent) => this._keyDown(ev), true));\n    this.register(addDisposableDomListener(this.textarea, 'keypress', (ev: KeyboardEvent) => this._keyPress(ev), true));\n    this.register(addDisposableDomListener(this.textarea, 'compositionstart', () => this._compositionHelper.compositionstart()));\n    this.register(addDisposableDomListener(this.textarea, 'compositionupdate', (e: CompositionEvent) => this._compositionHelper.compositionupdate(e)));\n    this.register(addDisposableDomListener(this.textarea, 'compositionend', () => this._compositionHelper.compositionend()));\n    this.register(this.onRender(() => this._compositionHelper.updateCompositionElements()));\n    this.register(this.onRender(e => this._queueLinkification(e.start, e.end)));\n  }\n\n  /**\n   * Opens the terminal within an element.\n   *\n   * @param parent The element to create the terminal within.\n   */\n  public open(parent: HTMLElement): void {\n    this._parent = parent || this._parent;\n\n    if (!this._parent) {\n      throw new Error('Terminal requires a parent element.');\n    }\n\n    // Grab global elements\n    this._context = this._parent.ownerDocument.defaultView;\n    this._document = this._parent.ownerDocument;\n\n    this._screenDprMonitor = new ScreenDprMonitor();\n    this._screenDprMonitor.setListener(() => this.emit('dprchange', window.devicePixelRatio));\n    this.register(this._screenDprMonitor);\n\n    // Create main element container\n    this.element = this._document.createElement('div');\n    this.element.dir = 'ltr';   // xterm.css assumes LTR\n    this.element.classList.add('terminal');\n    this.element.classList.add('xterm');\n    this.element.setAttribute('tabindex', '0');\n    this._parent.appendChild(this.element);\n\n    // Performance: Use a document fragment to build the terminal\n    // viewport and helper elements detached from the DOM\n    const fragment = document.createDocumentFragment();\n    this._viewportElement = document.createElement('div');\n    this._viewportElement.classList.add('xterm-viewport');\n    fragment.appendChild(this._viewportElement);\n    this._viewportScrollArea = document.createElement('div');\n    this._viewportScrollArea.classList.add('xterm-scroll-area');\n    this._viewportElement.appendChild(this._viewportScrollArea);\n\n    this.screenElement = document.createElement('div');\n    this.screenElement.classList.add('xterm-screen');\n    // Create the container that will hold helpers like the textarea for\n    // capturing DOM Events. Then produce the helpers.\n    this._helperContainer = document.createElement('div');\n    this._helperContainer.classList.add('xterm-helpers');\n    this.screenElement.appendChild(this._helperContainer);\n    fragment.appendChild(this.screenElement);\n\n    this._mouseZoneManager = new MouseZoneManager(this);\n    this.register(this._mouseZoneManager);\n    this.register(this.onScroll(() => this._mouseZoneManager.clearAll()));\n    this.linkifier.attachToDom(this._mouseZoneManager);\n\n    this.textarea = document.createElement('textarea');\n    this.textarea.classList.add('xterm-helper-textarea');\n    // TODO: New API to set title? This could say \"Terminal bash input\", etc.\n    this.textarea.setAttribute('aria-label', Strings.promptLabel);\n    this.textarea.setAttribute('aria-multiline', 'false');\n    this.textarea.setAttribute('autocorrect', 'off');\n    this.textarea.setAttribute('autocapitalize', 'off');\n    this.textarea.setAttribute('spellcheck', 'false');\n    this.textarea.tabIndex = 0;\n    this.register(addDisposableDomListener(this.textarea, 'focus', (ev: KeyboardEvent) => this._onTextAreaFocus(ev)));\n    this.register(addDisposableDomListener(this.textarea, 'blur', () => this._onTextAreaBlur()));\n    this._helperContainer.appendChild(this.textarea);\n\n    this._compositionView = document.createElement('div');\n    this._compositionView.classList.add('composition-view');\n    this._compositionHelper = new CompositionHelper(this.textarea, this._compositionView, this);\n    this._helperContainer.appendChild(this._compositionView);\n\n    this.charMeasure = new CharMeasure(document, this._helperContainer);\n\n    // Performance: Add viewport and helper elements from the fragment\n    this.element.appendChild(fragment);\n\n    this._setupRenderer();\n    this._theme = this.options.theme;\n    this.options.theme = null;\n    this.viewport = new Viewport(this, this._viewportElement, this._viewportScrollArea, this.charMeasure);\n    this.viewport.onThemeChanged(this.renderer.colorManager.colors);\n    this.register(this.viewport);\n\n    this.register(this.onCursorMove(() => this.renderer.onCursorMove()));\n    this.register(this.onResize(() => this.renderer.onResize(this.cols, this.rows)));\n    this.register(this.addDisposableListener('blur', () => this.renderer.onBlur()));\n    this.register(this.addDisposableListener('focus', () => this.renderer.onFocus()));\n    this.register(this.addDisposableListener('dprchange', () => this.renderer.onWindowResize(window.devicePixelRatio)));\n    // dprchange should handle this case, we need this as well for browsers that don't support the\n    // matchMedia query.\n    this.register(addDisposableDomListener(window, 'resize', () => this.renderer.onWindowResize(window.devicePixelRatio)));\n    this.register(this.charMeasure.onCharSizeChanged(() => this.renderer.onCharSizeChanged()));\n    this.register(this.renderer.onCanvasResize(() => this.viewport.syncScrollArea()));\n\n    this.selectionManager = new SelectionManager(this, this.charMeasure);\n    this.register(this.selectionManager.onSelectionChange(() => this._onSelectionChange.fire()));\n    this.register(addDisposableDomListener(this.element, 'mousedown', (e: MouseEvent) => this.selectionManager.onMouseDown(e)));\n    this.register(this.selectionManager.onRedrawRequest(e => this.renderer.onSelectionChanged(e.start, e.end, e.columnSelectMode)));\n    this.register(this.selectionManager.onLinuxMouseSelection(text => {\n      // If there's a new selection, put it into the textarea, focus and select it\n      // in order to register it as a selection on the OS. This event is fired\n      // only on Linux to enable middle click to paste selection.\n      this.textarea.value = text;\n      this.textarea.focus();\n      this.textarea.select();\n    }));\n    this.register(this.onScroll(() => {\n      this.viewport.syncScrollArea();\n      this.selectionManager.refresh();\n    }));\n    this.register(addDisposableDomListener(this._viewportElement, 'scroll', () => this.selectionManager.refresh()));\n\n    this.mouseHelper = new MouseHelper(this.renderer);\n    // apply mouse event classes set by escape codes before terminal was attached\n    this.element.classList.toggle('enable-mouse-events', this.mouseEvents);\n    if (this.mouseEvents) {\n      this.selectionManager.disable();\n    } else {\n      this.selectionManager.enable();\n    }\n\n    if (this.options.screenReaderMode) {\n      // Note that this must be done *after* the renderer is created in order to\n      // ensure the correct order of the dprchange event\n      this._accessibilityManager = new AccessibilityManager(this);\n    }\n\n    // Measure the character size\n    this.charMeasure.measure(this.options);\n\n    // Setup loop that draws to screen\n    this.refresh(0, this.rows - 1);\n\n    // Initialize global actions that need to be taken on the document.\n    this._initGlobal();\n\n    // Listen for mouse events and translate\n    // them into terminal mouse protocols.\n    this.bindMouse();\n\n  }\n\n  private _setupRenderer(): void {\n    switch (this.options.rendererType) {\n      case 'canvas': this.renderer = new Renderer(this, this.options.theme); break;\n      case 'dom': this.renderer = new DomRenderer(this, this.options.theme); break;\n      default: throw new Error(`Unrecognized rendererType \"${this.options.rendererType}\"`);\n    }\n    this.renderer.onRender(e => this._onRender.fire(e));\n    this.register(this.renderer);\n  }\n\n  /**\n   * Sets the theme on the renderer. The renderer must have been initialized.\n   * @param theme The theme to set.\n   */\n  private _setTheme(theme: ITheme): void {\n    this._theme = theme;\n    const colors = this.renderer.setTheme(theme);\n    if (this.viewport) {\n      this.viewport.onThemeChanged(colors);\n    }\n  }\n\n  /**\n   * XTerm mouse events\n   * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking\n   * To better understand these\n   * the xterm code is very helpful:\n   * Relevant files:\n   *   button.c, charproc.c, misc.c\n   * Relevant functions in xterm/button.c:\n   *   BtnCode, EmitButtonCode, EditorButton, SendMousePosition\n   */\n  public bindMouse(): void {\n    const el = this.element;\n    const self = this;\n    let pressed = 32;\n\n    // mouseup, mousedown, wheel\n    // left click: ^[[M 3<^[[M#3<\n    // wheel up: ^[[M`3>\n    function sendButton(ev: MouseEvent | WheelEvent): void {\n      let button;\n      let pos;\n\n      // get the xterm-style button\n      button = getButton(ev);\n\n      // get mouse coordinates\n      pos = self.mouseHelper.getRawByteCoords(ev, self.screenElement, self.charMeasure, self.cols, self.rows);\n      if (!pos) return;\n\n      sendEvent(button, pos);\n\n      switch ((<any>ev).overrideType || ev.type) {\n        case 'mousedown':\n          pressed = button;\n          break;\n        case 'mouseup':\n          // keep it at the left\n          // button, just in case.\n          pressed = 32;\n          break;\n        case 'wheel':\n          // nothing. don't\n          // interfere with\n          // `pressed`.\n          break;\n      }\n    }\n\n    // motion example of a left click:\n    // ^[[M 3<^[[M@4<^[[M@5<^[[M@6<^[[M@7<^[[M#7<\n    function sendMove(ev: MouseEvent): void {\n      let button = pressed;\n      const pos = self.mouseHelper.getRawByteCoords(ev, self.screenElement, self.charMeasure, self.cols, self.rows);\n      if (!pos) return;\n\n      // buttons marked as motions\n      // are incremented by 32\n      button += 32;\n\n      sendEvent(button, pos);\n    }\n\n    // encode button and\n    // position to characters\n    function encode(data: number[], ch: number): void {\n      if (!self.utfMouse) {\n        if (ch === 255) {\n          data.push(0);\n          return;\n        }\n        if (ch > 127) ch = 127;\n        data.push(ch);\n      } else {\n        if (ch > 2047) {\n          data.push(2047);\n          return;\n        }\n        data.push(ch);\n      }\n    }\n\n    // send a mouse event:\n    // regular/utf8: ^[[M Cb Cx Cy\n    // urxvt: ^[[ Cb ; Cx ; Cy M\n    // sgr: ^[[ Cb ; Cx ; Cy M/m\n    // vt300: ^[[ 24(1/3/5)~ [ Cx , Cy ] \\r\n    // locator: CSI P e ; P b ; P r ; P c ; P p & w\n    function sendEvent(button: number, pos: {x: number, y: number}): void {\n      // self.emit('mouse', {\n      //   x: pos.x - 32,\n      //   y: pos.x - 32,\n      //   button: button\n      // });\n\n      if (self._vt300Mouse) {\n        // NOTE: Unstable.\n        // http://www.vt100.net/docs/vt3xx-gp/chapter15.html\n        button &= 3;\n        pos.x -= 32;\n        pos.y -= 32;\n        let data = C0.ESC + '[24';\n        if (button === 0) data += '1';\n        else if (button === 1) data += '3';\n        else if (button === 2) data += '5';\n        else if (button === 3) return;\n        else data += '0';\n        data += '~[' + pos.x + ',' + pos.y + ']\\r';\n        self.handler(data);\n        return;\n      }\n\n      if (self._decLocator) {\n        // NOTE: Unstable.\n        button &= 3;\n        pos.x -= 32;\n        pos.y -= 32;\n        if (button === 0) button = 2;\n        else if (button === 1) button = 4;\n        else if (button === 2) button = 6;\n        else if (button === 3) button = 3;\n        self.handler(C0.ESC + '['\n                  + button\n                  + ';'\n                  + (button === 3 ? 4 : 0)\n                  + ';'\n                  + pos.y\n                  + ';'\n                  + pos.x\n                  + ';'\n                  // Not sure what page is meant to be\n                  + (<any>pos).page || 0\n                  + '&w');\n        return;\n      }\n\n      if (self.urxvtMouse) {\n        pos.x -= 32;\n        pos.y -= 32;\n        pos.x++;\n        pos.y++;\n        self.handler(C0.ESC + '[' + button + ';' + pos.x + ';' + pos.y + 'M');\n        return;\n      }\n\n      if (self.sgrMouse) {\n        pos.x -= 32;\n        pos.y -= 32;\n        self.handler(C0.ESC + '[<'\n                  + (((button & 3) === 3 ? button & ~3 : button) - 32)\n                  + ';'\n                  + pos.x\n                  + ';'\n                  + pos.y\n                  + ((button & 3) === 3 ? 'm' : 'M'));\n        return;\n      }\n\n      const data: number[] = [];\n\n      encode(data, button);\n      encode(data, pos.x);\n      encode(data, pos.y);\n\n      self.handler(C0.ESC + '[M' + String.fromCharCode.apply(String, data));\n    }\n\n    function getButton(ev: MouseEvent): number {\n      let button;\n      let shift;\n      let meta;\n      let ctrl;\n      let mod;\n\n      // two low bits:\n      // 0 = left\n      // 1 = middle\n      // 2 = right\n      // 3 = release\n      // wheel up/down:\n      // 1, and 2 - with 64 added\n      switch ((<any>ev).overrideType || ev.type) {\n        case 'mousedown':\n          button = ev.button !== null && ev.button !== undefined\n            ? +ev.button\n          : ev.which !== null && ev.which !== undefined\n            ? ev.which - 1\n          : null;\n\n          if (Browser.isMSIE) {\n            button = button === 1 ? 0 : button === 4 ? 1 : button;\n          }\n          break;\n        case 'mouseup':\n          button = 3;\n          break;\n        case 'DOMMouseScroll':\n          button = ev.detail < 0\n            ? 64\n          : 65;\n          break;\n        case 'wheel':\n          button = (<WheelEvent>ev).deltaY < 0\n            ? 64\n          : 65;\n          break;\n      }\n\n      // next three bits are the modifiers:\n      // 4 = shift, 8 = meta, 16 = control\n      shift = ev.shiftKey ? 4 : 0;\n      meta = ev.metaKey ? 8 : 0;\n      ctrl = ev.ctrlKey ? 16 : 0;\n      mod = shift | meta | ctrl;\n\n      // no mods\n      if (self.vt200Mouse) {\n        // ctrl only\n        mod &= ctrl;\n      } else if (!self.normalMouse) {\n        mod = 0;\n      }\n\n      // increment to SP\n      button = (32 + (mod << 2)) + button;\n\n      return button;\n    }\n\n    this.register(addDisposableDomListener(el, 'mousedown', (ev: MouseEvent) => {\n\n      // Prevent the focus on the textarea from getting lost\n      // and make sure we get focused on mousedown\n      ev.preventDefault();\n      this.focus();\n\n      // Don't send the mouse button to the pty if mouse events are disabled or\n      // if the selection manager is having selection forced (ie. a modifier is\n      // held).\n      if (!this.mouseEvents || this.selectionManager.shouldForceSelection(ev)) {\n        return;\n      }\n\n      // send the button\n      sendButton(ev);\n\n      // fix for odd bug\n      // if (this.vt200Mouse && !this.normalMouse) {\n      if (this.vt200Mouse) {\n        (<any>ev).overrideType = 'mouseup';\n        sendButton(ev);\n        return this.cancel(ev);\n      }\n\n      // TODO: All mouse handling should be pulled into its own file.\n\n      // bind events\n      let moveHandler: (event: MouseEvent) => void;\n      if (this.normalMouse) {\n        moveHandler = (event: MouseEvent) => {\n          // Do nothing if normal mouse mode is on. This can happen if the mouse is held down when the\n          // terminal exits normalMouse mode.\n          if (!this.normalMouse) {\n            return;\n          }\n          sendMove(event);\n        };\n        // TODO: these event listeners should be managed by the disposable, the Terminal reference may\n        // be kept aroud if Terminal.dispose is fired when the mouse is down\n        this._document.addEventListener('mousemove', moveHandler);\n      }\n\n      // x10 compatibility mode can't send button releases\n      const handler = (ev: MouseEvent) => {\n        if (this.normalMouse && !this.x10Mouse) {\n          sendButton(ev);\n        }\n        if (moveHandler) {\n          // Even though this should only be attached when this.normalMouse is true, holding the\n          // mouse button down when normalMouse changes can happen. Just always try to remove it.\n          this._document.removeEventListener('mousemove', moveHandler);\n          moveHandler = null;\n        }\n        this._document.removeEventListener('mouseup', handler);\n        return this.cancel(ev);\n      };\n      this._document.addEventListener('mouseup', handler);\n\n      return this.cancel(ev);\n    }));\n\n    // if (this.normalMouse) {\n    //  on(this.document, 'mousemove', sendMove);\n    // }\n\n    this.register(addDisposableDomListener(el, 'wheel', (ev: WheelEvent) => {\n      if (!this.mouseEvents) {\n        // Convert wheel events into up/down events when the buffer does not have scrollback, this\n        // enables scrolling in apps hosted in the alt buffer such as vim or tmux.\n        if (!this.buffer.hasScrollback) {\n          const amount = this.viewport.getLinesScrolled(ev);\n\n          // Do nothing if there's no vertical scroll\n          if (amount === 0) {\n            return;\n          }\n\n          // Construct and send sequences\n          const sequence = C0.ESC + (this.applicationCursor ? 'O' : '[') + ( ev.deltaY < 0 ? 'A' : 'B');\n          let data = '';\n          for (let i = 0; i < Math.abs(amount); i++) {\n            data += sequence;\n          }\n          this.handler(data);\n        }\n        return;\n      }\n      if (this.x10Mouse || this._vt300Mouse || this._decLocator) return;\n      sendButton(ev);\n      ev.preventDefault();\n    }));\n\n    // allow wheel scrolling in\n    // the shell for example\n    this.register(addDisposableDomListener(el, 'wheel', (ev: WheelEvent) => {\n      if (this.mouseEvents) return;\n      this.viewport.onWheel(ev);\n      return this.cancel(ev);\n    }));\n\n    this.register(addDisposableDomListener(el, 'touchstart', (ev: TouchEvent) => {\n      if (this.mouseEvents) return;\n      this.viewport.onTouchStart(ev);\n      return this.cancel(ev);\n    }));\n\n    this.register(addDisposableDomListener(el, 'touchmove', (ev: TouchEvent) => {\n      if (this.mouseEvents) return;\n      this.viewport.onTouchMove(ev);\n      return this.cancel(ev);\n    }));\n  }\n\n  /**\n   * Tells the renderer to refresh terminal content between two rows (inclusive) at the next\n   * opportunity.\n   * @param start The row to start from (between 0 and this.rows - 1).\n   * @param end The row to end at (between start and this.rows - 1).\n   */\n  public refresh(start: number, end: number): void {\n    if (this.renderer) {\n      this.renderer.refreshRows(start, end);\n    }\n  }\n\n  /**\n   * Queues linkification for the specified rows.\n   * @param start The row to start from (between 0 and this.rows - 1).\n   * @param end The row to end at (between start and this.rows - 1).\n   */\n  private _queueLinkification(start: number, end: number): void {\n    if (this.linkifier) {\n      this.linkifier.linkifyRows(start, end);\n    }\n  }\n\n  /**\n   * Change the cursor style for different selection modes\n   */\n  public updateCursorStyle(ev: KeyboardEvent): void {\n    if (this.selectionManager && this.selectionManager.shouldColumnSelect(ev)) {\n      this.element.classList.add('column-select');\n    } else {\n      this.element.classList.remove('column-select');\n    }\n  }\n\n  /**\n   * Display the cursor element\n   */\n  public showCursor(): void {\n    if (!this.cursorState) {\n      this.cursorState = 1;\n      this.refresh(this.buffer.y, this.buffer.y);\n    }\n  }\n\n  /**\n   * Scroll the terminal down 1 row, creating a blank line.\n   * @param isWrapped Whether the new line is wrapped from the previous line.\n   */\n  public scroll(isWrapped: boolean = false): void {\n    let newLine: IBufferLine;\n    newLine = this._blankLine;\n    const eraseAttr = this.eraseAttrData();\n    if (!newLine || newLine.length !== this.cols || newLine.getFg(0) !== eraseAttr.fg || newLine.getBg(0) !== eraseAttr.bg) {\n      newLine = this.buffer.getBlankLine(eraseAttr, isWrapped);\n      this._blankLine = newLine;\n    }\n    newLine.isWrapped = isWrapped;\n\n    const topRow = this.buffer.ybase + this.buffer.scrollTop;\n    const bottomRow = this.buffer.ybase + this.buffer.scrollBottom;\n\n    if (this.buffer.scrollTop === 0) {\n      // Determine whether the buffer is going to be trimmed after insertion.\n      const willBufferBeTrimmed = this.buffer.lines.isFull;\n\n      // Insert the line using the fastest method\n      if (bottomRow === this.buffer.lines.length - 1) {\n        if (willBufferBeTrimmed) {\n          this.buffer.lines.recycle().copyFrom(newLine);\n        } else {\n          this.buffer.lines.push(newLine.clone());\n        }\n      } else {\n        this.buffer.lines.splice(bottomRow + 1, 0, newLine.clone());\n      }\n\n      // Only adjust ybase and ydisp when the buffer is not trimmed\n      if (!willBufferBeTrimmed) {\n        this.buffer.ybase++;\n        // Only scroll the ydisp with ybase if the user has not scrolled up\n        if (!this._userScrolling) {\n          this.buffer.ydisp++;\n        }\n      } else {\n        // When the buffer is full and the user has scrolled up, keep the text\n        // stable unless ydisp is right at the top\n        if (this._userScrolling) {\n          this.buffer.ydisp = Math.max(this.buffer.ydisp - 1, 0);\n        }\n      }\n    } else {\n      // scrollTop is non-zero which means no line will be going to the\n      // scrollback, instead we can just shift them in-place.\n      const scrollRegionHeight = bottomRow - topRow + 1/*as it's zero-based*/;\n      this.buffer.lines.shiftElements(topRow + 1, scrollRegionHeight - 1, -1);\n      this.buffer.lines.set(bottomRow, newLine.clone());\n    }\n\n    // Move the viewport to the bottom of the buffer unless the user is\n    // scrolling.\n    if (!this._userScrolling) {\n      this.buffer.ydisp = this.buffer.ybase;\n    }\n\n    // Flag rows that need updating\n    this.updateRange(this.buffer.scrollTop);\n    this.updateRange(this.buffer.scrollBottom);\n\n    this._onScroll.fire(this.buffer.ydisp);\n  }\n\n  /**\n   * Scroll the display of the terminal\n   * @param disp The number of lines to scroll down (negative scroll up).\n   * @param suppressScrollEvent Don't emit the scroll event as scrollLines. This is used\n   * to avoid unwanted events being handled by the viewport when the event was triggered from the\n   * viewport originally.\n   */\n  public scrollLines(disp: number, suppressScrollEvent?: boolean): void {\n    if (disp < 0) {\n      if (this.buffer.ydisp === 0) {\n        return;\n      }\n      this._userScrolling = true;\n    } else if (disp + this.buffer.ydisp >= this.buffer.ybase) {\n      this._userScrolling = false;\n    }\n\n    const oldYdisp = this.buffer.ydisp;\n    this.buffer.ydisp = Math.max(Math.min(this.buffer.ydisp + disp, this.buffer.ybase), 0);\n\n    // No change occurred, don't trigger scroll/refresh\n    if (oldYdisp === this.buffer.ydisp) {\n      return;\n    }\n\n    if (!suppressScrollEvent) {\n      this._onScroll.fire(this.buffer.ydisp);\n    }\n\n    this.refresh(0, this.rows - 1);\n  }\n\n  /**\n   * Scroll the display of the terminal by a number of pages.\n   * @param pageCount The number of pages to scroll (negative scrolls up).\n   */\n  public scrollPages(pageCount: number): void {\n    this.scrollLines(pageCount * (this.rows - 1));\n  }\n\n  /**\n   * Scrolls the display of the terminal to the top.\n   */\n  public scrollToTop(): void {\n    this.scrollLines(-this.buffer.ydisp);\n  }\n\n  /**\n   * Scrolls the display of the terminal to the bottom.\n   */\n  public scrollToBottom(): void {\n    this.scrollLines(this.buffer.ybase - this.buffer.ydisp);\n  }\n\n  public scrollToLine(line: number): void {\n    const scrollAmount = line - this.buffer.ydisp;\n    if (scrollAmount !== 0) {\n      this.scrollLines(scrollAmount);\n    }\n  }\n\n  /**\n   * Writes text to the terminal.\n   * @param data The text to write to the terminal.\n   */\n  public write(data: string): void {\n    // Ensure the terminal isn't disposed\n    if (this._isDisposed) {\n      return;\n    }\n\n    // Ignore falsy data values (including the empty string)\n    if (!data) {\n      return;\n    }\n\n    this.writeBuffer.push(data);\n\n    // Send XOFF to pause the pty process if the write buffer becomes too large so\n    // xterm.js can catch up before more data is sent. This is necessary in order\n    // to keep signals such as ^C responsive.\n    if (this.options.useFlowControl && !this._xoffSentToCatchUp && this.writeBuffer.length >= WRITE_BUFFER_PAUSE_THRESHOLD) {\n      // XOFF - stop pty pipe\n      // XON will be triggered by emulator before processing data chunk\n      this.handler(C0.DC3);\n      this._xoffSentToCatchUp = true;\n    }\n\n    if (!this._writeInProgress && this.writeBuffer.length > 0) {\n      // Kick off a write which will write all data in sequence recursively\n      this._writeInProgress = true;\n      // Kick off an async innerWrite so more writes can come in while processing data\n      setTimeout(() => {\n        this._innerWrite();\n      });\n    }\n  }\n\n  protected _innerWrite(bufferOffset: number = 0): void {\n    // Ensure the terminal isn't disposed\n    if (this._isDisposed) {\n      this.writeBuffer = [];\n    }\n\n    const startTime = Date.now();\n    while (this.writeBuffer.length > bufferOffset) {\n      const data = this.writeBuffer[bufferOffset];\n      bufferOffset++;\n\n      // If XOFF was sent in order to catch up with the pty process, resume it if\n      // we reached the end of the writeBuffer to allow more data to come in.\n      if (this._xoffSentToCatchUp && this.writeBuffer.length === bufferOffset) {\n        this.handler(C0.DC1);\n        this._xoffSentToCatchUp = false;\n      }\n\n      this._refreshStart = this.buffer.y;\n      this._refreshEnd = this.buffer.y;\n\n      // HACK: Set the parser state based on it's state at the time of return.\n      // This works around the bug #662 which saw the parser state reset in the\n      // middle of parsing escape sequence in two chunks. For some reason the\n      // state of the parser resets to 0 after exiting parser.parse. This change\n      // just sets the state back based on the correct return statement.\n\n      this._inputHandler.parse(data);\n\n      this.updateRange(this.buffer.y);\n      this.refresh(this._refreshStart, this._refreshEnd);\n\n      if (Date.now() - startTime >= WRITE_TIMEOUT_MS) {\n        break;\n      }\n    }\n    if (this.writeBuffer.length > bufferOffset) {\n      // Allow renderer to catch up before processing the next batch\n      setTimeout(() => this._innerWrite(bufferOffset), 0);\n    } else {\n      this._writeInProgress = false;\n      this.writeBuffer = [];\n    }\n  }\n\n  /**\n   * Writes text to the terminal, followed by a break line character (\\n).\n   * @param data The text to write to the terminal.\n   */\n  public writeln(data: string): void {\n    this.write(data + '\\r\\n');\n  }\n\n  /**\n   * Attaches a custom key event handler which is run before keys are processed,\n   * giving consumers of xterm.js ultimate control as to what keys should be\n   * processed by the terminal and what keys should not.\n   * @param customKeyEventHandler The custom KeyboardEvent handler to attach.\n   * This is a function that takes a KeyboardEvent, allowing consumers to stop\n   * propagation and/or prevent the default action. The function returns whether\n   * the event should be processed by xterm.js.\n   */\n  public attachCustomKeyEventHandler(customKeyEventHandler: CustomKeyEventHandler): void {\n    this._customKeyEventHandler = customKeyEventHandler;\n  }\n\n  /** Add handler for CSI escape sequence. See xterm.d.ts for details. */\n  public addCsiHandler(flag: string, callback: (params: number[], collect: string) => boolean): IDisposable {\n    return this._inputHandler.addCsiHandler(flag, callback);\n  }\n  /** Add handler for OSC escape sequence. See xterm.d.ts for details. */\n  public addOscHandler(ident: number, callback: (data: string) => boolean): IDisposable {\n    return this._inputHandler.addOscHandler(ident, callback);\n  }\n\n  /**\n   * Registers a link matcher, allowing custom link patterns to be matched and\n   * handled.\n   * @param regex The regular expression to search for, specifically\n   * this searches the textContent of the rows. You will want to use \\s to match\n   * a space ' ' character for example.\n   * @param handler The callback when the link is called.\n   * @param options Options for the link matcher.\n   * @return The ID of the new matcher, this can be used to deregister.\n   */\n  public registerLinkMatcher(regex: RegExp, handler: LinkMatcherHandler, options?: ILinkMatcherOptions): number {\n    const matcherId = this.linkifier.registerLinkMatcher(regex, handler, options);\n    this.refresh(0, this.rows - 1);\n    return matcherId;\n  }\n\n  /**\n   * Deregisters a link matcher if it has been registered.\n   * @param matcherId The link matcher's ID (returned after register)\n   */\n  public deregisterLinkMatcher(matcherId: number): void {\n    if (this.linkifier.deregisterLinkMatcher(matcherId)) {\n      this.refresh(0, this.rows - 1);\n    }\n  }\n\n  public registerCharacterJoiner(handler: CharacterJoinerHandler): number {\n    const joinerId = this.renderer.registerCharacterJoiner(handler);\n    this.refresh(0, this.rows - 1);\n    return joinerId;\n  }\n\n  public deregisterCharacterJoiner(joinerId: number): void {\n    if (this.renderer.deregisterCharacterJoiner(joinerId)) {\n      this.refresh(0, this.rows - 1);\n    }\n  }\n\n  public get markers(): IMarker[] {\n    return this.buffer.markers;\n  }\n\n  public addMarker(cursorYOffset: number): IMarker {\n    // Disallow markers on the alt buffer\n    if (this.buffer !== this.buffers.normal) {\n      return;\n    }\n\n    return this.buffer.addMarker(this.buffer.ybase + this.buffer.y + cursorYOffset);\n  }\n\n  /**\n   * Gets whether the terminal has an active selection.\n   */\n  public hasSelection(): boolean {\n    return this.selectionManager ? this.selectionManager.hasSelection : false;\n  }\n\n  /**\n   * Gets the terminal's current selection, this is useful for implementing copy\n   * behavior outside of xterm.js.\n   */\n  public getSelection(): string {\n    return this.selectionManager ? this.selectionManager.selectionText : '';\n  }\n\n  /**\n   * Clears the current terminal selection.\n   */\n  public clearSelection(): void {\n    if (this.selectionManager) {\n      this.selectionManager.clearSelection();\n    }\n  }\n\n  /**\n   * Selects all text within the terminal.\n   */\n  public selectAll(): void {\n    if (this.selectionManager) {\n      this.selectionManager.selectAll();\n    }\n  }\n\n  public selectLines(start: number, end: number): void {\n    if (this.selectionManager) {\n      this.selectionManager.selectLines(start, end);\n    }\n  }\n\n  /**\n   * Handle a keydown event\n   * Key Resources:\n   *   - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n   * @param ev The keydown event to be handled.\n   */\n  protected _keyDown(event: KeyboardEvent): boolean {\n    if (this._customKeyEventHandler && this._customKeyEventHandler(event) === false) {\n      return false;\n    }\n\n    if (!this._compositionHelper.keydown(event)) {\n      if (this.buffer.ybase !== this.buffer.ydisp) {\n        this.scrollToBottom();\n      }\n      return false;\n    }\n\n    const result = evaluateKeyboardEvent(event, this.applicationCursor, this.browser.isMac, this.options.macOptionIsMeta);\n\n    this.updateCursorStyle(event);\n\n    // if (result.key === C0.DC3) { // XOFF\n    //   this._writeStopped = true;\n    // } else if (result.key === C0.DC1) { // XON\n    //   this._writeStopped = false;\n    // }\n\n    if (result.type === KeyboardResultType.PAGE_DOWN || result.type === KeyboardResultType.PAGE_UP) {\n      const scrollCount = this.rows - 1;\n      this.scrollLines(result.type === KeyboardResultType.PAGE_UP ? -scrollCount : scrollCount);\n      return this.cancel(event, true);\n    }\n\n    if (result.type === KeyboardResultType.SELECT_ALL) {\n      this.selectAll();\n    }\n\n    if (this._isThirdLevelShift(this.browser, event)) {\n      return true;\n    }\n\n    if (result.cancel) {\n      // The event is canceled at the end already, is this necessary?\n      this.cancel(event, true);\n    }\n\n    if (!result.key) {\n      return true;\n    }\n\n    this.emit('keydown', event);\n    this._onKey.fire({ key: result.key, domEvent: event });\n    this.showCursor();\n    this.handler(result.key);\n\n    return this.cancel(event, true);\n  }\n\n  private _isThirdLevelShift(browser: IBrowser, ev: IKeyboardEvent): boolean {\n    const thirdLevelKey =\n        (browser.isMac && !this.options.macOptionIsMeta && ev.altKey && !ev.ctrlKey && !ev.metaKey) ||\n        (browser.isMSWindows && ev.altKey && ev.ctrlKey && !ev.metaKey);\n\n    if (ev.type === 'keypress') {\n      return thirdLevelKey;\n    }\n\n    // Don't invoke for arrows, pageDown, home, backspace, etc. (on non-keypress events)\n    return thirdLevelKey && (!ev.keyCode || ev.keyCode > 47);\n  }\n\n  /**\n   * Set the G level of the terminal\n   * @param g\n   */\n  public setgLevel(g: number): void {\n    this.glevel = g;\n    this.charset = this.charsets[g];\n  }\n\n  /**\n   * Set the charset for the given G level of the terminal\n   * @param g\n   * @param charset\n   */\n  public setgCharset(g: number, charset: ICharset): void {\n    this.charsets[g] = charset;\n    if (this.glevel === g) {\n      this.charset = charset;\n    }\n  }\n\n  protected _keyUp(ev: KeyboardEvent): void {\n    this.updateCursorStyle(ev);\n  }\n\n  /**\n   * Handle a keypress event.\n   * Key Resources:\n   *   - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n   * @param ev The keypress event to be handled.\n   */\n  protected _keyPress(ev: KeyboardEvent): boolean {\n    let key;\n\n    if (this._customKeyEventHandler && this._customKeyEventHandler(ev) === false) {\n      return false;\n    }\n\n    this.cancel(ev);\n\n    if (ev.charCode) {\n      key = ev.charCode;\n    } else if (ev.which === null || ev.which === undefined) {\n      key = ev.keyCode;\n    } else if (ev.which !== 0 && ev.charCode !== 0) {\n      key = ev.which;\n    } else {\n      return false;\n    }\n\n    if (!key || (\n      (ev.altKey || ev.ctrlKey || ev.metaKey) && !this._isThirdLevelShift(this.browser, ev)\n    )) {\n      return false;\n    }\n\n    key = String.fromCharCode(key);\n\n    this.emit('keypress', key, ev);\n    this._onKey.fire({ key, domEvent: ev });\n    this.showCursor();\n    this.handler(key);\n\n    return true;\n  }\n\n  /**\n   * Ring the bell.\n   * Note: We could do sweet things with webaudio here\n   */\n  public bell(): void {\n    this.emit('bell');\n    if (this._soundBell()) {\n      this.soundManager.playBellSound();\n    }\n\n    if (this._visualBell()) {\n      this.element.classList.add('visual-bell-active');\n      clearTimeout(this._visualBellTimer);\n      this._visualBellTimer = window.setTimeout(() => {\n        this.element.classList.remove('visual-bell-active');\n      }, 200);\n    }\n  }\n\n  /**\n   * Log the current state to the console.\n   */\n  public log(text: string, data?: any): void {\n    if (!this.options.debug) return;\n    if (!this._context.console || !this._context.console.log) return;\n    this._context.console.log(text, data);\n  }\n\n  /**\n   * Log the current state as error to the console.\n   */\n  public error(text: string, data?: any): void {\n    if (!this.options.debug) return;\n    if (!this._context.console || !this._context.console.error) return;\n    this._context.console.error(text, data);\n  }\n\n  /**\n   * Resizes the terminal.\n   *\n   * @param x The number of columns to resize to.\n   * @param y The number of rows to resize to.\n   */\n  public resize(x: number, y: number): void {\n    if (isNaN(x) || isNaN(y)) {\n      return;\n    }\n\n    if (x === this.cols && y === this.rows) {\n      // Check if we still need to measure the char size (fixes #785).\n      if (this.charMeasure && (!this.charMeasure.width || !this.charMeasure.height)) {\n        this.charMeasure.measure(this.options);\n      }\n      return;\n    }\n\n    if (x < MINIMUM_COLS) x = MINIMUM_COLS;\n    if (y < MINIMUM_ROWS) y = MINIMUM_ROWS;\n\n    this.buffers.resize(x, y);\n\n    this.cols = x;\n    this.rows = y;\n    this.buffers.setupTabStops(this.cols);\n\n    if (this.charMeasure) {\n      this.charMeasure.measure(this.options);\n    }\n\n    this.refresh(0, this.rows - 1);\n    this._onResize.fire({ cols: x, rows: y });\n  }\n\n  /**\n   * Updates the range of rows to refresh\n   * @param y The number of rows to refresh next.\n   */\n  public updateRange(y: number): void {\n    if (y < this._refreshStart) this._refreshStart = y;\n    if (y > this._refreshEnd) this._refreshEnd = y;\n    // if (y > this.refreshEnd) {\n    //   this.refreshEnd = y;\n    //   if (y > this.rows - 1) {\n    //     this.refreshEnd = this.rows - 1;\n    //   }\n    // }\n  }\n\n  /**\n   * Set the range of refreshing to the maximum value\n   */\n  public maxRange(): void {\n    this._refreshStart = 0;\n    this._refreshEnd = this.rows - 1;\n  }\n\n  /**\n   * Clear the entire buffer, making the prompt line the new first line.\n   */\n  public clear(): void {\n    if (this.buffer.ybase === 0 && this.buffer.y === 0) {\n      // Don't clear if it's already clear\n      return;\n    }\n    this.buffer.lines.set(0, this.buffer.lines.get(this.buffer.ybase + this.buffer.y));\n    this.buffer.lines.length = 1;\n    this.buffer.ydisp = 0;\n    this.buffer.ybase = 0;\n    this.buffer.y = 0;\n    for (let i = 1; i < this.rows; i++) {\n      this.buffer.lines.push(this.buffer.getBlankLine(DEFAULT_ATTR_DATA));\n    }\n    this.refresh(0, this.rows - 1);\n    this._onScroll.fire(this.buffer.ydisp);\n  }\n\n  /**\n   * Evaluate if the current terminal is the given argument.\n   * @param term The terminal name to evaluate\n   */\n  public is(term: string): boolean {\n    return (this.options.termName + '').indexOf(term) === 0;\n  }\n\n  /**\n   * Emit the data event and populate the given data.\n   * @param data The data to populate in the event.\n   */\n  public handler(data: string): void {\n    // Prevents all events to pty process if stdin is disabled\n    if (this.options.disableStdin) {\n      return;\n    }\n\n    // Clear the selection if the selection manager is available and has an active selection\n    if (this.selectionManager && this.selectionManager.hasSelection) {\n      this.selectionManager.clearSelection();\n    }\n\n    // Input is being sent to the terminal, the terminal should focus the prompt.\n    if (this.buffer.ybase !== this.buffer.ydisp) {\n      this.scrollToBottom();\n    }\n    this._onData.fire(data);\n  }\n\n  /**\n   * Emit the 'title' event and populate the given title.\n   * @param title The title to populate in the event.\n   */\n  public handleTitle(title: string): void {\n    this._onTitleChange.fire(title);\n  }\n\n  /**\n   * ESC\n   */\n\n  /**\n   * ESC D Index (IND is 0x84).\n   */\n  public index(): void {\n    this.buffer.y++;\n    if (this.buffer.y > this.buffer.scrollBottom) {\n      this.buffer.y--;\n      this.scroll();\n    }\n    // If the end of the line is hit, prevent this action from wrapping around to the next line.\n    if (this.buffer.x >= this.cols) {\n      this.buffer.x--;\n    }\n  }\n\n  /**\n   * ESC M Reverse Index (RI is 0x8d).\n   *\n   * Move the cursor up one row, inserting a new blank line if necessary.\n   */\n  public reverseIndex(): void {\n    if (this.buffer.y === this.buffer.scrollTop) {\n      // possibly move the code below to term.reverseScroll();\n      // test: echo -ne '\\e[1;1H\\e[44m\\eM\\e[0m'\n      // blankLine(true) is xterm/linux behavior\n      const scrollRegionHeight = this.buffer.scrollBottom - this.buffer.scrollTop;\n      this.buffer.lines.shiftElements(this.buffer.y + this.buffer.ybase, scrollRegionHeight, 1);\n      this.buffer.lines.set(this.buffer.y + this.buffer.ybase, this.buffer.getBlankLine(this.eraseAttrData()));\n      this.updateRange(this.buffer.scrollTop);\n      this.updateRange(this.buffer.scrollBottom);\n    } else {\n      this.buffer.y--;\n    }\n  }\n\n  /**\n   * ESC c Full Reset (RIS).\n   */\n  public reset(): void {\n    this.options.rows = this.rows;\n    this.options.cols = this.cols;\n    const customKeyEventHandler = this._customKeyEventHandler;\n    const inputHandler = this._inputHandler;\n    const cursorState = this.cursorState;\n    this._setup();\n    this._customKeyEventHandler = customKeyEventHandler;\n    this._inputHandler = inputHandler;\n    this.cursorState = cursorState;\n    this.refresh(0, this.rows - 1);\n    if (this.viewport) {\n      this.viewport.syncScrollArea();\n    }\n  }\n\n\n  /**\n   * ESC H Tab Set (HTS is 0x88).\n   */\n  public tabSet(): void {\n    this.buffer.tabs[this.buffer.x] = true;\n  }\n\n  // TODO: Remove cancel function and cancelEvents option\n  public cancel(ev: Event, force?: boolean): boolean {\n    if (!this.options.cancelEvents && !force) {\n      return;\n    }\n    ev.preventDefault();\n    ev.stopPropagation();\n    return false;\n  }\n\n  private _visualBell(): boolean {\n    return false;\n    // return this.options.bellStyle === 'visual' ||\n    //     this.options.bellStyle === 'both';\n  }\n\n  private _soundBell(): boolean {\n    return this.options.bellStyle === 'sound';\n    // return this.options.bellStyle === 'sound' ||\n    //     this.options.bellStyle === 'both';\n  }\n}\n\n/**\n * Helpers\n */\n\nfunction wasModifierKeyOnlyEvent(ev: KeyboardEvent): boolean {\n  return ev.keyCode === 16 || // Shift\n    ev.keyCode === 17 || // Ctrl\n    ev.keyCode === 18; // Alt\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nexport let blankLine = 'Blank line';\nexport let promptLabel = 'Terminal input';\nexport let tooMuchOutput = 'Too much output to announce, navigate to rows manually to read';\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ITerminal, ISoundManager } from './Types';\n\n// Source: https://freesound.org/people/altemark/sounds/45759/\n// This sound is released under the Creative Commons Attribution 3.0 Unported\n// (CC BY 3.0) license. It was created by 'altemark'. No modifications have been\n// made, apart from the conversion to base64.\nexport const DEFAULT_BELL_SOUND = 'data:audio/wav;base64,UklGRigBAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQQBAADpAFgCwAMlBZoG/wdmCcoKRAypDQ8PbRDBEQQTOxRtFYcWlBePGIUZXhoiG88bcBz7HHIdzh0WHlMeZx51HmkeUx4WHs8dah0AHXwc3hs9G4saxRnyGBIYGBcQFv8U4RPAEoYRQBACD70NWwwHC6gJOwjWBloF7gOBAhABkf8b/qv8R/ve+Xf4Ife79W/0JfPZ8Z/wde9N7ijtE+wU6xvqM+lb6H7nw+YX5mrlxuQz5Mzje+Ma49fioeKD4nXiYeJy4pHitOL04j/jn+MN5IPkFOWs5U3mDefM55/ogOl36m7rdOyE7abuyu8D8Unyj/Pg9D/2qfcb+Yn6/vuK/Qj/lAAlAg==';\n\nexport class SoundManager implements ISoundManager {\n  private static _audioContext: AudioContext;\n\n  static get audioContext(): AudioContext | null {\n    if (!SoundManager._audioContext) {\n      const audioContextCtor: typeof AudioContext = (<any>window).AudioContext || (<any>window).webkitAudioContext;\n      if (!audioContextCtor) {\n        console.warn('Web Audio API is not supported by this browser. Consider upgrading to the latest version');\n        return null;\n      }\n      SoundManager._audioContext = new audioContextCtor();\n    }\n    return SoundManager._audioContext;\n  }\n\n  constructor(\n    private _terminal: ITerminal\n  ) {\n  }\n\n  public playBellSound(): void {\n    const ctx = SoundManager.audioContext;\n    if (!ctx) {\n      return;\n    }\n    const bellAudioSource = ctx.createBufferSource();\n    ctx.decodeAudioData(this._base64ToArrayBuffer(this._removeMimeType(this._terminal.options.bellSound)), (buffer) => {\n      bellAudioSource.buffer = buffer;\n      bellAudioSource.connect(ctx.destination);\n      bellAudioSource.start(0);\n    });\n  }\n\n  private _base64ToArrayBuffer(base64: string): ArrayBuffer {\n    const binaryString = window.atob(base64);\n    const len = binaryString.length;\n    const bytes = new Uint8Array(len);\n\n    for (let i = 0; i < len; i++) {\n      bytes[i] = binaryString.charCodeAt(i);\n    }\n\n    return bytes.buffer;\n  }\n\n  private _removeMimeType(dataURI: string): string {\n    // Split the input to get the mime-type and the data itself\n    const splitUri = dataURI.split(',');\n\n    // Return only the data\n    return splitUri[1];\n  }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ITerminal } from './Types';\n\n/**\n * Represents a selection within the buffer. This model only cares about column\n * and row coordinates, not wide characters.\n */\nexport class SelectionModel {\n  /**\n   * Whether select all is currently active.\n   */\n  public isSelectAllActive: boolean;\n\n  /**\n   * The [x, y] position the selection starts at.\n   */\n  public selectionStart: [number, number];\n\n  /**\n   * The minimal length of the selection from the start position. When double\n   * clicking on a word, the word will be selected which makes the selection\n   * start at the start of the word and makes this variable the length.\n   */\n  public selectionStartLength: number;\n\n  /**\n   * The [x, y] position the selection ends at.\n   */\n  public selectionEnd: [number, number];\n\n  constructor(\n    private _terminal: ITerminal\n  ) {\n    this.clearSelection();\n  }\n\n  /**\n   * Clears the current selection.\n   */\n  public clearSelection(): void {\n    this.selectionStart = null;\n    this.selectionEnd = null;\n    this.isSelectAllActive = false;\n    this.selectionStartLength = 0;\n  }\n\n  /**\n   * The final selection start, taking into consideration select all.\n   */\n  public get finalSelectionStart(): [number, number] {\n    if (this.isSelectAllActive) {\n      return [0, 0];\n    }\n\n    if (!this.selectionEnd || !this.selectionStart) {\n      return this.selectionStart;\n    }\n\n    return this.areSelectionValuesReversed() ? this.selectionEnd : this.selectionStart;\n  }\n\n  /**\n   * The final selection end, taking into consideration select all, double click\n   * word selection and triple click line selection.\n   */\n  public get finalSelectionEnd(): [number, number] {\n    if (this.isSelectAllActive) {\n      return [this._terminal.cols, this._terminal.buffer.ybase + this._terminal.rows - 1];\n    }\n\n    if (!this.selectionStart) {\n      return null;\n    }\n\n    // Use the selection start + length if the end doesn't exist or they're reversed\n    if (!this.selectionEnd || this.areSelectionValuesReversed()) {\n      const startPlusLength = this.selectionStart[0] + this.selectionStartLength;\n      if (startPlusLength > this._terminal.cols) {\n        return [startPlusLength % this._terminal.cols, this.selectionStart[1] + Math.floor(startPlusLength / this._terminal.cols)];\n      }\n      return [startPlusLength, this.selectionStart[1]];\n    }\n\n    // Ensure the the word/line is selected after a double/triple click\n    if (this.selectionStartLength) {\n      // Select the larger of the two when start and end are on the same line\n      if (this.selectionEnd[1] === this.selectionStart[1]) {\n        return [Math.max(this.selectionStart[0] + this.selectionStartLength, this.selectionEnd[0]), this.selectionEnd[1]];\n      }\n    }\n    return this.selectionEnd;\n  }\n\n  /**\n   * Returns whether the selection start and end are reversed.\n   */\n  public areSelectionValuesReversed(): boolean {\n    const start = this.selectionStart;\n    const end = this.selectionEnd;\n    if (!start || !end) {\n      return false;\n    }\n    return start[1] > end[1] || (start[1] === end[1] && start[0] > end[0]);\n  }\n\n  /**\n   * Handle the buffer being trimmed, adjust the selection position.\n   * @param amount The amount the buffer is being trimmed.\n   * @return Whether a refresh is necessary.\n   */\n  public onTrim(amount: number): boolean {\n    // Adjust the selection position based on the trimmed amount.\n    if (this.selectionStart) {\n      this.selectionStart[1] -= amount;\n    }\n    if (this.selectionEnd) {\n      this.selectionEnd[1] -= amount;\n    }\n\n    // The selection has moved off the buffer, clear it.\n    if (this.selectionEnd && this.selectionEnd[1] < 0) {\n      this.clearSelection();\n      return true;\n    }\n\n    // If the selection start is trimmed, ensure the start column is 0.\n    if (this.selectionStart && this.selectionStart[1] < 0) {\n      this.selectionStart[1] = 0;\n    }\n    return false;\n  }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ITerminal, ISelectionManager, IBuffer, IBufferLine, ISelectionRedrawRequestEvent } from './Types';\nimport { MouseHelper } from './MouseHelper';\nimport * as Browser from './common/Platform';\nimport { CharMeasure } from './CharMeasure';\nimport { SelectionModel } from './SelectionModel';\nimport { AltClickHandler } from './handlers/AltClickHandler';\nimport { CellData } from './BufferLine';\nimport { IDisposable } from 'xterm';\nimport { EventEmitter2, IEvent } from './common/EventEmitter2';\n\n/**\n * The number of pixels the mouse needs to be above or below the viewport in\n * order to scroll at the maximum speed.\n */\nconst DRAG_SCROLL_MAX_THRESHOLD = 50;\n\n/**\n * The maximum scrolling speed\n */\nconst DRAG_SCROLL_MAX_SPEED = 15;\n\n/**\n * The number of milliseconds between drag scroll updates.\n */\nconst DRAG_SCROLL_INTERVAL = 50;\n\n/**\n * The maximum amount of time that can have elapsed for an alt click to move the\n * cursor.\n */\nconst ALT_CLICK_MOVE_CURSOR_TIME = 500;\n\n/**\n * A string containing all characters that are considered word separated by the\n * double click to select work logic.\n */\nconst WORD_SEPARATORS = ' ()[]{}\\'\"';\n\nconst NON_BREAKING_SPACE_CHAR = String.fromCharCode(160);\nconst ALL_NON_BREAKING_SPACE_REGEX = new RegExp(NON_BREAKING_SPACE_CHAR, 'g');\n\n/**\n * Represents a position of a word on a line.\n */\ninterface IWordPosition {\n  start: number;\n  length: number;\n}\n\n/**\n * A selection mode, this drives how the selection behaves on mouse move.\n */\nexport const enum SelectionMode {\n  NORMAL,\n  WORD,\n  LINE,\n  COLUMN\n}\n\n/**\n * A class that manages the selection of the terminal. With help from\n * SelectionModel, SelectionManager handles with all logic associated with\n * dealing with the selection, including handling mouse interaction, wide\n * characters and fetching the actual text within the selection. Rendering is\n * not handled by the SelectionManager but the onRedrawRequest event is fired\n * when the selection is ready to be redrawn (on an animation frame).\n */\nexport class SelectionManager implements ISelectionManager {\n  protected _model: SelectionModel;\n\n  /**\n   * The amount to scroll every drag scroll update (depends on how far the mouse\n   * drag is above or below the terminal).\n   */\n  private _dragScrollAmount: number;\n\n  /**\n   * The current selection mode.\n   */\n  protected _activeSelectionMode: SelectionMode;\n\n  /**\n   * A setInterval timer that is active while the mouse is down whose callback\n   * scrolls the viewport when necessary.\n   */\n  private _dragScrollIntervalTimer: NodeJS.Timer;\n\n  /**\n   * The animation frame ID used for refreshing the selection.\n   */\n  private _refreshAnimationFrame: number;\n\n  /**\n   * Whether selection is enabled.\n   */\n  private _enabled = true;\n\n  private _mouseMoveListener: EventListener;\n  private _mouseUpListener: EventListener;\n  private _trimListener: IDisposable;\n  private _workCell: CellData = new CellData();\n\n  private _mouseDownTimeStamp: number;\n\n  private _onLinuxMouseSelection = new EventEmitter2<string>();\n  public get onLinuxMouseSelection(): IEvent<string> { return this._onLinuxMouseSelection.event; }\n  private _onRedrawRequest = new EventEmitter2<ISelectionRedrawRequestEvent>();\n  public get onRedrawRequest(): IEvent<ISelectionRedrawRequestEvent> { return this._onRedrawRequest.event; }\n  private _onSelectionChange = new EventEmitter2<void>();\n  public get onSelectionChange(): IEvent<void> { return this._onSelectionChange.event; }\n\n  constructor(\n    private _terminal: ITerminal,\n    private _charMeasure: CharMeasure\n  ) {\n    this._initListeners();\n    this.enable();\n\n    this._model = new SelectionModel(_terminal);\n    this._activeSelectionMode = SelectionMode.NORMAL;\n  }\n\n  public dispose(): void {\n    this._removeMouseDownListeners();\n  }\n\n  private get _buffer(): IBuffer {\n    return this._terminal.buffers.active;\n  }\n\n  /**\n   * Initializes listener variables.\n   */\n  private _initListeners(): void {\n    this._mouseMoveListener = event => this._onMouseMove(<MouseEvent>event);\n    this._mouseUpListener = event => this._onMouseUp(<MouseEvent>event);\n\n    this.initBuffersListeners();\n  }\n\n  public initBuffersListeners(): void {\n    this._trimListener = this._terminal.buffer.lines.onTrim(amount => this._onTrim(amount));\n    this._terminal.buffers.onBufferActivate(e => this._onBufferActivate(e));\n  }\n\n  /**\n   * Disables the selection manager. This is useful for when terminal mouse\n   * are enabled.\n   */\n  public disable(): void {\n    this.clearSelection();\n    this._enabled = false;\n  }\n\n  /**\n   * Enable the selection manager.\n   */\n  public enable(): void {\n    this._enabled = true;\n  }\n\n  public get selectionStart(): [number, number] { return this._model.finalSelectionStart; }\n  public get selectionEnd(): [number, number] { return this._model.finalSelectionEnd; }\n\n  /**\n   * Gets whether there is an active text selection.\n   */\n  public get hasSelection(): boolean {\n    const start = this._model.finalSelectionStart;\n    const end = this._model.finalSelectionEnd;\n    if (!start || !end) {\n      return false;\n    }\n    return start[0] !== end[0] || start[1] !== end[1];\n  }\n\n  /**\n   * Gets the text currently selected.\n   */\n  public get selectionText(): string {\n    const start = this._model.finalSelectionStart;\n    const end = this._model.finalSelectionEnd;\n    if (!start || !end) {\n      return '';\n    }\n\n    const result: string[] = [];\n\n    if (this._activeSelectionMode === SelectionMode.COLUMN) {\n      // Ignore zero width selections\n      if (start[0] === end[0]) {\n        return '';\n      }\n\n      for (let i = start[1]; i <= end[1]; i++) {\n        const lineText = this._buffer.translateBufferLineToString(i, true, start[0], end[0]);\n        result.push(lineText);\n      }\n    } else {\n      // Get first row\n      const startRowEndCol = start[1] === end[1] ? end[0] : undefined;\n      result.push(this._buffer.translateBufferLineToString(start[1], true, start[0], startRowEndCol));\n\n      // Get middle rows\n      for (let i = start[1] + 1; i <= end[1] - 1; i++) {\n        const bufferLine = this._buffer.lines.get(i);\n        const lineText = this._buffer.translateBufferLineToString(i, true);\n        if (bufferLine.isWrapped) {\n          result[result.length - 1] += lineText;\n        } else {\n          result.push(lineText);\n        }\n      }\n\n      // Get final row\n      if (start[1] !== end[1]) {\n        const bufferLine = this._buffer.lines.get(end[1]);\n        const lineText = this._buffer.translateBufferLineToString(end[1], true, 0, end[0]);\n        if (bufferLine.isWrapped) {\n          result[result.length - 1] += lineText;\n        } else {\n          result.push(lineText);\n        }\n      }\n    }\n\n    // Format string by replacing non-breaking space chars with regular spaces\n    // and joining the array into a multi-line string.\n    const formattedResult = result.map(line => {\n      return line.replace(ALL_NON_BREAKING_SPACE_REGEX, ' ');\n    }).join(Browser.isMSWindows ? '\\r\\n' : '\\n');\n\n    return formattedResult;\n  }\n\n  /**\n   * Clears the current terminal selection.\n   */\n  public clearSelection(): void {\n    this._model.clearSelection();\n    this._removeMouseDownListeners();\n    this.refresh();\n  }\n\n  /**\n   * Queues a refresh, redrawing the selection on the next opportunity.\n   * @param isLinuxMouseSelection Whether the selection should be registered as a new\n   * selection on Linux.\n   */\n  public refresh(isLinuxMouseSelection?: boolean): void {\n    // Queue the refresh for the renderer\n    if (!this._refreshAnimationFrame) {\n      this._refreshAnimationFrame = window.requestAnimationFrame(() => this._refresh());\n    }\n\n    // If the platform is Linux and the refresh call comes from a mouse event,\n    // we need to update the selection for middle click to paste selection.\n    if (Browser.isLinux && isLinuxMouseSelection) {\n      const selectionText = this.selectionText;\n      if (selectionText.length) {\n        this._onLinuxMouseSelection.fire(this.selectionText);\n      }\n    }\n  }\n\n  /**\n   * Fires the refresh event, causing consumers to pick it up and redraw the\n   * selection state.\n   */\n  private _refresh(): void {\n    this._refreshAnimationFrame = null;\n    this._onRedrawRequest.fire({\n      start: this._model.finalSelectionStart,\n      end: this._model.finalSelectionEnd,\n      columnSelectMode: this._activeSelectionMode === SelectionMode.COLUMN\n    });\n  }\n\n  /**\n   * Checks if the current click was inside the current selection\n   * @param event The mouse event\n   */\n  public isClickInSelection(event: MouseEvent): boolean {\n    const coords = this._getMouseBufferCoords(event);\n    const start = this._model.finalSelectionStart;\n    const end = this._model.finalSelectionEnd;\n\n    if (!start || !end) {\n      return false;\n    }\n\n    return this._areCoordsInSelection(coords, start, end);\n  }\n\n  protected _areCoordsInSelection(coords: [number, number], start: [number, number], end: [number, number]): boolean {\n    return (coords[1] > start[1] && coords[1] < end[1]) ||\n        (start[1] === end[1] && coords[1] === start[1] && coords[0] >= start[0] && coords[0] < end[0]) ||\n        (start[1] < end[1] && coords[1] === end[1] && coords[0] < end[0]) ||\n        (start[1] < end[1] && coords[1] === start[1] && coords[0] >= start[0]);\n  }\n\n  /**\n   * Selects word at the current mouse event coordinates.\n   * @param event The mouse event.\n   */\n  public selectWordAtCursor(event: MouseEvent): void {\n    const coords = this._getMouseBufferCoords(event);\n    if (coords) {\n      this._selectWordAt(coords, false);\n      this._model.selectionEnd = null;\n      this.refresh(true);\n    }\n  }\n\n  /**\n   * Selects all text within the terminal.\n   */\n  public selectAll(): void {\n    this._model.isSelectAllActive = true;\n    this.refresh();\n    this._onSelectionChange.fire();\n  }\n\n  public selectLines(start: number, end: number): void {\n    this._model.clearSelection();\n    start = Math.max(start, 0);\n    end = Math.min(end, this._terminal.buffer.lines.length - 1);\n    this._model.selectionStart = [0, start];\n    this._model.selectionEnd = [this._terminal.cols, end];\n    this.refresh();\n    this._onSelectionChange.fire();\n  }\n\n  /**\n   * Handle the buffer being trimmed, adjust the selection position.\n   * @param amount The amount the buffer is being trimmed.\n   */\n  private _onTrim(amount: number): void {\n    const needsRefresh = this._model.onTrim(amount);\n    if (needsRefresh) {\n      this.refresh();\n    }\n  }\n\n  /**\n   * Gets the 0-based [x, y] buffer coordinates of the current mouse event.\n   * @param event The mouse event.\n   */\n  private _getMouseBufferCoords(event: MouseEvent): [number, number] {\n    const coords = this._terminal.mouseHelper.getCoords(event, this._terminal.screenElement, this._charMeasure, this._terminal.cols, this._terminal.rows, true);\n    if (!coords) {\n      return null;\n    }\n\n    // Convert to 0-based\n    coords[0]--;\n    coords[1]--;\n\n    // Convert viewport coords to buffer coords\n    coords[1] += this._terminal.buffer.ydisp;\n    return coords;\n  }\n\n  /**\n   * Gets the amount the viewport should be scrolled based on how far out of the\n   * terminal the mouse is.\n   * @param event The mouse event.\n   */\n  private _getMouseEventScrollAmount(event: MouseEvent): number {\n    let offset = MouseHelper.getCoordsRelativeToElement(event, this._terminal.screenElement)[1];\n    const terminalHeight = this._terminal.rows * Math.ceil(this._charMeasure.height * this._terminal.options.lineHeight);\n    if (offset >= 0 && offset <= terminalHeight) {\n      return 0;\n    }\n    if (offset > terminalHeight) {\n      offset -= terminalHeight;\n    }\n\n    offset = Math.min(Math.max(offset, -DRAG_SCROLL_MAX_THRESHOLD), DRAG_SCROLL_MAX_THRESHOLD);\n    offset /= DRAG_SCROLL_MAX_THRESHOLD;\n    return (offset / Math.abs(offset)) + Math.round(offset * (DRAG_SCROLL_MAX_SPEED - 1));\n  }\n\n  /**\n   * Returns whether the selection manager should force selection, regardless of\n   * whether the terminal is in mouse events mode.\n   * @param event The mouse event.\n   */\n  public shouldForceSelection(event: MouseEvent): boolean {\n    if (Browser.isMac) {\n      return event.altKey && this._terminal.options.macOptionClickForcesSelection;\n    }\n\n    return event.shiftKey;\n  }\n\n  /**\n   * Handles te mousedown event, setting up for a new selection.\n   * @param event The mousedown event.\n   */\n  public onMouseDown(event: MouseEvent): void {\n    this._mouseDownTimeStamp = event.timeStamp;\n    // If we have selection, we want the context menu on right click even if the\n    // terminal is in mouse mode.\n    if (event.button === 2 && this.hasSelection) {\n      return;\n    }\n\n    // Only action the primary button\n    if (event.button !== 0) {\n      return;\n    }\n\n    // Allow selection when using a specific modifier key, even when disabled\n    if (!this._enabled) {\n      if (!this.shouldForceSelection(event)) {\n        return;\n      }\n\n      // Don't send the mouse down event to the current process, we want to select\n      event.stopPropagation();\n    }\n\n    // Tell the browser not to start a regular selection\n    event.preventDefault();\n\n    // Reset drag scroll state\n    this._dragScrollAmount = 0;\n\n    if (this._enabled && event.shiftKey) {\n      this._onIncrementalClick(event);\n    } else {\n      if (event.detail === 1) {\n        this._onSingleClick(event);\n      } else if (event.detail === 2) {\n        this._onDoubleClick(event);\n      } else if (event.detail === 3) {\n        this._onTripleClick(event);\n      }\n    }\n\n    this._addMouseDownListeners();\n    this.refresh(true);\n  }\n\n  /**\n   * Adds listeners when mousedown is triggered.\n   */\n  private _addMouseDownListeners(): void {\n    // Listen on the document so that dragging outside of viewport works\n    this._terminal.element.ownerDocument.addEventListener('mousemove', this._mouseMoveListener);\n    this._terminal.element.ownerDocument.addEventListener('mouseup', this._mouseUpListener);\n    this._dragScrollIntervalTimer = setInterval(() => this._dragScroll(), DRAG_SCROLL_INTERVAL);\n  }\n\n  /**\n   * Removes the listeners that are registered when mousedown is triggered.\n   */\n  private _removeMouseDownListeners(): void {\n    if (this._terminal.element.ownerDocument) {\n      this._terminal.element.ownerDocument.removeEventListener('mousemove', this._mouseMoveListener);\n      this._terminal.element.ownerDocument.removeEventListener('mouseup', this._mouseUpListener);\n    }\n    clearInterval(this._dragScrollIntervalTimer);\n    this._dragScrollIntervalTimer = null;\n  }\n\n  /**\n   * Performs an incremental click, setting the selection end position to the mouse\n   * position.\n   * @param event The mouse event.\n   */\n  private _onIncrementalClick(event: MouseEvent): void {\n    if (this._model.selectionStart) {\n      this._model.selectionEnd = this._getMouseBufferCoords(event);\n    }\n  }\n\n  /**\n   * Performs a single click, resetting relevant state and setting the selection\n   * start position.\n   * @param event The mouse event.\n   */\n  private _onSingleClick(event: MouseEvent): void {\n    this._model.selectionStartLength = 0;\n    this._model.isSelectAllActive = false;\n    this._activeSelectionMode = this.shouldColumnSelect(event) ? SelectionMode.COLUMN : SelectionMode.NORMAL;\n\n    // Initialize the new selection\n    this._model.selectionStart = this._getMouseBufferCoords(event);\n    if (!this._model.selectionStart) {\n      return;\n    }\n    this._model.selectionEnd = null;\n\n    // Ensure the line exists\n    const line = this._buffer.lines.get(this._model.selectionStart[1]);\n    if (!line) {\n      return;\n    }\n\n    // Return early if the click event is not in the buffer (eg. in scroll bar)\n    if (line.length >= this._model.selectionStart[0]) {\n      return;\n    }\n\n    // If the mouse is over the second half of a wide character, adjust the\n    // selection to cover the whole character\n    if (line.hasWidth(this._model.selectionStart[0]) === 0) {\n      this._model.selectionStart[0]++;\n    }\n  }\n\n  /**\n   * Performs a double click, selecting the current work.\n   * @param event The mouse event.\n   */\n  private _onDoubleClick(event: MouseEvent): void {\n    const coords = this._getMouseBufferCoords(event);\n    if (coords) {\n      this._activeSelectionMode = SelectionMode.WORD;\n      this._selectWordAt(coords, true);\n    }\n  }\n\n  /**\n   * Performs a triple click, selecting the current line and activating line\n   * select mode.\n   * @param event The mouse event.\n   */\n  private _onTripleClick(event: MouseEvent): void {\n    const coords = this._getMouseBufferCoords(event);\n    if (coords) {\n      this._activeSelectionMode = SelectionMode.LINE;\n      this._selectLineAt(coords[1]);\n    }\n  }\n\n  /**\n   * Returns whether the selection manager should operate in column select mode\n   * @param event the mouse or keyboard event\n   */\n  public shouldColumnSelect(event: KeyboardEvent | MouseEvent): boolean {\n    return event.altKey && !(Browser.isMac && this._terminal.options.macOptionClickForcesSelection);\n  }\n\n  /**\n   * Handles the mousemove event when the mouse button is down, recording the\n   * end of the selection and refreshing the selection.\n   * @param event The mousemove event.\n   */\n  private _onMouseMove(event: MouseEvent): void {\n    // If the mousemove listener is active it means that a selection is\n    // currently being made, we should stop propagation to prevent mouse events\n    // to be sent to the pty.\n    event.stopImmediatePropagation();\n\n    // Record the previous position so we know whether to redraw the selection\n    // at the end.\n    const previousSelectionEnd = this._model.selectionEnd ? [this._model.selectionEnd[0], this._model.selectionEnd[1]] : null;\n\n    // Set the initial selection end based on the mouse coordinates\n    this._model.selectionEnd = this._getMouseBufferCoords(event);\n    if (!this._model.selectionEnd) {\n      this.refresh(true);\n      return;\n    }\n\n    // Select the entire line if line select mode is active.\n    if (this._activeSelectionMode === SelectionMode.LINE) {\n      if (this._model.selectionEnd[1] < this._model.selectionStart[1]) {\n        this._model.selectionEnd[0] = 0;\n      } else {\n        this._model.selectionEnd[0] = this._terminal.cols;\n      }\n    } else if (this._activeSelectionMode === SelectionMode.WORD) {\n      this._selectToWordAt(this._model.selectionEnd);\n    }\n\n    // Determine the amount of scrolling that will happen.\n    this._dragScrollAmount = this._getMouseEventScrollAmount(event);\n\n    // If the cursor was above or below the viewport, make sure it's at the\n    // start or end of the viewport respectively. This should only happen when\n    // NOT in column select mode.\n    if (this._activeSelectionMode !== SelectionMode.COLUMN) {\n      if (this._dragScrollAmount > 0) {\n        this._model.selectionEnd[0] = this._terminal.cols;\n      } else if (this._dragScrollAmount < 0) {\n        this._model.selectionEnd[0] = 0;\n      }\n    }\n\n    // If the character is a wide character include the cell to the right in the\n    // selection. Note that selections at the very end of the line will never\n    // have a character.\n    if (this._model.selectionEnd[1] < this._buffer.lines.length) {\n      if (this._buffer.lines.get(this._model.selectionEnd[1]).hasWidth(this._model.selectionEnd[0]) === 0) {\n        this._model.selectionEnd[0]++;\n      }\n    }\n\n    // Only draw here if the selection changes.\n    if (!previousSelectionEnd ||\n      previousSelectionEnd[0] !== this._model.selectionEnd[0] ||\n      previousSelectionEnd[1] !== this._model.selectionEnd[1]) {\n      this.refresh(true);\n    }\n  }\n\n  /**\n   * The callback that occurs every DRAG_SCROLL_INTERVAL ms that does the\n   * scrolling of the viewport.\n   */\n  private _dragScroll(): void {\n    if (this._dragScrollAmount) {\n      this._terminal.scrollLines(this._dragScrollAmount, false);\n      // Re-evaluate selection\n      // If the cursor was above or below the viewport, make sure it's at the\n      // start or end of the viewport respectively. This should only happen when\n      // NOT in column select mode.\n      if (this._dragScrollAmount > 0) {\n        if (this._activeSelectionMode !== SelectionMode.COLUMN) {\n          this._model.selectionEnd[0] = this._terminal.cols;\n        }\n        this._model.selectionEnd[1] = Math.min(this._terminal.buffer.ydisp + this._terminal.rows, this._terminal.buffer.lines.length - 1);\n      } else {\n        if (this._activeSelectionMode !== SelectionMode.COLUMN) {\n          this._model.selectionEnd[0] = 0;\n        }\n        this._model.selectionEnd[1] = this._terminal.buffer.ydisp;\n      }\n      this.refresh();\n    }\n  }\n\n  /**\n   * Handles the mouseup event, removing the mousedown listeners.\n   * @param event The mouseup event.\n   */\n  private _onMouseUp(event: MouseEvent): void {\n    const timeElapsed = event.timeStamp - this._mouseDownTimeStamp;\n\n    this._removeMouseDownListeners();\n\n    if (this.selectionText.length <= 1 && timeElapsed < ALT_CLICK_MOVE_CURSOR_TIME) {\n      (new AltClickHandler(event, this._terminal)).move();\n    } else if (this.hasSelection) {\n      this._onSelectionChange.fire();\n    }\n  }\n\n  private _onBufferActivate(e: {activeBuffer: IBuffer, inactiveBuffer: IBuffer}): void {\n    this.clearSelection();\n    // Only adjust the selection on trim, shiftElements is rarely used (only in\n    // reverseIndex) and delete in a splice is only ever used when the same\n    // number of elements was just added. Given this is could actually be\n    // beneficial to leave the selection as is for these cases.\n    if (this._trimListener) {\n      this._trimListener.dispose();\n    }\n    this._trimListener = e.activeBuffer.lines.onTrim(amount => this._onTrim(amount));\n  }\n\n  /**\n   * Converts a viewport column to the character index on the buffer line, the\n   * latter takes into account wide characters.\n   * @param coords The coordinates to find the 2 index for.\n   */\n  private _convertViewportColToCharacterIndex(bufferLine: IBufferLine, coords: [number, number]): number {\n    let charIndex = coords[0];\n    for (let i = 0; coords[0] >= i; i++) {\n      const length = bufferLine.loadCell(i, this._workCell).getChars().length;\n      if (this._workCell.getWidth() === 0) {\n        // Wide characters aren't included in the line string so decrement the\n        // index so the index is back on the wide character.\n        charIndex--;\n      } else if (length > 1 && coords[0] !== i) {\n        // Emojis take up multiple characters, so adjust accordingly. For these\n        // we don't want ot include the character at the column as we're\n        // returning the start index in the string, not the end index.\n        charIndex += length - 1;\n      }\n    }\n    return charIndex;\n  }\n\n  public setSelection(col: number, row: number, length: number): void {\n    this._model.clearSelection();\n    this._removeMouseDownListeners();\n    this._model.selectionStart = [col, row];\n    this._model.selectionStartLength = length;\n    this.refresh();\n  }\n\n  /**\n   * Gets positional information for the word at the coordinated specified.\n   * @param coords The coordinates to get the word at.\n   */\n  private _getWordAt(coords: [number, number], allowWhitespaceOnlySelection: boolean, followWrappedLinesAbove: boolean = true, followWrappedLinesBelow: boolean = true): IWordPosition {\n    // Ensure coords are within viewport (eg. not within scroll bar)\n    if (coords[0] >= this._terminal.cols) {\n      return null;\n    }\n\n    const bufferLine = this._buffer.lines.get(coords[1]);\n    if (!bufferLine) {\n      return null;\n    }\n\n    const line = this._buffer.translateBufferLineToString(coords[1], false);\n\n    // Get actual index, taking into consideration wide characters\n    let startIndex = this._convertViewportColToCharacterIndex(bufferLine, coords);\n    let endIndex = startIndex;\n\n    // Record offset to be used later\n    const charOffset = coords[0] - startIndex;\n    let leftWideCharCount = 0;\n    let rightWideCharCount = 0;\n    let leftLongCharOffset = 0;\n    let rightLongCharOffset = 0;\n\n    if (line.charAt(startIndex) === ' ') {\n      // Expand until non-whitespace is hit\n      while (startIndex > 0 && line.charAt(startIndex - 1) === ' ') {\n        startIndex--;\n      }\n      while (endIndex < line.length && line.charAt(endIndex + 1) === ' ') {\n        endIndex++;\n      }\n    } else {\n      // Expand until whitespace is hit. This algorithm works by scanning left\n      // and right from the starting position, keeping both the index format\n      // (line) and the column format (bufferLine) in sync. When a wide\n      // character is hit, it is recorded and the column index is adjusted.\n      let startCol = coords[0];\n      let endCol = coords[0];\n\n      // Consider the initial position, skip it and increment the wide char\n      // variable\n      if (bufferLine.getWidth(startCol) === 0) {\n        leftWideCharCount++;\n        startCol--;\n      }\n      if (bufferLine.getWidth(endCol) === 2) {\n        rightWideCharCount++;\n        endCol++;\n      }\n\n      // Adjust the end index for characters whose length are > 1 (emojis)\n      const length = bufferLine.getString(endCol).length;\n      if (length > 1) {\n        rightLongCharOffset += length - 1;\n        endIndex += length - 1;\n      }\n\n      // Expand the string in both directions until a space is hit\n      while (startCol > 0 && startIndex > 0 && !this._isCharWordSeparator(bufferLine.loadCell(startCol - 1, this._workCell))) {\n        bufferLine.loadCell(startCol - 1, this._workCell);\n        const length = this._workCell.getChars().length;\n        if (this._workCell.getWidth() === 0) {\n          // If the next character is a wide char, record it and skip the column\n          leftWideCharCount++;\n          startCol--;\n        } else if (length > 1) {\n          // If the next character's string is longer than 1 char (eg. emoji),\n          // adjust the index\n          leftLongCharOffset += length - 1;\n          startIndex -= length - 1;\n        }\n        startIndex--;\n        startCol--;\n      }\n      while (endCol < bufferLine.length && endIndex + 1 < line.length && !this._isCharWordSeparator(bufferLine.loadCell(endCol + 1, this._workCell))) {\n        bufferLine.loadCell(endCol + 1, this._workCell);\n        const length = this._workCell.getChars().length;\n        if (this._workCell.getWidth() === 2) {\n          // If the next character is a wide char, record it and skip the column\n          rightWideCharCount++;\n          endCol++;\n        } else if (length > 1) {\n          // If the next character's string is longer than 1 char (eg. emoji),\n          // adjust the index\n          rightLongCharOffset += length - 1;\n          endIndex += length - 1;\n        }\n        endIndex++;\n        endCol++;\n      }\n    }\n\n    // Incremenet the end index so it is at the start of the next character\n    endIndex++;\n\n    // Calculate the start _column_, converting the the string indexes back to\n    // column coordinates.\n    let start =\n        startIndex // The index of the selection's start char in the line string\n        + charOffset // The difference between the initial char's column and index\n        - leftWideCharCount // The number of wide chars left of the initial char\n        + leftLongCharOffset; // The number of additional chars left of the initial char added by columns with strings longer than 1 (emojis)\n\n    // Calculate the length in _columns_, converting the the string indexes back\n    // to column coordinates.\n    let length = Math.min(this._terminal.cols, // Disallow lengths larger than the terminal cols\n        endIndex // The index of the selection's end char in the line string\n        - startIndex // The index of the selection's start char in the line string\n        + leftWideCharCount // The number of wide chars left of the initial char\n        + rightWideCharCount // The number of wide chars right of the initial char (inclusive)\n        - leftLongCharOffset // The number of additional chars left of the initial char added by columns with strings longer than 1 (emojis)\n        - rightLongCharOffset); // The number of additional chars right of the initial char (inclusive) added by columns with strings longer than 1 (emojis)\n\n    if (!allowWhitespaceOnlySelection && line.slice(startIndex, endIndex).trim() === '') {\n      return null;\n    }\n\n    // Recurse upwards if the line is wrapped and the word wraps to the above line\n    if (followWrappedLinesAbove) {\n      if (start === 0 && bufferLine.getCodePoint(0) !== 32 /*' '*/) {\n        const previousBufferLine = this._buffer.lines.get(coords[1] - 1);\n        if (previousBufferLine && bufferLine.isWrapped && previousBufferLine.getCodePoint(this._terminal.cols - 1) !== 32 /*' '*/) {\n          const previousLineWordPosition = this._getWordAt([this._terminal.cols - 1, coords[1] - 1], false, true, false);\n          if (previousLineWordPosition) {\n            const offset = this._terminal.cols - previousLineWordPosition.start;\n            start -= offset;\n            length += offset;\n          }\n        }\n      }\n    }\n\n    // Recurse downwards if the line is wrapped and the word wraps to the next line\n    if (followWrappedLinesBelow) {\n      if (start + length === this._terminal.cols && bufferLine.getCodePoint(this._terminal.cols - 1) !== 32 /*' '*/) {\n        const nextBufferLine = this._buffer.lines.get(coords[1] + 1);\n        if (nextBufferLine && nextBufferLine.isWrapped && nextBufferLine.getCodePoint(0) !== 32 /*' '*/) {\n          const nextLineWordPosition = this._getWordAt([0, coords[1] + 1], false, false, true);\n          if (nextLineWordPosition) {\n            length += nextLineWordPosition.length;\n          }\n        }\n      }\n    }\n\n    return { start, length };\n  }\n\n  /**\n   * Selects the word at the coordinates specified.\n   * @param coords The coordinates to get the word at.\n   * @param allowWhitespaceOnlySelection If whitespace should be selected\n   */\n  protected _selectWordAt(coords: [number, number], allowWhitespaceOnlySelection: boolean): void {\n    const wordPosition = this._getWordAt(coords, allowWhitespaceOnlySelection);\n    if (wordPosition) {\n      // Adjust negative start value\n      while (wordPosition.start < 0) {\n        wordPosition.start += this._terminal.cols;\n        coords[1]--;\n      }\n      this._model.selectionStart = [wordPosition.start, coords[1]];\n      this._model.selectionStartLength = wordPosition.length;\n    }\n  }\n\n  /**\n   * Sets the selection end to the word at the coordinated specified.\n   * @param coords The coordinates to get the word at.\n   */\n  private _selectToWordAt(coords: [number, number]): void {\n    const wordPosition = this._getWordAt(coords, true);\n    if (wordPosition) {\n      let endRow = coords[1];\n\n      // Adjust negative start value\n      while (wordPosition.start < 0) {\n        wordPosition.start += this._terminal.cols;\n        endRow--;\n      }\n\n      // Adjust wrapped length value, this only needs to happen when values are reversed as in that\n      // case we're interested in the start of the word, not the end\n      if (!this._model.areSelectionValuesReversed()) {\n        while (wordPosition.start + wordPosition.length > this._terminal.cols) {\n          wordPosition.length -= this._terminal.cols;\n          endRow++;\n        }\n      }\n\n      this._model.selectionEnd = [this._model.areSelectionValuesReversed() ? wordPosition.start : wordPosition.start + wordPosition.length, endRow];\n    }\n  }\n\n  /**\n   * Gets whether the character is considered a word separator by the select\n   * word logic.\n   * @param char The character to check.\n   */\n  private _isCharWordSeparator(cell: CellData): boolean {\n    // Zero width characters are never separators as they are always to the\n    // right of wide characters\n    if (cell.getWidth() === 0) {\n      return false;\n    }\n    return WORD_SEPARATORS.indexOf(cell.getChars()) >= 0;\n  }\n\n  /**\n   * Selects the line specified.\n   * @param line The line index.\n   */\n  protected _selectLineAt(line: number): void {\n    const wrappedRange = this._buffer.getWrappedRangeForLine(line);\n    this._model.selectionStart = [0, wrappedRange.first];\n    this._model.selectionEnd = [this._terminal.cols, wrappedRange.last];\n    this._model.selectionStartLength = 0;\n  }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ITerminal, IMouseZoneManager, IMouseZone } from './Types';\nimport { Disposable } from './common/Lifecycle';\nimport { addDisposableDomListener } from './ui/Lifecycle';\n\nconst HOVER_DURATION = 500;\n\n/**\n * The MouseZoneManager allows components to register zones within the terminal\n * that trigger hover and click callbacks.\n *\n * This class was intentionally made not so robust initially as the only case it\n * needed to support was single-line links which never overlap. Improvements can\n * be made in the future.\n */\nexport class MouseZoneManager extends Disposable implements IMouseZoneManager {\n  private _zones: IMouseZone[] = [];\n\n  private _areZonesActive: boolean = false;\n  private _mouseMoveListener: (e: MouseEvent) => any;\n  private _mouseLeaveListener: (e: MouseEvent) => any;\n  private _clickListener: (e: MouseEvent) => any;\n\n  private _tooltipTimeout: number = null;\n  private _currentZone: IMouseZone = null;\n  private _lastHoverCoords: [number, number] = [null, null];\n  private _initialSelectionLength: number;\n\n  constructor(\n    private _terminal: ITerminal\n  ) {\n    super();\n\n    this.register(addDisposableDomListener(this._terminal.element, 'mousedown', e => this._onMouseDown(e)));\n\n    // These events are expensive, only listen to it when mouse zones are active\n    this._mouseMoveListener = e => this._onMouseMove(e);\n    this._mouseLeaveListener = e => this._onMouseLeave(e);\n    this._clickListener = e => this._onClick(e);\n  }\n\n  public dispose(): void {\n    super.dispose();\n    this._deactivate();\n  }\n\n  public add(zone: IMouseZone): void {\n    this._zones.push(zone);\n    if (this._zones.length === 1) {\n      this._activate();\n    }\n  }\n\n  public clearAll(start?: number, end?: number): void {\n    // Exit if there's nothing to clear\n    if (this._zones.length === 0) {\n      return;\n    }\n\n    // Clear all if start/end weren't set\n    if (!end) {\n      start = 0;\n      end = this._terminal.rows - 1;\n    }\n\n    // Iterate through zones and clear them out if they're within the range\n    for (let i = 0; i < this._zones.length; i++) {\n      const zone = this._zones[i];\n      if ((zone.y1 > start && zone.y1 <= end + 1) ||\n          (zone.y2 > start && zone.y2 <= end + 1) ||\n          (zone.y1 < start && zone.y2 > end + 1)) {\n        if (this._currentZone && this._currentZone === zone) {\n          this._currentZone.leaveCallback();\n          this._currentZone = null;\n        }\n        this._zones.splice(i--, 1);\n      }\n    }\n\n    // Deactivate the mouse zone manager if all the zones have been removed\n    if (this._zones.length === 0) {\n      this._deactivate();\n    }\n  }\n\n  private _activate(): void {\n    if (!this._areZonesActive) {\n      this._areZonesActive = true;\n      this._terminal.element.addEventListener('mousemove', this._mouseMoveListener);\n      this._terminal.element.addEventListener('mouseleave', this._mouseLeaveListener);\n      this._terminal.element.addEventListener('click', this._clickListener);\n    }\n  }\n\n  private _deactivate(): void {\n    if (this._areZonesActive) {\n      this._areZonesActive = false;\n      this._terminal.element.removeEventListener('mousemove', this._mouseMoveListener);\n      this._terminal.element.removeEventListener('mouseleave', this._mouseLeaveListener);\n      this._terminal.element.removeEventListener('click', this._clickListener);\n    }\n  }\n\n  private _onMouseMove(e: MouseEvent): void {\n    // TODO: Ideally this would only clear the hover state when the mouse moves\n    // outside of the mouse zone\n    if (this._lastHoverCoords[0] !== e.pageX || this._lastHoverCoords[1] !== e.pageY) {\n      this._onHover(e);\n      // Record the current coordinates\n      this._lastHoverCoords = [e.pageX, e.pageY];\n    }\n  }\n\n  private _onHover(e: MouseEvent): void {\n    const zone = this._findZoneEventAt(e);\n\n    // Do nothing if the zone is the same\n    if (zone === this._currentZone) {\n      return;\n    }\n\n    // Fire the hover end callback and cancel any existing timer if a new zone\n    // is being hovered\n    if (this._currentZone) {\n      this._currentZone.leaveCallback();\n      this._currentZone = null;\n      if (this._tooltipTimeout) {\n        clearTimeout(this._tooltipTimeout);\n      }\n    }\n\n    // Exit if there is not zone\n    if (!zone) {\n      return;\n    }\n    this._currentZone = zone;\n\n    // Trigger the hover callback\n    if (zone.hoverCallback) {\n      zone.hoverCallback(e);\n    }\n\n    // Restart the tooltip timeout\n    this._tooltipTimeout = <number><any>setTimeout(() => this._onTooltip(e), HOVER_DURATION);\n  }\n\n  private _onTooltip(e: MouseEvent): void {\n    this._tooltipTimeout = null;\n    const zone = this._findZoneEventAt(e);\n    if (zone && zone.tooltipCallback) {\n      zone.tooltipCallback(e);\n    }\n  }\n\n  private _onMouseDown(e: MouseEvent): void {\n    // Store current terminal selection length, to check if we're performing\n    // a selection operation\n    this._initialSelectionLength = this._terminal.getSelection().length;\n\n    // Ignore the event if there are no zones active\n    if (!this._areZonesActive) {\n      return;\n    }\n\n    // Find the active zone, prevent event propagation if found to prevent other\n    // components from handling the mouse event.\n    const zone = this._findZoneEventAt(e);\n    if (zone) {\n      if (zone.willLinkActivate(e)) {\n        e.preventDefault();\n        e.stopImmediatePropagation();\n      }\n    }\n  }\n\n  private _onMouseLeave(e: MouseEvent): void {\n    // Fire the hover end callback and cancel any existing timer if the mouse\n    // leaves the terminal element\n    if (this._currentZone) {\n      this._currentZone.leaveCallback();\n      this._currentZone = null;\n      if (this._tooltipTimeout) {\n        clearTimeout(this._tooltipTimeout);\n      }\n    }\n  }\n\n  private _onClick(e: MouseEvent): void {\n    // Find the active zone and click it if found and no selection was\n    // being performed\n    const zone = this._findZoneEventAt(e);\n    const currentSelectionLength = this._terminal.getSelection().length;\n\n    if (zone && currentSelectionLength === this._initialSelectionLength) {\n      zone.clickCallback(e);\n      e.preventDefault();\n      e.stopImmediatePropagation();\n    }\n  }\n\n  private _findZoneEventAt(e: MouseEvent): IMouseZone {\n    const coords = this._terminal.mouseHelper.getCoords(e, this._terminal.screenElement, this._terminal.charMeasure, this._terminal.cols, this._terminal.rows);\n    if (!coords) {\n      return null;\n    }\n    const x = coords[0];\n    const y = coords[1];\n    for (let i = 0; i < this._zones.length; i++) {\n      const zone = this._zones[i];\n      if (zone.y1 === zone.y2) {\n        // Single line link\n        if (y === zone.y1 && x >= zone.x1 && x < zone.x2) {\n          return zone;\n        }\n      } else {\n        // Multi-line link\n        if ((y === zone.y1 && x >= zone.x1) ||\n            (y === zone.y2 && x < zone.x2) ||\n            (y > zone.y1 && y < zone.y2)) {\n          return zone;\n        }\n      }\n    }\n    return null;\n  }\n}\n\nexport class MouseZone implements IMouseZone {\n  constructor(\n    public x1: number,\n    public y1: number,\n    public x2: number,\n    public y2: number,\n    public clickCallback: (e: MouseEvent) => any,\n    public hoverCallback: (e: MouseEvent) => any,\n    public tooltipCallback: (e: MouseEvent) => any,\n    public leaveCallback: () => void,\n    public willLinkActivate: (e: MouseEvent) => boolean\n  ) {\n  }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICharMeasure, IMouseHelper } from './Types';\nimport { IRenderer } from './renderer/Types';\n\nexport class MouseHelper implements IMouseHelper {\n  constructor(private _renderer: IRenderer) {}\n\n  public setRenderer(renderer: IRenderer): void {\n    this._renderer = renderer;\n  }\n\n  public static getCoordsRelativeToElement(event: {clientX: number, clientY: number}, element: HTMLElement): [number, number] {\n    const rect = element.getBoundingClientRect();\n    return [event.clientX - rect.left, event.clientY - rect.top];\n  }\n\n  /**\n   * Gets coordinates within the terminal for a particular mouse event. The result\n   * is returned as an array in the form [x, y] instead of an object as it's a\n   * little faster and this function is used in some low level code.\n   * @param event The mouse event.\n   * @param element The terminal's container element.\n   * @param charMeasure The char measure object used to determine character sizes.\n   * @param colCount The number of columns in the terminal.\n   * @param rowCount The number of rows n the terminal.\n   * @param isSelection Whether the request is for the selection or not. This will\n   * apply an offset to the x value such that the left half of the cell will\n   * select that cell and the right half will select the next cell.\n   */\n  public getCoords(event: {clientX: number, clientY: number}, element: HTMLElement, charMeasure: ICharMeasure, colCount: number, rowCount: number, isSelection?: boolean): [number, number] {\n    // Coordinates cannot be measured if charMeasure has not been initialized\n    if (!charMeasure.width || !charMeasure.height) {\n      return null;\n    }\n\n    const coords = MouseHelper.getCoordsRelativeToElement(event, element);\n    if (!coords) {\n      return null;\n    }\n\n    coords[0] = Math.ceil((coords[0] + (isSelection ? this._renderer.dimensions.actualCellWidth / 2 : 0)) / this._renderer.dimensions.actualCellWidth);\n    coords[1] = Math.ceil(coords[1] / this._renderer.dimensions.actualCellHeight);\n\n    // Ensure coordinates are within the terminal viewport. Note that selections\n    // need an addition point of precision to cover the end point (as characters\n    // cover half of one char and half of the next).\n    coords[0] = Math.min(Math.max(coords[0], 1), colCount + (isSelection ? 1 : 0));\n    coords[1] = Math.min(Math.max(coords[1], 1), rowCount);\n\n    return coords;\n  }\n\n  /**\n   * Gets coordinates within the terminal for a particular mouse event, wrapping\n   * them to the bounds of the terminal and adding 32 to both the x and y values\n   * as expected by xterm.\n   * @param event The mouse event.\n   * @param element The terminal's container element.\n   * @param charMeasure The char measure object used to determine character sizes.\n   * @param colCount The number of columns in the terminal.\n   * @param rowCount The number of rows in the terminal.\n   */\n  public getRawByteCoords(event: MouseEvent, element: HTMLElement, charMeasure: ICharMeasure, colCount: number, rowCount: number): { x: number, y: number } {\n    const coords = this.getCoords(event, element, charMeasure, colCount, rowCount);\n    let x = coords[0];\n    let y = coords[1];\n\n    // xterm sends raw bytes and starts at 32 (SP) for each.\n    x += 32;\n    y += 32;\n\n    return { x, y };\n  }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ILinkifierEvent, ILinkMatcher, LinkMatcherHandler, ILinkMatcherOptions, ILinkifier, ITerminal, IBufferStringIteratorResult, IMouseZoneManager } from './Types';\nimport { MouseZone } from './MouseZoneManager';\nimport { getStringCellWidth } from './CharWidth';\nimport { EventEmitter2, IEvent } from './common/EventEmitter2';\n\n/**\n * The Linkifier applies links to rows shortly after they have been refreshed.\n */\nexport class Linkifier implements ILinkifier {\n  /**\n   * The time to wait after a row is changed before it is linkified. This prevents\n   * the costly operation of searching every row multiple times, potentially a\n   * huge amount of times.\n   */\n  protected static readonly TIME_BEFORE_LINKIFY = 200;\n\n  /**\n   * Limit of the unwrapping line expansion (overscan) at the top and bottom\n   * of the actual viewport in ASCII characters.\n   * A limit of 2000 should match most sane urls.\n   */\n  protected static readonly OVERSCAN_CHAR_LIMIT = 2000;\n\n  protected _linkMatchers: ILinkMatcher[] = [];\n\n  private _mouseZoneManager: IMouseZoneManager;\n  private _rowsTimeoutId: number;\n  private _nextLinkMatcherId = 0;\n  private _rowsToLinkify: { start: number, end: number };\n\n  private _onLinkHover = new EventEmitter2<ILinkifierEvent>();\n  public get onLinkHover(): IEvent<ILinkifierEvent> { return this._onLinkHover.event; }\n  private _onLinkLeave = new EventEmitter2<ILinkifierEvent>();\n  public get onLinkLeave(): IEvent<ILinkifierEvent> { return this._onLinkLeave.event; }\n  private _onLinkTooltip = new EventEmitter2<ILinkifierEvent>();\n  public get onLinkTooltip(): IEvent<ILinkifierEvent> { return this._onLinkTooltip.event; }\n\n  constructor(\n    protected _terminal: ITerminal\n  ) {\n    this._rowsToLinkify = {\n      start: null,\n      end: null\n    };\n  }\n\n  /**\n   * Attaches the linkifier to the DOM, enabling linkification.\n   * @param mouseZoneManager The mouse zone manager to register link zones with.\n   */\n  public attachToDom(mouseZoneManager: IMouseZoneManager): void {\n    this._mouseZoneManager = mouseZoneManager;\n  }\n\n  /**\n   * Queue linkification on a set of rows.\n   * @param start The row to linkify from (inclusive).\n   * @param end The row to linkify to (inclusive).\n   */\n  public linkifyRows(start: number, end: number): void {\n    // Don't attempt linkify if not yet attached to DOM\n    if (!this._mouseZoneManager) {\n      return;\n    }\n\n    // Increase range to linkify\n    if (this._rowsToLinkify.start === null) {\n      this._rowsToLinkify.start = start;\n      this._rowsToLinkify.end = end;\n    } else {\n      this._rowsToLinkify.start = Math.min(this._rowsToLinkify.start, start);\n      this._rowsToLinkify.end = Math.max(this._rowsToLinkify.end, end);\n    }\n\n    // Clear out any existing links on this row range\n    this._mouseZoneManager.clearAll(start, end);\n\n    // Restart timer\n    if (this._rowsTimeoutId) {\n      clearTimeout(this._rowsTimeoutId);\n    }\n    this._rowsTimeoutId = <number><any>setTimeout(() => this._linkifyRows(), Linkifier.TIME_BEFORE_LINKIFY);\n  }\n\n  /**\n   * Linkifies the rows requested.\n   */\n  private _linkifyRows(): void {\n    this._rowsTimeoutId = null;\n    const buffer = this._terminal.buffer;\n\n    // Ensure the start row exists\n    const absoluteRowIndexStart = buffer.ydisp + this._rowsToLinkify.start;\n    if (absoluteRowIndexStart >= buffer.lines.length) {\n      return;\n    }\n\n    // Invalidate bad end row values (if a resize happened)\n    const absoluteRowIndexEnd = buffer.ydisp + Math.min(this._rowsToLinkify.end, this._terminal.rows) + 1;\n\n    // Iterate over the range of unwrapped content strings within start..end\n    // (excluding).\n    // _doLinkifyRow gets full unwrapped lines with the start row as buffer offset\n    // for every matcher.\n    // The unwrapping is needed to also match content that got wrapped across\n    // several buffer lines. To avoid a worst case scenario where the whole buffer\n    // contains just a single unwrapped string we limit this line expansion beyond\n    // the viewport to +OVERSCAN_CHAR_LIMIT chars (overscan) at top and bottom.\n    // This comes with the tradeoff that matches longer than OVERSCAN_CHAR_LIMIT\n    // chars will not match anymore at the viewport borders.\n    const overscanLineLimit = Math.ceil(Linkifier.OVERSCAN_CHAR_LIMIT / this._terminal.cols);\n    const iterator = this._terminal.buffer.iterator(\n      false, absoluteRowIndexStart, absoluteRowIndexEnd, overscanLineLimit, overscanLineLimit);\n    while (iterator.hasNext()) {\n      const lineData: IBufferStringIteratorResult = iterator.next();\n      for (let i = 0; i < this._linkMatchers.length; i++) {\n        this._doLinkifyRow(lineData.range.first, lineData.content, this._linkMatchers[i]);\n      }\n    }\n\n    this._rowsToLinkify.start = null;\n    this._rowsToLinkify.end = null;\n  }\n\n  /**\n   * Registers a link matcher, allowing custom link patterns to be matched and\n   * handled.\n   * @param regex The regular expression to search for. Specifically, this\n   * searches the textContent of the rows. You will want to use \\s to match a\n   * space ' ' character for example.\n   * @param handler The callback when the link is called.\n   * @param options Options for the link matcher.\n   * @return The ID of the new matcher, this can be used to deregister.\n   */\n  public registerLinkMatcher(regex: RegExp, handler: LinkMatcherHandler, options: ILinkMatcherOptions = {}): number {\n    if (!handler) {\n      throw new Error('handler must be defined');\n    }\n    const matcher: ILinkMatcher = {\n      id: this._nextLinkMatcherId++,\n      regex,\n      handler,\n      matchIndex: options.matchIndex,\n      validationCallback: options.validationCallback,\n      hoverTooltipCallback: options.tooltipCallback,\n      hoverLeaveCallback: options.leaveCallback,\n      willLinkActivate: options.willLinkActivate,\n      priority: options.priority || 0\n    };\n    this._addLinkMatcherToList(matcher);\n    return matcher.id;\n  }\n\n  /**\n   * Inserts a link matcher to the list in the correct position based on the\n   * priority of each link matcher. New link matchers of equal priority are\n   * considered after older link matchers.\n   * @param matcher The link matcher to be added.\n   */\n  private _addLinkMatcherToList(matcher: ILinkMatcher): void {\n    if (this._linkMatchers.length === 0) {\n      this._linkMatchers.push(matcher);\n      return;\n    }\n\n    for (let i = this._linkMatchers.length - 1; i >= 0; i--) {\n      if (matcher.priority <= this._linkMatchers[i].priority) {\n        this._linkMatchers.splice(i + 1, 0, matcher);\n        return;\n      }\n    }\n\n    this._linkMatchers.splice(0, 0, matcher);\n  }\n\n  /**\n   * Deregisters a link matcher if it has been registered.\n   * @param matcherId The link matcher's ID (returned after register)\n   * @return Whether a link matcher was found and deregistered.\n   */\n  public deregisterLinkMatcher(matcherId: number): boolean {\n    for (let i = 0; i < this._linkMatchers.length; i++) {\n      if (this._linkMatchers[i].id === matcherId) {\n        this._linkMatchers.splice(i, 1);\n        return true;\n      }\n    }\n    return false;\n  }\n\n  /**\n   * Linkifies a row given a specific handler.\n   * @param rowIndex The row index to linkify (absolute index).\n   * @param text string content of the unwrapped row.\n   * @param matcher The link matcher for this line.\n   */\n  private _doLinkifyRow(rowIndex: number, text: string, matcher: ILinkMatcher): void {\n    // clone regex to do a global search on text\n    const rex = new RegExp(matcher.regex.source, matcher.regex.flags + 'g');\n    let match;\n    let stringIndex = -1;\n    while ((match = rex.exec(text)) !== null) {\n      const uri = match[typeof matcher.matchIndex !== 'number' ? 0 : matcher.matchIndex];\n      if (!uri) {\n        // something matched but does not comply with the given matchIndex\n        // since this is most likely a bug the regex itself we simply do nothing here\n        // DEBUG: print match and throw\n        if ((<any>this._terminal).debug) {\n          console.log({match, matcher});\n          throw new Error('match found without corresponding matchIndex');\n        }\n        break;\n      }\n\n      // Get index, match.index is for the outer match which includes negated chars\n      // therefore we cannot use match.index directly, instead we search the position\n      // of the match group in text again\n      // also correct regex and string search offsets for the next loop run\n      stringIndex = text.indexOf(uri, stringIndex + 1);\n      rex.lastIndex = stringIndex + uri.length;\n      if (stringIndex < 0) {\n        // invalid stringIndex (should not have happened)\n        break;\n      }\n\n      // get the buffer index as [absolute row, col] for the match\n      const bufferIndex = this._terminal.buffer.stringIndexToBufferIndex(rowIndex, stringIndex);\n      if (bufferIndex[0] < 0) {\n        // invalid bufferIndex (should not have happened)\n        break;\n      }\n\n      const line = this._terminal.buffer.lines.get(bufferIndex[0]);\n      const attr = line.getFg(bufferIndex[1]);\n      let fg: number | undefined;\n      if (attr) {\n        fg = (attr >> 9) & 0x1ff;\n      }\n\n      if (matcher.validationCallback) {\n        matcher.validationCallback(uri, isValid => {\n          // Discard link if the line has already changed\n          if (this._rowsTimeoutId) {\n            return;\n          }\n          if (isValid) {\n            this._addLink(bufferIndex[1], bufferIndex[0] - this._terminal.buffer.ydisp, uri, matcher, fg);\n          }\n        });\n      } else {\n        this._addLink(bufferIndex[1], bufferIndex[0] - this._terminal.buffer.ydisp, uri, matcher, fg);\n      }\n    }\n  }\n\n  /**\n   * Registers a link to the mouse zone manager.\n   * @param x The column the link starts.\n   * @param y The row the link is on.\n   * @param uri The URI of the link.\n   * @param matcher The link matcher for the link.\n   * @param fg The link color for hover event.\n   */\n  private _addLink(x: number, y: number, uri: string, matcher: ILinkMatcher, fg: number): void {\n    const width = getStringCellWidth(uri);\n    const x1 = x % this._terminal.cols;\n    const y1 = y + Math.floor(x / this._terminal.cols);\n    let x2 = (x1 + width) % this._terminal.cols;\n    let y2 = y1 + Math.floor((x1 + width) / this._terminal.cols);\n    if (x2 === 0) {\n      x2 = this._terminal.cols;\n      y2--;\n    }\n\n    this._mouseZoneManager.add(new MouseZone(\n      x1 + 1,\n      y1 + 1,\n      x2 + 1,\n      y2 + 1,\n      e => {\n        if (matcher.handler) {\n          return matcher.handler(e, uri);\n        }\n        window.open(uri, '_blank');\n      },\n      () => {\n        this._onLinkHover.fire(this._createLinkHoverEvent(x1, y1, x2, y2, fg));\n        this._terminal.element.classList.add('xterm-cursor-pointer');\n      },\n      e => {\n        this._onLinkTooltip.fire(this._createLinkHoverEvent(x1, y1, x2, y2, fg));\n        if (matcher.hoverTooltipCallback) {\n          matcher.hoverTooltipCallback(e, uri);\n        }\n      },\n      () => {\n        this._onLinkLeave.fire(this._createLinkHoverEvent(x1, y1, x2, y2, fg));\n        this._terminal.element.classList.remove('xterm-cursor-pointer');\n        if (matcher.hoverLeaveCallback) {\n          matcher.hoverLeaveCallback();\n        }\n      },\n      e => {\n        if (matcher.willLinkActivate) {\n          return matcher.willLinkActivate(e, uri);\n        }\n        return true;\n      }\n    ));\n  }\n\n  private _createLinkHoverEvent(x1: number, y1: number, x2: number, y2: number, fg: number): ILinkifierEvent {\n    return { x1, y1, x2, y2, cols: this._terminal.cols, fg };\n  }\n}\n","/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * @license MIT\n */\n\nimport { IInputHandler, IDcsHandler, IEscapeSequenceParser, IInputHandlingTerminal } from './Types';\nimport { C0, C1 } from './common/data/EscapeSequences';\nimport { CHARSETS, DEFAULT_CHARSET } from './core/data/Charsets';\nimport { NULL_CELL_WIDTH, NULL_CELL_CODE, DEFAULT_ATTR_DATA } from './Buffer';\nimport { wcwidth } from './CharWidth';\nimport { EscapeSequenceParser } from './EscapeSequenceParser';\nimport { IDisposable } from 'xterm';\nimport { Disposable } from './common/Lifecycle';\nimport { concat } from './common/TypedArrayUtils';\nimport { StringToUtf32, stringFromCodePoint, utf32ToString } from './core/input/TextDecoder';\nimport { CellData, Attributes, FgFlags, BgFlags, AttributeData } from './BufferLine';\nimport { EventEmitter2, IEvent } from './common/EventEmitter2';\n\n/**\n * Map collect to glevel. Used in `selectCharset`.\n */\nconst GLEVEL: {[key: string]: number} = {'(': 0, ')': 1, '*': 2, '+': 3, '-': 1, '.': 2};\n\n\n/**\n * DCS subparser implementations\n */\n\n/**\n * DCS $ q Pt ST\n *   DECRQSS (https://vt100.net/docs/vt510-rm/DECRQSS.html)\n *   Request Status String (DECRQSS), VT420 and up.\n *   Response: DECRPSS (https://vt100.net/docs/vt510-rm/DECRPSS.html)\n */\nclass DECRQSS implements IDcsHandler {\n  private _data: Uint32Array = new Uint32Array(0);\n\n  constructor(private _terminal: any) { }\n\n  hook(collect: string, params: number[], flag: number): void {\n    this._data = new Uint32Array(0);\n  }\n\n  put(data: Uint32Array, start: number, end: number): void {\n    this._data = concat(this._data, data.subarray(start, end));\n  }\n\n  unhook(): void {\n    const data = utf32ToString(this._data);\n    this._data = new Uint32Array(0);\n    switch (data) {\n      // valid: DCS 1 $ r Pt ST (xterm)\n      case '\"q': // DECSCA\n        return this._terminal.handler(`${C0.ESC}P1$r0\"q${C0.ESC}\\\\`);\n      case '\"p': // DECSCL\n        return this._terminal.handler(`${C0.ESC}P1$r61\"p${C0.ESC}\\\\`);\n      case 'r': // DECSTBM\n        const pt = '' + (this._terminal.buffer.scrollTop + 1) +\n                ';' + (this._terminal.buffer.scrollBottom + 1) + 'r';\n        return this._terminal.handler(`${C0.ESC}P1$r${pt}${C0.ESC}\\\\`);\n      case 'm': // SGR\n        // TODO: report real settings instead of 0m\n        return this._terminal.handler(`${C0.ESC}P1$r0m${C0.ESC}\\\\`);\n      case ' q': // DECSCUSR\n        const STYLES: {[key: string]: number} = {'block': 2, 'underline': 4, 'bar': 6};\n        let style = STYLES[this._terminal.getOption('cursorStyle')];\n        style -= this._terminal.getOption('cursorBlink');\n        return this._terminal.handler(`${C0.ESC}P1$r${style} q${C0.ESC}\\\\`);\n      default:\n        // invalid: DCS 0 $ r Pt ST (xterm)\n        this._terminal.error('Unknown DCS $q %s', data);\n        this._terminal.handler(`${C0.ESC}P0$r${C0.ESC}\\\\`);\n    }\n  }\n}\n\n/**\n * DCS Ps; Ps| Pt ST\n *   DECUDK (https://vt100.net/docs/vt510-rm/DECUDK.html)\n *   not supported\n */\n\n/**\n * DCS + q Pt ST (xterm)\n *   Request Terminfo String\n *   not implemented\n */\n\n/**\n * DCS + p Pt ST (xterm)\n *   Set Terminfo Data\n *   not supported\n */\n\n\n\n/**\n * The terminal's standard implementation of IInputHandler, this handles all\n * input from the Parser.\n *\n * Refer to http://invisible-island.net/xterm/ctlseqs/ctlseqs.html to understand\n * each function's header comment.\n */\nexport class InputHandler extends Disposable implements IInputHandler {\n  private _parseBuffer: Uint32Array = new Uint32Array(4096);\n  private _stringDecoder: StringToUtf32 = new StringToUtf32();\n  private _workCell: CellData = new CellData();\n\n  private _onCursorMove = new EventEmitter2<void>();\n  public get onCursorMove(): IEvent<void> { return this._onCursorMove.event; }\n  private _onData = new EventEmitter2<string>();\n  public get onData(): IEvent<string> { return this._onData.event; }\n  private _onLineFeed = new EventEmitter2<void>();\n  public get onLineFeed(): IEvent<void> { return this._onLineFeed.event; }\n  private _onScroll = new EventEmitter2<number>();\n  public get onScroll(): IEvent<number> { return this._onScroll.event; }\n\n  constructor(\n      protected _terminal: IInputHandlingTerminal,\n      private _parser: IEscapeSequenceParser = new EscapeSequenceParser())\n  {\n    super();\n\n    this.register(this._parser);\n\n    /**\n     * custom fallback handlers\n     */\n    this._parser.setCsiHandlerFallback((collect: string, params: number[], flag: number) => {\n      this._terminal.error('Unknown CSI code: ', { collect, params, flag: String.fromCharCode(flag) });\n    });\n    this._parser.setEscHandlerFallback((collect: string, flag: number) => {\n      this._terminal.error('Unknown ESC code: ', { collect, flag: String.fromCharCode(flag) });\n    });\n    this._parser.setExecuteHandlerFallback((code: number) => {\n      this._terminal.error('Unknown EXECUTE code: ', { code });\n    });\n    this._parser.setOscHandlerFallback((identifier: number, data: string) => {\n      this._terminal.error('Unknown OSC code: ', { identifier, data });\n    });\n\n    /**\n     * print handler\n     */\n    this._parser.setPrintHandler((data, start, end): void => this.print(data, start, end));\n\n    /**\n     * CSI handler\n     */\n    this._parser.setCsiHandler('@', (params, collect) => this.insertChars(params));\n    this._parser.setCsiHandler('A', (params, collect) => this.cursorUp(params));\n    this._parser.setCsiHandler('B', (params, collect) => this.cursorDown(params));\n    this._parser.setCsiHandler('C', (params, collect) => this.cursorForward(params));\n    this._parser.setCsiHandler('D', (params, collect) => this.cursorBackward(params));\n    this._parser.setCsiHandler('E', (params, collect) => this.cursorNextLine(params));\n    this._parser.setCsiHandler('F', (params, collect) => this.cursorPrecedingLine(params));\n    this._parser.setCsiHandler('G', (params, collect) => this.cursorCharAbsolute(params));\n    this._parser.setCsiHandler('H', (params, collect) => this.cursorPosition(params));\n    this._parser.setCsiHandler('I', (params, collect) => this.cursorForwardTab(params));\n    this._parser.setCsiHandler('J', (params, collect) => this.eraseInDisplay(params));\n    this._parser.setCsiHandler('K', (params, collect) => this.eraseInLine(params));\n    this._parser.setCsiHandler('L', (params, collect) => this.insertLines(params));\n    this._parser.setCsiHandler('M', (params, collect) => this.deleteLines(params));\n    this._parser.setCsiHandler('P', (params, collect) => this.deleteChars(params));\n    this._parser.setCsiHandler('S', (params, collect) => this.scrollUp(params));\n    this._parser.setCsiHandler('T', (params, collect) => this.scrollDown(params, collect));\n    this._parser.setCsiHandler('X', (params, collect) => this.eraseChars(params));\n    this._parser.setCsiHandler('Z', (params, collect) => this.cursorBackwardTab(params));\n    this._parser.setCsiHandler('`', (params, collect) => this.charPosAbsolute(params));\n    this._parser.setCsiHandler('a', (params, collect) => this.hPositionRelative(params));\n    this._parser.setCsiHandler('b', (params, collect) => this.repeatPrecedingCharacter(params));\n    this._parser.setCsiHandler('c', (params, collect) => this.sendDeviceAttributes(params, collect));\n    this._parser.setCsiHandler('d', (params, collect) => this.linePosAbsolute(params));\n    this._parser.setCsiHandler('e', (params, collect) => this.vPositionRelative(params));\n    this._parser.setCsiHandler('f', (params, collect) => this.hVPosition(params));\n    this._parser.setCsiHandler('g', (params, collect) => this.tabClear(params));\n    this._parser.setCsiHandler('h', (params, collect) => this.setMode(params, collect));\n    this._parser.setCsiHandler('l', (params, collect) => this.resetMode(params, collect));\n    this._parser.setCsiHandler('m', (params, collect) => this.charAttributes(params));\n    this._parser.setCsiHandler('n', (params, collect) => this.deviceStatus(params, collect));\n    this._parser.setCsiHandler('p', (params, collect) => this.softReset(params, collect));\n    this._parser.setCsiHandler('q', (params, collect) => this.setCursorStyle(params, collect));\n    this._parser.setCsiHandler('r', (params, collect) => this.setScrollRegion(params, collect));\n    this._parser.setCsiHandler('s', (params, collect) => this.saveCursor(params));\n    this._parser.setCsiHandler('u', (params, collect) => this.restoreCursor(params));\n\n    /**\n     * execute handler\n     */\n    this._parser.setExecuteHandler(C0.BEL, () => this.bell());\n    this._parser.setExecuteHandler(C0.LF, () => this.lineFeed());\n    this._parser.setExecuteHandler(C0.VT, () => this.lineFeed());\n    this._parser.setExecuteHandler(C0.FF, () => this.lineFeed());\n    this._parser.setExecuteHandler(C0.CR, () => this.carriageReturn());\n    this._parser.setExecuteHandler(C0.BS, () => this.backspace());\n    this._parser.setExecuteHandler(C0.HT, () => this.tab());\n    this._parser.setExecuteHandler(C0.SO, () => this.shiftOut());\n    this._parser.setExecuteHandler(C0.SI, () => this.shiftIn());\n    // FIXME:   What do to with missing? Old code just added those to print.\n\n    // some C1 control codes - FIXME: should those be enabled by default?\n    this._parser.setExecuteHandler(C1.IND, () => this.index());\n    this._parser.setExecuteHandler(C1.NEL, () => this.nextLine());\n    this._parser.setExecuteHandler(C1.HTS, () => this.tabSet());\n\n    /**\n     * OSC handler\n     */\n    //   0 - icon name + title\n    this._parser.setOscHandler(0, (data) => this.setTitle(data));\n    //   1 - icon name\n    //   2 - title\n    this._parser.setOscHandler(2, (data) => this.setTitle(data));\n    //   3 - set property X in the form \"prop=value\"\n    //   4 - Change Color Number\n    //   5 - Change Special Color Number\n    //   6 - Enable/disable Special Color Number c\n    //   7 - current directory? (not in xterm spec, see https://gitlab.com/gnachman/iterm2/issues/3939)\n    //  10 - Change VT100 text foreground color to Pt.\n    //  11 - Change VT100 text background color to Pt.\n    //  12 - Change text cursor color to Pt.\n    //  13 - Change mouse foreground color to Pt.\n    //  14 - Change mouse background color to Pt.\n    //  15 - Change Tektronix foreground color to Pt.\n    //  16 - Change Tektronix background color to Pt.\n    //  17 - Change highlight background color to Pt.\n    //  18 - Change Tektronix cursor color to Pt.\n    //  19 - Change highlight foreground color to Pt.\n    //  46 - Change Log File to Pt.\n    //  50 - Set Font to Pt.\n    //  51 - reserved for Emacs shell.\n    //  52 - Manipulate Selection Data.\n    // 104 ; c - Reset Color Number c.\n    // 105 ; c - Reset Special Color Number c.\n    // 106 ; c; f - Enable/disable Special Color Number c.\n    // 110 - Reset VT100 text foreground color.\n    // 111 - Reset VT100 text background color.\n    // 112 - Reset text cursor color.\n    // 113 - Reset mouse foreground color.\n    // 114 - Reset mouse background color.\n    // 115 - Reset Tektronix foreground color.\n    // 116 - Reset Tektronix background color.\n    // 117 - Reset highlight color.\n    // 118 - Reset Tektronix cursor color.\n    // 119 - Reset highlight foreground color.\n\n    /**\n     * ESC handlers\n     */\n    this._parser.setEscHandler('7', () => this.saveCursor([]));\n    this._parser.setEscHandler('8', () => this.restoreCursor([]));\n    this._parser.setEscHandler('D', () => this.index());\n    this._parser.setEscHandler('E', () => this.nextLine());\n    this._parser.setEscHandler('H', () => this.tabSet());\n    this._parser.setEscHandler('M', () => this.reverseIndex());\n    this._parser.setEscHandler('=', () => this.keypadApplicationMode());\n    this._parser.setEscHandler('>', () => this.keypadNumericMode());\n    this._parser.setEscHandler('c', () => this.reset());\n    this._parser.setEscHandler('n', () => this.setgLevel(2));\n    this._parser.setEscHandler('o', () => this.setgLevel(3));\n    this._parser.setEscHandler('|', () => this.setgLevel(3));\n    this._parser.setEscHandler('}', () => this.setgLevel(2));\n    this._parser.setEscHandler('~', () => this.setgLevel(1));\n    this._parser.setEscHandler('%@', () => this.selectDefaultCharset());\n    this._parser.setEscHandler('%G', () => this.selectDefaultCharset());\n    for (const flag in CHARSETS) {\n      this._parser.setEscHandler('(' + flag, () => this.selectCharset('(' + flag));\n      this._parser.setEscHandler(')' + flag, () => this.selectCharset(')' + flag));\n      this._parser.setEscHandler('*' + flag, () => this.selectCharset('*' + flag));\n      this._parser.setEscHandler('+' + flag, () => this.selectCharset('+' + flag));\n      this._parser.setEscHandler('-' + flag, () => this.selectCharset('-' + flag));\n      this._parser.setEscHandler('.' + flag, () => this.selectCharset('.' + flag));\n      this._parser.setEscHandler('/' + flag, () => this.selectCharset('/' + flag)); // TODO: supported?\n    }\n\n    /**\n     * error handler\n     */\n    this._parser.setErrorHandler((state) => {\n      this._terminal.error('Parsing error: ', state);\n      return state;\n    });\n\n    /**\n     * DCS handler\n     */\n    this._parser.setDcsHandler('$q', new DECRQSS(this._terminal));\n  }\n\n  public dispose(): void {\n    super.dispose();\n    this._terminal = null;\n  }\n\n  public parse(data: string): void {\n    // Ensure the terminal is not disposed\n    if (!this._terminal) {\n      return;\n    }\n\n    let buffer = this._terminal.buffer;\n    const cursorStartX = buffer.x;\n    const cursorStartY = buffer.y;\n\n    // TODO: Consolidate debug/logging #1560\n    if ((<any>this._terminal).debug) {\n      this._terminal.log('data: ' + data);\n    }\n\n    if (this._parseBuffer.length < data.length) {\n      this._parseBuffer = new Uint32Array(data.length);\n    }\n    this._parser.parse(this._parseBuffer, this._stringDecoder.decode(data, this._parseBuffer));\n\n    buffer = this._terminal.buffer;\n    if (buffer.x !== cursorStartX || buffer.y !== cursorStartY) {\n      this._onCursorMove.fire();\n    }\n  }\n\n  public print(data: Uint32Array, start: number, end: number): void {\n    let code: number;\n    let chWidth: number;\n    const buffer = this._terminal.buffer;\n    const charset = this._terminal.charset;\n    const screenReaderMode = this._terminal.options.screenReaderMode;\n    const cols = this._terminal.cols;\n    const wraparoundMode = this._terminal.wraparoundMode;\n    const insertMode = this._terminal.insertMode;\n    const curAttr = this._terminal.curAttrData;\n    let bufferRow = buffer.lines.get(buffer.y + buffer.ybase);\n\n    this._terminal.updateRange(buffer.y);\n    for (let pos = start; pos < end; ++pos) {\n      code = data[pos];\n\n      // calculate print space\n      // expensive call, therefore we save width in line buffer\n      chWidth = wcwidth(code);\n\n      // get charset replacement character\n      // charset is only defined for ASCII, therefore we only\n      // search for an replacement char if code < 127\n      if (code < 127 && charset) {\n        const ch = charset[String.fromCharCode(code)];\n        if (ch) {\n          code = ch.charCodeAt(0);\n        }\n      }\n\n      if (screenReaderMode) {\n        this._terminal.emit('a11y.char', stringFromCodePoint(code));\n      }\n\n      // insert combining char at last cursor position\n      // FIXME: needs handling after cursor jumps\n      // buffer.x should never be 0 for a combining char\n      // since they always follow a cell consuming char\n      // therefore we can test for buffer.x to avoid overflow left\n      if (!chWidth && buffer.x) {\n        if (!bufferRow.getWidth(buffer.x - 1)) {\n          // found empty cell after fullwidth, need to go 2 cells back\n          // it is save to step 2 cells back here\n          // since an empty cell is only set by fullwidth chars\n          bufferRow.addCodepointToCell(buffer.x - 2, code);\n        } else {\n          bufferRow.addCodepointToCell(buffer.x - 1, code);\n        }\n        continue;\n      }\n\n      // goto next line if ch would overflow\n      // TODO: needs a global min terminal width of 2\n      // FIXME: additionally ensure chWidth fits into a line\n      //   -->  maybe forbid cols<xy at higher level as it would\n      //        introduce a bad runtime penalty here\n      if (buffer.x + chWidth - 1 >= cols) {\n        // autowrap - DECAWM\n        // automatically wraps to the beginning of the next line\n        if (wraparoundMode) {\n          buffer.x = 0;\n          buffer.y++;\n          if (buffer.y > buffer.scrollBottom) {\n            buffer.y--;\n            this._terminal.scroll(true);\n          } else {\n            // The line already exists (eg. the initial viewport), mark it as a\n            // wrapped line\n            buffer.lines.get(buffer.y).isWrapped = true;\n          }\n          // row changed, get it again\n          bufferRow = buffer.lines.get(buffer.y + buffer.ybase);\n        } else {\n          if (chWidth === 2) {\n            // FIXME: check for xterm behavior\n            // What to do here? We got a wide char that does not fit into last cell\n            continue;\n          }\n          // FIXME: Do we have to set buffer.x to cols - 1, if not wrapping?\n        }\n      }\n\n      // insert mode: move characters to right\n      if (insertMode) {\n        // right shift cells according to the width\n        bufferRow.insertCells(buffer.x, chWidth, buffer.getNullCell(curAttr));\n        // test last cell - since the last cell has only room for\n        // a halfwidth char any fullwidth shifted there is lost\n        // and will be set to empty cell\n        if (bufferRow.getWidth(cols - 1) === 2) {\n          bufferRow.setCellFromCodePoint(cols - 1, NULL_CELL_CODE, NULL_CELL_WIDTH, curAttr.fg, curAttr.bg);\n        }\n      }\n\n      // write current char to buffer and advance cursor\n      bufferRow.setCellFromCodePoint(buffer.x++, code, chWidth, curAttr.fg, curAttr.bg);\n\n      // fullwidth char - also set next cell to placeholder stub and advance cursor\n      // for graphemes bigger than fullwidth we can simply loop to zero\n      // we already made sure above, that buffer.x + chWidth will not overflow right\n      if (chWidth > 0) {\n        while (--chWidth) {\n          // other than a regular empty cell a cell following a wide char has no width\n          bufferRow.setCellFromCodePoint(buffer.x++, 0, 0, curAttr.fg, curAttr.bg);\n        }\n      }\n    }\n    this._terminal.updateRange(buffer.y);\n  }\n\n  /**\n   * Forward addCsiHandler from parser.\n   */\n  public addCsiHandler(flag: string, callback: (params: number[], collect: string) => boolean): IDisposable {\n    return this._parser.addCsiHandler(flag, callback);\n  }\n\n  /**\n   * Forward addOscHandler from parser.\n   */\n  public addOscHandler(ident: number, callback: (data: string) => boolean): IDisposable {\n    return this._parser.addOscHandler(ident, callback);\n  }\n\n  /**\n   * BEL\n   * Bell (Ctrl-G).\n   */\n  public bell(): void {\n    this._terminal.bell();\n  }\n\n  /**\n   * LF\n   * Line Feed or New Line (NL).  (LF  is Ctrl-J).\n   */\n  public lineFeed(): void {\n    // make buffer local for faster access\n    const buffer = this._terminal.buffer;\n\n    if (this._terminal.options.convertEol) {\n      buffer.x = 0;\n    }\n    buffer.y++;\n    if (buffer.y > buffer.scrollBottom) {\n      buffer.y--;\n      this._terminal.scroll();\n    }\n    // If the end of the line is hit, prevent this action from wrapping around to the next line.\n    if (buffer.x >= this._terminal.cols) {\n      buffer.x--;\n    }\n\n    this._onLineFeed.fire();\n  }\n\n  /**\n   * CR\n   * Carriage Return (Ctrl-M).\n   */\n  public carriageReturn(): void {\n    this._terminal.buffer.x = 0;\n  }\n\n  /**\n   * BS\n   * Backspace (Ctrl-H).\n   */\n  public backspace(): void {\n    if (this._terminal.buffer.x > 0) {\n      this._terminal.buffer.x--;\n    }\n  }\n\n  /**\n   * TAB\n   * Horizontal Tab (HT) (Ctrl-I).\n   */\n  public tab(): void {\n    const originalX = this._terminal.buffer.x;\n    this._terminal.buffer.x = this._terminal.buffer.nextStop();\n    if (this._terminal.options.screenReaderMode) {\n      this._terminal.emit('a11y.tab', this._terminal.buffer.x - originalX);\n    }\n  }\n\n  /**\n   * SO\n   * Shift Out (Ctrl-N) -> Switch to Alternate Character Set.  This invokes the\n   * G1 character set.\n   */\n  public shiftOut(): void {\n    this._terminal.setgLevel(1);\n  }\n\n  /**\n   * SI\n   * Shift In (Ctrl-O) -> Switch to Standard Character Set.  This invokes the G0\n   * character set (the default).\n   */\n  public shiftIn(): void {\n    this._terminal.setgLevel(0);\n  }\n\n  /**\n   * CSI Ps @\n   * Insert Ps (Blank) Character(s) (default = 1) (ICH).\n   */\n  public insertChars(params: number[]): void {\n    this._terminal.buffer.lines.get(this._terminal.buffer.y + this._terminal.buffer.ybase).insertCells(\n      this._terminal.buffer.x,\n      params[0] || 1,\n      this._terminal.buffer.getNullCell(this._terminal.eraseAttrData())\n    );\n    this._terminal.updateRange(this._terminal.buffer.y);\n  }\n\n  /**\n   * CSI Ps A\n   * Cursor Up Ps Times (default = 1) (CUU).\n   */\n  public cursorUp(params: number[]): void {\n    let param = params[0];\n    if (param < 1) {\n      param = 1;\n    }\n    this._terminal.buffer.y -= param;\n    if (this._terminal.buffer.y < 0) {\n      this._terminal.buffer.y = 0;\n    }\n  }\n\n  /**\n   * CSI Ps B\n   * Cursor Down Ps Times (default = 1) (CUD).\n   */\n  public cursorDown(params: number[]): void {\n    let param = params[0];\n    if (param < 1) {\n      param = 1;\n    }\n    this._terminal.buffer.y += param;\n    if (this._terminal.buffer.y >= this._terminal.rows) {\n      this._terminal.buffer.y = this._terminal.rows - 1;\n    }\n    // If the end of the line is hit, prevent this action from wrapping around to the next line.\n    if (this._terminal.buffer.x >= this._terminal.cols) {\n      this._terminal.buffer.x--;\n    }\n  }\n\n  /**\n   * CSI Ps C\n   * Cursor Forward Ps Times (default = 1) (CUF).\n   */\n  public cursorForward(params: number[]): void {\n    let param = params[0];\n    if (param < 1) {\n      param = 1;\n    }\n    this._terminal.buffer.x += param;\n    if (this._terminal.buffer.x >= this._terminal.cols) {\n      this._terminal.buffer.x = this._terminal.cols - 1;\n    }\n  }\n\n  /**\n   * CSI Ps D\n   * Cursor Backward Ps Times (default = 1) (CUB).\n   */\n  public cursorBackward(params: number[]): void {\n    let param = params[0];\n    if (param < 1) {\n      param = 1;\n    }\n    // If the end of the line is hit, prevent this action from wrapping around to the next line.\n    if (this._terminal.buffer.x >= this._terminal.cols) {\n      this._terminal.buffer.x--;\n    }\n    this._terminal.buffer.x -= param;\n    if (this._terminal.buffer.x < 0) {\n      this._terminal.buffer.x = 0;\n    }\n  }\n\n  /**\n   * CSI Ps E\n   * Cursor Next Line Ps Times (default = 1) (CNL).\n   * same as CSI Ps B ?\n   */\n  public cursorNextLine(params: number[]): void {\n    let param = params[0];\n    if (param < 1) {\n      param = 1;\n    }\n    this._terminal.buffer.y += param;\n    if (this._terminal.buffer.y >= this._terminal.rows) {\n      this._terminal.buffer.y = this._terminal.rows - 1;\n    }\n    this._terminal.buffer.x = 0;\n  }\n\n\n  /**\n   * CSI Ps F\n   * Cursor Preceding Line Ps Times (default = 1) (CNL).\n   * reuse CSI Ps A ?\n   */\n  public cursorPrecedingLine(params: number[]): void {\n    let param = params[0];\n    if (param < 1) {\n      param = 1;\n    }\n    this._terminal.buffer.y -= param;\n    if (this._terminal.buffer.y < 0) {\n      this._terminal.buffer.y = 0;\n    }\n    this._terminal.buffer.x = 0;\n  }\n\n\n  /**\n   * CSI Ps G\n   * Cursor Character Absolute  [column] (default = [row,1]) (CHA).\n   */\n  public cursorCharAbsolute(params: number[]): void {\n    let param = params[0];\n    if (param < 1) {\n      param = 1;\n    }\n    this._terminal.buffer.x = param - 1;\n  }\n\n  /**\n   * CSI Ps ; Ps H\n   * Cursor Position [row;column] (default = [1,1]) (CUP).\n   */\n  public cursorPosition(params: number[]): void {\n    let col: number;\n    let row: number = params[0] - 1;\n\n    if (params.length >= 2) {\n      col = params[1] - 1;\n    } else {\n      col = 0;\n    }\n\n    if (row < 0) {\n      row = 0;\n    } else if (row >= this._terminal.rows) {\n      row = this._terminal.rows - 1;\n    }\n\n    if (col < 0) {\n      col = 0;\n    } else if (col >= this._terminal.cols) {\n      col = this._terminal.cols - 1;\n    }\n\n    this._terminal.buffer.x = col;\n    this._terminal.buffer.y = row;\n  }\n\n  /**\n   * CSI Ps I\n   *   Cursor Forward Tabulation Ps tab stops (default = 1) (CHT).\n   */\n  public cursorForwardTab(params: number[]): void {\n    let param = params[0] || 1;\n    while (param--) {\n      this._terminal.buffer.x = this._terminal.buffer.nextStop();\n    }\n  }\n\n  /**\n   * Helper method to erase cells in a terminal row.\n   * The cell gets replaced with the eraseChar of the terminal.\n   * @param y row index\n   * @param start first cell index to be erased\n   * @param end   end - 1 is last erased cell\n   */\n  private _eraseInBufferLine(y: number, start: number, end: number, clearWrap: boolean = false): void {\n    const line = this._terminal.buffer.lines.get(this._terminal.buffer.ybase + y);\n    line.replaceCells(\n      start,\n      end,\n      this._terminal.buffer.getNullCell(this._terminal.eraseAttrData())\n    );\n    if (clearWrap) {\n      line.isWrapped = false;\n    }\n  }\n\n  /**\n   * Helper method to reset cells in a terminal row.\n   * The cell gets replaced with the eraseChar of the terminal and the isWrapped property is set to false.\n   * @param y row index\n   */\n  private _resetBufferLine(y: number): void {\n    this._eraseInBufferLine(y, 0, this._terminal.cols, true);\n  }\n\n  /**\n   * CSI Ps J  Erase in Display (ED).\n   *     Ps = 0  -> Erase Below (default).\n   *     Ps = 1  -> Erase Above.\n   *     Ps = 2  -> Erase All.\n   *     Ps = 3  -> Erase Saved Lines (xterm).\n   * CSI ? Ps J\n   *   Erase in Display (DECSED).\n   *     Ps = 0  -> Selective Erase Below (default).\n   *     Ps = 1  -> Selective Erase Above.\n   *     Ps = 2  -> Selective Erase All.\n   */\n  public eraseInDisplay(params: number[]): void {\n    let j;\n    switch (params[0]) {\n      case 0:\n        j = this._terminal.buffer.y;\n        this._terminal.updateRange(j);\n        this._eraseInBufferLine(j++, this._terminal.buffer.x, this._terminal.cols, this._terminal.buffer.x === 0);\n        for (; j < this._terminal.rows; j++) {\n          this._resetBufferLine(j);\n        }\n        this._terminal.updateRange(j);\n        break;\n      case 1:\n        j = this._terminal.buffer.y;\n        this._terminal.updateRange(j);\n        // Deleted front part of line and everything before. This line will no longer be wrapped.\n        this._eraseInBufferLine(j, 0, this._terminal.buffer.x + 1, true);\n        if (this._terminal.buffer.x + 1 >= this._terminal.cols) {\n          // Deleted entire previous line. This next line can no longer be wrapped.\n          this._terminal.buffer.lines.get(j + 1).isWrapped = false;\n        }\n        while (j--) {\n          this._resetBufferLine(j);\n        }\n        this._terminal.updateRange(0);\n        break;\n      case 2:\n        j = this._terminal.rows;\n        this._terminal.updateRange(j - 1);\n        while (j--) {\n          this._resetBufferLine(j);\n        }\n        this._terminal.updateRange(0);\n        break;\n      case 3:\n        // Clear scrollback (everything not in viewport)\n        const scrollBackSize = this._terminal.buffer.lines.length - this._terminal.rows;\n        if (scrollBackSize > 0) {\n          this._terminal.buffer.lines.trimStart(scrollBackSize);\n          this._terminal.buffer.ybase = Math.max(this._terminal.buffer.ybase - scrollBackSize, 0);\n          this._terminal.buffer.ydisp = Math.max(this._terminal.buffer.ydisp - scrollBackSize, 0);\n          // Force a scroll event to refresh viewport\n          this._onScroll.fire(0);\n        }\n        break;\n    }\n  }\n\n  /**\n   * CSI Ps K  Erase in Line (EL).\n   *     Ps = 0  -> Erase to Right (default).\n   *     Ps = 1  -> Erase to Left.\n   *     Ps = 2  -> Erase All.\n   * CSI ? Ps K\n   *   Erase in Line (DECSEL).\n   *     Ps = 0  -> Selective Erase to Right (default).\n   *     Ps = 1  -> Selective Erase to Left.\n   *     Ps = 2  -> Selective Erase All.\n   */\n  public eraseInLine(params: number[]): void {\n    switch (params[0]) {\n      case 0:\n        this._eraseInBufferLine(this._terminal.buffer.y, this._terminal.buffer.x, this._terminal.cols);\n        break;\n      case 1:\n        this._eraseInBufferLine(this._terminal.buffer.y, 0, this._terminal.buffer.x + 1);\n        break;\n      case 2:\n        this._eraseInBufferLine(this._terminal.buffer.y, 0, this._terminal.cols);\n        break;\n    }\n    this._terminal.updateRange(this._terminal.buffer.y);\n  }\n\n  /**\n   * CSI Ps L\n   * Insert Ps Line(s) (default = 1) (IL).\n   */\n  public insertLines(params: number[]): void {\n    let param: number = params[0];\n    if (param < 1) {\n      param = 1;\n    }\n\n    // make buffer local for faster access\n    const buffer = this._terminal.buffer;\n\n    const row: number = buffer.y + buffer.ybase;\n\n    const scrollBottomRowsOffset = this._terminal.rows - 1 - buffer.scrollBottom;\n    const scrollBottomAbsolute = this._terminal.rows - 1 + buffer.ybase - scrollBottomRowsOffset + 1;\n    while (param--) {\n      // test: echo -e '\\e[44m\\e[1L\\e[0m'\n      // blankLine(true) - xterm/linux behavior\n      buffer.lines.splice(scrollBottomAbsolute - 1, 1);\n      buffer.lines.splice(row, 0, buffer.getBlankLine(this._terminal.eraseAttrData()));\n    }\n\n    // this.maxRange();\n    this._terminal.updateRange(buffer.y);\n    this._terminal.updateRange(buffer.scrollBottom);\n  }\n\n  /**\n   * CSI Ps M\n   * Delete Ps Line(s) (default = 1) (DL).\n   */\n  public deleteLines(params: number[]): void {\n    let param = params[0];\n    if (param < 1) {\n      param = 1;\n    }\n\n    // make buffer local for faster access\n    const buffer = this._terminal.buffer;\n\n    const row: number = buffer.y + buffer.ybase;\n\n    let j: number;\n    j = this._terminal.rows - 1 - buffer.scrollBottom;\n    j = this._terminal.rows - 1 + buffer.ybase - j;\n    while (param--) {\n      // test: echo -e '\\e[44m\\e[1M\\e[0m'\n      // blankLine(true) - xterm/linux behavior\n      buffer.lines.splice(row, 1);\n      buffer.lines.splice(j, 0, buffer.getBlankLine(this._terminal.eraseAttrData()));\n    }\n\n    // this.maxRange();\n    this._terminal.updateRange(buffer.y);\n    this._terminal.updateRange(buffer.scrollBottom);\n  }\n\n  /**\n   * CSI Ps P\n   * Delete Ps Character(s) (default = 1) (DCH).\n   */\n  public deleteChars(params: number[]): void {\n    this._terminal.buffer.lines.get(this._terminal.buffer.y + this._terminal.buffer.ybase).deleteCells(\n      this._terminal.buffer.x,\n      params[0] || 1,\n      this._terminal.buffer.getNullCell(this._terminal.eraseAttrData())\n    );\n    this._terminal.updateRange(this._terminal.buffer.y);\n  }\n\n  /**\n   * CSI Ps S  Scroll up Ps lines (default = 1) (SU).\n   */\n  public scrollUp(params: number[]): void {\n    let param = params[0] || 1;\n\n    // make buffer local for faster access\n    const buffer = this._terminal.buffer;\n\n    while (param--) {\n      buffer.lines.splice(buffer.ybase + buffer.scrollTop, 1);\n      buffer.lines.splice(buffer.ybase + buffer.scrollBottom, 0, buffer.getBlankLine(DEFAULT_ATTR_DATA));\n    }\n    // this.maxRange();\n    this._terminal.updateRange(buffer.scrollTop);\n    this._terminal.updateRange(buffer.scrollBottom);\n  }\n\n  /**\n   * CSI Ps T  Scroll down Ps lines (default = 1) (SD).\n   */\n  public scrollDown(params: number[], collect?: string): void {\n    if (params.length < 2 && !collect) {\n      let param = params[0] || 1;\n\n      // make buffer local for faster access\n      const buffer = this._terminal.buffer;\n\n      while (param--) {\n        buffer.lines.splice(buffer.ybase + buffer.scrollBottom, 1);\n        buffer.lines.splice(buffer.ybase + buffer.scrollTop, 0, buffer.getBlankLine(DEFAULT_ATTR_DATA));\n      }\n      // this.maxRange();\n      this._terminal.updateRange(buffer.scrollTop);\n      this._terminal.updateRange(buffer.scrollBottom);\n    }\n  }\n\n  /**\n   * CSI Ps X\n   * Erase Ps Character(s) (default = 1) (ECH).\n   */\n  public eraseChars(params: number[]): void {\n    this._terminal.buffer.lines.get(this._terminal.buffer.y + this._terminal.buffer.ybase).replaceCells(\n      this._terminal.buffer.x,\n      this._terminal.buffer.x + (params[0] || 1),\n      this._terminal.buffer.getNullCell(this._terminal.eraseAttrData())\n    );\n  }\n\n  /**\n   * CSI Ps Z  Cursor Backward Tabulation Ps tab stops (default = 1) (CBT).\n   */\n  public cursorBackwardTab(params: number[]): void {\n    let param = params[0] || 1;\n\n    // make buffer local for faster access\n    const buffer = this._terminal.buffer;\n\n    while (param--) {\n      buffer.x = buffer.prevStop();\n    }\n  }\n\n  /**\n   * CSI Pm `  Character Position Absolute\n   *   [column] (default = [row,1]) (HPA).\n   */\n  public charPosAbsolute(params: number[]): void {\n    let param = params[0];\n    if (param < 1) {\n      param = 1;\n    }\n    this._terminal.buffer.x = param - 1;\n    if (this._terminal.buffer.x >= this._terminal.cols) {\n      this._terminal.buffer.x = this._terminal.cols - 1;\n    }\n  }\n\n  /**\n   * CSI Pm a  Character Position Relative\n   *   [columns] (default = [row,col+1]) (HPR)\n   * reuse CSI Ps C ?\n   */\n  public hPositionRelative(params: number[]): void {\n    let param = params[0];\n    if (param < 1) {\n      param = 1;\n    }\n    this._terminal.buffer.x += param;\n    if (this._terminal.buffer.x >= this._terminal.cols) {\n      this._terminal.buffer.x = this._terminal.cols - 1;\n    }\n  }\n\n  /**\n   * CSI Ps b  Repeat the preceding graphic character Ps times (REP).\n   */\n  public repeatPrecedingCharacter(params: number[]): void {\n    // make buffer local for faster access\n    const buffer = this._terminal.buffer;\n    const line = buffer.lines.get(buffer.ybase + buffer.y);\n    line.loadCell(buffer.x - 1, this._workCell);\n    line.replaceCells(buffer.x,\n      buffer.x + (params[0] || 1),\n      (this._workCell.content !== undefined) ? this._workCell : buffer.getNullCell(DEFAULT_ATTR_DATA)\n    );\n    // FIXME: no updateRange here?\n  }\n\n  /**\n   * CSI Ps c  Send Device Attributes (Primary DA).\n   *     Ps = 0  or omitted -> request attributes from terminal.  The\n   *     response depends on the decTerminalID resource setting.\n   *     -> CSI ? 1 ; 2 c  (``VT100 with Advanced Video Option'')\n   *     -> CSI ? 1 ; 0 c  (``VT101 with No Options'')\n   *     -> CSI ? 6 c  (``VT102'')\n   *     -> CSI ? 6 0 ; 1 ; 2 ; 6 ; 8 ; 9 ; 1 5 ; c  (``VT220'')\n   *   The VT100-style response parameters do not mean anything by\n   *   themselves.  VT220 parameters do, telling the host what fea-\n   *   tures the terminal supports:\n   *     Ps = 1  -> 132-columns.\n   *     Ps = 2  -> Printer.\n   *     Ps = 6  -> Selective erase.\n   *     Ps = 8  -> User-defined keys.\n   *     Ps = 9  -> National replacement character sets.\n   *     Ps = 1 5  -> Technical characters.\n   *     Ps = 2 2  -> ANSI color, e.g., VT525.\n   *     Ps = 2 9  -> ANSI text locator (i.e., DEC Locator mode).\n   * CSI > Ps c\n   *   Send Device Attributes (Secondary DA).\n   *     Ps = 0  or omitted -> request the terminal's identification\n   *     code.  The response depends on the decTerminalID resource set-\n   *     ting.  It should apply only to VT220 and up, but xterm extends\n   *     this to VT100.\n   *     -> CSI  > Pp ; Pv ; Pc c\n   *   where Pp denotes the terminal type\n   *     Pp = 0  -> ``VT100''.\n   *     Pp = 1  -> ``VT220''.\n   *   and Pv is the firmware version (for xterm, this was originally\n   *   the XFree86 patch number, starting with 95).  In a DEC termi-\n   *   nal, Pc indicates the ROM cartridge registration number and is\n   *   always zero.\n   * More information:\n   *   xterm/charproc.c - line 2012, for more information.\n   *   vim responds with ^[[?0c or ^[[?1c after the terminal's response (?)\n   */\n  public sendDeviceAttributes(params: number[], collect?: string): void {\n    if (params[0] > 0) {\n      return;\n    }\n\n    if (!collect) {\n      if (this._terminal.is('xterm') || this._terminal.is('rxvt-unicode') || this._terminal.is('screen')) {\n        this._terminal.handler(C0.ESC + '[?1;2c');\n      } else if (this._terminal.is('linux')) {\n        this._terminal.handler(C0.ESC + '[?6c');\n      }\n    } else if (collect === '>') {\n      // xterm and urxvt\n      // seem to spit this\n      // out around ~370 times (?).\n      if (this._terminal.is('xterm')) {\n        this._terminal.handler(C0.ESC + '[>0;276;0c');\n      } else if (this._terminal.is('rxvt-unicode')) {\n        this._terminal.handler(C0.ESC + '[>85;95;0c');\n      } else if (this._terminal.is('linux')) {\n        // not supported by linux console.\n        // linux console echoes parameters.\n        this._terminal.handler(params[0] + 'c');\n      } else if (this._terminal.is('screen')) {\n        this._terminal.handler(C0.ESC + '[>83;40003;0c');\n      }\n    }\n  }\n\n  /**\n   * CSI Pm d  Vertical Position Absolute (VPA)\n   *   [row] (default = [1,column])\n   */\n  public linePosAbsolute(params: number[]): void {\n    let param = params[0];\n    if (param < 1) {\n      param = 1;\n    }\n    this._terminal.buffer.y = param - 1;\n    if (this._terminal.buffer.y >= this._terminal.rows) {\n      this._terminal.buffer.y = this._terminal.rows - 1;\n    }\n  }\n\n  /**\n   * CSI Pm e  Vertical Position Relative (VPR)\n   *   [rows] (default = [row+1,column])\n   * reuse CSI Ps B ?\n   */\n  public vPositionRelative(params: number[]): void {\n    let param = params[0];\n    if (param < 1) {\n      param = 1;\n    }\n    this._terminal.buffer.y += param;\n    if (this._terminal.buffer.y >= this._terminal.rows) {\n      this._terminal.buffer.y = this._terminal.rows - 1;\n    }\n    // If the end of the line is hit, prevent this action from wrapping around to the next line.\n    if (this._terminal.buffer.x >= this._terminal.cols) {\n      this._terminal.buffer.x--;\n    }\n  }\n\n  /**\n   * CSI Ps ; Ps f\n   *   Horizontal and Vertical Position [row;column] (default =\n   *   [1,1]) (HVP).\n   */\n  public hVPosition(params: number[]): void {\n    if (params[0] < 1) params[0] = 1;\n    if (params[1] < 1) params[1] = 1;\n\n    this._terminal.buffer.y = params[0] - 1;\n    if (this._terminal.buffer.y >= this._terminal.rows) {\n      this._terminal.buffer.y = this._terminal.rows - 1;\n    }\n\n    this._terminal.buffer.x = params[1] - 1;\n    if (this._terminal.buffer.x >= this._terminal.cols) {\n      this._terminal.buffer.x = this._terminal.cols - 1;\n    }\n  }\n\n  /**\n   * CSI Ps g  Tab Clear (TBC).\n   *     Ps = 0  -> Clear Current Column (default).\n   *     Ps = 3  -> Clear All.\n   * Potentially:\n   *   Ps = 2  -> Clear Stops on Line.\n   *   http://vt100.net/annarbor/aaa-ug/section6.html\n   */\n  public tabClear(params: number[]): void {\n    const param = params[0];\n    if (param <= 0) {\n      delete this._terminal.buffer.tabs[this._terminal.buffer.x];\n    } else if (param === 3) {\n      this._terminal.buffer.tabs = {};\n    }\n  }\n\n  /**\n   * CSI Pm h  Set Mode (SM).\n   *     Ps = 2  -> Keyboard Action Mode (AM).\n   *     Ps = 4  -> Insert Mode (IRM).\n   *     Ps = 1 2  -> Send/receive (SRM).\n   *     Ps = 2 0  -> Automatic Newline (LNM).\n   * CSI ? Pm h\n   *   DEC Private Mode Set (DECSET).\n   *     Ps = 1  -> Application Cursor Keys (DECCKM).\n   *     Ps = 2  -> Designate USASCII for character sets G0-G3\n   *     (DECANM), and set VT100 mode.\n   *     Ps = 3  -> 132 Column Mode (DECCOLM).\n   *     Ps = 4  -> Smooth (Slow) Scroll (DECSCLM).\n   *     Ps = 5  -> Reverse Video (DECSCNM).\n   *     Ps = 6  -> Origin Mode (DECOM).\n   *     Ps = 7  -> Wraparound Mode (DECAWM).\n   *     Ps = 8  -> Auto-repeat Keys (DECARM).\n   *     Ps = 9  -> Send Mouse X & Y on button press.  See the sec-\n   *     tion Mouse Tracking.\n   *     Ps = 1 0  -> Show toolbar (rxvt).\n   *     Ps = 1 2  -> Start Blinking Cursor (att610).\n   *     Ps = 1 8  -> Print form feed (DECPFF).\n   *     Ps = 1 9  -> Set print extent to full screen (DECPEX).\n   *     Ps = 2 5  -> Show Cursor (DECTCEM).\n   *     Ps = 3 0  -> Show scrollbar (rxvt).\n   *     Ps = 3 5  -> Enable font-shifting functions (rxvt).\n   *     Ps = 3 8  -> Enter Tektronix Mode (DECTEK).\n   *     Ps = 4 0  -> Allow 80 -> 132 Mode.\n   *     Ps = 4 1  -> more(1) fix (see curses resource).\n   *     Ps = 4 2  -> Enable Nation Replacement Character sets (DECN-\n   *     RCM).\n   *     Ps = 4 4  -> Turn On Margin Bell.\n   *     Ps = 4 5  -> Reverse-wraparound Mode.\n   *     Ps = 4 6  -> Start Logging.  This is normally disabled by a\n   *     compile-time option.\n   *     Ps = 4 7  -> Use Alternate Screen Buffer.  (This may be dis-\n   *     abled by the titeInhibit resource).\n   *     Ps = 6 6  -> Application keypad (DECNKM).\n   *     Ps = 6 7  -> Backarrow key sends backspace (DECBKM).\n   *     Ps = 1 0 0 0  -> Send Mouse X & Y on button press and\n   *     release.  See the section Mouse Tracking.\n   *     Ps = 1 0 0 1  -> Use Hilite Mouse Tracking.\n   *     Ps = 1 0 0 2  -> Use Cell Motion Mouse Tracking.\n   *     Ps = 1 0 0 3  -> Use All Motion Mouse Tracking.\n   *     Ps = 1 0 0 4  -> Send FocusIn/FocusOut events.\n   *     Ps = 1 0 0 5  -> Enable Extended Mouse Mode.\n   *     Ps = 1 0 1 0  -> Scroll to bottom on tty output (rxvt).\n   *     Ps = 1 0 1 1  -> Scroll to bottom on key press (rxvt).\n   *     Ps = 1 0 3 4  -> Interpret \"meta\" key, sets eighth bit.\n   *     (enables the eightBitInput resource).\n   *     Ps = 1 0 3 5  -> Enable special modifiers for Alt and Num-\n   *     Lock keys.  (This enables the numLock resource).\n   *     Ps = 1 0 3 6  -> Send ESC   when Meta modifies a key.  (This\n   *     enables the metaSendsEscape resource).\n   *     Ps = 1 0 3 7  -> Send DEL from the editing-keypad Delete\n   *     key.\n   *     Ps = 1 0 3 9  -> Send ESC  when Alt modifies a key.  (This\n   *     enables the altSendsEscape resource).\n   *     Ps = 1 0 4 0  -> Keep selection even if not highlighted.\n   *     (This enables the keepSelection resource).\n   *     Ps = 1 0 4 1  -> Use the CLIPBOARD selection.  (This enables\n   *     the selectToClipboard resource).\n   *     Ps = 1 0 4 2  -> Enable Urgency window manager hint when\n   *     Control-G is received.  (This enables the bellIsUrgent\n   *     resource).\n   *     Ps = 1 0 4 3  -> Enable raising of the window when Control-G\n   *     is received.  (enables the popOnBell resource).\n   *     Ps = 1 0 4 7  -> Use Alternate Screen Buffer.  (This may be\n   *     disabled by the titeInhibit resource).\n   *     Ps = 1 0 4 8  -> Save cursor as in DECSC.  (This may be dis-\n   *     abled by the titeInhibit resource).\n   *     Ps = 1 0 4 9  -> Save cursor as in DECSC and use Alternate\n   *     Screen Buffer, clearing it first.  (This may be disabled by\n   *     the titeInhibit resource).  This combines the effects of the 1\n   *     0 4 7  and 1 0 4 8  modes.  Use this with terminfo-based\n   *     applications rather than the 4 7  mode.\n   *     Ps = 1 0 5 0  -> Set terminfo/termcap function-key mode.\n   *     Ps = 1 0 5 1  -> Set Sun function-key mode.\n   *     Ps = 1 0 5 2  -> Set HP function-key mode.\n   *     Ps = 1 0 5 3  -> Set SCO function-key mode.\n   *     Ps = 1 0 6 0  -> Set legacy keyboard emulation (X11R6).\n   *     Ps = 1 0 6 1  -> Set VT220 keyboard emulation.\n   *     Ps = 2 0 0 4  -> Set bracketed paste mode.\n   * Modes:\n   *   http: *vt100.net/docs/vt220-rm/chapter4.html\n   */\n  public setMode(params: number[], collect?: string): void {\n    if (params.length > 1) {\n      for (let i = 0; i < params.length; i++) {\n        this.setMode([params[i]]);\n      }\n\n      return;\n    }\n\n    if (!collect) {\n      switch (params[0]) {\n        case 4:\n          this._terminal.insertMode = true;\n          break;\n        case 20:\n          // this._t.convertEol = true;\n          break;\n      }\n    } else if (collect === '?') {\n      switch (params[0]) {\n        case 1:\n          this._terminal.applicationCursor = true;\n          break;\n        case 2:\n          this._terminal.setgCharset(0, DEFAULT_CHARSET);\n          this._terminal.setgCharset(1, DEFAULT_CHARSET);\n          this._terminal.setgCharset(2, DEFAULT_CHARSET);\n          this._terminal.setgCharset(3, DEFAULT_CHARSET);\n          // set VT100 mode here\n          break;\n        case 3: // 132 col mode\n          this._terminal.savedCols = this._terminal.cols;\n          this._terminal.resize(132, this._terminal.rows);\n          break;\n        case 6:\n          this._terminal.originMode = true;\n          break;\n        case 7:\n          this._terminal.wraparoundMode = true;\n          break;\n        case 12:\n          // this.cursorBlink = true;\n          break;\n        case 66:\n          this._terminal.log('Serial port requested application keypad.');\n          this._terminal.applicationKeypad = true;\n          if (this._terminal.viewport) {\n            this._terminal.viewport.syncScrollArea();\n          }\n          break;\n        case 9: // X10 Mouse\n          // no release, no motion, no wheel, no modifiers.\n        case 1000: // vt200 mouse\n          // no motion.\n          // no modifiers, except control on the wheel.\n        case 1002: // button event mouse\n        case 1003: // any event mouse\n          // any event - sends motion events,\n          // even if there is no button held down.\n\n          // TODO: Why are params[0] compares nested within a switch for params[0]?\n\n          this._terminal.x10Mouse = params[0] === 9;\n          this._terminal.vt200Mouse = params[0] === 1000;\n          this._terminal.normalMouse = params[0] > 1000;\n          this._terminal.mouseEvents = true;\n          if (this._terminal.element) {\n            this._terminal.element.classList.add('enable-mouse-events');\n          }\n          if (this._terminal.selectionManager) {\n            this._terminal.selectionManager.disable();\n          }\n          this._terminal.log('Binding to mouse events.');\n          break;\n        case 1004: // send focusin/focusout events\n          // focusin: ^[[I\n          // focusout: ^[[O\n          this._terminal.sendFocus = true;\n          break;\n        case 1005: // utf8 ext mode mouse\n          this._terminal.utfMouse = true;\n          // for wide terminals\n          // simply encodes large values as utf8 characters\n          break;\n        case 1006: // sgr ext mode mouse\n          this._terminal.sgrMouse = true;\n          // for wide terminals\n          // does not add 32 to fields\n          // press: ^[[<b;x;yM\n          // release: ^[[<b;x;ym\n          break;\n        case 1015: // urxvt ext mode mouse\n          this._terminal.urxvtMouse = true;\n          // for wide terminals\n          // numbers for fields\n          // press: ^[[b;x;yM\n          // motion: ^[[b;x;yT\n          break;\n        case 25: // show cursor\n          this._terminal.cursorHidden = false;\n          break;\n        case 1048: // alt screen cursor\n          this.saveCursor(params);\n          break;\n        case 1049: // alt screen buffer cursor\n          this.saveCursor(params);\n          // FALL-THROUGH\n        case 47: // alt screen buffer\n        case 1047: // alt screen buffer\n          this._terminal.buffers.activateAltBuffer(this._terminal.eraseAttrData());\n          this._terminal.refresh(0, this._terminal.rows - 1);\n          if (this._terminal.viewport) {\n            this._terminal.viewport.syncScrollArea();\n          }\n          this._terminal.showCursor();\n          break;\n        case 2004: // bracketed paste mode (https://cirw.in/blog/bracketed-paste)\n          this._terminal.bracketedPasteMode = true;\n          break;\n      }\n    }\n  }\n\n  /**\n   * CSI Pm l  Reset Mode (RM).\n   *     Ps = 2  -> Keyboard Action Mode (AM).\n   *     Ps = 4  -> Replace Mode (IRM).\n   *     Ps = 1 2  -> Send/receive (SRM).\n   *     Ps = 2 0  -> Normal Linefeed (LNM).\n   * CSI ? Pm l\n   *   DEC Private Mode Reset (DECRST).\n   *     Ps = 1  -> Normal Cursor Keys (DECCKM).\n   *     Ps = 2  -> Designate VT52 mode (DECANM).\n   *     Ps = 3  -> 80 Column Mode (DECCOLM).\n   *     Ps = 4  -> Jump (Fast) Scroll (DECSCLM).\n   *     Ps = 5  -> Normal Video (DECSCNM).\n   *     Ps = 6  -> Normal Cursor Mode (DECOM).\n   *     Ps = 7  -> No Wraparound Mode (DECAWM).\n   *     Ps = 8  -> No Auto-repeat Keys (DECARM).\n   *     Ps = 9  -> Don't send Mouse X & Y on button press.\n   *     Ps = 1 0  -> Hide toolbar (rxvt).\n   *     Ps = 1 2  -> Stop Blinking Cursor (att610).\n   *     Ps = 1 8  -> Don't print form feed (DECPFF).\n   *     Ps = 1 9  -> Limit print to scrolling region (DECPEX).\n   *     Ps = 2 5  -> Hide Cursor (DECTCEM).\n   *     Ps = 3 0  -> Don't show scrollbar (rxvt).\n   *     Ps = 3 5  -> Disable font-shifting functions (rxvt).\n   *     Ps = 4 0  -> Disallow 80 -> 132 Mode.\n   *     Ps = 4 1  -> No more(1) fix (see curses resource).\n   *     Ps = 4 2  -> Disable Nation Replacement Character sets (DEC-\n   *     NRCM).\n   *     Ps = 4 4  -> Turn Off Margin Bell.\n   *     Ps = 4 5  -> No Reverse-wraparound Mode.\n   *     Ps = 4 6  -> Stop Logging.  (This is normally disabled by a\n   *     compile-time option).\n   *     Ps = 4 7  -> Use Normal Screen Buffer.\n   *     Ps = 6 6  -> Numeric keypad (DECNKM).\n   *     Ps = 6 7  -> Backarrow key sends delete (DECBKM).\n   *     Ps = 1 0 0 0  -> Don't send Mouse X & Y on button press and\n   *     release.  See the section Mouse Tracking.\n   *     Ps = 1 0 0 1  -> Don't use Hilite Mouse Tracking.\n   *     Ps = 1 0 0 2  -> Don't use Cell Motion Mouse Tracking.\n   *     Ps = 1 0 0 3  -> Don't use All Motion Mouse Tracking.\n   *     Ps = 1 0 0 4  -> Don't send FocusIn/FocusOut events.\n   *     Ps = 1 0 0 5  -> Disable Extended Mouse Mode.\n   *     Ps = 1 0 1 0  -> Don't scroll to bottom on tty output\n   *     (rxvt).\n   *     Ps = 1 0 1 1  -> Don't scroll to bottom on key press (rxvt).\n   *     Ps = 1 0 3 4  -> Don't interpret \"meta\" key.  (This disables\n   *     the eightBitInput resource).\n   *     Ps = 1 0 3 5  -> Disable special modifiers for Alt and Num-\n   *     Lock keys.  (This disables the numLock resource).\n   *     Ps = 1 0 3 6  -> Don't send ESC  when Meta modifies a key.\n   *     (This disables the metaSendsEscape resource).\n   *     Ps = 1 0 3 7  -> Send VT220 Remove from the editing-keypad\n   *     Delete key.\n   *     Ps = 1 0 3 9  -> Don't send ESC  when Alt modifies a key.\n   *     (This disables the altSendsEscape resource).\n   *     Ps = 1 0 4 0  -> Do not keep selection when not highlighted.\n   *     (This disables the keepSelection resource).\n   *     Ps = 1 0 4 1  -> Use the PRIMARY selection.  (This disables\n   *     the selectToClipboard resource).\n   *     Ps = 1 0 4 2  -> Disable Urgency window manager hint when\n   *     Control-G is received.  (This disables the bellIsUrgent\n   *     resource).\n   *     Ps = 1 0 4 3  -> Disable raising of the window when Control-\n   *     G is received.  (This disables the popOnBell resource).\n   *     Ps = 1 0 4 7  -> Use Normal Screen Buffer, clearing screen\n   *     first if in the Alternate Screen.  (This may be disabled by\n   *     the titeInhibit resource).\n   *     Ps = 1 0 4 8  -> Restore cursor as in DECRC.  (This may be\n   *     disabled by the titeInhibit resource).\n   *     Ps = 1 0 4 9  -> Use Normal Screen Buffer and restore cursor\n   *     as in DECRC.  (This may be disabled by the titeInhibit\n   *     resource).  This combines the effects of the 1 0 4 7  and 1 0\n   *     4 8  modes.  Use this with terminfo-based applications rather\n   *     than the 4 7  mode.\n   *     Ps = 1 0 5 0  -> Reset terminfo/termcap function-key mode.\n   *     Ps = 1 0 5 1  -> Reset Sun function-key mode.\n   *     Ps = 1 0 5 2  -> Reset HP function-key mode.\n   *     Ps = 1 0 5 3  -> Reset SCO function-key mode.\n   *     Ps = 1 0 6 0  -> Reset legacy keyboard emulation (X11R6).\n   *     Ps = 1 0 6 1  -> Reset keyboard emulation to Sun/PC style.\n   *     Ps = 2 0 0 4  -> Reset bracketed paste mode.\n   */\n  public resetMode(params: number[], collect?: string): void {\n    if (params.length > 1) {\n      for (let i = 0; i < params.length; i++) {\n        this.resetMode([params[i]]);\n      }\n\n      return;\n    }\n\n    if (!collect) {\n      switch (params[0]) {\n        case 4:\n          this._terminal.insertMode = false;\n          break;\n        case 20:\n          // this._t.convertEol = false;\n          break;\n      }\n    } else if (collect === '?') {\n      switch (params[0]) {\n        case 1:\n          this._terminal.applicationCursor = false;\n          break;\n        case 3:\n          if (this._terminal.cols === 132 && this._terminal.savedCols) {\n            this._terminal.resize(this._terminal.savedCols, this._terminal.rows);\n          }\n          delete this._terminal.savedCols;\n          break;\n        case 6:\n          this._terminal.originMode = false;\n          break;\n        case 7:\n          this._terminal.wraparoundMode = false;\n          break;\n        case 12:\n          // this.cursorBlink = false;\n          break;\n        case 66:\n          this._terminal.log('Switching back to normal keypad.');\n          this._terminal.applicationKeypad = false;\n          if (this._terminal.viewport) {\n            this._terminal.viewport.syncScrollArea();\n          }\n          break;\n        case 9: // X10 Mouse\n        case 1000: // vt200 mouse\n        case 1002: // button event mouse\n        case 1003: // any event mouse\n          this._terminal.x10Mouse = false;\n          this._terminal.vt200Mouse = false;\n          this._terminal.normalMouse = false;\n          this._terminal.mouseEvents = false;\n          if (this._terminal.element) {\n            this._terminal.element.classList.remove('enable-mouse-events');\n          }\n          if (this._terminal.selectionManager) {\n            this._terminal.selectionManager.enable();\n          }\n          break;\n        case 1004: // send focusin/focusout events\n          this._terminal.sendFocus = false;\n          break;\n        case 1005: // utf8 ext mode mouse\n          this._terminal.utfMouse = false;\n          break;\n        case 1006: // sgr ext mode mouse\n          this._terminal.sgrMouse = false;\n          break;\n        case 1015: // urxvt ext mode mouse\n          this._terminal.urxvtMouse = false;\n          break;\n        case 25: // hide cursor\n          this._terminal.cursorHidden = true;\n          break;\n        case 1048: // alt screen cursor\n          this.restoreCursor(params);\n          break;\n        case 1049: // alt screen buffer cursor\n           // FALL-THROUGH\n        case 47: // normal screen buffer\n        case 1047: // normal screen buffer - clearing it first\n          // Ensure the selection manager has the correct buffer\n          this._terminal.buffers.activateNormalBuffer();\n          if (params[0] === 1049) {\n            this.restoreCursor(params);\n          }\n          this._terminal.refresh(0, this._terminal.rows - 1);\n          if (this._terminal.viewport) {\n            this._terminal.viewport.syncScrollArea();\n          }\n          this._terminal.showCursor();\n          break;\n        case 2004: // bracketed paste mode (https://cirw.in/blog/bracketed-paste)\n          this._terminal.bracketedPasteMode = false;\n          break;\n      }\n    }\n  }\n\n  /**\n   * CSI Pm m  Character Attributes (SGR).\n   *     Ps = 0  -> Normal (default).\n   *     Ps = 1  -> Bold.\n   *     Ps = 2  -> Faint, decreased intensity (ISO 6429).\n   *     Ps = 4  -> Underlined.\n   *     Ps = 5  -> Blink (appears as Bold).\n   *     Ps = 7  -> Inverse.\n   *     Ps = 8  -> Invisible, i.e., hidden (VT300).\n   *     Ps = 2 2  -> Normal (neither bold nor faint).\n   *     Ps = 2 4  -> Not underlined.\n   *     Ps = 2 5  -> Steady (not blinking).\n   *     Ps = 2 7  -> Positive (not inverse).\n   *     Ps = 2 8  -> Visible, i.e., not hidden (VT300).\n   *     Ps = 3 0  -> Set foreground color to Black.\n   *     Ps = 3 1  -> Set foreground color to Red.\n   *     Ps = 3 2  -> Set foreground color to Green.\n   *     Ps = 3 3  -> Set foreground color to Yellow.\n   *     Ps = 3 4  -> Set foreground color to Blue.\n   *     Ps = 3 5  -> Set foreground color to Magenta.\n   *     Ps = 3 6  -> Set foreground color to Cyan.\n   *     Ps = 3 7  -> Set foreground color to White.\n   *     Ps = 3 9  -> Set foreground color to default (original).\n   *     Ps = 4 0  -> Set background color to Black.\n   *     Ps = 4 1  -> Set background color to Red.\n   *     Ps = 4 2  -> Set background color to Green.\n   *     Ps = 4 3  -> Set background color to Yellow.\n   *     Ps = 4 4  -> Set background color to Blue.\n   *     Ps = 4 5  -> Set background color to Magenta.\n   *     Ps = 4 6  -> Set background color to Cyan.\n   *     Ps = 4 7  -> Set background color to White.\n   *     Ps = 4 9  -> Set background color to default (original).\n   *\n   *   If 16-color support is compiled, the following apply.  Assume\n   *   that xterm's resources are set so that the ISO color codes are\n   *   the first 8 of a set of 16.  Then the aixterm colors are the\n   *   bright versions of the ISO colors:\n   *     Ps = 9 0  -> Set foreground color to Black.\n   *     Ps = 9 1  -> Set foreground color to Red.\n   *     Ps = 9 2  -> Set foreground color to Green.\n   *     Ps = 9 3  -> Set foreground color to Yellow.\n   *     Ps = 9 4  -> Set foreground color to Blue.\n   *     Ps = 9 5  -> Set foreground color to Magenta.\n   *     Ps = 9 6  -> Set foreground color to Cyan.\n   *     Ps = 9 7  -> Set foreground color to White.\n   *     Ps = 1 0 0  -> Set background color to Black.\n   *     Ps = 1 0 1  -> Set background color to Red.\n   *     Ps = 1 0 2  -> Set background color to Green.\n   *     Ps = 1 0 3  -> Set background color to Yellow.\n   *     Ps = 1 0 4  -> Set background color to Blue.\n   *     Ps = 1 0 5  -> Set background color to Magenta.\n   *     Ps = 1 0 6  -> Set background color to Cyan.\n   *     Ps = 1 0 7  -> Set background color to White.\n   *\n   *   If xterm is compiled with the 16-color support disabled, it\n   *   supports the following, from rxvt:\n   *     Ps = 1 0 0  -> Set foreground and background color to\n   *     default.\n   *\n   *   If 88- or 256-color support is compiled, the following apply.\n   *     Ps = 3 8  ; 5  ; Ps -> Set foreground color to the second\n   *     Ps.\n   *     Ps = 4 8  ; 5  ; Ps -> Set background color to the second\n   *     Ps.\n   */\n  public charAttributes(params: number[]): void {\n    // Optimize a single SGR0.\n    if (params.length === 1 && params[0] === 0) {\n      this._terminal.curAttrData.fg = DEFAULT_ATTR_DATA.fg;\n      this._terminal.curAttrData.bg = DEFAULT_ATTR_DATA.bg;\n      return;\n    }\n\n    const l = params.length;\n    let p;\n    const attr = this._terminal.curAttrData;\n\n    for (let i = 0; i < l; i++) {\n      p = params[i];\n      if (p >= 30 && p <= 37) {\n        // fg color 8\n        attr.fg &= ~(Attributes.CM_MASK | Attributes.PCOLOR_MASK);\n        attr.fg |= Attributes.CM_P16 | (p - 30);\n      } else if (p >= 40 && p <= 47) {\n        // bg color 8\n        attr.bg &= ~(Attributes.CM_MASK | Attributes.PCOLOR_MASK);\n        attr.bg |= Attributes.CM_P16 | (p - 40);\n      } else if (p >= 90 && p <= 97) {\n        // fg color 16\n        attr.fg &= ~(Attributes.CM_MASK | Attributes.PCOLOR_MASK);\n        attr.fg |= Attributes.CM_P16 | (p - 90) | 8;\n      } else if (p >= 100 && p <= 107) {\n        // bg color 16\n        attr.bg &= ~(Attributes.CM_MASK | Attributes.PCOLOR_MASK);\n        attr.bg |= Attributes.CM_P16 | (p - 100) | 8;\n      } else if (p === 0) {\n        // default\n        attr.fg = DEFAULT_ATTR_DATA.fg;\n        attr.bg = DEFAULT_ATTR_DATA.bg;\n      } else if (p === 1) {\n        // bold text\n        attr.fg |= FgFlags.BOLD;\n      } else if (p === 3) {\n        // italic text\n        attr.bg |= BgFlags.ITALIC;\n      } else if (p === 4) {\n        // underlined text\n        attr.fg |= FgFlags.UNDERLINE;\n      } else if (p === 5) {\n        // blink\n        attr.fg |= FgFlags.BLINK;\n      } else if (p === 7) {\n        // inverse and positive\n        // test with: echo -e '\\e[31m\\e[42mhello\\e[7mworld\\e[27mhi\\e[m'\n        attr.fg |= FgFlags.INVERSE;\n      } else if (p === 8) {\n        // invisible\n        attr.fg |= FgFlags.INVISIBLE;\n      } else if (p === 2) {\n        // dimmed text\n        attr.bg |= BgFlags.DIM;\n      } else if (p === 22) {\n        // not bold nor faint\n        attr.fg &= ~FgFlags.BOLD;\n        attr.bg &= ~BgFlags.DIM;\n      } else if (p === 23) {\n        // not italic\n        attr.bg &= ~BgFlags.ITALIC;\n      } else if (p === 24) {\n        // not underlined\n        attr.fg &= ~FgFlags.UNDERLINE;\n      } else if (p === 25) {\n        // not blink\n        attr.fg &= ~FgFlags.BLINK;\n      } else if (p === 27) {\n        // not inverse\n        attr.fg &= ~FgFlags.INVERSE;\n      } else if (p === 28) {\n        // not invisible\n        attr.fg &= ~FgFlags.INVISIBLE;\n      } else if (p === 39) {\n        // reset fg\n        attr.fg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n        attr.fg |= DEFAULT_ATTR_DATA.fg & (Attributes.PCOLOR_MASK | Attributes.RGB_MASK);\n      } else if (p === 49) {\n        // reset bg\n        attr.bg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n        attr.bg |= DEFAULT_ATTR_DATA.bg & (Attributes.PCOLOR_MASK | Attributes.RGB_MASK);\n      } else if (p === 38) {\n        // fg color 256\n        if (params[i + 1] === 2) {\n          i += 2;\n          attr.fg |= Attributes.CM_RGB;\n          attr.fg &= ~Attributes.RGB_MASK;\n          attr.fg |= AttributeData.fromColorRGB([params[i], params[i + 1], params[i + 2]]);\n          i += 2;\n        } else if (params[i + 1] === 5) {\n          i += 2;\n          p = params[i] & 0xff;\n          attr.fg &= ~Attributes.PCOLOR_MASK;\n          attr.fg |= Attributes.CM_P256 | p;\n        }\n      } else if (p === 48) {\n        // bg color 256\n        if (params[i + 1] === 2) {\n          i += 2;\n          attr.bg |= Attributes.CM_RGB;\n          attr.bg &= ~Attributes.RGB_MASK;\n          attr.bg |= AttributeData.fromColorRGB([params[i], params[i + 1], params[i + 2]]);\n          i += 2;\n        } else if (params[i + 1] === 5) {\n          i += 2;\n          p = params[i] & 0xff;\n          attr.bg &= ~Attributes.PCOLOR_MASK;\n          attr.bg |= Attributes.CM_P256 | p;\n        }\n      } else if (p === 100) {\n        // reset fg/bg\n        attr.fg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n        attr.fg |= DEFAULT_ATTR_DATA.fg & (Attributes.PCOLOR_MASK | Attributes.RGB_MASK);\n        attr.bg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);\n        attr.bg |= DEFAULT_ATTR_DATA.bg & (Attributes.PCOLOR_MASK | Attributes.RGB_MASK);\n      } else {\n        this._terminal.error('Unknown SGR attribute: %d.', p);\n      }\n    }\n  }\n\n  /**\n   * CSI Ps n  Device Status Report (DSR).\n   *     Ps = 5  -> Status Report.  Result (``OK'') is\n   *   CSI 0 n\n   *     Ps = 6  -> Report Cursor Position (CPR) [row;column].\n   *   Result is\n   *   CSI r ; c R\n   * CSI ? Ps n\n   *   Device Status Report (DSR, DEC-specific).\n   *     Ps = 6  -> Report Cursor Position (CPR) [row;column] as CSI\n   *     ? r ; c R (assumes page is zero).\n   *     Ps = 1 5  -> Report Printer status as CSI ? 1 0  n  (ready).\n   *     or CSI ? 1 1  n  (not ready).\n   *     Ps = 2 5  -> Report UDK status as CSI ? 2 0  n  (unlocked)\n   *     or CSI ? 2 1  n  (locked).\n   *     Ps = 2 6  -> Report Keyboard status as\n   *   CSI ? 2 7  ;  1  ;  0  ;  0  n  (North American).\n   *   The last two parameters apply to VT400 & up, and denote key-\n   *   board ready and LK01 respectively.\n   *     Ps = 5 3  -> Report Locator status as\n   *   CSI ? 5 3  n  Locator available, if compiled-in, or\n   *   CSI ? 5 0  n  No Locator, if not.\n   */\n  public deviceStatus(params: number[], collect?: string): void {\n    if (!collect) {\n      switch (params[0]) {\n        case 5:\n          // status report\n          this._onData.fire(`${C0.ESC}[0n`);\n          break;\n        case 6:\n          // cursor position\n          const y = this._terminal.buffer.y + 1;\n          const x = this._terminal.buffer.x + 1;\n          this._onData.fire(`${C0.ESC}[${y};${x}R`);\n          break;\n      }\n    } else if (collect === '?') {\n      // modern xterm doesnt seem to\n      // respond to any of these except ?6, 6, and 5\n      switch (params[0]) {\n        case 6:\n          // cursor position\n          const y = this._terminal.buffer.y + 1;\n          const x = this._terminal.buffer.x + 1;\n          this._onData.fire(`${C0.ESC}[?${y};${x}R`);\n          break;\n        case 15:\n          // no printer\n          // this.handler(C0.ESC + '[?11n');\n          break;\n        case 25:\n          // dont support user defined keys\n          // this.handler(C0.ESC + '[?21n');\n          break;\n        case 26:\n          // north american keyboard\n          // this.handler(C0.ESC + '[?27;1;0;0n');\n          break;\n        case 53:\n          // no dec locator/mouse\n          // this.handler(C0.ESC + '[?50n');\n          break;\n      }\n    }\n  }\n\n  /**\n   * CSI ! p   Soft terminal reset (DECSTR).\n   * http://vt100.net/docs/vt220-rm/table4-10.html\n   */\n  public softReset(params: number[], collect?: string): void {\n    if (collect === '!') {\n      this._terminal.cursorHidden = false;\n      this._terminal.insertMode = false;\n      this._terminal.originMode = false;\n      this._terminal.wraparoundMode = true;  // defaults: xterm - true, vt100 - false\n      this._terminal.applicationKeypad = false; // ?\n      if (this._terminal.viewport) {\n        this._terminal.viewport.syncScrollArea();\n      }\n      this._terminal.applicationCursor = false;\n      this._terminal.buffer.scrollTop = 0;\n      this._terminal.buffer.scrollBottom = this._terminal.rows - 1;\n      this._terminal.curAttrData = DEFAULT_ATTR_DATA;\n      this._terminal.buffer.x = this._terminal.buffer.y = 0; // ?\n      this._terminal.charset = null;\n      this._terminal.glevel = 0; // ??\n      this._terminal.charsets = [null]; // ??\n    }\n  }\n\n  /**\n   * CSI Ps SP q  Set cursor style (DECSCUSR, VT520).\n   *   Ps = 0  -> blinking block.\n   *   Ps = 1  -> blinking block (default).\n   *   Ps = 2  -> steady block.\n   *   Ps = 3  -> blinking underline.\n   *   Ps = 4  -> steady underline.\n   *   Ps = 5  -> blinking bar (xterm).\n   *   Ps = 6  -> steady bar (xterm).\n   */\n  public setCursorStyle(params?: number[], collect?: string): void {\n    if (collect === ' ') {\n      const param = params[0] < 1 ? 1 : params[0];\n      switch (param) {\n        case 1:\n        case 2:\n          this._terminal.setOption('cursorStyle', 'block');\n          break;\n        case 3:\n        case 4:\n          this._terminal.setOption('cursorStyle', 'underline');\n          break;\n        case 5:\n        case 6:\n          this._terminal.setOption('cursorStyle', 'bar');\n          break;\n      }\n      const isBlinking = param % 2 === 1;\n      this._terminal.setOption('cursorBlink', isBlinking);\n    }\n  }\n\n  /**\n   * CSI Ps ; Ps r\n   *   Set Scrolling Region [top;bottom] (default = full size of win-\n   *   dow) (DECSTBM).\n   * CSI ? Pm r\n   */\n  public setScrollRegion(params: number[], collect?: string): void {\n    if (collect) {\n      return;\n    }\n    this._terminal.buffer.scrollTop = (params[0] || 1) - 1;\n    this._terminal.buffer.scrollBottom = (params[1] && params[1] <= this._terminal.rows ? params[1] : this._terminal.rows) - 1;\n    this._terminal.buffer.x = 0;\n    this._terminal.buffer.y = 0;\n  }\n\n\n  /**\n   * CSI s\n   * ESC 7\n   *   Save cursor (ANSI.SYS).\n   */\n  public saveCursor(params: number[]): void {\n    this._terminal.buffer.savedX = this._terminal.buffer.x;\n    this._terminal.buffer.savedY = this._terminal.buffer.y;\n    this._terminal.buffer.savedCurAttrData.fg = this._terminal.curAttrData.fg;\n    this._terminal.buffer.savedCurAttrData.bg = this._terminal.curAttrData.bg;\n  }\n\n\n  /**\n   * CSI u\n   * ESC 8\n   *   Restore cursor (ANSI.SYS).\n   */\n  public restoreCursor(params: number[]): void {\n    this._terminal.buffer.x = this._terminal.buffer.savedX || 0;\n    this._terminal.buffer.y = this._terminal.buffer.savedY || 0;\n    this._terminal.curAttrData.fg = this._terminal.buffer.savedCurAttrData.fg;\n    this._terminal.curAttrData.bg = this._terminal.buffer.savedCurAttrData.bg;\n  }\n\n\n  /**\n   * OSC 0; <data> ST (set icon name + window title)\n   * OSC 2; <data> ST (set window title)\n   *   Proxy to set window title. Icon name is not supported.\n   */\n  public setTitle(data: string): void {\n    this._terminal.handleTitle(data);\n  }\n\n  /**\n   * ESC E\n   * C1.NEL\n   *   DEC mnemonic: NEL (https://vt100.net/docs/vt510-rm/NEL)\n   *   Moves cursor to first position on next line.\n   */\n  public nextLine(): void {\n    this._terminal.buffer.x = 0;\n    this.index();\n  }\n\n  /**\n   * ESC =\n   *   DEC mnemonic: DECKPAM (https://vt100.net/docs/vt510-rm/DECKPAM.html)\n   *   Enables the numeric keypad to send application sequences to the host.\n   */\n  public keypadApplicationMode(): void {\n    this._terminal.log('Serial port requested application keypad.');\n    this._terminal.applicationKeypad = true;\n    if (this._terminal.viewport) {\n      this._terminal.viewport.syncScrollArea();\n    }\n  }\n\n  /**\n   * ESC >\n   *   DEC mnemonic: DECKPNM (https://vt100.net/docs/vt510-rm/DECKPNM.html)\n   *   Enables the keypad to send numeric characters to the host.\n   */\n  public keypadNumericMode(): void {\n    this._terminal.log('Switching back to normal keypad.');\n    this._terminal.applicationKeypad = false;\n    if (this._terminal.viewport) {\n      this._terminal.viewport.syncScrollArea();\n    }\n  }\n\n  /**\n   * ESC % @\n   * ESC % G\n   *   Select default character set. UTF-8 is not supported (string are unicode anyways)\n   *   therefore ESC % G does the same.\n   */\n  public selectDefaultCharset(): void {\n    this._terminal.setgLevel(0);\n    this._terminal.setgCharset(0, DEFAULT_CHARSET); // US (default)\n  }\n\n  /**\n   * ESC ( C\n   *   Designate G0 Character Set, VT100, ISO 2022.\n   * ESC ) C\n   *   Designate G1 Character Set (ISO 2022, VT100).\n   * ESC * C\n   *   Designate G2 Character Set (ISO 2022, VT220).\n   * ESC + C\n   *   Designate G3 Character Set (ISO 2022, VT220).\n   * ESC - C\n   *   Designate G1 Character Set (VT300).\n   * ESC . C\n   *   Designate G2 Character Set (VT300).\n   * ESC / C\n   *   Designate G3 Character Set (VT300). C = A  -> ISO Latin-1 Supplemental. - Supported?\n   */\n  public selectCharset(collectAndFlag: string): void {\n    if (collectAndFlag.length !== 2) {\n      this.selectDefaultCharset();\n      return;\n    }\n    if (collectAndFlag[0] === '/') {\n      return;  // TODO: Is this supported?\n    }\n    this._terminal.setgCharset(GLEVEL[collectAndFlag[0]], CHARSETS[collectAndFlag[1]] || DEFAULT_CHARSET);\n    return;\n  }\n\n  /**\n   * ESC D\n   * C1.IND\n   *   DEC mnemonic: IND (https://vt100.net/docs/vt510-rm/IND.html)\n   *   Moves the cursor down one line in the same column.\n   */\n  public index(): void {\n    this._terminal.index();  // TODO: save to move from terminal?\n  }\n\n  /**\n   * ESC H\n   * C1.HTS\n   *   DEC mnemonic: HTS (https://vt100.net/docs/vt510-rm/HTS.html)\n   *   Sets a horizontal tab stop at the column position indicated by\n   *   the value of the active column when the terminal receives an HTS.\n   */\n  public tabSet(): void {\n    this._terminal.tabSet();  // TODO: save to move from terminal?\n  }\n\n  /**\n   * ESC M\n   * C1.RI\n   *   DEC mnemonic: HTS\n   *   Moves the cursor up one line in the same column. If the cursor is at the top margin,\n   *   the page scrolls down.\n   */\n  public reverseIndex(): void {\n    this._terminal.reverseIndex();  // TODO: save to move from terminal?\n  }\n\n  /**\n   * ESC c\n   *   DEC mnemonic: RIS (https://vt100.net/docs/vt510-rm/RIS.html)\n   *   Reset to initial state.\n   */\n  public reset(): void {\n    this._parser.reset();\n    this._terminal.reset();  // TODO: save to move from terminal?\n  }\n\n  /**\n   * ESC n\n   * ESC o\n   * ESC |\n   * ESC }\n   * ESC ~\n   *   DEC mnemonic: LS (https://vt100.net/docs/vt510-rm/LS.html)\n   *   When you use a locking shift, the character set remains in GL or GR until\n   *   you use another locking shift. (partly supported)\n   */\n  public setgLevel(level: number): void {\n    this._terminal.setgLevel(level);  // TODO: save to move from terminal?\n  }\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ParserState, ParserAction, IParsingState, IDcsHandler, IEscapeSequenceParser } from './Types';\nimport { IDisposable } from 'xterm';\nimport { Disposable } from './common/Lifecycle';\nimport { utf32ToString } from './core/input/TextDecoder';\n\ninterface IHandlerCollection<T> {\n  [key: string]: T[];\n}\n\ntype CsiHandler = (params: number[], collect: string) => boolean | void;\ntype OscHandler = (data: string) => boolean | void;\n\n/**\n * Returns an array filled with numbers between the low and high parameters (right exclusive).\n * @param low The low number.\n * @param high The high number.\n */\nfunction r(low: number, high: number): number[] {\n  let c = high - low;\n  const arr = new Array(c);\n  while (c--) {\n    arr[c] = --high;\n  }\n  return arr;\n}\n\n/**\n * Transition table for EscapeSequenceParser.\n * NOTE: data in the underlying table is packed like this:\n *   currentState << 8 | characterCode  -->  action << 4 | nextState\n */\nexport class TransitionTable {\n  public table: Uint8Array | number[];\n\n  constructor(length: number) {\n    this.table = (typeof Uint8Array === 'undefined')\n      ? new Array(length)\n      : new Uint8Array(length);\n  }\n\n  /**\n   * Add a transition to the transition table.\n   * @param code input character code\n   * @param state current parser state\n   * @param action parser action to be done\n   * @param next next parser state\n   */\n  add(code: number, state: number, action: number | null, next: number | null): void {\n    this.table[state << 8 | code] = ((action | 0) << 4) | ((next === undefined) ? state : next);\n  }\n\n  /**\n   * Add transitions for multiple input character codes.\n   * @param codes input character code array\n   * @param state current parser state\n   * @param action parser action to be done\n   * @param next next parser state\n   */\n  addMany(codes: number[], state: number, action: number | null, next: number | null): void {\n    for (let i = 0; i < codes.length; i++) {\n      this.add(codes[i], state, action, next);\n    }\n  }\n}\n\n\n/**\n * Default definitions for the VT500_TRANSITION_TABLE.\n */\nconst PRINTABLES = r(0x20, 0x7f);\nconst EXECUTABLES = r(0x00, 0x18);\nEXECUTABLES.push(0x19);\nEXECUTABLES.push.apply(EXECUTABLES, r(0x1c, 0x20));\n// Pseudo-character placeholder for printable non-ascii characters.\nconst NON_ASCII_PRINTABLE = 0xA0;\n\n/**\n * VT500 compatible transition table.\n * Taken from https://vt100.net/emu/dec_ansi_parser.\n */\nexport const VT500_TRANSITION_TABLE = (function (): TransitionTable {\n  const table: TransitionTable = new TransitionTable(4095);\n\n  const states: number[] = r(ParserState.GROUND, ParserState.DCS_PASSTHROUGH + 1);\n  let state: any;\n\n  // table with default transition\n  for (state in states) {\n    // NOTE: table lookup is capped at 0xa0 in parse to keep the table small\n    for (let code = 0; code <= NON_ASCII_PRINTABLE; ++code) {\n      table.add(code, state, ParserAction.ERROR, ParserState.GROUND);\n    }\n  }\n  // printables\n  table.addMany(PRINTABLES, ParserState.GROUND, ParserAction.PRINT, ParserState.GROUND);\n  // global anywhere rules\n  for (state in states) {\n    table.addMany([0x18, 0x1a, 0x99, 0x9a], state, ParserAction.EXECUTE, ParserState.GROUND);\n    table.addMany(r(0x80, 0x90), state, ParserAction.EXECUTE, ParserState.GROUND);\n    table.addMany(r(0x90, 0x98), state, ParserAction.EXECUTE, ParserState.GROUND);\n    table.add(0x9c, state, ParserAction.IGNORE, ParserState.GROUND); // ST as terminator\n    table.add(0x1b, state, ParserAction.CLEAR, ParserState.ESCAPE);  // ESC\n    table.add(0x9d, state, ParserAction.OSC_START, ParserState.OSC_STRING);  // OSC\n    table.addMany([0x98, 0x9e, 0x9f], state, ParserAction.IGNORE, ParserState.SOS_PM_APC_STRING);\n    table.add(0x9b, state, ParserAction.CLEAR, ParserState.CSI_ENTRY);  // CSI\n    table.add(0x90, state, ParserAction.CLEAR, ParserState.DCS_ENTRY);  // DCS\n  }\n  // rules for executables and 7f\n  table.addMany(EXECUTABLES, ParserState.GROUND, ParserAction.EXECUTE, ParserState.GROUND);\n  table.addMany(EXECUTABLES, ParserState.ESCAPE, ParserAction.EXECUTE, ParserState.ESCAPE);\n  table.add(0x7f, ParserState.ESCAPE, ParserAction.IGNORE, ParserState.ESCAPE);\n  table.addMany(EXECUTABLES, ParserState.OSC_STRING, ParserAction.IGNORE, ParserState.OSC_STRING);\n  table.addMany(EXECUTABLES, ParserState.CSI_ENTRY, ParserAction.EXECUTE, ParserState.CSI_ENTRY);\n  table.add(0x7f, ParserState.CSI_ENTRY, ParserAction.IGNORE, ParserState.CSI_ENTRY);\n  table.addMany(EXECUTABLES, ParserState.CSI_PARAM, ParserAction.EXECUTE, ParserState.CSI_PARAM);\n  table.add(0x7f, ParserState.CSI_PARAM, ParserAction.IGNORE, ParserState.CSI_PARAM);\n  table.addMany(EXECUTABLES, ParserState.CSI_IGNORE, ParserAction.EXECUTE, ParserState.CSI_IGNORE);\n  table.addMany(EXECUTABLES, ParserState.CSI_INTERMEDIATE, ParserAction.EXECUTE, ParserState.CSI_INTERMEDIATE);\n  table.add(0x7f, ParserState.CSI_INTERMEDIATE, ParserAction.IGNORE, ParserState.CSI_INTERMEDIATE);\n  table.addMany(EXECUTABLES, ParserState.ESCAPE_INTERMEDIATE, ParserAction.EXECUTE, ParserState.ESCAPE_INTERMEDIATE);\n  table.add(0x7f, ParserState.ESCAPE_INTERMEDIATE, ParserAction.IGNORE, ParserState.ESCAPE_INTERMEDIATE);\n  // osc\n  table.add(0x5d, ParserState.ESCAPE, ParserAction.OSC_START, ParserState.OSC_STRING);\n  table.addMany(PRINTABLES, ParserState.OSC_STRING, ParserAction.OSC_PUT, ParserState.OSC_STRING);\n  table.add(0x7f, ParserState.OSC_STRING, ParserAction.OSC_PUT, ParserState.OSC_STRING);\n  table.addMany([0x9c, 0x1b, 0x18, 0x1a, 0x07], ParserState.OSC_STRING, ParserAction.OSC_END, ParserState.GROUND);\n  table.addMany(r(0x1c, 0x20), ParserState.OSC_STRING, ParserAction.IGNORE, ParserState.OSC_STRING);\n  // sos/pm/apc does nothing\n  table.addMany([0x58, 0x5e, 0x5f], ParserState.ESCAPE, ParserAction.IGNORE, ParserState.SOS_PM_APC_STRING);\n  table.addMany(PRINTABLES, ParserState.SOS_PM_APC_STRING, ParserAction.IGNORE, ParserState.SOS_PM_APC_STRING);\n  table.addMany(EXECUTABLES, ParserState.SOS_PM_APC_STRING, ParserAction.IGNORE, ParserState.SOS_PM_APC_STRING);\n  table.add(0x9c, ParserState.SOS_PM_APC_STRING, ParserAction.IGNORE, ParserState.GROUND);\n  table.add(0x7f, ParserState.SOS_PM_APC_STRING, ParserAction.IGNORE, ParserState.SOS_PM_APC_STRING);\n  // csi entries\n  table.add(0x5b, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.CSI_ENTRY);\n  table.addMany(r(0x40, 0x7f), ParserState.CSI_ENTRY, ParserAction.CSI_DISPATCH, ParserState.GROUND);\n  table.addMany(r(0x30, 0x3a), ParserState.CSI_ENTRY, ParserAction.PARAM, ParserState.CSI_PARAM);\n  table.add(0x3b, ParserState.CSI_ENTRY, ParserAction.PARAM, ParserState.CSI_PARAM);\n  table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.CSI_ENTRY, ParserAction.COLLECT, ParserState.CSI_PARAM);\n  table.addMany(r(0x30, 0x3a), ParserState.CSI_PARAM, ParserAction.PARAM, ParserState.CSI_PARAM);\n  table.add(0x3b, ParserState.CSI_PARAM, ParserAction.PARAM, ParserState.CSI_PARAM);\n  table.addMany(r(0x40, 0x7f), ParserState.CSI_PARAM, ParserAction.CSI_DISPATCH, ParserState.GROUND);\n  table.addMany([0x3a, 0x3c, 0x3d, 0x3e, 0x3f], ParserState.CSI_PARAM, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n  table.addMany(r(0x20, 0x40), ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n  table.add(0x7f, ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n  table.addMany(r(0x40, 0x7f), ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.GROUND);\n  table.add(0x3a, ParserState.CSI_ENTRY, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n  table.addMany(r(0x20, 0x30), ParserState.CSI_ENTRY, ParserAction.COLLECT, ParserState.CSI_INTERMEDIATE);\n  table.addMany(r(0x20, 0x30), ParserState.CSI_INTERMEDIATE, ParserAction.COLLECT, ParserState.CSI_INTERMEDIATE);\n  table.addMany(r(0x30, 0x40), ParserState.CSI_INTERMEDIATE, ParserAction.IGNORE, ParserState.CSI_IGNORE);\n  table.addMany(r(0x40, 0x7f), ParserState.CSI_INTERMEDIATE, ParserAction.CSI_DISPATCH, ParserState.GROUND);\n  table.addMany(r(0x20, 0x30), ParserState.CSI_PARAM, ParserAction.COLLECT, ParserState.CSI_INTERMEDIATE);\n  // esc_intermediate\n  table.addMany(r(0x20, 0x30), ParserState.ESCAPE, ParserAction.COLLECT, ParserState.ESCAPE_INTERMEDIATE);\n  table.addMany(r(0x20, 0x30), ParserState.ESCAPE_INTERMEDIATE, ParserAction.COLLECT, ParserState.ESCAPE_INTERMEDIATE);\n  table.addMany(r(0x30, 0x7f), ParserState.ESCAPE_INTERMEDIATE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n  table.addMany(r(0x30, 0x50), ParserState.ESCAPE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n  table.addMany(r(0x51, 0x58), ParserState.ESCAPE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n  table.addMany([0x59, 0x5a, 0x5c], ParserState.ESCAPE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n  table.addMany(r(0x60, 0x7f), ParserState.ESCAPE, ParserAction.ESC_DISPATCH, ParserState.GROUND);\n  // dcs entry\n  table.add(0x50, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.DCS_ENTRY);\n  table.addMany(EXECUTABLES, ParserState.DCS_ENTRY, ParserAction.IGNORE, ParserState.DCS_ENTRY);\n  table.add(0x7f, ParserState.DCS_ENTRY, ParserAction.IGNORE, ParserState.DCS_ENTRY);\n  table.addMany(r(0x1c, 0x20), ParserState.DCS_ENTRY, ParserAction.IGNORE, ParserState.DCS_ENTRY);\n  table.addMany(r(0x20, 0x30), ParserState.DCS_ENTRY, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);\n  table.add(0x3a, ParserState.DCS_ENTRY, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n  table.addMany(r(0x30, 0x3a), ParserState.DCS_ENTRY, ParserAction.PARAM, ParserState.DCS_PARAM);\n  table.add(0x3b, ParserState.DCS_ENTRY, ParserAction.PARAM, ParserState.DCS_PARAM);\n  table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.DCS_ENTRY, ParserAction.COLLECT, ParserState.DCS_PARAM);\n  table.addMany(EXECUTABLES, ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n  table.addMany(r(0x20, 0x80), ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n  table.addMany(r(0x1c, 0x20), ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n  table.addMany(EXECUTABLES, ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_PARAM);\n  table.add(0x7f, ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_PARAM);\n  table.addMany(r(0x1c, 0x20), ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_PARAM);\n  table.addMany(r(0x30, 0x3a), ParserState.DCS_PARAM, ParserAction.PARAM, ParserState.DCS_PARAM);\n  table.add(0x3b, ParserState.DCS_PARAM, ParserAction.PARAM, ParserState.DCS_PARAM);\n  table.addMany([0x3a, 0x3c, 0x3d, 0x3e, 0x3f], ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n  table.addMany(r(0x20, 0x30), ParserState.DCS_PARAM, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);\n  table.addMany(EXECUTABLES, ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_INTERMEDIATE);\n  table.add(0x7f, ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_INTERMEDIATE);\n  table.addMany(r(0x1c, 0x20), ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_INTERMEDIATE);\n  table.addMany(r(0x20, 0x30), ParserState.DCS_INTERMEDIATE, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);\n  table.addMany(r(0x30, 0x40), ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_IGNORE);\n  table.addMany(r(0x40, 0x7f), ParserState.DCS_INTERMEDIATE, ParserAction.DCS_HOOK, ParserState.DCS_PASSTHROUGH);\n  table.addMany(r(0x40, 0x7f), ParserState.DCS_PARAM, ParserAction.DCS_HOOK, ParserState.DCS_PASSTHROUGH);\n  table.addMany(r(0x40, 0x7f), ParserState.DCS_ENTRY, ParserAction.DCS_HOOK, ParserState.DCS_PASSTHROUGH);\n  table.addMany(EXECUTABLES, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);\n  table.addMany(PRINTABLES, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);\n  table.add(0x7f, ParserState.DCS_PASSTHROUGH, ParserAction.IGNORE, ParserState.DCS_PASSTHROUGH);\n  table.addMany([0x1b, 0x9c], ParserState.DCS_PASSTHROUGH, ParserAction.DCS_UNHOOK, ParserState.GROUND);\n  table.add(NON_ASCII_PRINTABLE, ParserState.OSC_STRING, ParserAction.OSC_PUT, ParserState.OSC_STRING);\n  return table;\n})();\n\n/**\n * Dummy DCS handler as default fallback.\n */\nclass DcsDummy implements IDcsHandler {\n  hook(collect: string, params: number[], flag: number): void { }\n  put(data: Uint32Array, start: number, end: number): void { }\n  unhook(): void { }\n}\n\n/**\n * EscapeSequenceParser.\n * This class implements the ANSI/DEC compatible parser described by\n * Paul Williams (https://vt100.net/emu/dec_ansi_parser).\n * To implement custom ANSI compliant escape sequences it is not needed to\n * alter this parser, instead consider registering a custom handler.\n * For non ANSI compliant sequences change the transition table with\n * the optional `transitions` contructor argument and\n * reimplement the `parse` method.\n * NOTE: The parameter element notation is currently not supported.\n * TODO: implement error recovery hook via error handler return values\n */\nexport class EscapeSequenceParser extends Disposable implements IEscapeSequenceParser {\n  public initialState: number;\n  public currentState: number;\n\n  // buffers over several parse calls\n  protected _osc: string;\n  protected _params: number[];\n  protected _collect: string;\n\n  // handler lookup containers\n  protected _printHandler: (data: Uint32Array, start: number, end: number) => void;\n  protected _executeHandlers: any;\n  protected _csiHandlers: IHandlerCollection<CsiHandler>;\n  protected _escHandlers: any;\n  protected _oscHandlers: IHandlerCollection<OscHandler>;\n  protected _dcsHandlers: any;\n  protected _activeDcsHandler: IDcsHandler | null;\n  protected _errorHandler: (state: IParsingState) => IParsingState;\n\n  // fallback handlers\n  protected _printHandlerFb: (data: Uint32Array, start: number, end: number) => void;\n  protected _executeHandlerFb: (code: number) => void;\n  protected _csiHandlerFb: (collect: string, params: number[], flag: number) => void;\n  protected _escHandlerFb: (collect: string, flag: number) => void;\n  protected _oscHandlerFb: (identifier: number, data: string) => void;\n  protected _dcsHandlerFb: IDcsHandler;\n  protected _errorHandlerFb: (state: IParsingState) => IParsingState;\n\n  constructor(readonly TRANSITIONS: TransitionTable = VT500_TRANSITION_TABLE) {\n    super();\n\n    this.initialState = ParserState.GROUND;\n    this.currentState = this.initialState;\n    this._osc = '';\n    this._params = [0];\n    this._collect = '';\n\n    // set default fallback handlers and handler lookup containers\n    this._printHandlerFb = (data, start, end): void => { };\n    this._executeHandlerFb = (code: number): void => { };\n    this._csiHandlerFb = (collect: string, params: number[], flag: number): void => { };\n    this._escHandlerFb = (collect: string, flag: number): void => { };\n    this._oscHandlerFb = (identifier: number, data: string): void => { };\n    this._dcsHandlerFb = new DcsDummy();\n    this._errorHandlerFb = (state: IParsingState): IParsingState => state;\n    this._printHandler = this._printHandlerFb;\n    this._executeHandlers = Object.create(null);\n    this._csiHandlers = Object.create(null);\n    this._escHandlers = Object.create(null);\n    this._oscHandlers = Object.create(null);\n    this._dcsHandlers = Object.create(null);\n    this._activeDcsHandler = null;\n    this._errorHandler = this._errorHandlerFb;\n\n    // swallow 7bit ST (ESC+\\)\n    this.setEscHandler('\\\\', () => {});\n  }\n\n  public dispose(): void {\n    this._printHandlerFb = null;\n    this._executeHandlerFb = null;\n    this._csiHandlerFb = null;\n    this._escHandlerFb = null;\n    this._oscHandlerFb = null;\n    this._dcsHandlerFb = null;\n    this._errorHandlerFb = null;\n    this._printHandler = null;\n    this._executeHandlers = null;\n    this._escHandlers = null;\n    this._csiHandlers = null;\n    this._oscHandlers = null;\n    this._dcsHandlers = null;\n    this._activeDcsHandler = null;\n    this._errorHandler = null;\n  }\n\n  setPrintHandler(callback: (data: Uint32Array, start: number, end: number) => void): void {\n    this._printHandler = callback;\n  }\n  clearPrintHandler(): void {\n    this._printHandler = this._printHandlerFb;\n  }\n\n  setExecuteHandler(flag: string, callback: () => void): void {\n    this._executeHandlers[flag.charCodeAt(0)] = callback;\n  }\n  clearExecuteHandler(flag: string): void {\n    if (this._executeHandlers[flag.charCodeAt(0)]) delete this._executeHandlers[flag.charCodeAt(0)];\n  }\n  setExecuteHandlerFallback(callback: (code: number) => void): void {\n    this._executeHandlerFb = callback;\n  }\n\n  addCsiHandler(flag: string, callback: CsiHandler): IDisposable {\n    const index = flag.charCodeAt(0);\n    if (this._csiHandlers[index] === undefined) {\n      this._csiHandlers[index] = [];\n    }\n    const handlerList = this._csiHandlers[index];\n    handlerList.push(callback);\n    return {\n      dispose: () => {\n        const handlerIndex = handlerList.indexOf(callback);\n        if (handlerIndex !== -1) {\n          handlerList.splice(handlerIndex, 1);\n        }\n      }\n    };\n  }\n  setCsiHandler(flag: string, callback: (params: number[], collect: string) => void): void {\n    this._csiHandlers[flag.charCodeAt(0)] = [callback];\n  }\n  clearCsiHandler(flag: string): void {\n    if (this._csiHandlers[flag.charCodeAt(0)]) delete this._csiHandlers[flag.charCodeAt(0)];\n  }\n  setCsiHandlerFallback(callback: (collect: string, params: number[], flag: number) => void): void {\n    this._csiHandlerFb = callback;\n  }\n\n  setEscHandler(collectAndFlag: string, callback: () => void): void {\n    this._escHandlers[collectAndFlag] = callback;\n  }\n  clearEscHandler(collectAndFlag: string): void {\n    if (this._escHandlers[collectAndFlag]) delete this._escHandlers[collectAndFlag];\n  }\n  setEscHandlerFallback(callback: (collect: string, flag: number) => void): void {\n    this._escHandlerFb = callback;\n  }\n\n  addOscHandler(ident: number, callback: (data: string) => boolean): IDisposable {\n    if (this._oscHandlers[ident] === undefined) {\n      this._oscHandlers[ident] = [];\n    }\n    const handlerList = this._oscHandlers[ident];\n    handlerList.push(callback);\n    return {\n      dispose: () => {\n        const handlerIndex = handlerList.indexOf(callback);\n        if (handlerIndex !== -1) {\n          handlerList.splice(handlerIndex, 1);\n        }\n      }\n    };\n  }\n  setOscHandler(ident: number, callback: (data: string) => void): void {\n    this._oscHandlers[ident] = [callback];\n  }\n  clearOscHandler(ident: number): void {\n    if (this._oscHandlers[ident]) delete this._oscHandlers[ident];\n  }\n  setOscHandlerFallback(callback: (identifier: number, data: string) => void): void {\n    this._oscHandlerFb = callback;\n  }\n\n  setDcsHandler(collectAndFlag: string, handler: IDcsHandler): void {\n    this._dcsHandlers[collectAndFlag] = handler;\n  }\n  clearDcsHandler(collectAndFlag: string): void {\n    if (this._dcsHandlers[collectAndFlag]) delete this._dcsHandlers[collectAndFlag];\n  }\n  setDcsHandlerFallback(handler: IDcsHandler): void {\n    this._dcsHandlerFb = handler;\n  }\n\n  setErrorHandler(callback: (state: IParsingState) => IParsingState): void {\n    this._errorHandler = callback;\n  }\n  clearErrorHandler(): void {\n    this._errorHandler = this._errorHandlerFb;\n  }\n\n  reset(): void {\n    this.currentState = this.initialState;\n    this._osc = '';\n    this._params = [0];\n    this._collect = '';\n    this._activeDcsHandler = null;\n  }\n\n  parse(data: Uint32Array, length: number): void {\n    let code = 0;\n    let transition = 0;\n    let error = false;\n    let currentState = this.currentState;\n    let print = -1;\n    let dcs = -1;\n    let osc = this._osc;\n    let collect = this._collect;\n    let params = this._params;\n    const table: Uint8Array | number[] = this.TRANSITIONS.table;\n    let dcsHandler: IDcsHandler | null = this._activeDcsHandler;\n    let callback: Function | null = null;\n\n    // process input string\n    for (let i = 0; i < length; ++i) {\n      code = data[i];\n\n      // shortcut for most chars (print action)\n      if (currentState === ParserState.GROUND && code > 0x1f && code < 0x80) {\n        print = (~print) ? print : i;\n        do i++;\n        while (i < length && data[i] > 0x1f && data[i] < 0x80);\n        i--;\n        continue;\n      }\n\n      // shortcut for CSI params\n      if (currentState === ParserState.CSI_PARAM && (code > 0x2f && code < 0x39)) {\n        params[params.length - 1] = params[params.length - 1] * 10 + code - 48;\n        continue;\n      }\n\n      // normal transition & action lookup\n      transition = table[currentState << 8 | (code < 0xa0 ? code : NON_ASCII_PRINTABLE)];\n      switch (transition >> 4) {\n        case ParserAction.PRINT:\n          print = (~print) ? print : i;\n          break;\n        case ParserAction.EXECUTE:\n          if (~print) {\n            this._printHandler(data, print, i);\n            print = -1;\n          }\n          callback = this._executeHandlers[code];\n          if (callback) callback();\n          else this._executeHandlerFb(code);\n          break;\n        case ParserAction.IGNORE:\n          // handle leftover print or dcs chars\n          if (~print) {\n            this._printHandler(data, print, i);\n            print = -1;\n          } else if (~dcs) {\n            dcsHandler.put(data, dcs, i);\n            dcs = -1;\n          }\n          break;\n        case ParserAction.ERROR:\n          // chars higher than 0x9f are handled by this action\n          // to keep the transition table small\n          if (code > 0x9f) {\n            switch (currentState) {\n              case ParserState.GROUND:\n                print = (~print) ? print : i;\n                break;\n              case ParserState.CSI_IGNORE:\n                transition |= ParserState.CSI_IGNORE;\n                break;\n              case ParserState.DCS_IGNORE:\n                transition |= ParserState.DCS_IGNORE;\n                break;\n              case ParserState.DCS_PASSTHROUGH:\n                dcs = (~dcs) ? dcs : i;\n                transition |= ParserState.DCS_PASSTHROUGH;\n                break;\n              default:\n                error = true;\n            }\n          } else {\n            error = true;\n          }\n          // if we end up here a real error happened\n          if (error) {\n            const inject: IParsingState = this._errorHandler(\n              {\n                position: i,\n                code,\n                currentState,\n                print,\n                dcs,\n                osc,\n                collect,\n                params,\n                abort: false\n              });\n            if (inject.abort) return;\n          // TODO: inject return values\n            error = false;\n          }\n          break;\n        case ParserAction.CSI_DISPATCH:\n          // Trigger CSI Handler\n          const handlers = this._csiHandlers[code];\n          let j = handlers ? handlers.length - 1 : -1;\n          for (; j >= 0; j--) {\n            // undefined or true means success and to stop bubbling\n            if (handlers[j](params, collect) !== false) {\n              break;\n            }\n          }\n          if (j < 0) {\n            this._csiHandlerFb(collect, params, code);\n          }\n          break;\n        case ParserAction.PARAM:\n          if (code === 0x3b) params.push(0);\n          else params[params.length - 1] = params[params.length - 1] * 10 + code - 48;\n          break;\n        case ParserAction.COLLECT:\n          collect += String.fromCharCode(code);\n          break;\n        case ParserAction.ESC_DISPATCH:\n          callback = this._escHandlers[collect + String.fromCharCode(code)];\n          if (callback) callback(collect, code);\n          else this._escHandlerFb(collect, code);\n          break;\n        case ParserAction.CLEAR:\n          if (~print) {\n            this._printHandler(data, print, i);\n            print = -1;\n          }\n          osc = '';\n          params = [0];\n          collect = '';\n          dcs = -1;\n          break;\n        case ParserAction.DCS_HOOK:\n          dcsHandler = this._dcsHandlers[collect + String.fromCharCode(code)];\n          if (!dcsHandler) dcsHandler = this._dcsHandlerFb;\n          dcsHandler.hook(collect, params, code);\n          break;\n        case ParserAction.DCS_PUT:\n          dcs = (~dcs) ? dcs : i;\n          break;\n        case ParserAction.DCS_UNHOOK:\n          if (dcsHandler) {\n            if (~dcs) dcsHandler.put(data, dcs, i);\n            dcsHandler.unhook();\n            dcsHandler = null;\n          }\n          if (code === 0x1b) transition |= ParserState.ESCAPE;\n          osc = '';\n          params = [0];\n          collect = '';\n          dcs = -1;\n          break;\n        case ParserAction.OSC_START:\n          if (~print) {\n            this._printHandler(data, print, i);\n            print = -1;\n          }\n          osc = '';\n          break;\n        case ParserAction.OSC_PUT:\n          for (let j = i + 1; ; j++) {\n            if (j >= length\n                || (code = data[j]) < 0x20\n                || (code > 0x7f && code <= 0x9f)) {\n              osc += utf32ToString(data, i, j);\n              i = j - 1;\n              break;\n            }\n          }\n          break;\n        case ParserAction.OSC_END:\n          if (osc && code !== 0x18 && code !== 0x1a) {\n            // NOTE: OSC subparsing is not part of the original parser\n            // we do basic identifier parsing here to offer a jump table for OSC as well\n            const idx = osc.indexOf(';');\n            if (idx === -1) {\n              this._oscHandlerFb(-1, osc);  // this is an error (malformed OSC)\n            } else {\n              // Note: NaN is not handled here\n              // either catch it with the fallback handler\n              // or with an explicit NaN OSC handler\n              const identifier = parseInt(osc.substring(0, idx));\n              const content = osc.substring(idx + 1);\n              // Trigger OSC Handler\n              const handlers = this._oscHandlers[identifier];\n              let j = handlers ? handlers.length - 1 : -1;\n              for (; j >= 0; j--) {\n                // undefined or true means success and to stop bubbling\n                if (handlers[j](content) !== false) {\n                  break;\n                }\n              }\n              if (j < 0) {\n                this._oscHandlerFb(identifier, content);\n              }\n            }\n          }\n          if (code === 0x1b) transition |= ParserState.ESCAPE;\n          osc = '';\n          params = [0];\n          collect = '';\n          dcs = -1;\n          break;\n      }\n      currentState = transition & 15;\n    }\n\n    // push leftover pushable buffers to terminal\n    if (currentState === ParserState.GROUND && ~print) {\n      this._printHandler(data, print, length);\n    } else if (currentState === ParserState.DCS_PASSTHROUGH && ~dcs && dcsHandler) {\n      dcsHandler.put(data, dcs, length);\n    }\n\n    // save non pushable buffers\n    this._osc = osc;\n    this._collect = collect;\n    this._params = params;\n\n    // save active dcs handler reference\n    this._activeDcsHandler = dcsHandler;\n\n    // save state\n    this.currentState = currentState;\n  }\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ITerminal } from './Types';\n\ninterface IPosition {\n  start: number;\n  end: number;\n}\n\n/**\n * Encapsulates the logic for handling compositionstart, compositionupdate and compositionend\n * events, displaying the in-progress composition to the UI and forwarding the final composition\n * to the handler.\n */\nexport class CompositionHelper {\n  /**\n   * Whether input composition is currently happening, eg. via a mobile keyboard, speech input or\n   * IME. This variable determines whether the compositionText should be displayed on the UI.\n   */\n  private _isComposing: boolean;\n\n  /**\n   * The position within the input textarea's value of the current composition.\n   */\n  private _compositionPosition: IPosition;\n\n  /**\n   * Whether a composition is in the process of being sent, setting this to false will cancel any\n   * in-progress composition.\n   */\n  private _isSendingComposition: boolean;\n\n  /**\n   * Creates a new CompositionHelper.\n   * @param _textarea The textarea that xterm uses for input.\n   * @param _compositionView The element to display the in-progress composition in.\n   * @param _terminal The Terminal to forward the finished composition to.\n   */\n  constructor(\n    private _textarea: HTMLTextAreaElement,\n    private _compositionView: HTMLElement,\n    private _terminal: ITerminal\n  ) {\n    this._isComposing = false;\n    this._isSendingComposition = false;\n    this._compositionPosition = { start: null, end: null };\n  }\n\n  /**\n   * Handles the compositionstart event, activating the composition view.\n   */\n  public compositionstart(): void {\n    this._isComposing = true;\n    this._compositionPosition.start = this._textarea.value.length;\n    this._compositionView.textContent = '';\n    this._compositionView.classList.add('active');\n  }\n\n  /**\n   * Handles the compositionupdate event, updating the composition view.\n   * @param ev The event.\n   */\n  public compositionupdate(ev: CompositionEvent): void {\n    this._compositionView.textContent = ev.data;\n    this.updateCompositionElements();\n    setTimeout(() => {\n      this._compositionPosition.end = this._textarea.value.length;\n    }, 0);\n  }\n\n  /**\n   * Handles the compositionend event, hiding the composition view and sending the composition to\n   * the handler.\n   */\n  public compositionend(): void {\n    this._finalizeComposition(true);\n  }\n\n  /**\n   * Handles the keydown event, routing any necessary events to the CompositionHelper functions.\n   * @param ev The keydown event.\n   * @return Whether the Terminal should continue processing the keydown event.\n   */\n  public keydown(ev: KeyboardEvent): boolean {\n    if (this._isComposing || this._isSendingComposition) {\n      if (ev.keyCode === 229) {\n        // Continue composing if the keyCode is the \"composition character\"\n        return false;\n      } else if (ev.keyCode === 16 || ev.keyCode === 17 || ev.keyCode === 18) {\n        // Continue composing if the keyCode is a modifier key\n        return false;\n      }\n      // Finish composition immediately. This is mainly here for the case where enter is\n      // pressed and the handler needs to be triggered before the command is executed.\n      this._finalizeComposition(false);\n    }\n\n    if (ev.keyCode === 229) {\n      // If the \"composition character\" is used but gets to this point it means a non-composition\n      // character (eg. numbers and punctuation) was pressed when the IME was active.\n      this._handleAnyTextareaChanges();\n      return false;\n    }\n\n    return true;\n  }\n\n  /**\n   * Finalizes the composition, resuming regular input actions. This is called when a composition\n   * is ending.\n   * @param waitForPropagation Whether to wait for events to propagate before sending\n   *   the input. This should be false if a non-composition keystroke is entered before the\n   *   compositionend event is triggered, such as enter, so that the composition is sent before\n   *   the command is executed.\n   */\n  private _finalizeComposition(waitForPropagation: boolean): void {\n    this._compositionView.classList.remove('active');\n    this._isComposing = false;\n    this._clearTextareaPosition();\n\n    if (!waitForPropagation) {\n      // Cancel any delayed composition send requests and send the input immediately.\n      this._isSendingComposition = false;\n      const input = this._textarea.value.substring(this._compositionPosition.start, this._compositionPosition.end);\n      this._terminal.handler(input);\n    } else {\n      // Make a deep copy of the composition position here as a new compositionstart event may\n      // fire before the setTimeout executes.\n      const currentCompositionPosition = {\n        start: this._compositionPosition.start,\n        end: this._compositionPosition.end\n      };\n\n      // Since composition* events happen before the changes take place in the textarea on most\n      // browsers, use a setTimeout with 0ms time to allow the native compositionend event to\n      // complete. This ensures the correct character is retrieved.\n      // This solution was used because:\n      // - The compositionend event's data property is unreliable, at least on Chromium\n      // - The last compositionupdate event's data property does not always accurately describe\n      //   the character, a counter example being Korean where an ending consonsant can move to\n      //   the following character if the following input is a vowel.\n      this._isSendingComposition = true;\n      setTimeout(() => {\n        // Ensure that the input has not already been sent\n        if (this._isSendingComposition) {\n          this._isSendingComposition = false;\n          let input;\n          if (this._isComposing) {\n            // Use the end position to get the string if a new composition has started.\n            input = this._textarea.value.substring(currentCompositionPosition.start, currentCompositionPosition.end);\n          } else {\n            // Don't use the end position here in order to pick up any characters after the\n            // composition has finished, for example when typing a non-composition character\n            // (eg. 2) after a composition character.\n            input = this._textarea.value.substring(currentCompositionPosition.start);\n          }\n          this._terminal.handler(input);\n        }\n      }, 0);\n    }\n  }\n\n  /**\n   * Apply any changes made to the textarea after the current event chain is allowed to complete.\n   * This should be called when not currently composing but a keydown event with the \"composition\n   * character\" (229) is triggered, in order to allow non-composition text to be entered when an\n   * IME is active.\n   */\n  private _handleAnyTextareaChanges(): void {\n    const oldValue = this._textarea.value;\n    setTimeout(() => {\n      // Ignore if a composition has started since the timeout\n      if (!this._isComposing) {\n        const newValue = this._textarea.value;\n        const diff = newValue.replace(oldValue, '');\n        if (diff.length > 0) {\n          this._terminal.handler(diff);\n        }\n      }\n    }, 0);\n  }\n\n  /**\n   * Positions the composition view on top of the cursor and the textarea just below it (so the\n   * IME helper dialog is positioned correctly).\n   * @param dontRecurse Whether to use setTimeout to recursively trigger another update, this is\n   *   necessary as the IME events across browsers are not consistently triggered.\n   */\n  public updateCompositionElements(dontRecurse?: boolean): void {\n    if (!this._isComposing) {\n      return;\n    }\n\n    if (this._terminal.buffer.isCursorInViewport) {\n      const cellHeight = Math.ceil(this._terminal.charMeasure.height * this._terminal.options.lineHeight);\n      const cursorTop = this._terminal.buffer.y * cellHeight;\n      const cursorLeft = this._terminal.buffer.x * this._terminal.charMeasure.width;\n\n      this._compositionView.style.left = cursorLeft + 'px';\n      this._compositionView.style.top = cursorTop + 'px';\n      this._compositionView.style.height = cellHeight + 'px';\n      this._compositionView.style.lineHeight = cellHeight + 'px';\n      this._compositionView.style.fontFamily = this._terminal.options.fontFamily;\n      this._compositionView.style.fontSize = this._terminal.options.fontSize + 'px';\n      // Sync the textarea to the exact position of the composition view so the IME knows where the\n      // text is.\n      const compositionViewBounds = this._compositionView.getBoundingClientRect();\n      this._textarea.style.left = cursorLeft + 'px';\n      this._textarea.style.top = cursorTop + 'px';\n      this._textarea.style.width = compositionViewBounds.width + 'px';\n      this._textarea.style.height = compositionViewBounds.height + 'px';\n      this._textarea.style.lineHeight = compositionViewBounds.height + 'px';\n    }\n\n    if (!dontRecurse) {\n      setTimeout(() => this.updateCompositionElements(true), 0);\n    }\n  }\n\n  /**\n   * Clears the textarea's position so that the cursor does not blink on IE.\n   * @private\n   */\n  private _clearTextareaPosition(): void {\n    this._textarea.style.left = '';\n    this._textarea.style.top = '';\n  }\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ITerminal, ISelectionManager } from './Types';\n\ninterface IWindow extends Window {\n  clipboardData?: {\n    getData(format: string): string;\n    setData(format: string, data: string): void;\n  };\n}\n\ndeclare var window: IWindow;\n\n/**\n * Prepares text to be pasted into the terminal by normalizing the line endings\n * @param text The pasted text that needs processing before inserting into the terminal\n */\nexport function prepareTextForTerminal(text: string): string {\n  return text.replace(/\\r?\\n/g, '\\r');\n}\n\n/**\n * Bracket text for paste, if necessary, as per https://cirw.in/blog/bracketed-paste\n * @param text The pasted text to bracket\n */\nexport function bracketTextForPaste(text: string, bracketedPasteMode: boolean): string {\n  if (bracketedPasteMode) {\n    return '\\x1b[200~' + text + '\\x1b[201~';\n  }\n  return text;\n}\n\n/**\n * Binds copy functionality to the given terminal.\n * @param ev The original copy event to be handled\n */\nexport function copyHandler(ev: ClipboardEvent, term: ITerminal, selectionManager: ISelectionManager): void {\n  if (term.browser.isMSIE) {\n    window.clipboardData.setData('Text', selectionManager.selectionText);\n  } else {\n    ev.clipboardData.setData('text/plain', selectionManager.selectionText);\n  }\n\n  // Prevent or the original text will be copied.\n  ev.preventDefault();\n}\n\n/**\n * Redirect the clipboard's data to the terminal's input handler.\n * @param ev The original paste event to be handled\n * @param term The terminal on which to apply the handled paste event\n */\nexport function pasteHandler(ev: ClipboardEvent, term: ITerminal): void {\n  ev.stopPropagation();\n\n  let text: string;\n\n  const dispatchPaste = function(text: string): void {\n    text = prepareTextForTerminal(text);\n    text = bracketTextForPaste(text, term.bracketedPasteMode);\n    term.handler(text);\n    term.textarea.value = '';\n    term.emit('paste', text);\n    term.cancel(ev);\n  };\n\n  if (term.browser.isMSIE) {\n    if (window.clipboardData) {\n      text = window.clipboardData.getData('Text');\n      dispatchPaste(text);\n    }\n  } else {\n    if (ev.clipboardData) {\n      text = ev.clipboardData.getData('text/plain');\n      dispatchPaste(text);\n    }\n  }\n}\n\n/**\n * Moves the textarea under the mouse cursor and focuses it.\n * @param ev The original right click event to be handled.\n * @param textarea The terminal's textarea.\n */\nexport function moveTextAreaUnderMouseCursor(ev: MouseEvent, term: ITerminal): void {\n\n  // Calculate textarea position relative to the screen element\n  const pos = term.screenElement.getBoundingClientRect();\n  const left = ev.clientX - pos.left - 10;\n  const top = ev.clientY - pos.top - 10;\n\n  // Bring textarea at the cursor position\n  term.textarea.style.position = 'absolute';\n  term.textarea.style.width = '20px';\n  term.textarea.style.height = '20px';\n  term.textarea.style.left = `${left}px`;\n  term.textarea.style.top = `${top}px`;\n  term.textarea.style.zIndex = '1000';\n\n  term.textarea.focus();\n\n  // Reset the terminal textarea's styling\n  // Timeout needs to be long enough for click event to be handled.\n  setTimeout(() => {\n    term.textarea.style.position = null;\n    term.textarea.style.width = null;\n    term.textarea.style.height = null;\n    term.textarea.style.left = null;\n    term.textarea.style.top = null;\n    term.textarea.style.zIndex = null;\n  }, 200);\n}\n\n/**\n * Bind to right-click event and allow right-click copy and paste.\n * @param ev The original right click event to be handled.\n * @param textarea The terminal's textarea.\n * @param selectionManager The terminal's selection manager.\n * @param shouldSelectWord If true and there is no selection the current word will be selected\n */\nexport function rightClickHandler(ev: MouseEvent, term: ITerminal, selectionManager: ISelectionManager, shouldSelectWord: boolean): void {\n  moveTextAreaUnderMouseCursor(ev, term);\n\n  if (shouldSelectWord && !selectionManager.isClickInSelection(ev)) {\n    selectionManager.selectWordAtCursor(ev);\n  }\n\n  // Get textarea ready to copy from the context menu\n  term.textarea.value = selectionManager.selectionText;\n  term.textarea.select();\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { fill } from './common/TypedArrayUtils';\n\nexport const wcwidth = (function(opts: {nul: number, control: number}): (ucs: number) => number {\n  // extracted from https://www.cl.cam.ac.uk/%7Emgk25/ucs/wcwidth.c\n  // combining characters\n  const COMBINING_BMP = [\n    [0x0300, 0x036F], [0x0483, 0x0486], [0x0488, 0x0489],\n    [0x0591, 0x05BD], [0x05BF, 0x05BF], [0x05C1, 0x05C2],\n    [0x05C4, 0x05C5], [0x05C7, 0x05C7], [0x0600, 0x0603],\n    [0x0610, 0x0615], [0x064B, 0x065E], [0x0670, 0x0670],\n    [0x06D6, 0x06E4], [0x06E7, 0x06E8], [0x06EA, 0x06ED],\n    [0x070F, 0x070F], [0x0711, 0x0711], [0x0730, 0x074A],\n    [0x07A6, 0x07B0], [0x07EB, 0x07F3], [0x0901, 0x0902],\n    [0x093C, 0x093C], [0x0941, 0x0948], [0x094D, 0x094D],\n    [0x0951, 0x0954], [0x0962, 0x0963], [0x0981, 0x0981],\n    [0x09BC, 0x09BC], [0x09C1, 0x09C4], [0x09CD, 0x09CD],\n    [0x09E2, 0x09E3], [0x0A01, 0x0A02], [0x0A3C, 0x0A3C],\n    [0x0A41, 0x0A42], [0x0A47, 0x0A48], [0x0A4B, 0x0A4D],\n    [0x0A70, 0x0A71], [0x0A81, 0x0A82], [0x0ABC, 0x0ABC],\n    [0x0AC1, 0x0AC5], [0x0AC7, 0x0AC8], [0x0ACD, 0x0ACD],\n    [0x0AE2, 0x0AE3], [0x0B01, 0x0B01], [0x0B3C, 0x0B3C],\n    [0x0B3F, 0x0B3F], [0x0B41, 0x0B43], [0x0B4D, 0x0B4D],\n    [0x0B56, 0x0B56], [0x0B82, 0x0B82], [0x0BC0, 0x0BC0],\n    [0x0BCD, 0x0BCD], [0x0C3E, 0x0C40], [0x0C46, 0x0C48],\n    [0x0C4A, 0x0C4D], [0x0C55, 0x0C56], [0x0CBC, 0x0CBC],\n    [0x0CBF, 0x0CBF], [0x0CC6, 0x0CC6], [0x0CCC, 0x0CCD],\n    [0x0CE2, 0x0CE3], [0x0D41, 0x0D43], [0x0D4D, 0x0D4D],\n    [0x0DCA, 0x0DCA], [0x0DD2, 0x0DD4], [0x0DD6, 0x0DD6],\n    [0x0E31, 0x0E31], [0x0E34, 0x0E3A], [0x0E47, 0x0E4E],\n    [0x0EB1, 0x0EB1], [0x0EB4, 0x0EB9], [0x0EBB, 0x0EBC],\n    [0x0EC8, 0x0ECD], [0x0F18, 0x0F19], [0x0F35, 0x0F35],\n    [0x0F37, 0x0F37], [0x0F39, 0x0F39], [0x0F71, 0x0F7E],\n    [0x0F80, 0x0F84], [0x0F86, 0x0F87], [0x0F90, 0x0F97],\n    [0x0F99, 0x0FBC], [0x0FC6, 0x0FC6], [0x102D, 0x1030],\n    [0x1032, 0x1032], [0x1036, 0x1037], [0x1039, 0x1039],\n    [0x1058, 0x1059], [0x1160, 0x11FF], [0x135F, 0x135F],\n    [0x1712, 0x1714], [0x1732, 0x1734], [0x1752, 0x1753],\n    [0x1772, 0x1773], [0x17B4, 0x17B5], [0x17B7, 0x17BD],\n    [0x17C6, 0x17C6], [0x17C9, 0x17D3], [0x17DD, 0x17DD],\n    [0x180B, 0x180D], [0x18A9, 0x18A9], [0x1920, 0x1922],\n    [0x1927, 0x1928], [0x1932, 0x1932], [0x1939, 0x193B],\n    [0x1A17, 0x1A18], [0x1B00, 0x1B03], [0x1B34, 0x1B34],\n    [0x1B36, 0x1B3A], [0x1B3C, 0x1B3C], [0x1B42, 0x1B42],\n    [0x1B6B, 0x1B73], [0x1DC0, 0x1DCA], [0x1DFE, 0x1DFF],\n    [0x200B, 0x200F], [0x202A, 0x202E], [0x2060, 0x2063],\n    [0x206A, 0x206F], [0x20D0, 0x20EF], [0x302A, 0x302F],\n    [0x3099, 0x309A], [0xA806, 0xA806], [0xA80B, 0xA80B],\n    [0xA825, 0xA826], [0xFB1E, 0xFB1E], [0xFE00, 0xFE0F],\n    [0xFE20, 0xFE23], [0xFEFF, 0xFEFF], [0xFFF9, 0xFFFB]\n  ];\n  const COMBINING_HIGH = [\n    [0x10A01, 0x10A03], [0x10A05, 0x10A06], [0x10A0C, 0x10A0F],\n    [0x10A38, 0x10A3A], [0x10A3F, 0x10A3F], [0x1D167, 0x1D169],\n    [0x1D173, 0x1D182], [0x1D185, 0x1D18B], [0x1D1AA, 0x1D1AD],\n    [0x1D242, 0x1D244], [0xE0001, 0xE0001], [0xE0020, 0xE007F],\n    [0xE0100, 0xE01EF]\n  ];\n  // binary search\n  function bisearch(ucs: number, data: number[][]): boolean {\n    let min = 0;\n    let max = data.length - 1;\n    let mid;\n    if (ucs < data[0][0] || ucs > data[max][1]) {\n      return false;\n    }\n    while (max >= min) {\n      mid = (min + max) >> 1;\n      if (ucs > data[mid][1]) {\n        min = mid + 1;\n      } else if (ucs < data[mid][0]) {\n        max = mid - 1;\n      } else {\n        return true;\n      }\n    }\n    return false;\n  }\n  function wcwidthHigh(ucs: number): 0 | 1 | 2 {\n    if (bisearch(ucs, COMBINING_HIGH)) {\n      return 0;\n    }\n    if ((ucs >= 0x20000 && ucs <= 0x2fffd) || (ucs >= 0x30000 && ucs <= 0x3fffd)) {\n      return 2;\n    }\n    return 1;\n  }\n  const control = opts.control | 0;\n\n  // create lookup table for BMP plane\n  const table = new Uint8Array(65536);\n  fill(table, 1);\n  table[0] = opts.nul;\n  // control chars\n  fill(table, opts.control, 1, 32);\n  fill(table, opts.control, 0x7f, 0xa0);\n\n  // apply wide char rules first\n  // wide chars\n  fill(table, 2, 0x1100, 0x1160);\n  table[0x2329] = 2;\n  table[0x232a] = 2;\n  fill(table, 2, 0x2e80, 0xa4d0);\n  table[0x303f] = 1;  // wrongly in last line\n\n  fill(table, 2, 0xac00, 0xd7a4);\n  fill(table, 2, 0xf900, 0xfb00);\n  fill(table, 2, 0xfe10, 0xfe1a);\n  fill(table, 2, 0xfe30, 0xfe70);\n  fill(table, 2, 0xff00, 0xff61);\n  fill(table, 2, 0xffe0, 0xffe7);\n\n  // apply combining last to ensure we overwrite\n  // wrongly wide set chars:\n  //    the original algo evals combining first and falls\n  //    through to wide check so we simply do here the opposite\n  // combining 0\n  for (let r = 0; r < COMBINING_BMP.length; ++r) {\n    fill(table, 0, COMBINING_BMP[r][0], COMBINING_BMP[r][1] + 1);\n  }\n\n  return function (num: number): number {\n    if (num < 32) {\n      return control | 0;\n    }\n    if (num < 127) {\n      return 1;\n    }\n    if (num < 65536) {\n      return table[num];\n    }\n    // do a full search for high codepoints\n    return wcwidthHigh(num);\n  };\n})({nul: 0, control: 0});  // configurable options\n\n/**\n * Get the terminal cell width for a string.\n */\nexport function getStringCellWidth(s: string): number {\n  let result = 0;\n  const length = s.length;\n  for (let i = 0; i < length; ++i) {\n    let code = s.charCodeAt(i);\n    // surrogate pair first\n    if (0xD800 <= code && code <= 0xDBFF) {\n      if (++i >= length) {\n        // this should not happen with strings retrieved from\n        // Buffer.translateToString as it converts from UTF-32\n        // and therefore always should contain the second part\n        // for any other string we still have to handle it somehow:\n        // simply treat the lonely surrogate first as a single char (UCS-2 behavior)\n        return result + wcwidth(code);\n      }\n      const second = s.charCodeAt(i);\n      // convert surrogate pair to high codepoint only for valid second part (UTF-16)\n      // otherwise treat them independently (UCS-2 behavior)\n      if (0xDC00 <= second && second <= 0xDFFF) {\n        code = (code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;\n      } else {\n        result += wcwidth(second);\n      }\n    }\n    result += wcwidth(code);\n  }\n  return result;\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICharMeasure, ITerminalOptions } from './Types';\nimport { EventEmitter2, IEvent } from './common/EventEmitter2';\n\n/**\n * Utility class that measures the size of a character. Measurements are done in\n * the DOM rather than with a canvas context because support for extracting the\n * height of characters is patchy across browsers.\n */\nexport class CharMeasure implements ICharMeasure {\n  private _document: Document;\n  private _parentElement: HTMLElement;\n  private _measureElement: HTMLElement;\n  private _width: number;\n  private _height: number;\n\n  private _onCharSizeChanged = new EventEmitter2<void>();\n  public get onCharSizeChanged(): IEvent<void> { return this._onCharSizeChanged.event; }\n\n  constructor(document: Document, parentElement: HTMLElement) {\n    this._document = document;\n    this._parentElement = parentElement;\n    this._measureElement = this._document.createElement('span');\n    this._measureElement.classList.add('xterm-char-measure-element');\n    this._measureElement.textContent = 'W';\n    this._measureElement.setAttribute('aria-hidden', 'true');\n    this._parentElement.appendChild(this._measureElement);\n  }\n\n  public get width(): number {\n    return this._width;\n  }\n\n  public get height(): number {\n    return this._height;\n  }\n\n  public measure(options: ITerminalOptions): void {\n    this._measureElement.style.fontFamily = options.fontFamily;\n    this._measureElement.style.fontSize = `${options.fontSize}px`;\n    const geometry = this._measureElement.getBoundingClientRect();\n    // The element is likely currently display:none, we should retain the\n    // previous value.\n    if (geometry.width === 0 || geometry.height === 0) {\n      return;\n    }\n    const adjustedHeight = Math.ceil(geometry.height);\n    if (this._width !== geometry.width || this._height !== adjustedHeight) {\n      this._width = geometry.width;\n      this._height = adjustedHeight;\n      this._onCharSizeChanged.fire();\n    }\n  }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ITerminal, IBufferSet, IAttributeData, IBuffer } from './Types';\nimport { Buffer } from './Buffer';\nimport { EventEmitter2, IEvent } from './common/EventEmitter2';\n\n/**\n * The BufferSet represents the set of two buffers used by xterm terminals (normal and alt) and\n * provides also utilities for working with them.\n */\nexport class BufferSet implements IBufferSet {\n  private _normal: Buffer;\n  private _alt: Buffer;\n  private _activeBuffer: Buffer;\n\n\n  private _onBufferActivate = new EventEmitter2<{activeBuffer: IBuffer, inactiveBuffer: IBuffer}>();\n  public get onBufferActivate(): IEvent<{activeBuffer: IBuffer, inactiveBuffer: IBuffer}> { return this._onBufferActivate.event; }\n\n  /**\n   * Create a new BufferSet for the given terminal.\n   * @param _terminal - The terminal the BufferSet will belong to\n   */\n  constructor(private _terminal: ITerminal) {\n    this._normal = new Buffer(this._terminal, true);\n    this._normal.fillViewportRows();\n\n    // The alt buffer should never have scrollback.\n    // See http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer\n    this._alt = new Buffer(this._terminal, false);\n    this._activeBuffer = this._normal;\n\n    this.setupTabStops();\n  }\n\n  /**\n   * Returns the alt Buffer of the BufferSet\n   */\n  public get alt(): Buffer {\n    return this._alt;\n  }\n\n  /**\n   * Returns the normal Buffer of the BufferSet\n   */\n  public get active(): Buffer {\n    return this._activeBuffer;\n  }\n\n  /**\n   * Returns the currently active Buffer of the BufferSet\n   */\n  public get normal(): Buffer {\n    return this._normal;\n  }\n\n  /**\n   * Sets the normal Buffer of the BufferSet as its currently active Buffer\n   */\n  public activateNormalBuffer(): void {\n    if (this._activeBuffer === this._normal) {\n      return;\n    }\n    this._normal.x = this._alt.x;\n    this._normal.y = this._alt.y;\n    // The alt buffer should always be cleared when we switch to the normal\n    // buffer. This frees up memory since the alt buffer should always be new\n    // when activated.\n    this._alt.clear();\n    this._activeBuffer = this._normal;\n    this._onBufferActivate.fire({\n      activeBuffer: this._normal,\n      inactiveBuffer: this._alt\n    });\n  }\n\n  /**\n   * Sets the alt Buffer of the BufferSet as its currently active Buffer\n   */\n  public activateAltBuffer(fillAttr?: IAttributeData): void {\n    if (this._activeBuffer === this._alt) {\n      return;\n    }\n    // Since the alt buffer is always cleared when the normal buffer is\n    // activated, we want to fill it when switching to it.\n    this._alt.fillViewportRows(fillAttr);\n    this._alt.x = this._normal.x;\n    this._alt.y = this._normal.y;\n    this._activeBuffer = this._alt;\n    this._onBufferActivate.fire({\n      activeBuffer: this._alt,\n      inactiveBuffer: this._normal\n    });\n  }\n\n  /**\n   * Resizes both normal and alt buffers, adjusting their data accordingly.\n   * @param newCols The new number of columns.\n   * @param newRows The new number of rows.\n   */\n  public resize(newCols: number, newRows: number): void {\n    this._normal.resize(newCols, newRows);\n    this._alt.resize(newCols, newRows);\n  }\n\n  /**\n   * Setup the tab stops.\n   * @param i The index to start setting up tab stops from.\n   */\n  public setupTabStops(i?: number): void {\n    this._normal.setupTabStops(i);\n    this._alt.setupTabStops(i);\n  }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { BufferLine } from './BufferLine';\nimport { CircularList } from './common/CircularList';\nimport { IBufferLine, ICellData } from './Types';\n\nexport interface INewLayoutResult {\n  layout: number[];\n  countRemoved: number;\n}\n\n/**\n * Evaluates and returns indexes to be removed after a reflow larger occurs. Lines will be removed\n * when a wrapped line unwraps.\n * @param lines The buffer lines.\n * @param newCols The columns after resize.\n */\nexport function reflowLargerGetLinesToRemove(lines: CircularList<IBufferLine>, oldCols: number, newCols: number, bufferAbsoluteY: number, nullCell: ICellData): number[] {\n  // Gather all BufferLines that need to be removed from the Buffer here so that they can be\n  // batched up and only committed once\n  const toRemove: number[] = [];\n\n  for (let y = 0; y < lines.length - 1; y++) {\n    // Check if this row is wrapped\n    let i = y;\n    let nextLine = lines.get(++i) as BufferLine;\n    if (!nextLine.isWrapped) {\n      continue;\n    }\n\n    // Check how many lines it's wrapped for\n    const wrappedLines: BufferLine[] = [lines.get(y) as BufferLine];\n    while (i < lines.length && nextLine.isWrapped) {\n      wrappedLines.push(nextLine);\n      nextLine = lines.get(++i) as BufferLine;\n    }\n\n    // If these lines contain the cursor don't touch them, the program will handle fixing up wrapped\n    // lines with the cursor\n    if (bufferAbsoluteY >= y && bufferAbsoluteY < i) {\n      y += wrappedLines.length - 1;\n      continue;\n    }\n\n    // Copy buffer data to new locations\n    let destLineIndex = 0;\n    let destCol = getWrappedLineTrimmedLength(wrappedLines, destLineIndex, oldCols);\n    let srcLineIndex = 1;\n    let srcCol = 0;\n    while (srcLineIndex < wrappedLines.length) {\n      const srcTrimmedTineLength = getWrappedLineTrimmedLength(wrappedLines, srcLineIndex, oldCols);\n      const srcRemainingCells = srcTrimmedTineLength - srcCol;\n      const destRemainingCells = newCols - destCol;\n      const cellsToCopy = Math.min(srcRemainingCells, destRemainingCells);\n\n      wrappedLines[destLineIndex].copyCellsFrom(wrappedLines[srcLineIndex], srcCol, destCol, cellsToCopy, false);\n\n      destCol += cellsToCopy;\n      if (destCol === newCols) {\n        destLineIndex++;\n        destCol = 0;\n      }\n      srcCol += cellsToCopy;\n      if (srcCol === srcTrimmedTineLength) {\n        srcLineIndex++;\n        srcCol = 0;\n      }\n\n      // Make sure the last cell isn't wide, if it is copy it to the current dest\n      if (destCol === 0 && destLineIndex !== 0) {\n        if (wrappedLines[destLineIndex - 1].getWidth(newCols - 1) === 2) {\n          wrappedLines[destLineIndex].copyCellsFrom(wrappedLines[destLineIndex - 1], newCols - 1, destCol++, 1, false);\n          // Null out the end of the last row\n          wrappedLines[destLineIndex - 1].setCell(newCols - 1, nullCell);\n        }\n      }\n    }\n\n    // Clear out remaining cells or fragments could remain;\n    wrappedLines[destLineIndex].replaceCells(destCol, newCols, nullCell);\n\n    // Work backwards and remove any rows at the end that only contain null cells\n    let countToRemove = 0;\n    for (let i = wrappedLines.length - 1; i > 0; i--) {\n      if (i > destLineIndex || wrappedLines[i].getTrimmedLength() === 0) {\n        countToRemove++;\n      } else {\n        break;\n      }\n    }\n\n    if (countToRemove > 0) {\n      toRemove.push(y + wrappedLines.length - countToRemove); // index\n      toRemove.push(countToRemove);\n    }\n\n    y += wrappedLines.length - 1;\n  }\n  return toRemove;\n}\n\n/**\n * Creates and return the new layout for lines given an array of indexes to be removed.\n * @param lines The buffer lines.\n * @param toRemove The indexes to remove.\n */\nexport function reflowLargerCreateNewLayout(lines: CircularList<IBufferLine>, toRemove: number[]): INewLayoutResult {\n  const layout: number[] = [];\n  // First iterate through the list and get the actual indexes to use for rows\n  let nextToRemoveIndex = 0;\n  let nextToRemoveStart = toRemove[nextToRemoveIndex];\n  let countRemovedSoFar = 0;\n  for (let i = 0; i < lines.length; i++) {\n    if (nextToRemoveStart === i) {\n      const countToRemove = toRemove[++nextToRemoveIndex];\n\n      // Tell markers that there was a deletion\n      lines.onDeleteEmitter.fire({\n        index: i - countRemovedSoFar,\n        amount: countToRemove\n      });\n\n      i += countToRemove - 1;\n      countRemovedSoFar += countToRemove;\n      nextToRemoveStart = toRemove[++nextToRemoveIndex];\n    } else {\n      layout.push(i);\n    }\n  }\n  return {\n    layout,\n    countRemoved: countRemovedSoFar\n  };\n}\n\n/**\n * Applies a new layout to the buffer. This essentially does the same as many splice calls but it's\n * done all at once in a single iteration through the list since splice is very expensive.\n * @param lines The buffer lines.\n * @param newLayout The new layout to apply.\n */\nexport function reflowLargerApplyNewLayout(lines: CircularList<IBufferLine>, newLayout: number[]): void {\n  // Record original lines so they don't get overridden when we rearrange the list\n  const newLayoutLines: BufferLine[] = [];\n  for (let i = 0; i < newLayout.length; i++) {\n    newLayoutLines.push(lines.get(newLayout[i]) as BufferLine);\n  }\n\n  // Rearrange the list\n  for (let i = 0; i < newLayoutLines.length; i++) {\n    lines.set(i, newLayoutLines[i]);\n  }\n  lines.length = newLayout.length;\n}\n\n/**\n * Gets the new line lengths for a given wrapped line. The purpose of this function it to pre-\n * compute the wrapping points since wide characters may need to be wrapped onto the following line.\n * This function will return an array of numbers of where each line wraps to, the resulting array\n * will only contain the values `newCols` (when the line does not end with a wide character) and\n * `newCols - 1` (when the line does end with a wide character), except for the last value which\n * will contain the remaining items to fill the line.\n *\n * Calling this with a `newCols` value of `1` will lock up.\n *\n * @param wrappedLines The wrapped lines to evaluate.\n * @param oldCols The columns before resize.\n * @param newCols The columns after resize.\n */\nexport function reflowSmallerGetNewLineLengths(wrappedLines: BufferLine[], oldCols: number, newCols: number): number[] {\n  const newLineLengths: number[] = [];\n  const cellsNeeded = wrappedLines.map((l, i) => getWrappedLineTrimmedLength(wrappedLines, i, oldCols)).reduce((p, c) => p + c);\n\n  // Use srcCol and srcLine to find the new wrapping point, use that to get the cellsAvailable and\n  // linesNeeded\n  let srcCol = 0;\n  let srcLine = 0;\n  let cellsAvailable = 0;\n  while (cellsAvailable < cellsNeeded) {\n    if (cellsNeeded - cellsAvailable < newCols) {\n      // Add the final line and exit the loop\n      newLineLengths.push(cellsNeeded - cellsAvailable);\n      break;\n    }\n    srcCol += newCols;\n    const oldTrimmedLength = getWrappedLineTrimmedLength(wrappedLines, srcLine, oldCols);\n    if (srcCol > oldTrimmedLength) {\n      srcCol -= oldTrimmedLength;\n      srcLine++;\n    }\n    const endsWithWide = wrappedLines[srcLine].getWidth(srcCol - 1) === 2;\n    if (endsWithWide) {\n      srcCol--;\n    }\n    const lineLength = endsWithWide ? newCols - 1 : newCols;\n    newLineLengths.push(lineLength);\n    cellsAvailable += lineLength;\n  }\n\n  return newLineLengths;\n}\n\nexport function getWrappedLineTrimmedLength(lines: BufferLine[], i: number, cols: number): number {\n  // If this is the last row in the wrapped line, get the actual trimmed length\n  if (i === lines.length - 1) {\n    return lines[i].getTrimmedLength();\n  }\n  // Detect whether the following line starts with a wide character and the end of the current line\n  // is null, if so then we can be pretty sure the null character should be excluded from the line\n  // length]\n  const endsInNull = !(lines[i].hasContent(cols - 1)) && lines[i].getWidth(cols - 1) === 1;\n  const followingLineStartsWithWide = lines[i + 1].getWidth(0) === 2;\n  if (endsInNull && followingLineStartsWithWide) {\n    return cols - 1;\n  }\n  return cols;\n}\n","/**\n * Copyright (c) 2018 The xterm.js authors. All rights reserved.\n * @license MIT\n */\nimport { CharData, IBufferLine, ICellData, IColorRGB, IAttributeData } from './Types';\nimport { NULL_CELL_CODE, NULL_CELL_WIDTH, NULL_CELL_CHAR, CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, WHITESPACE_CELL_CHAR, CHAR_DATA_ATTR_INDEX } from './Buffer';\nimport { stringFromCodePoint } from './core/input/TextDecoder';\n\n\n/**\n * buffer memory layout:\n *\n *   |             uint32_t             |        uint32_t         |        uint32_t         |\n *   |             `content`            |          `FG`           |          `BG`           |\n *   | wcwidth(2) comb(1) codepoint(21) | flags(8) R(8) G(8) B(8) | flags(8) R(8) G(8) B(8) |\n */\n\n\n/** typed array slots taken by one cell */\nconst CELL_SIZE = 3;\n\n/**\n * Cell member indices.\n *\n * Direct access:\n *    `content = data[column * CELL_SIZE + Cell.CONTENT];`\n *    `fg = data[column * CELL_SIZE + Cell.FG];`\n *    `bg = data[column * CELL_SIZE + Cell.BG];`\n */\nconst enum Cell {\n  CONTENT = 0,\n  FG = 1, // currently simply holds all known attrs\n  BG = 2  // currently unused\n}\n\n/**\n * Bitmasks for accessing data in `content`.\n */\nexport const enum Content {\n  /**\n   * bit 1..21    codepoint, max allowed in UTF32 is 0x10FFFF (21 bits taken)\n   *              read:   `codepoint = content & Content.codepointMask;`\n   *              write:  `content |= codepoint & Content.codepointMask;`\n   *                      shortcut if precondition `codepoint <= 0x10FFFF` is met:\n   *                      `content |= codepoint;`\n   */\n  CODEPOINT_MASK = 0x1FFFFF,\n\n  /**\n   * bit 22       flag indication whether a cell contains combined content\n   *              read:   `isCombined = content & Content.isCombined;`\n   *              set:    `content |= Content.isCombined;`\n   *              clear:  `content &= ~Content.isCombined;`\n   */\n  IS_COMBINED_MASK = 0x200000,  // 1 << 21\n\n  /**\n   * bit 1..22    mask to check whether a cell contains any string data\n   *              we need to check for codepoint and isCombined bits to see\n   *              whether a cell contains anything\n   *              read:   `isEmpty = !(content & Content.hasContent)`\n   */\n  HAS_CONTENT_MASK = 0x3FFFFF,\n\n  /**\n   * bit 23..24   wcwidth value of cell, takes 2 bits (ranges from 0..2)\n   *              read:   `width = (content & Content.widthMask) >> Content.widthShift;`\n   *                      `hasWidth = content & Content.widthMask;`\n   *                      as long as wcwidth is highest value in `content`:\n   *                      `width = content >> Content.widthShift;`\n   *              write:  `content |= (width << Content.widthShift) & Content.widthMask;`\n   *                      shortcut if precondition `0 <= width <= 3` is met:\n   *                      `content |= width << Content.widthShift;`\n   */\n  WIDTH_MASK = 0xC00000,   // 3 << 22\n  WIDTH_SHIFT = 22\n}\n\n\nexport const enum Attributes {\n  /**\n   * bit 1..8     blue in RGB, color in P256 and P16\n   */\n  BLUE_MASK = 0xFF,\n  BLUE_SHIFT = 0,\n  PCOLOR_MASK = 0xFF,\n  PCOLOR_SHIFT = 0,\n\n  /**\n   * bit 9..16    green in RGB\n   */\n  GREEN_MASK = 0xFF00,\n  GREEN_SHIFT = 8,\n\n  /**\n   * bit 17..24   red in RGB\n   */\n  RED_MASK = 0xFF0000,\n  RED_SHIFT = 16,\n\n  /**\n   * bit 25..26   color mode: DEFAULT (0) | P16 (1) | P256 (2) | RGB (3)\n   */\n  CM_MASK = 0x3000000,\n  CM_DEFAULT = 0,\n  CM_P16 = 0x1000000,\n  CM_P256 = 0x2000000,\n  CM_RGB = 0x3000000,\n\n  /**\n   * bit 1..24  RGB room\n   */\n  RGB_MASK = 0xFFFFFF\n}\n\nexport const enum FgFlags {\n  /**\n   * bit 27..31 (32th bit unused)\n   */\n  INVERSE = 0x4000000,\n  BOLD = 0x8000000,\n  UNDERLINE = 0x10000000,\n  BLINK = 0x20000000,\n  INVISIBLE = 0x40000000\n}\n\nexport const enum BgFlags {\n  /**\n   * bit 27..32 (upper 4 unused)\n   */\n  ITALIC = 0x4000000,\n  DIM = 0x8000000\n}\n\nexport class AttributeData implements IAttributeData {\n  static toColorRGB(value: number): IColorRGB {\n    return [\n      value >>> Attributes.RED_SHIFT & 255,\n      value >>> Attributes.GREEN_SHIFT & 255,\n      value & 255\n    ];\n  }\n  static fromColorRGB(value: IColorRGB): number {\n    return (value[0] & 255) << Attributes.RED_SHIFT | (value[1] & 255) << Attributes.GREEN_SHIFT | value[2] & 255;\n  }\n\n  public clone(): IAttributeData {\n    const newObj = new AttributeData();\n    newObj.fg = this.fg;\n    newObj.bg = this.bg;\n    return newObj;\n  }\n\n  // data\n  public fg: number = 0;\n  public bg: number = 0;\n\n  // flags\n  public isInverse(): number   { return this.fg & FgFlags.INVERSE; }\n  public isBold(): number      { return this.fg & FgFlags.BOLD; }\n  public isUnderline(): number { return this.fg & FgFlags.UNDERLINE; }\n  public isBlink(): number     { return this.fg & FgFlags.BLINK; }\n  public isInvisible(): number { return this.fg & FgFlags.INVISIBLE; }\n  public isItalic(): number    { return this.bg & BgFlags.ITALIC; }\n  public isDim(): number       { return this.bg & BgFlags.DIM; }\n\n  // color modes\n  public getFgColorMode(): number { return this.fg & Attributes.CM_MASK; }\n  public getBgColorMode(): number { return this.bg & Attributes.CM_MASK; }\n  public isFgRGB(): boolean       { return (this.fg & Attributes.CM_MASK) === Attributes.CM_RGB; }\n  public isBgRGB(): boolean       { return (this.bg & Attributes.CM_MASK) === Attributes.CM_RGB; }\n  public isFgPalette(): boolean   { return (this.fg & Attributes.CM_MASK) === Attributes.CM_P16 || (this.fg & Attributes.CM_MASK) === Attributes.CM_P256; }\n  public isBgPalette(): boolean   { return (this.bg & Attributes.CM_MASK) === Attributes.CM_P16 || (this.bg & Attributes.CM_MASK) === Attributes.CM_P256; }\n  public isFgDefault(): boolean   { return (this.fg & Attributes.CM_MASK) === 0; }\n  public isBgDefault(): boolean   { return (this.bg & Attributes.CM_MASK) === 0; }\n\n  // colors\n  public getFgColor(): number {\n    switch (this.fg & Attributes.CM_MASK) {\n      case Attributes.CM_P16:\n      case Attributes.CM_P256:  return this.fg & Attributes.PCOLOR_MASK;\n      case Attributes.CM_RGB:   return this.fg & Attributes.RGB_MASK;\n      default:                  return -1;  // CM_DEFAULT defaults to -1\n    }\n  }\n  public getBgColor(): number {\n    switch (this.bg & Attributes.CM_MASK) {\n      case Attributes.CM_P16:\n      case Attributes.CM_P256:  return this.bg & Attributes.PCOLOR_MASK;\n      case Attributes.CM_RGB:   return this.bg & Attributes.RGB_MASK;\n      default:                  return -1;  // CM_DEFAULT defaults to -1\n    }\n  }\n}\n\n/**\n * CellData - represents a single Cell in the terminal buffer.\n */\nexport class CellData extends AttributeData implements ICellData {\n\n  /** Helper to create CellData from CharData. */\n  public static fromCharData(value: CharData): CellData {\n    const obj = new CellData();\n    obj.setFromCharData(value);\n    return obj;\n  }\n\n  /** Primitives from terminal buffer. */\n  public content: number = 0;\n  public fg: number = 0;\n  public bg: number = 0;\n  public combinedData: string = '';\n\n  /** Whether cell contains a combined string. */\n  public isCombined(): number {\n    return this.content & Content.IS_COMBINED_MASK;\n  }\n\n  /** Width of the cell. */\n  public getWidth(): number {\n    return this.content >> Content.WIDTH_SHIFT;\n  }\n\n  /** JS string of the content. */\n  public getChars(): string {\n    if (this.content & Content.IS_COMBINED_MASK) {\n      return this.combinedData;\n    }\n    if (this.content & Content.CODEPOINT_MASK) {\n      return stringFromCodePoint(this.content & Content.CODEPOINT_MASK);\n    }\n    return '';\n  }\n\n  /**\n   * Codepoint of cell\n   * Note this returns the UTF32 codepoint of single chars,\n   * if content is a combined string it returns the codepoint\n   * of the last char in string to be in line with code in CharData.\n   * */\n  public getCode(): number {\n    return (this.isCombined())\n      ? this.combinedData.charCodeAt(this.combinedData.length - 1)\n      : this.content & Content.CODEPOINT_MASK;\n  }\n\n  /** Set data from CharData */\n  public setFromCharData(value: CharData): void {\n    this.fg = value[CHAR_DATA_ATTR_INDEX];\n    this.bg = 0;\n    let combined = false;\n\n    // surrogates and combined strings need special treatment\n    if (value[CHAR_DATA_CHAR_INDEX].length > 2) {\n      combined = true;\n    } else if (value[CHAR_DATA_CHAR_INDEX].length === 2) {\n      const code = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0);\n      // if the 2-char string is a surrogate create single codepoint\n      // everything else is combined\n      if (0xD800 <= code && code <= 0xDBFF) {\n        const second = value[CHAR_DATA_CHAR_INDEX].charCodeAt(1);\n        if (0xDC00 <= second && second <= 0xDFFF) {\n          this.content = ((code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n        } else {\n          combined = true;\n        }\n      } else {\n        combined = true;\n      }\n    } else {\n      this.content = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n    }\n    if (combined) {\n      this.combinedData = value[CHAR_DATA_CHAR_INDEX];\n      this.content = Content.IS_COMBINED_MASK | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n    }\n  }\n\n  /** Get data as CharData. */\n  public getAsCharData(): CharData {\n    return [this.fg, this.getChars(), this.getWidth(), this.getCode()];\n  }\n}\n\n\n/**\n * Typed array based bufferline implementation.\n *\n * There are 2 ways to insert data into the cell buffer:\n * - `setCellFromCodepoint` + `addCodepointToCell`\n *   Use these for data that is already UTF32.\n *   Used during normal input in `InputHandler` for faster buffer access.\n * - `setCell`\n *   This method takes a CellData object and stores the data in the buffer.\n *   Use `CellData.fromCharData` to create the CellData object (e.g. from JS string).\n *\n * To retrieve data from the buffer use either one of the primitive methods\n * (if only one particular value is needed) or `loadCell`. For `loadCell` in a loop\n * memory allocs / GC pressure can be greatly reduced by reusing the CellData object.\n */\nexport class BufferLine implements IBufferLine {\n  protected _data: Uint32Array | null = null;\n  protected _combined: {[index: number]: string} = {};\n  public length: number;\n\n  constructor(cols: number, fillCellData?: ICellData, public isWrapped: boolean = false) {\n    if (cols) {\n      this._data = new Uint32Array(cols * CELL_SIZE);\n      const cell = fillCellData || CellData.fromCharData([0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]);\n      for (let i = 0; i < cols; ++i) {\n        this.setCell(i, cell);\n      }\n    }\n    this.length = cols;\n  }\n\n  /**\n   * Get cell data CharData.\n   * @deprecated\n   */\n  public get(index: number): CharData {\n    const content = this._data[index * CELL_SIZE + Cell.CONTENT];\n    const cp = content & Content.CODEPOINT_MASK;\n    return [\n      this._data[index * CELL_SIZE + Cell.FG],\n      (content & Content.IS_COMBINED_MASK)\n        ? this._combined[index]\n        : (cp) ? stringFromCodePoint(cp) : '',\n      content >> Content.WIDTH_SHIFT,\n      (content & Content.IS_COMBINED_MASK)\n        ? this._combined[index].charCodeAt(this._combined[index].length - 1)\n        : cp\n    ];\n  }\n\n  /**\n   * Set cell data from CharData.\n   * @deprecated\n   */\n  public set(index: number, value: CharData): void {\n    this._data[index * CELL_SIZE + Cell.FG] = value[CHAR_DATA_ATTR_INDEX];\n    if (value[CHAR_DATA_CHAR_INDEX].length > 1) {\n      this._combined[index] = value[1];\n      this._data[index * CELL_SIZE + Cell.CONTENT] = index | Content.IS_COMBINED_MASK | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n    } else {\n      this._data[index * CELL_SIZE + Cell.CONTENT] = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);\n    }\n  }\n\n  /**\n   * primitive getters\n   * use these when only one value is needed, otherwise use `loadCell`\n   */\n  public getWidth(index: number): number {\n    return this._data[index * CELL_SIZE + Cell.CONTENT] >> Content.WIDTH_SHIFT;\n  }\n\n  /** Test whether content has width. */\n  public hasWidth(index: number): number {\n    return this._data[index * CELL_SIZE + Cell.CONTENT] & Content.WIDTH_MASK;\n  }\n\n  /** Get FG cell component. */\n  public getFg(index: number): number {\n    return this._data[index * CELL_SIZE + Cell.FG];\n  }\n\n  /** Get BG cell component. */\n  public getBg(index: number): number {\n    return this._data[index * CELL_SIZE + Cell.BG];\n  }\n\n  /**\n   * Test whether contains any chars.\n   * Basically an empty has no content, but other cells might differ in FG/BG\n   * from real empty cells.\n   * */\n  public hasContent(index: number): number {\n    return this._data[index * CELL_SIZE + Cell.CONTENT] & Content.HAS_CONTENT_MASK;\n  }\n\n  /**\n   * Get codepoint of the cell.\n   * To be in line with `code` in CharData this either returns\n   * a single UTF32 codepoint or the last codepoint of a combined string.\n   */\n  public getCodePoint(index: number): number {\n    const content = this._data[index * CELL_SIZE + Cell.CONTENT];\n    if (content & Content.IS_COMBINED_MASK) {\n      return this._combined[index].charCodeAt(this._combined[index].length - 1);\n    }\n    return content & Content.CODEPOINT_MASK;\n  }\n\n  /** Test whether the cell contains a combined string. */\n  public isCombined(index: number): number {\n    return this._data[index * CELL_SIZE + Cell.CONTENT] & Content.IS_COMBINED_MASK;\n  }\n\n  /** Returns the string content of the cell. */\n  public getString(index: number): string {\n    const content = this._data[index * CELL_SIZE + Cell.CONTENT];\n    if (content & Content.IS_COMBINED_MASK) {\n      return this._combined[index];\n    }\n    if (content & Content.CODEPOINT_MASK) {\n      return stringFromCodePoint(content & Content.CODEPOINT_MASK);\n    }\n    // return empty string for empty cells\n    return '';\n  }\n\n  /**\n   * Load data at `index` into `cell`. This is used to access cells in a way that's more friendly\n   * to GC as it significantly reduced the amount of new objects/references needed.\n   */\n  public loadCell(index: number, cell: ICellData): ICellData {\n    const startIndex = index * CELL_SIZE;\n    cell.content = this._data[startIndex + Cell.CONTENT];\n    cell.fg = this._data[startIndex + Cell.FG];\n    cell.bg = this._data[startIndex + Cell.BG];\n    if (cell.content & Content.IS_COMBINED_MASK) {\n      cell.combinedData = this._combined[index];\n    }\n    return cell;\n  }\n\n  /**\n   * Set data at `index` to `cell`.\n   */\n  public setCell(index: number, cell: ICellData): void {\n    if (cell.content & Content.IS_COMBINED_MASK) {\n      this._combined[index] = cell.combinedData;\n    }\n    this._data[index * CELL_SIZE + Cell.CONTENT] = cell.content;\n    this._data[index * CELL_SIZE + Cell.FG] = cell.fg;\n    this._data[index * CELL_SIZE + Cell.BG] = cell.bg;\n  }\n\n  /**\n   * Set cell data from input handler.\n   * Since the input handler see the incoming chars as UTF32 codepoints,\n   * it gets an optimized access method.\n   */\n  public setCellFromCodePoint(index: number, codePoint: number, width: number, fg: number, bg: number): void {\n    this._data[index * CELL_SIZE + Cell.CONTENT] = codePoint | (width << Content.WIDTH_SHIFT);\n    this._data[index * CELL_SIZE + Cell.FG] = fg;\n    this._data[index * CELL_SIZE + Cell.BG] = bg;\n  }\n\n  /**\n   * Add a codepoint to a cell from input handler.\n   * During input stage combining chars with a width of 0 follow and stack\n   * onto a leading char. Since we already set the attrs\n   * by the previous `setDataFromCodePoint` call, we can omit it here.\n   */\n  public addCodepointToCell(index: number, codePoint: number): void {\n    let content = this._data[index * CELL_SIZE + Cell.CONTENT];\n    if (content & Content.IS_COMBINED_MASK) {\n      // we already have a combined string, simply add\n      this._combined[index] += stringFromCodePoint(codePoint);\n    } else {\n      if (content & Content.CODEPOINT_MASK) {\n        // normal case for combining chars:\n        //  - move current leading char + new one into combined string\n        //  - set combined flag\n        this._combined[index] = stringFromCodePoint(content & Content.CODEPOINT_MASK) + stringFromCodePoint(codePoint);\n        content &= ~Content.CODEPOINT_MASK; // set codepoint in buffer to 0\n        content |= Content.IS_COMBINED_MASK;\n      } else {\n        // should not happen - we actually have no data in the cell yet\n        // simply set the data in the cell buffer with a width of 1\n        content = codePoint | (1 << Content.WIDTH_SHIFT);\n      }\n      this._data[index * CELL_SIZE + Cell.CONTENT] = content;\n    }\n  }\n\n  public insertCells(pos: number, n: number, fillCellData: ICellData): void {\n    pos %= this.length;\n    if (n < this.length - pos) {\n      const cell = new CellData();\n      for (let i = this.length - pos - n - 1; i >= 0; --i) {\n        this.setCell(pos + n + i, this.loadCell(pos + i, cell));\n      }\n      for (let i = 0; i < n; ++i) {\n        this.setCell(pos + i, fillCellData);\n      }\n    } else {\n      for (let i = pos; i < this.length; ++i) {\n        this.setCell(i, fillCellData);\n      }\n    }\n  }\n\n  public deleteCells(pos: number, n: number, fillCellData: ICellData): void {\n    pos %= this.length;\n    if (n < this.length - pos) {\n      const cell = new CellData();\n      for (let i = 0; i < this.length - pos - n; ++i) {\n        this.setCell(pos + i, this.loadCell(pos + n + i, cell));\n      }\n      for (let i = this.length - n; i < this.length; ++i) {\n        this.setCell(i, fillCellData);\n      }\n    } else {\n      for (let i = pos; i < this.length; ++i) {\n        this.setCell(i, fillCellData);\n      }\n    }\n  }\n\n  public replaceCells(start: number, end: number, fillCellData: ICellData): void {\n    while (start < end  && start < this.length) {\n      this.setCell(start++, fillCellData);\n    }\n  }\n\n  public resize(cols: number, fillCellData: ICellData): void {\n    if (cols === this.length) {\n      return;\n    }\n    if (cols > this.length) {\n      const data = new Uint32Array(cols * CELL_SIZE);\n      if (this.length) {\n        if (cols * CELL_SIZE < this._data.length) {\n          data.set(this._data.subarray(0, cols * CELL_SIZE));\n        } else {\n          data.set(this._data);\n        }\n      }\n      this._data = data;\n      for (let i = this.length; i < cols; ++i) {\n        this.setCell(i, fillCellData);\n      }\n    } else {\n      if (cols) {\n        const data = new Uint32Array(cols * CELL_SIZE);\n        data.set(this._data.subarray(0, cols * CELL_SIZE));\n        this._data = data;\n        // Remove any cut off combined data\n        const keys = Object.keys(this._combined);\n        for (let i = 0; i < keys.length; i++) {\n          const key = parseInt(keys[i], 10);\n          if (key >= cols) {\n            delete this._combined[key];\n          }\n        }\n      } else {\n        this._data = null;\n        this._combined = {};\n      }\n    }\n    this.length = cols;\n  }\n\n  /** fill a line with fillCharData */\n  public fill(fillCellData: ICellData): void {\n    this._combined = {};\n    for (let i = 0; i < this.length; ++i) {\n      this.setCell(i, fillCellData);\n    }\n  }\n\n  /** alter to a full copy of line  */\n  public copyFrom(line: BufferLine): void {\n    if (this.length !== line.length) {\n      this._data = new Uint32Array(line._data);\n    } else {\n      // use high speed copy if lengths are equal\n      this._data.set(line._data);\n    }\n    this.length = line.length;\n    this._combined = {};\n    for (const el in line._combined) {\n      this._combined[el] = line._combined[el];\n    }\n    this.isWrapped = line.isWrapped;\n  }\n\n  /** create a new clone */\n  public clone(): IBufferLine {\n    const newLine = new BufferLine(0);\n    newLine._data = new Uint32Array(this._data);\n    newLine.length = this.length;\n    for (const el in this._combined) {\n      newLine._combined[el] = this._combined[el];\n    }\n    newLine.isWrapped = this.isWrapped;\n    return newLine;\n  }\n\n  public getTrimmedLength(): number {\n    for (let i = this.length - 1; i >= 0; --i) {\n      if ((this._data[i * CELL_SIZE + Cell.CONTENT] & Content.HAS_CONTENT_MASK)) {\n        return i + (this._data[i * CELL_SIZE + Cell.CONTENT] >> Content.WIDTH_SHIFT);\n      }\n    }\n    return 0;\n  }\n\n  public copyCellsFrom(src: BufferLine, srcCol: number, destCol: number, length: number, applyInReverse: boolean): void {\n    const srcData = src._data;\n    if (applyInReverse) {\n      for (let cell = length - 1; cell >= 0; cell--) {\n        for (let i = 0; i < CELL_SIZE; i++) {\n          this._data[(destCol + cell) * CELL_SIZE + i] = srcData[(srcCol + cell) * CELL_SIZE + i];\n        }\n      }\n    } else {\n      for (let cell = 0; cell < length; cell++) {\n        for (let i = 0; i < CELL_SIZE; i++) {\n          this._data[(destCol + cell) * CELL_SIZE + i] = srcData[(srcCol + cell) * CELL_SIZE + i];\n        }\n      }\n    }\n\n    // Move any combined data over as needed\n    const srcCombinedKeys = Object.keys(src._combined);\n    for (let i = 0; i < srcCombinedKeys.length; i++) {\n      const key = parseInt(srcCombinedKeys[i], 10);\n      if (key >= srcCol) {\n        this._combined[key - srcCol + destCol] = src._combined[key];\n      }\n    }\n  }\n\n  public translateToString(trimRight: boolean = false, startCol: number = 0, endCol: number = this.length): string {\n    if (trimRight) {\n      endCol = Math.min(endCol, this.getTrimmedLength());\n    }\n    let result = '';\n    while (startCol < endCol) {\n      const content = this._data[startCol * CELL_SIZE + Cell.CONTENT];\n      const cp = content & Content.CODEPOINT_MASK;\n      result += (content & Content.IS_COMBINED_MASK) ? this._combined[startCol] : (cp) ? stringFromCodePoint(cp) : WHITESPACE_CELL_CHAR;\n      startCol += (content >> Content.WIDTH_SHIFT) || 1; // always advance by 1\n    }\n    return result;\n  }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { CircularList, IInsertEvent } from './common/CircularList';\nimport { ITerminal, IBuffer, IBufferLine, BufferIndex, IBufferStringIterator, IBufferStringIteratorResult, ICellData, IAttributeData } from './Types';\nimport { IMarker } from 'xterm';\nimport { BufferLine, CellData, AttributeData } from './BufferLine';\nimport { reflowLargerApplyNewLayout, reflowLargerCreateNewLayout, reflowLargerGetLinesToRemove, reflowSmallerGetNewLineLengths, getWrappedLineTrimmedLength } from './BufferReflow';\nimport { DEFAULT_COLOR } from './renderer/atlas/Types';\nimport { EventEmitter2, IEvent } from './common/EventEmitter2';\nimport { Disposable } from '../lib/common/Lifecycle';\n\nexport const DEFAULT_ATTR = (0 << 18) | (DEFAULT_COLOR << 9) | (256 << 0);\n\nexport const DEFAULT_ATTR_DATA = new AttributeData();\n\nexport const CHAR_DATA_ATTR_INDEX = 0;\nexport const CHAR_DATA_CHAR_INDEX = 1;\nexport const CHAR_DATA_WIDTH_INDEX = 2;\nexport const CHAR_DATA_CODE_INDEX = 3;\nexport const MAX_BUFFER_SIZE = 4294967295; // 2^32 - 1\n\n/**\n * Null cell - a real empty cell (containing nothing).\n * Note that code should always be 0 for a null cell as\n * several test condition of the buffer line rely on this.\n */\nexport const NULL_CELL_CHAR = '';\nexport const NULL_CELL_WIDTH = 1;\nexport const NULL_CELL_CODE = 0;\n\n/**\n * Whitespace cell.\n * This is meant as a replacement for empty cells when needed\n * during rendering lines to preserve correct aligment.\n */\nexport const WHITESPACE_CELL_CHAR = ' ';\nexport const WHITESPACE_CELL_WIDTH = 1;\nexport const WHITESPACE_CELL_CODE = 32;\n\n/**\n * This class represents a terminal buffer (an internal state of the terminal), where the\n * following information is stored (in high-level):\n *   - text content of this particular buffer\n *   - cursor position\n *   - scroll position\n */\nexport class Buffer implements IBuffer {\n  public lines: CircularList<IBufferLine>;\n  public ydisp: number;\n  public ybase: number;\n  public y: number;\n  public x: number;\n  public scrollBottom: number;\n  public scrollTop: number;\n  public tabs: any;\n  public savedY: number;\n  public savedX: number;\n  public savedCurAttrData = DEFAULT_ATTR_DATA.clone();\n  public markers: Marker[] = [];\n  private _nullCell: ICellData = CellData.fromCharData([0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]);\n  private _whitespaceCell: ICellData = CellData.fromCharData([0, WHITESPACE_CELL_CHAR, WHITESPACE_CELL_WIDTH, WHITESPACE_CELL_CODE]);\n  private _cols: number;\n  private _rows: number;\n\n  /**\n   * Create a new Buffer.\n   * @param _terminal The terminal the Buffer will belong to.\n   * @param _hasScrollback Whether the buffer should respect the scrollback of\n   * the terminal.\n   */\n  constructor(\n    private _terminal: ITerminal,\n    private _hasScrollback: boolean\n  ) {\n    this._cols = this._terminal.cols;\n    this._rows = this._terminal.rows;\n    this.clear();\n  }\n\n  public getNullCell(attr?: IAttributeData): ICellData {\n    if (attr) {\n      this._nullCell.fg = attr.fg;\n      this._nullCell.bg = attr.bg;\n    } else {\n      this._nullCell.fg = 0;\n      this._nullCell.bg = 0;\n    }\n    return this._nullCell;\n  }\n\n  public getWhitespaceCell(attr?: IAttributeData): ICellData {\n    if (attr) {\n      this._whitespaceCell.fg = attr.fg;\n      this._whitespaceCell.bg = attr.bg;\n    } else {\n      this._whitespaceCell.fg = 0;\n      this._whitespaceCell.bg = 0;\n    }\n    return this._whitespaceCell;\n  }\n\n  public getBlankLine(attr: IAttributeData, isWrapped?: boolean): IBufferLine {\n    return new BufferLine(this._terminal.cols, this.getNullCell(attr), isWrapped);\n  }\n\n  public get hasScrollback(): boolean {\n    return this._hasScrollback && this.lines.maxLength > this._rows;\n  }\n\n  public get isCursorInViewport(): boolean {\n    const absoluteY = this.ybase + this.y;\n    const relativeY = absoluteY - this.ydisp;\n    return (relativeY >= 0 && relativeY < this._rows);\n  }\n\n  /**\n   * Gets the correct buffer length based on the rows provided, the terminal's\n   * scrollback and whether this buffer is flagged to have scrollback or not.\n   * @param rows The terminal rows to use in the calculation.\n   */\n  private _getCorrectBufferLength(rows: number): number {\n    if (!this._hasScrollback) {\n      return rows;\n    }\n\n    const correctBufferLength = rows + this._terminal.options.scrollback;\n\n    return correctBufferLength > MAX_BUFFER_SIZE ? MAX_BUFFER_SIZE : correctBufferLength;\n  }\n\n  /**\n   * Fills the buffer's viewport with blank lines.\n   */\n  public fillViewportRows(fillAttr?: IAttributeData): void {\n    if (this.lines.length === 0) {\n      if (fillAttr === undefined) {\n        fillAttr = DEFAULT_ATTR_DATA;\n      }\n      let i = this._rows;\n      while (i--) {\n        this.lines.push(this.getBlankLine(fillAttr));\n      }\n    }\n  }\n\n  /**\n   * Clears the buffer to it's initial state, discarding all previous data.\n   */\n  public clear(): void {\n    this.ydisp = 0;\n    this.ybase = 0;\n    this.y = 0;\n    this.x = 0;\n    this.lines = new CircularList<IBufferLine>(this._getCorrectBufferLength(this._rows));\n    this.scrollTop = 0;\n    this.scrollBottom = this._rows - 1;\n    this.setupTabStops();\n  }\n\n  /**\n   * Resizes the buffer, adjusting its data accordingly.\n   * @param newCols The new number of columns.\n   * @param newRows The new number of rows.\n   */\n  public resize(newCols: number, newRows: number): void {\n    // store reference to null cell with default attrs\n    const nullCell = this.getNullCell(DEFAULT_ATTR_DATA);\n\n    // Increase max length if needed before adjustments to allow space to fill\n    // as required.\n    const newMaxLength = this._getCorrectBufferLength(newRows);\n    if (newMaxLength > this.lines.maxLength) {\n      this.lines.maxLength = newMaxLength;\n    }\n\n    // The following adjustments should only happen if the buffer has been\n    // initialized/filled.\n    if (this.lines.length > 0) {\n      // Deal with columns increasing (reducing needs to happen after reflow)\n      if (this._cols < newCols) {\n        for (let i = 0; i < this.lines.length; i++) {\n          this.lines.get(i).resize(newCols, nullCell);\n        }\n      }\n\n      // Resize rows in both directions as needed\n      let addToY = 0;\n      if (this._rows < newRows) {\n        for (let y = this._rows; y < newRows; y++) {\n          if (this.lines.length < newRows + this.ybase) {\n            if (this.ybase > 0 && this.lines.length <= this.ybase + this.y + addToY + 1) {\n              // There is room above the buffer and there are no empty elements below the line,\n              // scroll up\n              this.ybase--;\n              addToY++;\n              if (this.ydisp > 0) {\n                // Viewport is at the top of the buffer, must increase downwards\n                this.ydisp--;\n              }\n            } else {\n              // Add a blank line if there is no buffer left at the top to scroll to, or if there\n              // are blank lines after the cursor\n              this.lines.push(new BufferLine(newCols, nullCell));\n            }\n          }\n        }\n      } else { // (this._rows >= newRows)\n        for (let y = this._rows; y > newRows; y--) {\n          if (this.lines.length > newRows + this.ybase) {\n            if (this.lines.length > this.ybase + this.y + 1) {\n              // The line is a blank line below the cursor, remove it\n              this.lines.pop();\n            } else {\n              // The line is the cursor, scroll down\n              this.ybase++;\n              this.ydisp++;\n            }\n          }\n        }\n      }\n\n      // Reduce max length if needed after adjustments, this is done after as it\n      // would otherwise cut data from the bottom of the buffer.\n      if (newMaxLength < this.lines.maxLength) {\n        // Trim from the top of the buffer and adjust ybase and ydisp.\n        const amountToTrim = this.lines.length - newMaxLength;\n        if (amountToTrim > 0) {\n          this.lines.trimStart(amountToTrim);\n          this.ybase = Math.max(this.ybase - amountToTrim, 0);\n          this.ydisp = Math.max(this.ydisp - amountToTrim, 0);\n        }\n        this.lines.maxLength = newMaxLength;\n      }\n\n      // Make sure that the cursor stays on screen\n      this.x = Math.min(this.x, newCols - 1);\n      this.y = Math.min(this.y, newRows - 1);\n      if (addToY) {\n        this.y += addToY;\n      }\n      this.savedY = Math.min(this.savedY, newRows - 1);\n      this.savedX = Math.min(this.savedX, newCols - 1);\n\n      this.scrollTop = 0;\n    }\n\n    this.scrollBottom = newRows - 1;\n\n    if (this._isReflowEnabled) {\n      this._reflow(newCols, newRows);\n\n      // Trim the end of the line off if cols shrunk\n      if (this._cols > newCols) {\n        for (let i = 0; i < this.lines.length; i++) {\n          this.lines.get(i).resize(newCols, nullCell);\n        }\n      }\n    }\n\n    this._cols = newCols;\n    this._rows = newRows;\n  }\n\n  private get _isReflowEnabled(): boolean {\n    return this._hasScrollback && !this._terminal.options.windowsMode;\n  }\n\n  private _reflow(newCols: number, newRows: number): void {\n    if (this._cols === newCols) {\n      return;\n    }\n\n    // Iterate through rows, ignore the last one as it cannot be wrapped\n    if (newCols > this._cols) {\n      this._reflowLarger(newCols, newRows);\n    } else {\n      this._reflowSmaller(newCols, newRows);\n    }\n  }\n\n  private _reflowLarger(newCols: number, newRows: number): void {\n    const toRemove: number[] = reflowLargerGetLinesToRemove(this.lines, this._cols, newCols, this.ybase + this.y, this.getNullCell(DEFAULT_ATTR_DATA));\n    if (toRemove.length > 0) {\n      const newLayoutResult = reflowLargerCreateNewLayout(this.lines, toRemove);\n      reflowLargerApplyNewLayout(this.lines, newLayoutResult.layout);\n      this._reflowLargerAdjustViewport(newCols, newRows, newLayoutResult.countRemoved);\n    }\n  }\n\n  private _reflowLargerAdjustViewport(newCols: number, newRows: number, countRemoved: number): void {\n    const nullCell = this.getNullCell(DEFAULT_ATTR_DATA);\n    // Adjust viewport based on number of items removed\n    let viewportAdjustments = countRemoved;\n    while (viewportAdjustments-- > 0) {\n      if (this.ybase === 0) {\n        if (this.y > 0) {\n          this.y--;\n        }\n        if (this.lines.length < newRows) {\n          // Add an extra row at the bottom of the viewport\n          this.lines.push(new BufferLine(newCols, nullCell));\n        }\n      } else {\n        if (this.ydisp === this.ybase) {\n          this.ydisp--;\n        }\n        this.ybase--;\n      }\n    }\n  }\n\n  private _reflowSmaller(newCols: number, newRows: number): void {\n    const nullCell = this.getNullCell(DEFAULT_ATTR_DATA);\n    // Gather all BufferLines that need to be inserted into the Buffer here so that they can be\n    // batched up and only committed once\n    const toInsert = [];\n    let countToInsert = 0;\n    // Go backwards as many lines may be trimmed and this will avoid considering them\n    for (let y = this.lines.length - 1; y >= 0; y--) {\n      // Check whether this line is a problem\n      let nextLine = this.lines.get(y) as BufferLine;\n      if (!nextLine.isWrapped && nextLine.getTrimmedLength() <= newCols) {\n        continue;\n      }\n\n      // Gather wrapped lines and adjust y to be the starting line\n      const wrappedLines: BufferLine[] = [nextLine];\n      while (nextLine.isWrapped && y > 0) {\n        nextLine = this.lines.get(--y) as BufferLine;\n        wrappedLines.unshift(nextLine);\n      }\n\n      // If these lines contain the cursor don't touch them, the program will handle fixing up\n      // wrapped lines with the cursor\n      const absoluteY = this.ybase + this.y;\n      if (absoluteY >= y && absoluteY < y + wrappedLines.length) {\n        continue;\n      }\n\n      const lastLineLength = wrappedLines[wrappedLines.length - 1].getTrimmedLength();\n      const destLineLengths = reflowSmallerGetNewLineLengths(wrappedLines, this._cols, newCols);\n      const linesToAdd = destLineLengths.length - wrappedLines.length;\n      let trimmedLines: number;\n      if (this.ybase === 0 && this.y !== this.lines.length - 1) {\n        // If the top section of the buffer is not yet filled\n        trimmedLines = Math.max(0, this.y - this.lines.maxLength + linesToAdd);\n      } else {\n        trimmedLines = Math.max(0, this.lines.length - this.lines.maxLength + linesToAdd);\n      }\n\n      // Add the new lines\n      const newLines: BufferLine[] = [];\n      for (let i = 0; i < linesToAdd; i++) {\n        const newLine = this.getBlankLine(DEFAULT_ATTR_DATA, true) as BufferLine;\n        newLines.push(newLine);\n      }\n      if (newLines.length > 0) {\n        toInsert.push({\n          // countToInsert here gets the actual index, taking into account other inserted items.\n          // using this we can iterate through the list forwards\n          start: y + wrappedLines.length + countToInsert,\n          newLines\n        });\n        countToInsert += newLines.length;\n      }\n      wrappedLines.push(...newLines);\n\n      // Copy buffer data to new locations, this needs to happen backwards to do in-place\n      let destLineIndex = destLineLengths.length - 1; // Math.floor(cellsNeeded / newCols);\n      let destCol = destLineLengths[destLineIndex]; // cellsNeeded % newCols;\n      if (destCol === 0) {\n        destLineIndex--;\n        destCol = destLineLengths[destLineIndex];\n      }\n      let srcLineIndex = wrappedLines.length - linesToAdd - 1;\n      let srcCol = lastLineLength;\n      while (srcLineIndex >= 0) {\n        const cellsToCopy = Math.min(srcCol, destCol);\n        wrappedLines[destLineIndex].copyCellsFrom(wrappedLines[srcLineIndex], srcCol - cellsToCopy, destCol - cellsToCopy, cellsToCopy, true);\n        destCol -= cellsToCopy;\n        if (destCol === 0) {\n          destLineIndex--;\n          destCol = destLineLengths[destLineIndex];\n        }\n        srcCol -= cellsToCopy;\n        if (srcCol === 0) {\n          srcLineIndex--;\n          const wrappedLinesIndex = Math.max(srcLineIndex, 0);\n          srcCol = getWrappedLineTrimmedLength(wrappedLines, wrappedLinesIndex, this._cols);\n        }\n      }\n\n      // Null out the end of the line ends if a wide character wrapped to the following line\n      for (let i = 0; i < wrappedLines.length; i++) {\n        if (destLineLengths[i] < newCols) {\n          wrappedLines[i].setCell(destLineLengths[i], nullCell);\n        }\n      }\n\n      // Adjust viewport as needed\n      let viewportAdjustments = linesToAdd - trimmedLines;\n      while (viewportAdjustments-- > 0) {\n        if (this.ybase === 0) {\n          if (this.y < newRows - 1) {\n            this.y++;\n            this.lines.pop();\n          } else {\n            this.ybase++;\n            this.ydisp++;\n          }\n        } else {\n          // Ensure ybase does not exceed its maximum value\n          if (this.ybase < Math.min(this.lines.maxLength, this.lines.length + countToInsert) - newRows) {\n            if (this.ybase === this.ydisp) {\n              this.ydisp++;\n            }\n            this.ybase++;\n          }\n        }\n      }\n    }\n\n    // Rearrange lines in the buffer if there are any insertions, this is done at the end rather\n    // than earlier so that it's a single O(n) pass through the buffer, instead of O(n^2) from many\n    // costly calls to CircularList.splice.\n    if (toInsert.length > 0) {\n      // Record buffer insert events and then play them back backwards so that the indexes are\n      // correct\n      const insertEvents: IInsertEvent[] = [];\n\n      // Record original lines so they don't get overridden when we rearrange the list\n      const originalLines: BufferLine[] = [];\n      for (let i = 0; i < this.lines.length; i++) {\n        originalLines.push(this.lines.get(i) as BufferLine);\n      }\n      const originalLinesLength = this.lines.length;\n\n      let originalLineIndex = originalLinesLength - 1;\n      let nextToInsertIndex = 0;\n      let nextToInsert = toInsert[nextToInsertIndex];\n      this.lines.length = Math.min(this.lines.maxLength, this.lines.length + countToInsert);\n      let countInsertedSoFar = 0;\n      for (let i = Math.min(this.lines.maxLength - 1, originalLinesLength + countToInsert - 1); i >= 0; i--) {\n        if (nextToInsert && nextToInsert.start > originalLineIndex + countInsertedSoFar) {\n          // Insert extra lines here, adjusting i as needed\n          for (let nextI = nextToInsert.newLines.length - 1; nextI >= 0; nextI--) {\n            this.lines.set(i--, nextToInsert.newLines[nextI]);\n          }\n          i++;\n\n          // Create insert events for later\n          insertEvents.push({\n            index: originalLineIndex + 1,\n            amount: nextToInsert.newLines.length\n          });\n\n          countInsertedSoFar += nextToInsert.newLines.length;\n          nextToInsert = toInsert[++nextToInsertIndex];\n        } else {\n          this.lines.set(i, originalLines[originalLineIndex--]);\n        }\n      }\n\n      // Update markers\n      let insertCountEmitted = 0;\n      for (let i = insertEvents.length - 1; i >= 0; i--) {\n        insertEvents[i].index += insertCountEmitted;\n        this.lines.onInsertEmitter.fire(insertEvents[i]);\n        insertCountEmitted += insertEvents[i].amount;\n      }\n      const amountToTrim = Math.max(0, originalLinesLength + countToInsert - this.lines.maxLength);\n      if (amountToTrim > 0) {\n        this.lines.onTrimEmitter.fire(amountToTrim);\n      }\n    }\n  }\n\n  // private _reflowSmallerGetLinesNeeded()\n\n  /**\n   * Translates a string index back to a BufferIndex.\n   * To get the correct buffer position the string must start at `startCol` 0\n   * (default in translateBufferLineToString).\n   * The method also works on wrapped line strings given rows were not trimmed.\n   * The method operates on the CharData string length, there are no\n   * additional content or boundary checks. Therefore the string and the buffer\n   * should not be altered in between.\n   * TODO: respect trim flag after fixing #1685\n   * @param lineIndex line index the string was retrieved from\n   * @param stringIndex index within the string\n   * @param startCol column offset the string was retrieved from\n   */\n  public stringIndexToBufferIndex(lineIndex: number, stringIndex: number, trimRight: boolean = false): BufferIndex {\n    while (stringIndex) {\n      const line = this.lines.get(lineIndex);\n      if (!line) {\n        return [-1, -1];\n      }\n      const length = (trimRight) ? line.getTrimmedLength() : line.length;\n      for (let i = 0; i < length; ++i) {\n        if (line.get(i)[CHAR_DATA_WIDTH_INDEX]) {\n          // empty cells report a string length of 0, but get replaced\n          // with a whitespace in translateToString, thus replace with 1\n          stringIndex -= line.get(i)[CHAR_DATA_CHAR_INDEX].length || 1;\n        }\n        if (stringIndex < 0) {\n          return [lineIndex, i];\n        }\n      }\n      lineIndex++;\n    }\n    return [lineIndex, 0];\n  }\n\n  /**\n   * Translates a buffer line to a string, with optional start and end columns.\n   * Wide characters will count as two columns in the resulting string. This\n   * function is useful for getting the actual text underneath the raw selection\n   * position.\n   * @param line The line being translated.\n   * @param trimRight Whether to trim whitespace to the right.\n   * @param startCol The column to start at.\n   * @param endCol The column to end at.\n   */\n  public translateBufferLineToString(lineIndex: number, trimRight: boolean, startCol: number = 0, endCol?: number): string {\n    const line = this.lines.get(lineIndex);\n    if (!line) {\n      return '';\n    }\n    return line.translateToString(trimRight, startCol, endCol);\n  }\n\n  public getWrappedRangeForLine(y: number): { first: number, last: number } {\n    let first = y;\n    let last = y;\n    // Scan upwards for wrapped lines\n    while (first > 0 && this.lines.get(first).isWrapped) {\n      first--;\n    }\n    // Scan downwards for wrapped lines\n    while (last + 1 < this.lines.length && this.lines.get(last + 1).isWrapped) {\n      last++;\n    }\n    return { first, last };\n  }\n\n  /**\n   * Setup the tab stops.\n   * @param i The index to start setting up tab stops from.\n   */\n  public setupTabStops(i?: number): void {\n    if (i !== null && i !== undefined) {\n      if (!this.tabs[i]) {\n        i = this.prevStop(i);\n      }\n    } else {\n      this.tabs = {};\n      i = 0;\n    }\n\n    for (; i < this._cols; i += this._terminal.options.tabStopWidth) {\n      this.tabs[i] = true;\n    }\n  }\n\n  /**\n   * Move the cursor to the previous tab stop from the given position (default is current).\n   * @param x The position to move the cursor to the previous tab stop.\n   */\n  public prevStop(x?: number): number {\n    if (x === null || x === undefined) {\n      x = this.x;\n    }\n    while (!this.tabs[--x] && x > 0);\n    return x >= this._cols ? this._cols - 1 : x < 0 ? 0 : x;\n  }\n\n  /**\n   * Move the cursor one tab stop forward from the given position (default is current).\n   * @param x The position to move the cursor one tab stop forward.\n   */\n  public nextStop(x?: number): number {\n    if (x === null || x === undefined) {\n      x = this.x;\n    }\n    while (!this.tabs[++x] && x < this._cols);\n    return x >= this._cols ? this._cols - 1 : x < 0 ? 0 : x;\n  }\n\n  public addMarker(y: number): Marker {\n    const marker = new Marker(y);\n    this.markers.push(marker);\n    marker.register(this.lines.onTrim(amount => {\n      marker.line -= amount;\n      // The marker should be disposed when the line is trimmed from the buffer\n      if (marker.line < 0) {\n        marker.dispose();\n      }\n    }));\n    marker.register(this.lines.onInsert(event => {\n      if (marker.line >= event.index) {\n        marker.line += event.amount;\n      }\n    }));\n    marker.register(this.lines.onDelete(event => {\n      // Delete the marker if it's within the range\n      if (marker.line >= event.index && marker.line < event.index + event.amount) {\n        marker.dispose();\n      }\n\n      // Shift the marker if it's after the deleted range\n      if (marker.line > event.index) {\n        marker.line -= event.amount;\n      }\n    }));\n    marker.register(marker.onDispose(() => this._removeMarker(marker)));\n    return marker;\n  }\n\n  private _removeMarker(marker: Marker): void {\n    this.markers.splice(this.markers.indexOf(marker), 1);\n  }\n\n  public iterator(trimRight: boolean, startIndex?: number, endIndex?: number, startOverscan?: number, endOverscan?: number): IBufferStringIterator {\n    return new BufferStringIterator(this, trimRight, startIndex, endIndex, startOverscan, endOverscan);\n  }\n}\n\nexport class Marker extends Disposable implements IMarker {\n  private static _nextId = 1;\n\n  private _id: number = Marker._nextId++;\n  public isDisposed: boolean = false;\n\n  public get id(): number { return this._id; }\n\n  private _onDispose = new EventEmitter2<void>();\n  public get onDispose(): IEvent<void> { return this._onDispose.event; }\n\n  constructor(\n    public line: number\n  ) {\n    super();\n  }\n\n  public dispose(): void {\n    if (this.isDisposed) {\n      return;\n    }\n    this.isDisposed = true;\n    // Emit before super.dispose such that dispose listeners get a change to react\n    this._onDispose.fire();\n  }\n}\n\n/**\n * Iterator to get unwrapped content strings from the buffer.\n * The iterator returns at least the string data between the borders\n * `startIndex` and `endIndex` (exclusive) and will expand the lines\n * by `startOverscan` to the top and by `endOverscan` to the bottom,\n * if no new line was found in between.\n * It will never read/return string data beyond `startIndex - startOverscan`\n * or `endIndex + endOverscan`. Therefore the first and last line might be truncated.\n * It is possible to always get the full string for the first and last line as well\n * by setting the overscan values to the actual buffer length. This not recommended\n * since it might return the whole buffer within a single string in a worst case scenario.\n */\nexport class BufferStringIterator implements IBufferStringIterator {\n  private _current: number;\n\n  constructor (\n    private _buffer: IBuffer,\n    private _trimRight: boolean,\n    private _startIndex: number = 0,\n    private _endIndex: number = _buffer.lines.length,\n    private _startOverscan: number = 0,\n    private _endOverscan: number = 0\n  ) {\n    if (this._startIndex < 0) {\n      this._startIndex = 0;\n    }\n    if (this._endIndex > this._buffer.lines.length) {\n      this._endIndex = this._buffer.lines.length;\n    }\n    this._current = this._startIndex;\n  }\n\n  public hasNext(): boolean {\n    return this._current < this._endIndex;\n  }\n\n  public next(): IBufferStringIteratorResult {\n    const range = this._buffer.getWrappedRangeForLine(this._current);\n    // limit search window to overscan value at both borders\n    if (range.first < this._startIndex - this._startOverscan) {\n      range.first = this._startIndex - this._startOverscan;\n    }\n    if (range.last > this._endIndex + this._endOverscan) {\n      range.last = this._endIndex + this._endOverscan;\n    }\n    // limit to current buffer length\n    range.first = Math.max(range.first, 0);\n    range.last = Math.min(range.last, this._buffer.lines.length);\n    let result = '';\n    for (let i = range.first; i <= range.last; ++i) {\n      result += this._buffer.translateBufferLineToString(i, this._trimRight);\n    }\n    this._current = range.last + 1;\n    return {range: range, content: result};\n  }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport * as Strings from './Strings';\nimport { ITerminal, IBuffer } from './Types';\nimport { isMac } from './common/Platform';\nimport { RenderDebouncer } from './ui/RenderDebouncer';\nimport { addDisposableDomListener } from './ui/Lifecycle';\nimport { Disposable } from './common/Lifecycle';\n\nconst MAX_ROWS_TO_READ = 20;\n\nconst enum BoundaryPosition {\n  TOP,\n  BOTTOM\n}\n\nexport class AccessibilityManager extends Disposable {\n  private _accessibilityTreeRoot: HTMLElement;\n  private _rowContainer: HTMLElement;\n  private _rowElements: HTMLElement[];\n  private _liveRegion: HTMLElement;\n  private _liveRegionLineCount: number = 0;\n\n  private _renderRowsDebouncer: RenderDebouncer;\n\n  private _topBoundaryFocusListener: (e: FocusEvent) => void;\n  private _bottomBoundaryFocusListener: (e: FocusEvent) => void;\n\n  /**\n   * This queue has a character pushed to it for keys that are pressed, if the\n   * next character added to the terminal is equal to the key char then it is\n   * not announced (added to live region) because it has already been announced\n   * by the textarea event (which cannot be canceled). There are some race\n   * condition cases if there is typing while data is streaming, but this covers\n   * the main case of typing into the prompt and inputting the answer to a\n   * question (Y/N, etc.).\n   */\n  private _charsToConsume: string[] = [];\n\n  constructor(private _terminal: ITerminal) {\n    super();\n    this._accessibilityTreeRoot = document.createElement('div');\n    this._accessibilityTreeRoot.classList.add('xterm-accessibility');\n\n    this._rowContainer = document.createElement('div');\n    this._rowContainer.classList.add('xterm-accessibility-tree');\n    this._rowElements = [];\n    for (let i = 0; i < this._terminal.rows; i++) {\n      this._rowElements[i] = this._createAccessibilityTreeNode();\n      this._rowContainer.appendChild(this._rowElements[i]);\n    }\n\n    this._topBoundaryFocusListener = e => this._onBoundaryFocus(e, BoundaryPosition.TOP);\n    this._bottomBoundaryFocusListener = e => this._onBoundaryFocus(e, BoundaryPosition.BOTTOM);\n    this._rowElements[0].addEventListener('focus', this._topBoundaryFocusListener);\n    this._rowElements[this._rowElements.length - 1].addEventListener('focus', this._bottomBoundaryFocusListener);\n\n    this._refreshRowsDimensions();\n    this._accessibilityTreeRoot.appendChild(this._rowContainer);\n\n    this._renderRowsDebouncer = new RenderDebouncer(this._renderRows.bind(this));\n    this._refreshRows();\n\n    this._liveRegion = document.createElement('div');\n    this._liveRegion.classList.add('live-region');\n    this._liveRegion.setAttribute('aria-live', 'assertive');\n    this._accessibilityTreeRoot.appendChild(this._liveRegion);\n\n    this._terminal.element.insertAdjacentElement('afterbegin', this._accessibilityTreeRoot);\n\n    this.register(this._renderRowsDebouncer);\n    this.register(this._terminal.onResize(e => this._onResize(e.rows)));\n    this.register(this._terminal.onRender(e => this._refreshRows(e.start, e.end)));\n    this.register(this._terminal.onScroll(() => this._refreshRows()));\n    // Line feed is an issue as the prompt won't be read out after a command is run\n    this.register(this._terminal.addDisposableListener('a11y.char', (char) => this._onChar(char)));\n    this.register(this._terminal.onLineFeed(() => this._onChar('\\n')));\n    this.register(this._terminal.addDisposableListener('a11y.tab', spaceCount => this._onTab(spaceCount)));\n    this.register(this._terminal.onKey(e => this._onKey(e.key)));\n    this.register(this._terminal.addDisposableListener('blur', () => this._clearLiveRegion()));\n    // TODO: Maybe renderer should fire an event on terminal when the characters change and that\n    //       should be listened to instead? That would mean that the order of events are always\n    //       guarenteed\n    this.register(this._terminal.addDisposableListener('dprchange', () => this._refreshRowsDimensions()));\n    this.register(this._terminal.renderer.onCanvasResize(() => this._refreshRowsDimensions()));\n    // This shouldn't be needed on modern browsers but is present in case the\n    // media query that drives the dprchange event isn't supported\n    this.register(addDisposableDomListener(window, 'resize', () => this._refreshRowsDimensions()));\n  }\n\n  public dispose(): void {\n    super.dispose();\n    this._terminal.element.removeChild(this._accessibilityTreeRoot);\n    this._rowElements.length = 0;\n  }\n\n  private _onBoundaryFocus(e: FocusEvent, position: BoundaryPosition): void {\n    const boundaryElement = <HTMLElement>e.target;\n    const beforeBoundaryElement = this._rowElements[position === BoundaryPosition.TOP ? 1 : this._rowElements.length - 2];\n\n    // Don't scroll if the buffer top has reached the end in that direction\n    const posInSet = boundaryElement.getAttribute('aria-posinset');\n    const lastRowPos = position === BoundaryPosition.TOP ? '1' : `${this._terminal.buffer.lines.length}`;\n    if (posInSet === lastRowPos) {\n      return;\n    }\n\n    // Don't scroll when the last focused item was not the second row (focus is going the other\n    // direction)\n    if (e.relatedTarget !== beforeBoundaryElement) {\n      return;\n    }\n\n    // Remove old boundary element from array\n    let topBoundaryElement: HTMLElement;\n    let bottomBoundaryElement: HTMLElement;\n    if (position === BoundaryPosition.TOP) {\n      topBoundaryElement = boundaryElement;\n      bottomBoundaryElement = this._rowElements.pop()!;\n      this._rowContainer.removeChild(bottomBoundaryElement);\n    } else {\n      topBoundaryElement = this._rowElements.shift()!;\n      bottomBoundaryElement = boundaryElement;\n      this._rowContainer.removeChild(topBoundaryElement);\n    }\n\n    // Remove listeners from old boundary elements\n    topBoundaryElement.removeEventListener('focus', this._topBoundaryFocusListener);\n    bottomBoundaryElement.removeEventListener('focus', this._bottomBoundaryFocusListener);\n\n    // Add new element to array/DOM\n    if (position === BoundaryPosition.TOP) {\n      const newElement = this._createAccessibilityTreeNode();\n      this._rowElements.unshift(newElement);\n      this._rowContainer.insertAdjacentElement('afterbegin', newElement);\n    } else {\n      const newElement = this._createAccessibilityTreeNode();\n      this._rowElements.push(newElement);\n      this._rowContainer.appendChild(newElement);\n    }\n\n    // Add listeners to new boundary elements\n    this._rowElements[0].addEventListener('focus', this._topBoundaryFocusListener);\n    this._rowElements[this._rowElements.length - 1].addEventListener('focus', this._bottomBoundaryFocusListener);\n\n    // Scroll up\n    this._terminal.scrollLines(position === BoundaryPosition.TOP ? -1 : 1);\n\n    // Focus new boundary before element\n    this._rowElements[position === BoundaryPosition.TOP ? 1 : this._rowElements.length - 2].focus();\n\n    // Prevent the standard behavior\n    e.preventDefault();\n    e.stopImmediatePropagation();\n  }\n\n  private _onResize(rows: number): void {\n    // Remove bottom boundary listener\n    this._rowElements[this._rowElements.length - 1].removeEventListener('focus', this._bottomBoundaryFocusListener);\n\n    // Grow rows as required\n    for (let i = this._rowContainer.children.length; i < this._terminal.rows; i++) {\n      this._rowElements[i] = this._createAccessibilityTreeNode();\n      this._rowContainer.appendChild(this._rowElements[i]);\n    }\n    // Shrink rows as required\n    while (this._rowElements.length > rows) {\n      this._rowContainer.removeChild(this._rowElements.pop()!);\n    }\n\n    // Add bottom boundary listener\n    this._rowElements[this._rowElements.length - 1].addEventListener('focus', this._bottomBoundaryFocusListener);\n\n    this._refreshRowsDimensions();\n  }\n\n  private _createAccessibilityTreeNode(): HTMLElement {\n    const element = document.createElement('div');\n    element.setAttribute('role', 'listitem');\n    element.tabIndex = -1;\n    this._refreshRowDimensions(element);\n    return element;\n  }\n\n  private _onTab(spaceCount: number): void {\n    for (let i = 0; i < spaceCount; i++) {\n      this._onChar(' ');\n    }\n  }\n\n  private _onChar(char: string): void {\n    if (this._liveRegionLineCount < MAX_ROWS_TO_READ + 1) {\n      if (this._charsToConsume.length > 0) {\n        // Have the screen reader ignore the char if it was just input\n        const shiftedChar = this._charsToConsume.shift();\n        if (shiftedChar !== char) {\n          this._announceCharacter(char);\n        }\n      } else {\n        this._announceCharacter(char);\n      }\n\n      if (char === '\\n') {\n        this._liveRegionLineCount++;\n        if (this._liveRegionLineCount === MAX_ROWS_TO_READ + 1) {\n          this._liveRegion.textContent += Strings.tooMuchOutput;\n        }\n      }\n\n      // Only detach/attach on mac as otherwise messages can go unaccounced\n      if (isMac) {\n        if (this._liveRegion.textContent && this._liveRegion.textContent.length > 0 && !this._liveRegion.parentNode) {\n          setTimeout(() => {\n            this._accessibilityTreeRoot.appendChild(this._liveRegion);\n          }, 0);\n        }\n      }\n    }\n  }\n\n  private _clearLiveRegion(): void {\n    this._liveRegion.textContent = '';\n    this._liveRegionLineCount = 0;\n\n    // Only detach/attach on mac as otherwise messages can go unaccounced\n    if (isMac) {\n      if (this._liveRegion.parentNode) {\n        this._accessibilityTreeRoot.removeChild(this._liveRegion);\n      }\n    }\n  }\n\n  private _onKey(keyChar: string): void {\n    this._clearLiveRegion();\n    this._charsToConsume.push(keyChar);\n  }\n\n  private _refreshRows(start?: number, end?: number): void {\n    this._renderRowsDebouncer.refresh(start, end, this._terminal.rows);\n  }\n\n  private _renderRows(start: number, end: number): void {\n    const buffer: IBuffer = this._terminal.buffer;\n    const setSize = buffer.lines.length.toString();\n    for (let i = start; i <= end; i++) {\n      const lineData = buffer.translateBufferLineToString(buffer.ydisp + i, true);\n      const posInSet = (buffer.ydisp + i + 1).toString();\n      const element = this._rowElements[i];\n      if (element) {\n        element.textContent = lineData.length === 0 ? Strings.blankLine : lineData;\n        element.setAttribute('aria-posinset', posInSet);\n        element.setAttribute('aria-setsize', setSize);\n      }\n    }\n  }\n\n  private _refreshRowsDimensions(): void {\n    if (!this._terminal.renderer.dimensions.actualCellHeight) {\n      return;\n    }\n    if (this._rowElements.length !== this._terminal.rows) {\n      this._onResize(this._terminal.rows);\n    }\n    for (let i = 0; i < this._terminal.rows; i++) {\n      this._refreshRowDimensions(this._rowElements[i]);\n    }\n  }\n\n  private _refreshRowDimensions(element: HTMLElement): void {\n    element.style.height = `${this._terminal.renderer.dimensions.actualCellHeight}px`;\n  }\n\n  private _announceCharacter(char: string): void {\n    if (char === ' ') {\n      // Always use nbsp for spaces in order to preserve the space between characters in\n      // voiceover's caption window\n      this._liveRegion.innerHTML += '&nbsp;';\n    } else {\n      this._liveRegion.textContent += char;\n    }\n  }\n}\n",null],"names":[],"mappings":"A0DAA;;;;;;;;;;;;;;;;ADKA;AAEA;AACA;AACA;AACA;AAEA;AAOA;AAAA;AAuBA;AAAA;AAAA;AAlBA;AAgBA;AAIA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAIA;AACA;AAGA;;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAGA;AACA;AAGA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAGA;AACA;AAGA;AAGA;AAGA;AACA;AACA;AAEA;AAEA;AAGA;AACA;AACA;AACA;AAEA;AACA;AACA;AAGA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAGA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AAzQa;;;;;;;;;;;;;;;;;;ADdb;AAGA;AACA;AACA;AACA;AACA;AAEa;AAEA;AAEA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AAOA;AACA;AACA;AASb;AAwBA;AACA;AACA;AAfA;AACA;AACA;AACA;AAcA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AAAA;AACA;AACA;AACA;AACA;;;AAAA;AAOA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AAEA;AAIA;AACA;AACA;AACA;AAIA;AAEA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AAIA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AAGA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAiBA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAYA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AApkBa;AAskBb;AAAA;AAWA;AAAA;AACA;AATA;AACA;AAIA;;AAOA;AATA;AAAA;;;AAAA;AAGA;AAAA;;;AAAA;AAQA;AACA;AACA;AACA;AACA;AAEA;AACA;AAvBA;AAwBA;AAAA;AAzBa;AAuCb;AAGA;AAGA;AACA;AACA;AACA;AALA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AA3Ca;;;;;;;;;;;;;;;;;;ADzpBb;AACA;AAaA;AAmHA;AAAA;AAoBA;AACA;AAsCA;AA1DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AA3Da;AAgEb;AAAA;AAAA;AAAA;AAUA;AACA;AACA;AACA;;AAuEA;AAjFA;AACA;AACA;AACA;AACA;AASA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AAAA;AACA;AAGA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAAA;AApFa;AAsGb;AAKA;AAAA;AAAA;AAJA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAMA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAOA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AAEA;AACA;AAAA;AACA;AAIA;AACA;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AApVa;;;;;ADxRb;AAGA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AAGA;AAGA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAlFA;AAyFA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AA3BA;AAmCA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAZA;AA4BA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AA/BA;AAiCA;AAEA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AAdA;;;;;ADvMA;AACA;AAMA;AAaA;AAAA;AAPA;AAQA;AACA;AAIA;AACA;AAEA;AACA;AAhBA;AAAA;;;AAAA;AAqBA;AAAA;AACA;AACA;;;AAAA;AAKA;AAAA;AACA;AACA;;;AAAA;AAKA;AAAA;AACA;AACA;;;AAAA;AAKA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAAA;AAvGa;;;;;ADPb;AAOA;AAUA;AAHA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAVA;AAAA;;;AAAA;AAYA;AAAA;AACA;AACA;;;AAAA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AA5Ca;;;;;ADRb;AAEa;AAGb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AAIA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AACA;AAGA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AA3BA;;;;;AD3HA;AACA;AACA;AAFA;AAQA;AACA;AACA;AACA;AACA;AACA;AALA;AAWA;AACA;AACA;AACA;AAAA;AACA;AACA;AAGA;AACA;AATA;AAgBA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAzBA;AAgCA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AA3BA;AAoCA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AAVA;;;;;AD1GA;AAwBA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAMA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAOA;AACA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AAGA;AACA;AAEA;AAGA;AACA;AACA;AAEA;AACA;AAUA;AAAA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;AAUA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAAA;AArNa;;;;;;;;;;;;;;;;;;ADVb;AACA;AAcA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AAGA;AACA;AACA;AACA;AACA;AASA;AACA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;AAAA;AAhCa;AAsCb;AACA;AACA;AACA;AAEA;AAMa;AACb;AAEA;AACA;AAGA;AAEA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AAAA;AAIA;AAHA;AACA;AACA;AACA;AAAA;AAcA;AAAA;AA4BA;AAAA;AAAA;AAAA;AAGA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAGA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAAA;AAIA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAAA;AACA;AACA;AAGA;AACA;AACA;AAGA;AAGA;AACA;AACA;AAAA;AAzZa;;;;;;;;;;;;;;;;;;ADvNb;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAKA;AAaA;AAGA;AAAA;AAFA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AA6BA;AAAA;AAcA;AAEA;AAFA;AACA;AACA;AAfA;AACA;AACA;AAEA;AAEA;AAEA;AAEA;AASA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AAMA;AAGA;AAqCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAPA;AAAA;AAQA;AAKA;AACA;AACA;AACA;AAKA;;AACA;AAlLA;AAAA;;;AAAA;AAEA;AAAA;;;AAAA;AAEA;AAAA;;;AAAA;AAEA;AAAA;;;AAAA;AA8KA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAIA;AAKA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAOA;AACA;AAIA;AACA;AAAA;AACA;AACA;AACA;AACA;AAOA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AAAA;AACA;AAGA;AACA;AAEA;AACA;AAGA;AAEA;AAIA;AACA;AACA;AACA;AAGA;AAKA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AAKA;AACA;AACA;AAMA;AACA;AACA;AAMA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAMA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AAOA;AACA;AACA;AAMA;AACA;AAKA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AASA;AAAA;AACA;AACA;AAKA;AACA;AACA;AACA;AAOA;AACA;AACA;AAcA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAaA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAGA;AAEA;AAEA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAGA;AAEA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAMA;AACA;AAKA;AACA;AAKA;AACA;AAGA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAKA;AACA;AACA;AAGA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAMA;AACA;AAKA;AAKA;AACA;AAGA;AAEA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AAEA;AACA;AACA;AACA;AAKA;AAuCA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AAIA;AACA;AACA;AAAA;AACA;AACA;AAAA;AAGA;AACA;AAAA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAOA;AACA;AAAA;AACA;AAAA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAUA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAwFA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AAKA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAoFA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAmEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAGA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAyBA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AAGA;AACA;AAGA;AACA;AAGA;AACA;AAGA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAYA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AAQA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AAkBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AASA;AACA;AACA;AASA;AACA;AACA;AAOA;AACA;AACA;AACA;AAYA;AACA;AACA;AACA;AAAA;AAv3Da;;;;;ADlGb;AACA;AACA;AAKA;AA6BA;AACA;AAfA;AAIA;AAGA;AAEA;AAEA;AAMA;AACA;AACA;AACA;AACA;AAbA;AAAA;;;AAAA;AAEA;AAAA;;;AAAA;AAEA;AAAA;;;AAAA;AAeA;AACA;AACA;AAOA;AAAA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAGA;AAGA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AAYA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAYA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AAAA;AAEA;AACA;AACA;;AAEA;AACA;AAIA;AACA;AACA;AACA;;AAEA;AAMA;AACA;AACA;;AAGA;AAGA;AACA;;AAGA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;;;AAlDA;;;;AAmDA;AACA;AAUA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAMA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AA3SA;AAOA;AAqSA;AAAA;AAlTa;;;;;ADLb;AACA;AAAA;AAAA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAeA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAKA;AACA;AAEA;AACA;AAYA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AArEa;;;;;;;;;;;;;;;;;;ADFb;AACA;AAEA;AAUA;AAAA;AAaA;AAAA;AACA;AAbA;AAEA;AAKA;AACA;AACA;AAQA;AAGA;AACA;AACA;;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AAEA;AACA;AACA;AAEA;AAAA;AACA;AAGA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AAGA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAlNa;AAoNb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAba;;;;;ADjOb;AACA;AAEA;AACA;AACA;AAEA;AAMA;AAKA;AAKA;AAMA;AAMA;AAEA;AACA;AA4BA;AA4CA;AACA;AACA;AAlBA;AAKA;AAIA;AAEA;AAEA;AAOA;AACA;AAEA;AACA;AACA;AAfA;AAAA;;;AAAA;AAEA;AAAA;;;AAAA;AAEA;AAAA;;;AAAA;AAaA;AACA;AACA;AAEA;AAAA;AACA;AACA;;;AAAA;AAKA;AAAA;AACA;AACA;AAEA;AACA;AAEA;AAAA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AAKA;AACA;AACA;AAEA;AAAA;;;AAAA;AACA;AAAA;;;AAAA;AAKA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAAA;AAKA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AAEA;AACA;;;AAAA;AAKA;AACA;AACA;AACA;AACA;AAOA;AAAA;AAEA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAGA;AACA;AAGA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AAGA;AAGA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AAKA;AAAA;AAEA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AAIA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAOA;AAIA;AAIA;AAGA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AAGA;AAKA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AAAA;AACA;AAKA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AAGA;AACA;AAAA;AAIA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AAAA;AAAA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAGA;AACA;AAGA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAKA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AAIA;AAEA;AACA;AACA;AAIA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAOA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAOA;AAGA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAn1Ba;;;;;AD7Db;AAuBA;AACA;AAEA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAKA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;;;AAAA;AAMA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAAA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AAEA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAAA;AA5Ha;;;;;ADAA;AAEb;AAeA;AACA;AAEA;AAfA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAAA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AAGA;AACA;AACA;AAAA;AApDa;;;;;ADRF;AACA;AACA;;;;;;;;;;;;;;;;;;ADkBX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AAEA;AAGA;AAOA;AAQA;AAEA;AACA;AAKA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AAyIA;AACA;AADA;AAvHA;AAmFA;AAKA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAmBA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA;AAhDA;AAAA;;;AAAA;AAEA;AAAA;;;AAAA;AAEA;AAAA;;;AAAA;AAEA;AAAA;;;AAAA;AAEA;AAAA;;;AAAA;AAEA;AAAA;;;AAAA;AAEA;AAAA;;;AAAA;AAEA;AAAA;;;AAAA;AAEA;AAAA;;;AAAA;AAkCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AAKA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AACA;AAGA;AACA;AAEA;AAEA;AAGA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAKA;AAAA;AACA;AACA;;;AAAA;AAKA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;;;AAAA;AAMA;AACA;AACA;AACA;AAEA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAKA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AAAA;AACA;AAGA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAKA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AAAA;AACA;AAEA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAGA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AAGA;AACA;AAGA;AAGA;AAGA;AAIA;AAEA;AAEA;AAAA;AACA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AAYA;AAAA;AACA;AACA;AACA;AAKA;AACA;AACA;AAGA;AAGA;AACA;AAAA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAIA;AACA;AACA;AAIA;AACA;AACA;AACA;AAAA;AAIA;AAEA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AAOA;AAGA;AACA;AACA;AACA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AAGA;AAEA;AACA;AAAA;AACA;AACA;AAGA;AAEA;AACA;AAEA;AAIA;AACA;AAKA;AACA;AACA;AAGA;AAIA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAGA;AACA;AAGA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AAGA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAIA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAMA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;AAIA;AACA;AACA;AAGA;AACA;AAEA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAMA;AACA;AACA;AAKA;AACA;AACA;AAKA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAMA;AAAA;AAEA;AACA;AACA;AAGA;AACA;AACA;AAEA;AAKA;AAGA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAAA;AAAA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AAEA;AACA;AAQA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAWA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AAYA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AAKA;AACA;AACA;AAMA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAQA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AAGA;AACA;AAMA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAQA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAEA;AAGA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAMA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAAA;AACA;AAAA;AACA;AACA;AAKA;AACA;AAAA;AACA;AAAA;AACA;AACA;AAQA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AAAA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAMA;AACA;AAAA;AACA;AAAA;AAOA;AAKA;AACA;AACA;AACA;AAKA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAMA;AAEA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAOA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AAEA;AACA;AAGA;AACA;AAAA;AAxyDa;AA8yDb;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;AD/5DA;AACA;AAEA;AAMA;AAAA;AAwBA;AAAA;AACA;AACA;AACA;AACA;AA3BA;AACA;AACA;AACA;AACA;AAEA;AAKA;AAEA;AACA;AAoBA;AACA;AAGA;;AACA;AAEA;AACA;AACA;AAMA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAGA;AACA;AACA;AAEA;AACA;AAKA;AAEA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAOA;AAEA;AAIA;AACA;AACA;AAGA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAOA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AA3Na;;;;;ADVb;AAEA;AAWA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AApBA;;;;;ADHA;AAgBA;AAYA;AACA;AARA;AAEA;AAEA;AAMA;AACA;AACA;AACA;AAZA;AAAA;;;AAAA;AAEA;AAAA;;;AAAA;AAEA;AAAA;;;AAAA;AAUA;AAAA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAjBA;AAmBA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AATA;AAmBA;AACA;AACA;AAUA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AAAA;AACA;AACA;;;AAAA;AAMA;AACA;AACA;AAWA;AAAA;AAAA;AAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AAAA;AApNa;;;;;ADdb;AAAA;AACA;AACA;AACA;AAGA;AACA;AACA;AAGA;AAEA;AAEA;AACA;AAEA;AACA;AAnBA;;;;;;;;;;;;;;;;;;ADFA;AAEA;AAAA;AAGA;AAAA;AAIA;;AACA;AAEA;AACA;AACA;AACA;AAOA;AAAA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAAA;AAAA;AAAA;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AAAA;AAAA;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AAzFa;;;;;ADOb;AAAA;AACA;AAgCA;AA7BA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAjCa;;;;;ADJb;AAIA;AAHA;AACA;AAGA;AAKA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAnCsB;;;;;ADItB;AACA;AACA;AAEa;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AAOb;AACA;AACA;;;;;ADzBA;AAEA;AACA;AACA;AACA;AACA;AANA;AAQA;AAAA;AAAA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAlBA;AAwBA;AACA;AACA;AACA;AACA;AACA;AALA;;;;;ADrCA;AAAA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AACA;AAMA;AAAA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AACA;;;;;ADzIa;AAKA;AAYb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AAMA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ADtPA;AAGA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAMA;AACA;AAGA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAIA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAIA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AArUA;;;;;AD7BA;AAAA;AACA;AA8DA;AAzDA;AACA;AACA;AAUA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AA/Da;AAoEb;AACA;AAEA;AACA;AACA;AACA;AACA;AAPA;AAcA;AAAA;AAAA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAjBA;;;;;ADpFA;AASA;AAOA;;AACA;AACA;AAEA;AACA;AACA;AAEA;AASA;AACA;;AAEA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AAOA;AAEA;AACA;AACA;AAGA;AACA;AAOA;AACA;AACA;AACA;AACA;AAIA;AAMA;AACA;AACA;AAEA;AAEA;AACA;AAKA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AAEA;AAIA;AAEA;AACA;AACA;AACA;AAUA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AASA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAWA;AAOA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AAAA;AACA;AAGA;AACA;AACA;AACA;AACA;AAEA;AAGA;AAMA;AACA;AACA;AACA;AACA;AAAA;AA5Oa;AAoPb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ADpQA;AACA;AAGA;AAGA;AACA;AACA;AAEA;AAAA;;;AAAA;AACA;AAAA;;;AAAA;AACA;AAAA;;;AAAA;AACA;AAAA;;;AAAA;AACA;AAAA;;;AAAA;AACA;AAAA;;;AAAA;AACA;AAAA;;;AAAA;AACA;AAAA;;;AAAA;AACA;AAAA;;;AAAA;AAEA;AAAA;;;AAAA;AACA;AAAA;;;AAAA;AACA;AAAA;;;AAAA;AACA;AAAA;;;AAAA;AACA;AAAA;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AAYA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;;;AAAA;AACA;AAAA;AA/Ja;;;;;ADJb;AAEA;AACA;AACA;AACA;AAEA;AAyBA;AACA;AAGA;AACA;AA3BA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AAWA;AACA;AAKA;AAQA;AAAA;AACA;AAKA;AAQA;AACA;AAKA;AAQA;AACA;AACA;AAKA;AAKA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AASA;AACA;AACA;AAKA;AAAA;AACA;AACA;AAKA;AACA;AAYA;AACA;AACA;AACA;AACA;AAIA;AAgBA;AAMA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AAaA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AACA;AAEA;AAIA;AACA;AAOA;AACA;AACA;AAKA;AACA;AAOA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAhXsB;;;;;;;;;;;;;;;;;;ADZtB;AACA;AAEA;AAAA;AASA;AAAA;AALA;AAGA;AAIA;AACA;AACA;AACA;;AACA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAGA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AA3Ca;AA6Cb;AAMA;AAAA;AAJA;AACA;AACA;AAGA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AAGA;AAGA;AACA;AAOA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AAOA;AACA;AACA;AACA;AAEA;AACA;AAUA;AACA;AAIA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAUA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AAIA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AAGA;AAGA;AACA;AACA;AAMA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAIA;AACA;AAIA;AACA;AACA;AACA;AAUA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAGA;AACA;AACA;AAEA;AAGA;AACA;AACA;AAGA;AACA;AAAA;AACA;AAGA;AACA;AACA;AAEA;AAGA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAAA;AAEA;AACA;AAEA;AACA;AACA;AAAA;AA9Qa;;;;;AD1Cb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIa;AACb;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAKA;AAKA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AAEA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAiBA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AAtGa;;;;;;;;;;;;;;;;;;AD7Eb;AAEA;AAaA;AAEA;AAAA;AAMA;AAAA;AAFA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AArMa;AAuMb;AAcA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAAA;;;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AAAA;AAEA;AACA;AACA;AAMA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAGA;AAEA;AAGA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;;;;;AD1VA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AA3Ba;;;;;;;;;;;;;;;;;;ADEb;AACA;AACA;AAEA;AAAA;AAGA;AAAA;AAFA;AAIA;AACA;;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AAEA;AACA;AAAA;AACA;AACA;AAEA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AA1Da;;;;;;;;;;;;;;;;;;ADNb;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAAA;AAkBA;AAAA;AAAA;AAZA;AACA;AAMA;AAEA;AAKA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;;AACA;AAjDA;AAAA;;;AAAA;AAEA;AAAA;;;AAAA;AAiDA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AAGA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AAEA;AAAA;AAEA;AAGA;AAGA;AACA;AACA;AAAA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAAA;AACA;AACA;AAEA;AAAA;AACA;AACA;AAEA;AAAA;AAAA;AACA;AACA;AAEA;AAAA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AAAA;AACA;AACA;AACA;AAKA;AAEA;AACA;AACA;AAMA;AAKA;AAMA;AAIA;AAGA;AAIA;AAIA;AACA;AAOA;AACA;AAQA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AAhQa;;;;;;;;;;;;;;;;;;ADZb;AASA;AAAA;AAGA;AAAA;AAEA;;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAGA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAGA;AACA;AAGA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAtGa;;;;;;;;;;;;;;;;;;ADXb;AAGA;AACA;AACA;AACA;AASA;AAAA;AAQA;AAAA;AAJA;AAEA;AAIA;AACA;;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAWA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAIA;AACA;AACA;AAKA;AACA;AACA;AAKA;AAOA;AACA;AAMA;AAQA;AAEA;AACA;AAMA;AACA;AAEA;AAMA;AACA;AACA;AACA;AAMA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAGA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAEA;AAGA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAKA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAEA;AAGA;AACA;AACA;AAGA;AACA;AAKA;AAGA;AAGA;AACA;AACA;AAgBA;AAAA;AAlSa;;;;;ADZb;AAAA;AACA;AA8CA;AA5CA;AAMA;AACA;AACA;AACA;AACA;AACA;AAMA;AASA;AAkBA;AAAA;;;;;;ADhDA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAUA;AAQA;AAMA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AA/CA;AAqDA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AAfA;;;;;ADnFA;AAEA;AAQA;AACA;AACA;AACA;AAIA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AAEA;AACA;AAEA;AAGA;AAEA;AACA;AAvFA;AA6FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAfA;AAiBA;AACA;AACA;;;;;ADzHA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAxBA;AA0BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAjBA;AAmBA;AACA;AACA;AAFA;;;;;;;;;;;;;;;;;;ADjDA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAEA;AACA;AACA;AACA;AAQA;AAMA;AAQA;AAUA;AACA;AAXA;AAaA;AAAA;AA2BA;AAAA;AAAA;AAXA;AAGA;AAGA;AAGA;AAIA;AACA;AACA;AAIA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;;AAIA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAOA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAQA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAOA;AACA;AACA;AACA;AACA;AACA;AAWA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAIA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AAIA;AACA;AAEA;AAGA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AACA;AAEA;AACA;AAIA;AAGA;AACA;AACA;AACA;AAGA;AACA;AAEA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAAA;AAKA;AACA;AACA;AAGA;AAGA;AACA;AACA;AAEA;AACA;AAEA;AAAA;AACA;AACA;AACA;AAEA;AAIA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAAA;;;;;;AD7TA;AAOA;AAAA;AANA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;;;;;;;;;;;;;;;;;;;AD/HA;AAEA;AAAA;AACA;AACA;AACA;AAEA;AAMA;AACA;AACA;AAAA;;;;;;;;;;;;;;;;;;;ADlBA;AACA;AACA;AACA;AAEA;AAAA;AAGA;AAAA;AAAA;AAAA;AAIA;AACA;AACA;AACA;AAKA;AACA;;AAXA;AAaA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAOA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AAGA;AACA;AACA;AAEA;AAYA;AAEA;AACA;AACA;AAAA;;;;;;AD3Fa;AACA;AACA;AAEA;;;;;;;;;;;;;;;;;;ADJb;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAUA;AAAA;AAmBA;AAAA;AAAA;AAhBA;AAKA;AAMA;AAEA;AAKA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;;AACA;AA5CA;AAAA;;;AAAA;AAEA;AAAA;;;AAAA;AA4CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAGA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AAGA;AAEA;AACA;AAGA;AAAA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AAQA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AA5Wa;;;;;AD3Bb;AAEA;AACA;AAEa;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEb;AAGA;AACA;AACA;AAJA;AAMA;AAEA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAGA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AA9Ga;;;;;ADRb;AAMA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAhBA;;;;;ADFA;AAMA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AAGA;AACA;AAGA;AAGA;AACA;AACA;AACA;AACA;AAAA;AApDa;;;;;;;;;;;;;;;;;;ADLb;AAcA;AAAA;AAAA;AAAA;AACA;;AAgDA;AA3CA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAGA;AAGA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAjDa;;;;;ADZb;AAEA;"}
\ No newline at end of file
diff --git a/xterm-3.12.0.tgz b/xterm-3.12.0.tgz
deleted file mode 100644 (file)
index cb98ec5..0000000
Binary files a/xterm-3.12.0.tgz and /dev/null differ