From 1877e7019d479724ae45568d0b99c080a3bd949c Mon Sep 17 00:00:00 2001 From: Bruno Ribeito Date: Mon, 6 Nov 2017 23:20:57 +0000 Subject: [PATCH 01/58] Implement #778 --- src/Interfaces.ts | 3 +++ src/SelectionManager.ts | 26 +++++++++++++++++++++----- src/Terminal.ts | 7 ++++--- src/handlers/Clipboard.ts | 6 +++++- typings/xterm.d.ts | 4 ++-- 5 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/Interfaces.ts b/src/Interfaces.ts index e98385c11..ea1d00a0e 100644 --- a/src/Interfaces.ts +++ b/src/Interfaces.ts @@ -149,6 +149,7 @@ export interface ITerminalOptions { termName?: string; theme?: ITheme; useFlowControl?: boolean; + rightClickSelectsWord?: boolean; } export interface IBuffer { @@ -194,11 +195,13 @@ export interface ISelectionManager { selectionText: string; selectionStart: [number, number]; selectionEnd: [number, number]; + hasSelection: boolean; disable(): void; enable(): void; setBuffer(buffer: IBuffer): void; setSelection(row: number, col: number, length: number): void; + selectWordAtCursor(event: MouseEvent): void; } export interface ICompositionHelper { diff --git a/src/SelectionManager.ts b/src/SelectionManager.ts index bf5144cba..87b71a129 100644 --- a/src/SelectionManager.ts +++ b/src/SelectionManager.ts @@ -249,6 +249,18 @@ export class SelectionManager extends EventEmitter implements ISelectionManager this.emit('refresh', { start: this._model.finalSelectionStart, end: this._model.finalSelectionEnd }); } + /** + * Selects word at the current mouse event coordenates. + * @param event The mouse event. + */ + public selectWordAtCursor(event: MouseEvent): void { + const coords = this._getMouseBufferCoords(event); + if (coords) { + this._selectWordAt(coords, false); + this.refresh(true); + } + } + /** * Selects all text within the terminal. */ @@ -439,7 +451,7 @@ export class SelectionManager extends EventEmitter implements ISelectionManager const coords = this._getMouseBufferCoords(event); if (coords) { this._activeSelectionMode = SelectionMode.WORD; - this._selectWordAt(coords); + this._selectWordAt(coords, true); } } @@ -578,7 +590,7 @@ export class SelectionManager extends EventEmitter implements ISelectionManager * Gets positional information for the word at the coordinated specified. * @param coords The coordinates to get the word at. */ - private _getWordAt(coords: [number, number]): IWordPosition { + private _getWordAt(coords: [number, number], selectWhiteSpace: boolean): IWordPosition { const bufferLine = this._buffer.lines.get(coords[1]); if (!bufferLine) { return null; @@ -684,15 +696,19 @@ export class SelectionManager extends EventEmitter implements ISelectionManager - leftLongCharOffset // The number of additional chars left of the initial char added by columns with strings longer than 1 (emojis) - rightLongCharOffset); // The number of additional chars right of the initial char (inclusive) added by columns with strings longer than 1 (emojis) + if (!selectWhiteSpace && line.slice(startIndex, endIndex).trim() === '') + return null; + return { start, length }; } /** * Selects the word at the coordinates specified. * @param coords The coordinates to get the word at. + * @param selectWhiteSpace If whitespace should be selected */ - protected _selectWordAt(coords: [number, number]): void { - const wordPosition = this._getWordAt(coords); + protected _selectWordAt(coords: [number, number], selectWhiteSpace: boolean): void { + const wordPosition = this._getWordAt(coords, selectWhiteSpace); if (wordPosition) { this._model.selectionStart = [wordPosition.start, coords[1]]; this._model.selectionStartLength = wordPosition.length; @@ -704,7 +720,7 @@ export class SelectionManager extends EventEmitter implements ISelectionManager * @param coords The coordinates to get the word at. */ private _selectToWordAt(coords: [number, number]): void { - const wordPosition = this._getWordAt(coords); + const wordPosition = this._getWordAt(coords, true); if (wordPosition) { this._model.selectionEnd = [this._model.areSelectionValuesReversed() ? wordPosition.start : (wordPosition.start + wordPosition.length), coords[1]]; } diff --git a/src/Terminal.ts b/src/Terminal.ts index 5ac8a1a0c..7dbdeb760 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -89,7 +89,8 @@ const DEFAULT_OPTIONS: ITerminalOptions = { disableStdin: false, useFlowControl: false, tabStopWidth: 8, - theme: null + theme: null, + rightClickSelectsWord: Browser.isMac // programFeatures: false, // focusKeys: false, }; @@ -492,12 +493,12 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT // Firefox doesn't appear to fire the contextmenu event on right click on(this.element, 'mousedown', (event: MouseEvent) => { if (event.button === 2) { - rightClickHandler(event, this.textarea, this.selectionManager); + rightClickHandler(event, this.textarea, this.selectionManager, this.options.rightClickSelectsWord); } }); } else { on(this.element, 'contextmenu', (event: MouseEvent) => { - rightClickHandler(event, this.textarea, this.selectionManager); + rightClickHandler(event, this.textarea, this.selectionManager, this.options.rightClickSelectsWord); }); } diff --git a/src/handlers/Clipboard.ts b/src/handlers/Clipboard.ts index a97353520..86a604f28 100644 --- a/src/handlers/Clipboard.ts +++ b/src/handlers/Clipboard.ts @@ -103,10 +103,14 @@ export function moveTextAreaUnderMouseCursor(ev: MouseEvent, textarea: HTMLTextA * @param ev The original right click event to be handled. * @param textarea The terminal's textarea. * @param selectionManager The terminal's selection manager. + * @param shouldSelectWord If true and there is no selection the current word will be selected */ -export function rightClickHandler(ev: MouseEvent, textarea: HTMLTextAreaElement, selectionManager: ISelectionManager): void { +export function rightClickHandler(ev: MouseEvent, textarea: HTMLTextAreaElement, selectionManager: ISelectionManager, shouldSelectWord: boolean): void { moveTextAreaUnderMouseCursor(ev, textarea); + if (shouldSelectWord && !selectionManager.hasSelection) + selectionManager.selectWordAtCursor(ev); + // Get textarea ready to copy from the context menu textarea.value = selectionManager.selectionText; textarea.select(); diff --git a/typings/xterm.d.ts b/typings/xterm.d.ts index 9ab61ce67..a5137797d 100644 --- a/typings/xterm.d.ts +++ b/typings/xterm.d.ts @@ -409,7 +409,7 @@ declare module 'xterm' { * Retrieves an option's value from the terminal. * @param key The option key. */ - getOption(key: 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'debug' | 'disableStdin' | 'enableBold' | 'popOnBell' | 'screenKeys' | 'useFlowControl' | 'visualBell'): boolean; + getOption(key: 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'debug' | 'disableStdin' | 'enableBold' | 'popOnBell' | 'screenKeys' | 'useFlowControl' | 'visualBell' | 'rightClickSelectsWord'): boolean; /** * Retrieves an option's value from the terminal. * @param key The option key. @@ -459,7 +459,7 @@ declare module 'xterm' { * @param key The option key. * @param value The option value. */ - setOption(key: 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'debug' | 'disableStdin' | 'enableBold' | 'popOnBell' | 'screenKeys' | 'useFlowControl' | 'visualBell', value: boolean): void; + setOption(key: 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'debug' | 'disableStdin' | 'enableBold' | 'popOnBell' | 'screenKeys' | 'useFlowControl' | 'visualBell' | 'rightClickSelectsWord', value: boolean): void; /** * Sets an option on the terminal. * @param key The option key. From 2865d935b646a43b2dbaa7f8e5f176b4d2f90518 Mon Sep 17 00:00:00 2001 From: Bruno Ribeito Date: Tue, 7 Nov 2017 21:21:44 +0000 Subject: [PATCH 02/58] Adress feedback --- fixtures/typings-test/typings-test.ts | 2 ++ src/SelectionManager.test.ts | 2 +- src/SelectionManager.ts | 13 +++++++------ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/fixtures/typings-test/typings-test.ts b/fixtures/typings-test/typings-test.ts index 9d73535ec..d61b22f20 100644 --- a/fixtures/typings-test/typings-test.ts +++ b/fixtures/typings-test/typings-test.ts @@ -143,6 +143,7 @@ namespace methods_core { const r20: string = t.getOption('bellStyle'); const r21: boolean = t.getOption('enableBold'); const r22: number = t.getOption('letterSpacing'); + const r23: boolean = t.getOption('rightClickSelectsWord'); } { const t: Terminal = new Terminal(); @@ -177,6 +178,7 @@ namespace methods_core { t.setOption('lineHeight', 1); t.setOption('fontFamily', 'foo'); t.setOption('theme', {background: '#ff0000'}); + t.setOption('rightClickSelectsWord', false); } } namespace scrolling { diff --git a/src/SelectionManager.test.ts b/src/SelectionManager.test.ts index 8c6ea3e18..e229889ee 100644 --- a/src/SelectionManager.test.ts +++ b/src/SelectionManager.test.ts @@ -26,7 +26,7 @@ class TestSelectionManager extends SelectionManager { public get model(): SelectionModel { return this._model; } public selectLineAt(line: number): void { this._selectLineAt(line); } - public selectWordAt(coords: [number, number]): void { this._selectWordAt(coords); } + public selectWordAt(coords: [number, number]): void { this._selectWordAt(coords, true); } // Disable DOM interaction public enable(): void {} diff --git a/src/SelectionManager.ts b/src/SelectionManager.ts index 87b71a129..1fccc8b17 100644 --- a/src/SelectionManager.ts +++ b/src/SelectionManager.ts @@ -250,7 +250,7 @@ export class SelectionManager extends EventEmitter implements ISelectionManager } /** - * Selects word at the current mouse event coordenates. + * Selects word at the current mouse event coordinates. * @param event The mouse event. */ public selectWordAtCursor(event: MouseEvent): void { @@ -590,7 +590,7 @@ export class SelectionManager extends EventEmitter implements ISelectionManager * Gets positional information for the word at the coordinated specified. * @param coords The coordinates to get the word at. */ - private _getWordAt(coords: [number, number], selectWhiteSpace: boolean): IWordPosition { + private _getWordAt(coords: [number, number], allowWhitespaceOnlySelection: boolean): IWordPosition { const bufferLine = this._buffer.lines.get(coords[1]); if (!bufferLine) { return null; @@ -696,8 +696,9 @@ export class SelectionManager extends EventEmitter implements ISelectionManager - leftLongCharOffset // The number of additional chars left of the initial char added by columns with strings longer than 1 (emojis) - rightLongCharOffset); // The number of additional chars right of the initial char (inclusive) added by columns with strings longer than 1 (emojis) - if (!selectWhiteSpace && line.slice(startIndex, endIndex).trim() === '') + if (!allowWhitespaceOnlySelection && line.slice(startIndex, endIndex).trim() === '') { return null; + } return { start, length }; } @@ -705,10 +706,10 @@ export class SelectionManager extends EventEmitter implements ISelectionManager /** * Selects the word at the coordinates specified. * @param coords The coordinates to get the word at. - * @param selectWhiteSpace If whitespace should be selected + * @param allowWhitespaceOnlySelection If whitespace should be selected */ - protected _selectWordAt(coords: [number, number], selectWhiteSpace: boolean): void { - const wordPosition = this._getWordAt(coords, selectWhiteSpace); + protected _selectWordAt(coords: [number, number], allowWhitespaceOnlySelection: boolean): void { + const wordPosition = this._getWordAt(coords, allowWhitespaceOnlySelection); if (wordPosition) { this._model.selectionStart = [wordPosition.start, coords[1]]; this._model.selectionStartLength = wordPosition.length; From 18b86a1cbc4cb1d99f67599992985b733fa6e1a8 Mon Sep 17 00:00:00 2001 From: Bruno Ribeito Date: Wed, 8 Nov 2017 23:27:00 +0000 Subject: [PATCH 03/58] Do the selection even if there is already a selection --- src/Interfaces.ts | 1 + src/SelectionManager.ts | 26 +++++++++++++++++++++++--- src/handlers/Clipboard.ts | 2 +- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/Interfaces.ts b/src/Interfaces.ts index ea1d00a0e..69e7fcb2b 100644 --- a/src/Interfaces.ts +++ b/src/Interfaces.ts @@ -201,6 +201,7 @@ export interface ISelectionManager { enable(): void; setBuffer(buffer: IBuffer): void; setSelection(row: number, col: number, length: number): void; + isClickInSelection(event: MouseEvent): boolean; selectWordAtCursor(event: MouseEvent): void; } diff --git a/src/SelectionManager.ts b/src/SelectionManager.ts index 1fccc8b17..3bf366ce1 100644 --- a/src/SelectionManager.ts +++ b/src/SelectionManager.ts @@ -249,6 +249,22 @@ export class SelectionManager extends EventEmitter implements ISelectionManager this.emit('refresh', { start: this._model.finalSelectionStart, end: this._model.finalSelectionEnd }); } + /** + * Checks if the current click was inside the current selection + * @param event The mouse event + */ + public isClickInSelection(event: MouseEvent): boolean { + const coords = this._getMouseBufferCoords(event); + const start = this._model.finalSelectionStart; + const end = this._model.finalSelectionEnd; + + if (!start || !end) { + return false; + } + + return (start[1] < coords[1] && end[1] > coords[1]) || (start[1] === coords[1] && coords[0] > start[0]) || (end[1] === coords[1] && coords[0] < end[0]); + } + /** * Selects word at the current mouse event coordinates. * @param event The mouse event. @@ -256,10 +272,14 @@ export class SelectionManager extends EventEmitter implements ISelectionManager public selectWordAtCursor(event: MouseEvent): void { const coords = this._getMouseBufferCoords(event); if (coords) { - this._selectWordAt(coords, false); - this.refresh(true); + const wordPosition = this._getWordAt(coords, true); + if (wordPosition) { + this._model.selectionStart = [wordPosition.start, coords[1]]; + this._model.selectionStartLength = wordPosition.length; + this._model.selectionEnd = [this._model.areSelectionValuesReversed() ? wordPosition.start : (wordPosition.start + wordPosition.length), coords[1]]; + this.refresh(true); + } } - } /** * Selects all text within the terminal. diff --git a/src/handlers/Clipboard.ts b/src/handlers/Clipboard.ts index 86a604f28..6814d269c 100644 --- a/src/handlers/Clipboard.ts +++ b/src/handlers/Clipboard.ts @@ -108,7 +108,7 @@ export function moveTextAreaUnderMouseCursor(ev: MouseEvent, textarea: HTMLTextA export function rightClickHandler(ev: MouseEvent, textarea: HTMLTextAreaElement, selectionManager: ISelectionManager, shouldSelectWord: boolean): void { moveTextAreaUnderMouseCursor(ev, textarea); - if (shouldSelectWord && !selectionManager.hasSelection) + if (shouldSelectWord && (!selectionManager.hasSelection || !selectionManager.isClickInSelection(ev))) selectionManager.selectWordAtCursor(ev); // Get textarea ready to copy from the context menu From 6822070222945574d4b017b4bb80b725e133a255 Mon Sep 17 00:00:00 2001 From: Bruno Ribeito Date: Sun, 12 Nov 2017 23:15:09 +0000 Subject: [PATCH 04/58] Fix typo + Cleanup logic --- src/Interfaces.ts | 1 - src/SelectionManager.ts | 1 + src/handlers/Clipboard.ts | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Interfaces.ts b/src/Interfaces.ts index 69e7fcb2b..39b81baf9 100644 --- a/src/Interfaces.ts +++ b/src/Interfaces.ts @@ -195,7 +195,6 @@ export interface ISelectionManager { selectionText: string; selectionStart: [number, number]; selectionEnd: [number, number]; - hasSelection: boolean; disable(): void; enable(): void; diff --git a/src/SelectionManager.ts b/src/SelectionManager.ts index 3bf366ce1..7e04119e2 100644 --- a/src/SelectionManager.ts +++ b/src/SelectionManager.ts @@ -280,6 +280,7 @@ export class SelectionManager extends EventEmitter implements ISelectionManager this.refresh(true); } } + } /** * Selects all text within the terminal. diff --git a/src/handlers/Clipboard.ts b/src/handlers/Clipboard.ts index 6814d269c..f110ed1fa 100644 --- a/src/handlers/Clipboard.ts +++ b/src/handlers/Clipboard.ts @@ -108,7 +108,7 @@ export function moveTextAreaUnderMouseCursor(ev: MouseEvent, textarea: HTMLTextA export function rightClickHandler(ev: MouseEvent, textarea: HTMLTextAreaElement, selectionManager: ISelectionManager, shouldSelectWord: boolean): void { moveTextAreaUnderMouseCursor(ev, textarea); - if (shouldSelectWord && (!selectionManager.hasSelection || !selectionManager.isClickInSelection(ev))) + if (shouldSelectWord && !selectionManager.isClickInSelection(ev)) selectionManager.selectWordAtCursor(ev); // Get textarea ready to copy from the context menu From 9f85790ad15716694d7ca0d2c17002662a816015 Mon Sep 17 00:00:00 2001 From: CHaBou Date: Thu, 14 Dec 2017 15:42:53 +0100 Subject: [PATCH 05/58] Add allowTransparency option Fixes #1004 --- fixtures/typings-test/typings-test.ts | 2 ++ src/Interfaces.ts | 1 + src/Terminal.ts | 5 +++-- src/renderer/CharAtlas.ts | 8 ++++---- src/renderer/ColorManager.ts | 18 +----------------- src/renderer/Renderer.ts | 5 +++-- src/renderer/TextRenderLayer.ts | 4 ++-- typings/xterm.d.ts | 10 ++++++++-- 8 files changed, 24 insertions(+), 29 deletions(-) diff --git a/fixtures/typings-test/typings-test.ts b/fixtures/typings-test/typings-test.ts index 887eb3227..d1fda14dc 100644 --- a/fixtures/typings-test/typings-test.ts +++ b/fixtures/typings-test/typings-test.ts @@ -144,6 +144,7 @@ namespace methods_core { const r20: string = t.getOption('bellStyle'); const r21: boolean = t.getOption('enableBold'); const r22: number = t.getOption('letterSpacing'); + const r23: boolean = t.getOption('allowTransparency'); } { const t: Terminal = new Terminal(); @@ -160,6 +161,7 @@ namespace methods_core { t.setOption('popOnBell', true); t.setOption('screenKeys', true); t.setOption('useFlowControl', true); + t.setOption('allowTransparency', true); t.setOption('visualBell', true); t.setOption('colors', ['a', 'b']); t.setOption('letterSpacing', 1); diff --git a/src/Interfaces.ts b/src/Interfaces.ts index f90cb8c04..2fab9e837 100644 --- a/src/Interfaces.ts +++ b/src/Interfaces.ts @@ -150,6 +150,7 @@ export interface ITerminalOptions { termName?: string; theme?: ITheme; useFlowControl?: boolean; + allowTransparency?: boolean; } export interface IBuffer { diff --git a/src/Terminal.ts b/src/Terminal.ts index 9e6312a59..739988da9 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -89,6 +89,7 @@ const DEFAULT_OPTIONS: ITerminalOptions = { cancelEvents: false, disableStdin: false, useFlowControl: false, + allowTransparency: false, tabStopWidth: 8, theme: null // programFeatures: false, @@ -578,7 +579,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT this.document = this.parent.ownerDocument; this.body = this.document.body; - initializeCharAtlas(this.document); + initializeCharAtlas(this.document, this.options.allowTransparency); // Create main element container this.element = this.document.createElement('div'); @@ -629,7 +630,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT this.charMeasure = new CharMeasure(document, this.helperContainer); - this.renderer = new Renderer(this, this.options.theme); + this.renderer = new Renderer(this, this.options.theme, this.options.allowTransparency); this.options.theme = null; this.viewport = new Viewport(this, this.viewportElement, this.viewportScrollArea, this.charMeasure); this.viewport.onThemeChanged(this.renderer.colorManager.colors); diff --git a/src/renderer/CharAtlas.ts b/src/renderer/CharAtlas.ts index 9ac1e1618..8cd091195 100644 --- a/src/renderer/CharAtlas.ts +++ b/src/renderer/CharAtlas.ts @@ -110,9 +110,9 @@ let generator: CharAtlasGenerator; * Initializes the char atlas generator. * @param document The document. */ -export function initialize(document: Document): void { +export function initialize(document: Document, alpha: boolean): void { if (!generator) { - generator = new CharAtlasGenerator(document); + generator = new CharAtlasGenerator(document, alpha); } } @@ -120,9 +120,9 @@ class CharAtlasGenerator { private _canvas: HTMLCanvasElement; private _ctx: CanvasRenderingContext2D; - constructor(private _document: Document) { + constructor(private _document: Document, alpha: boolean) { this._canvas = this._document.createElement('canvas'); - this._ctx = this._canvas.getContext('2d', {alpha: false}); + this._ctx = this._canvas.getContext('2d', {alpha}); this._ctx.scale(window.devicePixelRatio, window.devicePixelRatio); } diff --git a/src/renderer/ColorManager.ts b/src/renderer/ColorManager.ts index 6c0d29454..ea5f1cb09 100644 --- a/src/renderer/ColorManager.ts +++ b/src/renderer/ColorManager.ts @@ -86,7 +86,7 @@ export class ColorManager implements IColorManager { */ public setTheme(theme: ITheme): void { this.colors.foreground = theme.foreground || DEFAULT_FOREGROUND; - this.colors.background = this._validateColor(theme.background, DEFAULT_BACKGROUND); + this.colors.background = theme.background || DEFAULT_BACKGROUND; this.colors.cursor = theme.cursor || DEFAULT_CURSOR; this.colors.cursorAccent = theme.cursorAccent || DEFAULT_CURSOR_ACCENT; this.colors.selection = theme.selection || DEFAULT_SELECTION; @@ -107,20 +107,4 @@ export class ColorManager implements IColorManager { this.colors.ansi[14] = theme.brightCyan || DEFAULT_ANSI_COLORS[14]; this.colors.ansi[15] = theme.brightWhite || DEFAULT_ANSI_COLORS[15]; } - - private _validateColor(color: string, fallback: string): string { - if (!color) { - return fallback; - } - if (color.length === 7 && color.charAt(0) === '#') { - return color; - } - if (color.length === 4 && color.charAt(0) === '#') { - const r = color.charAt(1); - const g = color.charAt(2); - const b = color.charAt(3); - return `#${r}${r}${g}${g}${b}${b}`; - } - return fallback; - } } diff --git a/src/renderer/Renderer.ts b/src/renderer/Renderer.ts index ea373e5ef..27ba76ad9 100644 --- a/src/renderer/Renderer.ts +++ b/src/renderer/Renderer.ts @@ -25,14 +25,15 @@ export class Renderer extends EventEmitter implements IRenderer { public colorManager: ColorManager; public dimensions: IRenderDimensions; - constructor(private _terminal: ITerminal, theme: ITheme) { + constructor(private _terminal: ITerminal, theme: ITheme, alpha: boolean) { super(); this.colorManager = new ColorManager(); if (theme) { this.colorManager.setTheme(theme); } + this._renderLayers = [ - new TextRenderLayer(this._terminal.element, 0, this.colorManager.colors), + new TextRenderLayer(this._terminal.element, 0, alpha, this.colorManager.colors), new SelectionRenderLayer(this._terminal.element, 1, this.colorManager.colors), new LinkRenderLayer(this._terminal.element, 2, this.colorManager.colors, this._terminal), new CursorRenderLayer(this._terminal.element, 3, this.colorManager.colors) diff --git a/src/renderer/TextRenderLayer.ts b/src/renderer/TextRenderLayer.ts index 2ecb6ec6e..fd8acbdfd 100644 --- a/src/renderer/TextRenderLayer.ts +++ b/src/renderer/TextRenderLayer.ts @@ -24,8 +24,8 @@ export class TextRenderLayer extends BaseRenderLayer { private _characterFont: string; private _characterOverlapCache: { [key: string]: boolean } = {}; - constructor(container: HTMLElement, zIndex: number, colors: IColorSet) { - super(container, 'text', zIndex, false, colors); + constructor(container: HTMLElement, zIndex: number, alpha: boolean, colors: IColorSet) { + super(container, 'text', zIndex, alpha, colors); this._state = new GridCache(); } diff --git a/typings/xterm.d.ts b/typings/xterm.d.ts index 43be69c23..4e26dff16 100644 --- a/typings/xterm.d.ts +++ b/typings/xterm.d.ts @@ -12,6 +12,12 @@ declare module 'xterm' { * An object containing start up options for the terminal. */ export interface ITerminalOptions { + /** + * Whether background should support non-opaque color. It must be set before + * executing open() method and can't be changed later without excuting it again. + * Warning: Enabling this option can reduce performances somewhat. + */ + allowTransparency?: boolean; /** * A data uri of the sound to use for the bell (needs bellStyle = 'sound'). */ @@ -409,7 +415,7 @@ declare module 'xterm' { * Retrieves an option's value from the terminal. * @param key The option key. */ - getOption(key: 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'debug' | 'disableStdin' | 'enableBold' | 'popOnBell' | 'screenKeys' | 'useFlowControl' | 'visualBell'): boolean; + getOption(key: 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'debug' | 'disableStdin' | 'enableBold' | 'popOnBell' | 'screenKeys' | 'useFlowControl' | 'visualBell' | 'allowTransparency'): boolean; /** * Retrieves an option's value from the terminal. * @param key The option key. @@ -454,7 +460,7 @@ declare module 'xterm' { * @param key The option key. * @param value The option value. */ - setOption(key: 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'debug' | 'disableStdin' | 'enableBold' | 'popOnBell' | 'screenKeys' | 'useFlowControl' | 'visualBell', value: boolean): void; + setOption(key: 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'debug' | 'disableStdin' | 'enableBold' | 'popOnBell' | 'screenKeys' | 'useFlowControl' | 'visualBell' | 'allowTransparency', value: boolean): void; /** * Sets an option on the terminal. * @param key The option key. From 9c5aaed4415428a0a28eac51dd80762520110888 Mon Sep 17 00:00:00 2001 From: CHaBou Date: Fri, 15 Dec 2017 00:02:37 +0100 Subject: [PATCH 06/58] Fix some function parameters --- src/Terminal.ts | 2 +- src/renderer/Renderer.ts | 4 ++-- src/renderer/TextRenderLayer.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Terminal.ts b/src/Terminal.ts index 739988da9..c2d04cbb9 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -630,7 +630,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT this.charMeasure = new CharMeasure(document, this.helperContainer); - this.renderer = new Renderer(this, this.options.theme, this.options.allowTransparency); + this.renderer = new Renderer(this, this.options.theme); this.options.theme = null; this.viewport = new Viewport(this, this.viewportElement, this.viewportScrollArea, this.charMeasure); this.viewport.onThemeChanged(this.renderer.colorManager.colors); diff --git a/src/renderer/Renderer.ts b/src/renderer/Renderer.ts index 27ba76ad9..3ba896a6b 100644 --- a/src/renderer/Renderer.ts +++ b/src/renderer/Renderer.ts @@ -25,7 +25,7 @@ export class Renderer extends EventEmitter implements IRenderer { public colorManager: ColorManager; public dimensions: IRenderDimensions; - constructor(private _terminal: ITerminal, theme: ITheme, alpha: boolean) { + constructor(private _terminal: ITerminal, theme: ITheme) { super(); this.colorManager = new ColorManager(); if (theme) { @@ -33,7 +33,7 @@ export class Renderer extends EventEmitter implements IRenderer { } this._renderLayers = [ - new TextRenderLayer(this._terminal.element, 0, alpha, this.colorManager.colors), + new TextRenderLayer(this._terminal.element, 0, this.colorManager.colors, this._terminal.options.allowTransparency), new SelectionRenderLayer(this._terminal.element, 1, this.colorManager.colors), new LinkRenderLayer(this._terminal.element, 2, this.colorManager.colors, this._terminal), new CursorRenderLayer(this._terminal.element, 3, this.colorManager.colors) diff --git a/src/renderer/TextRenderLayer.ts b/src/renderer/TextRenderLayer.ts index fd8acbdfd..c5198e156 100644 --- a/src/renderer/TextRenderLayer.ts +++ b/src/renderer/TextRenderLayer.ts @@ -24,7 +24,7 @@ export class TextRenderLayer extends BaseRenderLayer { private _characterFont: string; private _characterOverlapCache: { [key: string]: boolean } = {}; - constructor(container: HTMLElement, zIndex: number, alpha: boolean, colors: IColorSet) { + constructor(container: HTMLElement, zIndex: number, colors: IColorSet, alpha: boolean) { super(container, 'text', zIndex, alpha, colors); this._state = new GridCache(); } From 14498104fc409d82e15b25b2c9d7a7ca43fad2ee Mon Sep 17 00:00:00 2001 From: npezza93 Date: Thu, 17 Aug 2017 18:19:56 -0400 Subject: [PATCH 07/58] Alt+click will move the prompt cursor to that position Fixes #890 --- src/Terminal.ts | 2 + src/handlers/AltClickHandler.ts | 130 ++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 src/handlers/AltClickHandler.ts diff --git a/src/Terminal.ts b/src/Terminal.ts index 044f5351f..b6a94ddbb 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -27,6 +27,7 @@ import { CompositionHelper } from './CompositionHelper'; import { EventEmitter } from './EventEmitter'; import { Viewport } from './Viewport'; import { rightClickHandler, moveTextAreaUnderMouseCursor, pasteHandler, copyHandler } from './handlers/Clipboard'; +import { AltClickHandler } from './handlers/AltClickHandler'; import { CircularList } from './utils/CircularList'; import { C0 } from './EscapeSequences'; import { InputHandler } from './InputHandler'; @@ -953,6 +954,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT // if the selection manager is having selection forced (ie. a modifier is // held). if (!this.mouseEvents || this.selectionManager.shouldForceSelection(ev)) { + (new AltClickHandler(ev, this)).move(); return; } diff --git a/src/handlers/AltClickHandler.ts b/src/handlers/AltClickHandler.ts new file mode 100644 index 000000000..827e9fdcf --- /dev/null +++ b/src/handlers/AltClickHandler.ts @@ -0,0 +1,130 @@ +/** + * Alt+Click handler module: exports methods for handling all alt+click-related events in the + * terminal. + * @module xterm/handlers/AltClickHandler + * @license MIT + */ + +import { Terminal } from '../Terminal'; +import { CHAR_DATA_WIDTH_INDEX } from '../Buffer'; +import { C0 } from '../EscapeSequences'; + +export class AltClickHandler { + private _terminal: Terminal; + private _mouseRow: number; + private _mouseCol: number; + private _mouseEvent: MouseEvent; + + constructor(mouseEvent: MouseEvent, terminal: Terminal) { + this._terminal = terminal; + + [this._mouseCol, this._mouseRow] = this._terminal.mouseHelper.getCoords( + (this._mouseEvent = mouseEvent), + this._terminal.element, + this._terminal.charMeasure, + this._terminal.options.lineHeight, + this._terminal.cols, + this._terminal.rows, + true + ).map((coordinate: number) => { + return coordinate - 1; + }); + } + + public move(): void { + if (!this._mouseEvent.altKey) return; + + let keyboardArrows; + + if (this._terminal.buffer === this._terminal.buffers.normal) { + keyboardArrows = this.buildArrowSequence(this.normalCharCount(), this.horizontalCursorCommand(this.normalMoveForward())); + } else { + keyboardArrows = this.buildArrowSequence(this.altVerticalCharCount(), this.verticalCursorCommand(this.altMoveUpward())); + keyboardArrows += this.buildArrowSequence(this.altHorizontalCharCount(), this.horizontalCursorCommand(this.altMoveForward())); + } + + this._terminal.send(keyboardArrows); + } + + private buildArrowSequence(count: number, sequence: string): string { + return Array(count).join(sequence); + } + + private altMoveUpward(): boolean { + return this._terminal.buffer.y > this._mouseRow; + } + + private altMoveForward(): boolean { + return this._terminal.buffer.x < this._mouseCol; + } + + private normalMoveForward(): boolean { + return (this._terminal.buffer.x < this._mouseCol && + this._terminal.buffer.y <= this._mouseRow) || // down/right or same row/right + (this._terminal.buffer.x >= this._mouseCol && + this._terminal.buffer.y < this._mouseRow); // down/left or same row/left + } + + private horizontalCursorCommand(moveForward: boolean): string { + let mod = this._terminal.applicationCursor ? 'O' : '['; + + if (moveForward) { + return C0.ESC + mod + 'C'; + } else { + return C0.ESC + mod + 'D'; + } + } + + private verticalCursorCommand(moveUp: boolean): string { + let mod = this._terminal.applicationCursor ? 'O' : '['; + + if (moveUp) { + return C0.ESC + mod + 'A'; + } else { + return C0.ESC + mod + 'B'; + } + } + + private altVerticalCharCount(): number { + return Math.abs(this._terminal.buffer.y - this._mouseRow) + 1; + } + + private altHorizontalCharCount(): number { + return Math.abs(this._terminal.buffer.x - this._mouseCol) + 1; + } + + private normalCharCount(): number { + let currentX = this._terminal.buffer.x; + let currentY = this._terminal.buffer.y; + let startCol = this._terminal.buffer.x; + let bufferStr = ''; + + while (currentX !== this._mouseCol || (currentY !== this._mouseRow)) { + if (this.normalMoveForward()) { + currentX++; + if (currentX > this._terminal.cols - 1) { + bufferStr += this._terminal.buffer.translateBufferLineToString(currentY, false, startCol, currentX); + currentX = 0; + startCol = 0; + currentY++; + } + } else { + currentX--; + if (currentX < 0) { + bufferStr += this._terminal.buffer.translateBufferLineToString(currentY, false, 0, startCol + 1); + currentX = this._terminal.cols - 1; + startCol = currentX; + currentY--; + } + } + } + + if (this.normalMoveForward()) { + currentX++; + } else { + currentX--; + } + bufferStr += this._terminal.buffer.translateBufferLineToString(currentY, false, startCol, currentX); + return bufferStr.length; + } +} From 7e0a4840004cbea7c3efd73d67cf080e17554c7a Mon Sep 17 00:00:00 2001 From: npezza93 Date: Mon, 23 Oct 2017 19:49:39 -0400 Subject: [PATCH 08/58] Handle going back and up in the alt buffer from a long line to a short line --- src/handlers/AltClickHandler.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/handlers/AltClickHandler.ts b/src/handlers/AltClickHandler.ts index 827e9fdcf..42fdc4433 100644 --- a/src/handlers/AltClickHandler.ts +++ b/src/handlers/AltClickHandler.ts @@ -39,8 +39,14 @@ export class AltClickHandler { if (this._terminal.buffer === this._terminal.buffers.normal) { keyboardArrows = this.buildArrowSequence(this.normalCharCount(), this.horizontalCursorCommand(this.normalMoveForward())); } else { - keyboardArrows = this.buildArrowSequence(this.altVerticalCharCount(), this.verticalCursorCommand(this.altMoveUpward())); - keyboardArrows += this.buildArrowSequence(this.altHorizontalCharCount(), this.horizontalCursorCommand(this.altMoveForward())); + let verticalChars = this.buildArrowSequence(this.altVerticalCharCount(), this.verticalCursorCommand(this.altMoveUpward())); + let horizontalChars = this.buildArrowSequence(this.altHorizontalCharCount(), this.horizontalCursorCommand(this.altMoveForward())); + + if (this.altMoveForward()) { + keyboardArrows = verticalChars + horizontalChars + } else { + keyboardArrows = horizontalChars + verticalChars + } } this._terminal.send(keyboardArrows); From 8d41c4c603a07e5ec3ace62d5eb4a72b9ee0e363 Mon Sep 17 00:00:00 2001 From: npezza93 Date: Mon, 23 Oct 2017 19:55:24 -0400 Subject: [PATCH 09/58] Fix lints --- src/handlers/AltClickHandler.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/handlers/AltClickHandler.ts b/src/handlers/AltClickHandler.ts index 42fdc4433..e595ce49d 100644 --- a/src/handlers/AltClickHandler.ts +++ b/src/handlers/AltClickHandler.ts @@ -43,9 +43,9 @@ export class AltClickHandler { let horizontalChars = this.buildArrowSequence(this.altHorizontalCharCount(), this.horizontalCursorCommand(this.altMoveForward())); if (this.altMoveForward()) { - keyboardArrows = verticalChars + horizontalChars + keyboardArrows = verticalChars + horizontalChars; } else { - keyboardArrows = horizontalChars + verticalChars + keyboardArrows = horizontalChars + verticalChars; } } From 027bc9535ef66ba59dbc2f2b4f2c64086c1252a2 Mon Sep 17 00:00:00 2001 From: npezza93 Date: Tue, 23 Jan 2018 20:57:31 -0500 Subject: [PATCH 10/58] Pass false for isSelection so the right half of the cell wont select the next element --- src/handlers/AltClickHandler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/handlers/AltClickHandler.ts b/src/handlers/AltClickHandler.ts index e595ce49d..59962d960 100644 --- a/src/handlers/AltClickHandler.ts +++ b/src/handlers/AltClickHandler.ts @@ -25,7 +25,7 @@ export class AltClickHandler { this._terminal.options.lineHeight, this._terminal.cols, this._terminal.rows, - true + false ).map((coordinate: number) => { return coordinate - 1; }); From 4c6f18c36f925fe4aeae5e9188d14b24cdd35212 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 25 Jan 2018 09:19:40 -0800 Subject: [PATCH 11/58] Revert "Add support for modifiers for PageUp / PageDown keys." This reverts commit 83921c0b26874216ee9c28ebab8d523acf5ff63e. Fixes #1245 --- src/Terminal.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Terminal.ts b/src/Terminal.ts index 3746cb585..6a61bb4e8 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -1600,8 +1600,6 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT // page up if (ev.shiftKey) { result.scrollLines = -(this.rows - 1); - } else if (modifiers) { - result.key = C0.ESC + '[5;' + (modifiers + 1) + '~'; } else { result.key = C0.ESC + '[5~'; } @@ -1610,8 +1608,6 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT // page down if (ev.shiftKey) { result.scrollLines = this.rows - 1; - } else if (modifiers) { - result.key = C0.ESC + '[6;' + (modifiers + 1) + '~'; } else { result.key = C0.ESC + '[6~'; } From 9c62a817d0b8a6c6623a24c45cd383bc496df8d6 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 25 Jan 2018 12:01:51 -0800 Subject: [PATCH 12/58] Fix build after merge --- src/Interfaces.ts | 378 ---------------------------------------------- src/Types.ts | 2 + 2 files changed, 2 insertions(+), 378 deletions(-) delete mode 100644 src/Interfaces.ts diff --git a/src/Interfaces.ts b/src/Interfaces.ts deleted file mode 100644 index 2524d2349..000000000 --- a/src/Interfaces.ts +++ /dev/null @@ -1,378 +0,0 @@ -/** - * Copyright (c) 2017 The xterm.js authors. All rights reserved. - * @license MIT - */ - -import { ICharset, ILinkMatcherOptions } from './Interfaces'; -import { LinkMatcherHandler, LinkMatcherValidationCallback, LineData } from './Types'; -import { IColorSet, IRenderer } from './renderer/Interfaces'; -import { IMouseZoneManager } from './input/Interfaces'; - -export interface IBrowser { - isNode: boolean; - userAgent: string; - platform: string; - isFirefox: boolean; - isMSIE: boolean; - isMac: boolean; - isIpad: boolean; - isIphone: boolean; - isMSWindows: boolean; -} - -export interface IBufferAccessor { - buffer: IBuffer; -} - -export interface IElementAccessor { - element: HTMLElement; -} - -export interface ILinkifierAccessor { - linkifier: ILinkifier; -} - -export interface ITerminal extends ILinkifierAccessor, IBufferAccessor, IElementAccessor, IEventEmitter { - selectionManager: ISelectionManager; - charMeasure: ICharMeasure; - textarea: HTMLTextAreaElement; - renderer: IRenderer; - rows: number; - cols: number; - browser: IBrowser; - writeBuffer: string[]; - cursorHidden: boolean; - cursorState: number; - defAttr: number; - options: ITerminalOptions; - buffers: IBufferSet; - isFocused: boolean; - mouseHelper: IMouseHelper; - bracketedPasteMode: boolean; - - /** - * Emit the 'data' event and populate the given data. - * @param data The data to populate in the event. - */ - handler(data: string): void; - scrollLines(disp: number, suppressScrollEvent?: boolean): void; - cancel(ev: Event, force?: boolean): boolean | void; - log(text: string): void; - reset(): void; - showCursor(): void; - blankLine(cur?: boolean, isWrapped?: boolean, cols?: number): LineData; - refresh(start: number, end: number): void; -} - -/** - * This interface encapsulates everything needed from the Terminal by the - * InputHandler. This cleanly separates the large amount of methods needed by - * InputHandler cleanly from the ITerminal interface. - */ -export interface IInputHandlingTerminal extends IEventEmitter { - element: HTMLElement; - options: ITerminalOptions; - cols: number; - rows: number; - charset: ICharset; - gcharset: number; - glevel: number; - charsets: ICharset[]; - applicationKeypad: boolean; - applicationCursor: boolean; - originMode: boolean; - insertMode: boolean; - wraparoundMode: boolean; - bracketedPasteMode: boolean; - defAttr: number; - curAttr: number; - prefix: string; - savedCols: number; - x10Mouse: boolean; - vt200Mouse: boolean; - normalMouse: boolean; - mouseEvents: boolean; - sendFocus: boolean; - utfMouse: boolean; - sgrMouse: boolean; - urxvtMouse: boolean; - cursorHidden: boolean; - - buffers: IBufferSet; - buffer: IBuffer; - viewport: IViewport; - selectionManager: ISelectionManager; - - bell(): void; - focus(): void; - convertEol: boolean; - updateRange(y: number): void; - scroll(isWrapped?: boolean): void; - setgLevel(g: number): void; - eraseAttr(): number; - eraseRight(x: number, y: number): void; - eraseLine(y: number): void; - eraseLeft(x: number, y: number): void; - blankLine(cur?: boolean, isWrapped?: boolean): LineData; - is(term: string): boolean; - send(data: string): void; - setgCharset(g: number, charset: ICharset): void; - resize(x: number, y: number): void; - log(text: string, data?: any): void; - reset(): void; - showCursor(): void; - refresh(start: number, end: number): void; - matchColor(r1: number, g1: number, b1: number): number; - error(text: string, data?: any): void; - setOption(key: string, value: any): void; -} - -export interface ITerminalOptions { - bellSound?: string; - bellStyle?: string; - cancelEvents?: boolean; - cols?: number; - convertEol?: boolean; - cursorBlink?: boolean; - cursorStyle?: string; - debug?: boolean; - disableStdin?: boolean; - enableBold?: boolean; - fontSize?: number; - fontFamily?: string; - handler?: (data: string) => void; - letterSpacing?: number; - lineHeight?: number; - rows?: number; - screenKeys?: boolean; - scrollback?: number; - tabStopWidth?: number; - termName?: string; - theme?: ITheme; - useFlowControl?: boolean; - rightClickSelectsWord?: boolean; -} - -export interface IBuffer { - lines: ICircularList; - ydisp: number; - ybase: number; - y: number; - x: number; - tabs: any; - scrollBottom: number; - scrollTop: number; - savedY: number; - savedX: number; - isCursorInViewport: boolean; - translateBufferLineToString(lineIndex: number, trimRight: boolean, startCol?: number, endCol?: number): string; - nextStop(x?: number): number; - prevStop(x?: number): number; -} - -export interface IBufferSet { - alt: IBuffer; - normal: IBuffer; - active: IBuffer; - - activateNormalBuffer(): void; - activateAltBuffer(): void; -} - -export interface IMouseHelper { - getCoords(event: {pageX: number, pageY: number}, element: HTMLElement, charMeasure: ICharMeasure, lineHeight: number, colCount: number, rowCount: number, isSelection?: boolean): [number, number]; - getRawByteCoords(event: MouseEvent, element: HTMLElement, charMeasure: ICharMeasure, lineHeight: number, colCount: number, rowCount: number): { x: number, y: number }; -} - -export interface IViewport { - syncScrollArea(): void; - onWheel(ev: WheelEvent): void; - onTouchStart(ev: TouchEvent): void; - onTouchMove(ev: TouchEvent): void; - onThemeChanged(colors: IColorSet): void; -} - -export interface ISelectionManager { - selectionText: string; - selectionStart: [number, number]; - selectionEnd: [number, number]; - - disable(): void; - enable(): void; - setBuffer(buffer: IBuffer): void; - setSelection(row: number, col: number, length: number): void; - isClickInSelection(event: MouseEvent): boolean; - selectWordAtCursor(event: MouseEvent): void; -} - -export interface ICompositionHelper { - compositionstart(): void; - compositionupdate(ev: CompositionEvent): void; - compositionend(): void; - updateCompositionElements(dontRecurse?: boolean): void; - keydown(ev: KeyboardEvent): boolean; -} - -export interface ICharMeasure { - width: number; - height: number; - measure(options: ITerminalOptions): void; -} - -export interface ILinkifier extends IEventEmitter { - attachToDom(mouseZoneManager: IMouseZoneManager): void; - linkifyRows(start: number, end: number): void; - setHypertextLinkHandler(handler: LinkMatcherHandler): void; - setHypertextValidationCallback(callback: LinkMatcherValidationCallback): void; - registerLinkMatcher(regex: RegExp, handler: LinkMatcherHandler, options?: ILinkMatcherOptions): number; - deregisterLinkMatcher(matcherId: number): boolean; -} - -export interface ICircularList extends IEventEmitter { - length: number; - maxLength: number; - forEach: (callbackfn: (value: T, index: number) => void) => void; - - get(index: number): T; - set(index: number, value: T): void; - push(value: T): void; - pop(): T; - splice(start: number, deleteCount: number, ...items: T[]): void; - trimStart(count: number): void; - shiftElements(start: number, count: number, offset: number): void; -} - -export interface IEventEmitter { - on(type: string, listener: IListenerType): void; - off(type: string, listener: IListenerType): void; - emit(type: string, data?: any): void; -} - -export interface IListenerType { - (data?: any): void; - listener?: (data?: any) => void; -} - -export interface ILinkMatcherOptions { - /** - * The index of the link from the regex.match(text) call. This defaults to 0 - * (for regular expressions without capture groups). - */ - matchIndex?: number; - /** - * A callback that validates an individual link, returning true if valid and - * false if invalid. - */ - validationCallback?: LinkMatcherValidationCallback; - /** - * A callback that fires when the mouse hovers over a link. - */ - tooltipCallback?: LinkMatcherHandler; - /** - * A callback that fires when the mouse leaves a link that was hovered. - */ - leaveCallback?: () => void; - /** - * The priority of the link matcher, this defines the order in which the link - * matcher is evaluated relative to others, from highest to lowest. The - * default value is 0. - */ - priority?: number; -} - -/** - * Handles actions generated by the parser. - */ -export interface IInputHandler { - addChar(char: string, code: number): void; - - /** C0 BEL */ bell(): void; - /** C0 LF */ lineFeed(): void; - /** C0 CR */ carriageReturn(): void; - /** C0 BS */ backspace(): void; - /** C0 HT */ tab(): void; - /** C0 SO */ shiftOut(): void; - /** C0 SI */ shiftIn(): void; - - /** CSI @ */ insertChars(params?: number[]): void; - /** CSI A */ cursorUp(params?: number[]): void; - /** CSI B */ cursorDown(params?: number[]): void; - /** CSI C */ cursorForward(params?: number[]): void; - /** CSI D */ cursorBackward(params?: number[]): void; - /** CSI E */ cursorNextLine(params?: number[]): void; - /** CSI F */ cursorPrecedingLine(params?: number[]): void; - /** CSI G */ cursorCharAbsolute(params?: number[]): void; - /** CSI H */ cursorPosition(params?: number[]): void; - /** CSI I */ cursorForwardTab(params?: number[]): void; - /** CSI J */ eraseInDisplay(params?: number[]): void; - /** CSI K */ eraseInLine(params?: number[]): void; - /** CSI L */ insertLines(params?: number[]): void; - /** CSI M */ deleteLines(params?: number[]): void; - /** CSI P */ deleteChars(params?: number[]): void; - /** CSI S */ scrollUp(params?: number[]): void; - /** CSI T */ scrollDown(params?: number[]): void; - /** CSI X */ eraseChars(params?: number[]): void; - /** CSI Z */ cursorBackwardTab(params?: number[]): void; - /** CSI ` */ charPosAbsolute(params?: number[]): void; - /** CSI a */ HPositionRelative(params?: number[]): void; - /** CSI b */ repeatPrecedingCharacter(params?: number[]): void; - /** CSI c */ sendDeviceAttributes(params?: number[]): void; - /** CSI d */ linePosAbsolute(params?: number[]): void; - /** CSI e */ VPositionRelative(params?: number[]): void; - /** CSI f */ HVPosition(params?: number[]): void; - /** CSI g */ tabClear(params?: number[]): void; - /** CSI h */ setMode(params?: number[]): void; - /** CSI l */ resetMode(params?: number[]): void; - /** CSI m */ charAttributes(params?: number[]): void; - /** CSI n */ deviceStatus(params?: number[]): void; - /** CSI p */ softReset(params?: number[]): void; - /** CSI q */ setCursorStyle(params?: number[]): void; - /** CSI r */ setScrollRegion(params?: number[]): void; - /** CSI s */ saveCursor(params?: number[]): void; - /** CSI u */ restoreCursor(params?: number[]): void; -} - -export interface ITheme { - foreground?: string; - background?: string; - cursor?: string; - cursorAccent?: string; - selection?: string; - black?: string; - red?: string; - green?: string; - yellow?: string; - blue?: string; - magenta?: string; - cyan?: string; - white?: string; - brightBlack?: string; - brightRed?: string; - brightGreen?: string; - brightYellow?: string; - brightBlue?: string; - brightMagenta?: string; - brightCyan?: string; - brightWhite?: string; -} - -export interface ILinkMatcher { - id: number; - regex: RegExp; - handler: LinkMatcherHandler; - hoverTooltipCallback?: LinkMatcherHandler; - hoverLeaveCallback?: () => void; - matchIndex?: number; - validationCallback?: LinkMatcherValidationCallback; - priority?: number; -} - -export interface ICharset { - [key: string]: string; -} - -export interface ILinkHoverEvent { - x: number; - y: number; - length: number; -} diff --git a/src/Types.ts b/src/Types.ts index f3e9bb941..f78e52a5e 100644 --- a/src/Types.ts +++ b/src/Types.ts @@ -283,6 +283,8 @@ export interface ISelectionManager { disable(): void; enable(): void; setSelection(row: number, col: number, length: number): void; + isClickInSelection(event: MouseEvent): boolean; + selectWordAtCursor(event: MouseEvent): void; } export interface ILinkifier extends IEventEmitter { From 1dce76dbbb02ee562ec7517b513b00cd3242a28e Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 25 Jan 2018 12:17:56 -0800 Subject: [PATCH 13/58] Add curly to tslint, fix errors Fixes #1248 --- src/CharWidth.ts | 34 ++++++++++++++++++++++------------ src/InputHandler.ts | 3 ++- src/Parser.ts | 3 ++- src/SelectionManager.ts | 3 ++- src/Terminal.ts | 14 ++++++++------ tslint.json | 4 ++++ 6 files changed, 40 insertions(+), 21 deletions(-) diff --git a/src/CharWidth.ts b/src/CharWidth.ts index d296b4357..512ed5f00 100644 --- a/src/CharWidth.ts +++ b/src/CharWidth.ts @@ -63,28 +63,33 @@ export const wcwidth = (function(opts: {nul: number, control: number}): (ucs: nu let min = 0; let max = data.length - 1; let mid; - if (ucs < data[0][0] || ucs > data[max][1]) + if (ucs < data[0][0] || ucs > data[max][1]) { return false; + } while (max >= min) { mid = (min + max) >> 1; - if (ucs > data[mid][1]) + if (ucs > data[mid][1]) { min = mid + 1; - else if (ucs < data[mid][0]) + } else if (ucs < data[mid][0]) { max = mid - 1; - else + } else { return true; + } } return false; } function wcwidthBMP(ucs: number): number { // test for 8-bit control characters - if (ucs === 0) + if (ucs === 0) { return opts.nul; - if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) + } + if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) { return opts.control; + } // binary search in table of non-spacing characters - if (bisearch(ucs, COMBINING_BMP)) + if (bisearch(ucs, COMBINING_BMP)) { return 0; + } // if we arrive here, ucs is not a combining or C0/C1 control character if (isWideBMP(ucs)) { return 2; @@ -106,8 +111,9 @@ export const wcwidth = (function(opts: {nul: number, control: number}): (ucs: nu (ucs >= 0xffe0 && ucs <= 0xffe6))); } function wcwidthHigh(ucs: number): 0 | 1 | 2 { - if (bisearch(ucs, COMBINING_HIGH)) + if (bisearch(ucs, COMBINING_HIGH)) { return 0; + } if ((ucs >= 0x20000 && ucs <= 0x2fffd) || (ucs >= 0x30000 && ucs <= 0x3fffd)) { return 2; } @@ -128,8 +134,9 @@ export const wcwidth = (function(opts: {nul: number, control: number}): (ucs: nu for (let i = 0; i < CONTAINERSIZE; ++i) { let num = 0; let pos = CODEPOINTS_PER_ITEM; - while (pos--) + while (pos--) { num = (num << 2) | wcwidthBMP(CODEPOINTS_PER_ITEM * i + pos); + } table[i] = num; } return table; @@ -148,13 +155,16 @@ export const wcwidth = (function(opts: {nul: number, control: number}): (ucs: nu // ==> n = n & 3 e.g. 000000000000000000000000000000XX return function (num: number): number { num = num | 0; // get asm.js like optimization under V8 - if (num < 32) + if (num < 32) { return control | 0; - if (num < 127) + } + if (num < 127) { return 1; + } let t = table || init_table(); - if (num < 65536) + if (num < 65536) { return t[num >> 4] >> ((num & 15) << 1) & 3; + } // do a full search for high codepoints return wcwidthHigh(num); }; diff --git a/src/InputHandler.ts b/src/InputHandler.ts index f71117f83..9cdaddaae 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -69,8 +69,9 @@ export class InputHandler implements IInputHandler { (this._terminal.buffer.lines.get(this._terminal.buffer.y)).isWrapped = true; } } else { - if (chWidth === 2) // FIXME: check for xterm behavior + if (chWidth === 2) { // FIXME: check for xterm behavior return; + } } } row = this._terminal.buffer.y + this._terminal.buffer.ybase; diff --git a/src/Parser.ts b/src/Parser.ts index 3ac03e4fb..03b4a39e6 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -224,8 +224,9 @@ export class Parser { ch += data.charAt(this._position + 1); } // surrogate low - already handled above - if (0xDC00 <= code && code <= 0xDFFF) + if (0xDC00 <= code && code <= 0xDFFF) { continue; + } switch (this._state) { case ParserState.NORMAL: diff --git a/src/SelectionManager.ts b/src/SelectionManager.ts index 10612c5c6..383427b97 100644 --- a/src/SelectionManager.ts +++ b/src/SelectionManager.ts @@ -538,8 +538,9 @@ export class SelectionManager extends EventEmitter implements ISelectionManager private _onMouseUp(event: MouseEvent): void { this._removeMouseDownListeners(); - if (this.hasSelection) + if (this.hasSelection) { this._terminal.emit('selection'); + } } private _onBufferActivate(e: {activeBuffer: IBuffer, inactiveBuffer: IBuffer}): void { diff --git a/src/Terminal.ts b/src/Terminal.ts index 5536cf03c..a894f8c09 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -1580,21 +1580,23 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT break; case 36: // home - if (modifiers) + if (modifiers) { result.key = C0.ESC + '[1;' + (modifiers + 1) + 'H'; - else if (this.applicationCursor) + } else if (this.applicationCursor) { result.key = C0.ESC + 'OH'; - else + } else { result.key = C0.ESC + '[H'; + } break; case 35: // end - if (modifiers) + if (modifiers) { result.key = C0.ESC + '[1;' + (modifiers + 1) + 'F'; - else if (this.applicationCursor) + } else if (this.applicationCursor) { result.key = C0.ESC + 'OF'; - else + } else { result.key = C0.ESC + '[F'; + } break; case 33: // page up diff --git a/tslint.json b/tslint.json index f6ad759a7..37ede7fea 100644 --- a/tslint.json +++ b/tslint.json @@ -9,6 +9,10 @@ true, "check-space" ], + "curly": [ + true, + "ignore-same-line" + ], "indent": [ true, "spaces" From 2c065b66bec4a84083339575b8163645d0d7ecfe Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 25 Jan 2018 12:31:48 -0800 Subject: [PATCH 14/58] Add SQL Operations Studio to real world uses --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 730fc9af9..a5d34632b 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,7 @@ computational environment for Jupyter, supporting interactive data science and s - [**rtty**](https://github.com/zhaojh329/rtty): A reverse proxy WebTTY. It is composed of the client and the server. - [**Pisth**](https://github.com/ColdGrub1384/Pisth): An SFTP and SSH client for iOS - [**abstruse**](https://github.com/bleenco/abstruse): Abstruse CI is a continuous integration platform based on Node.JS and Docker. +- [**Microsoft SQL Operations Studio**](https://github.com/Microsoft/sqlopsstudio): A data management tool that enables working with SQL Server, Azure SQL DB and SQL DW from Windows, macOS and Linux Do you use xterm.js in your application as well? Please [open a Pull Request](https://github.com/sourcelair/xterm.js/pulls) to include it here. We would love to have it in our list. From e6c6e0766a7d5fd79f808b65814653c0ab709a21 Mon Sep 17 00:00:00 2001 From: Bruno Ribeito Date: Thu, 25 Jan 2018 21:00:10 +0000 Subject: [PATCH 15/58] Fix usage of allowWhitespaceOnlySelection variable --- src/SelectionManager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SelectionManager.ts b/src/SelectionManager.ts index a4a0b80c6..00d22fb6a 100644 --- a/src/SelectionManager.ts +++ b/src/SelectionManager.ts @@ -267,7 +267,7 @@ export class SelectionManager extends EventEmitter implements ISelectionManager public selectWordAtCursor(event: MouseEvent): void { const coords = this._getMouseBufferCoords(event); if (coords) { - const wordPosition = this._getWordAt(coords, true); + const wordPosition = this._getWordAt(coords, false); if (wordPosition) { this._model.selectionStart = [wordPosition.start, coords[1]]; this._model.selectionStartLength = wordPosition.length; From fe53e1a09136828cb32faab5326d48ec11456c1f Mon Sep 17 00:00:00 2001 From: CHaBou Date: Thu, 25 Jan 2018 23:20:20 +0100 Subject: [PATCH 16/58] Change canvas transparency when option is updated --- src/renderer/BaseRenderLayer.ts | 22 +++++++++++++++++++++- src/renderer/CharAtlas.ts | 3 +++ src/renderer/TextRenderLayer.ts | 4 ++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts index bf952d06f..b9627dee0 100644 --- a/src/renderer/BaseRenderLayer.ts +++ b/src/renderer/BaseRenderLayer.ts @@ -54,6 +54,26 @@ export abstract class BaseRenderLayer implements IRenderLayer { this._refreshCharAtlas(terminal, colorSet); } + protected setTransparency(terminal: ITerminal, alpha: boolean): void { + if (alpha === this._alpha) { + return; + } + this._alpha = alpha + const oldCanvas = this._canvas + // Cloning preserves canvas properties and permits to acquire a new context + this._canvas = this._canvas.cloneNode(); + this._ctx = this._canvas.getContext('2d', {alpha: this._alpha}); + this._ctx.scale(window.devicePixelRatio, window.devicePixelRatio); + // Draw the background if this is an opaque layer + if (!this._alpha) { + this.clearAll(); + } + oldCanvas.parentNode.replaceChild(this._canvas, oldCanvas); + this._refreshCharAtlas(terminal, this._colors); + // Force a full redraw + this.onGridChanged(terminal, 0, terminal.rows - 1) + } + /** * Refreshes the char atlas, aquiring a new one if necessary. * @param terminal The terminal. @@ -64,7 +84,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { return; } this._charAtlas = null; - const result = acquireCharAtlas(terminal, this._colors, this._scaledCharWidth, this._scaledCharHeight); + const result = acquireCharAtlas(terminal, colorSet, this._scaledCharWidth, this._scaledCharHeight); if (result instanceof HTMLCanvasElement) { this._charAtlas = result; } else { diff --git a/src/renderer/CharAtlas.ts b/src/renderer/CharAtlas.ts index f5a13492a..1911d4e2f 100644 --- a/src/renderer/CharAtlas.ts +++ b/src/renderer/CharAtlas.ts @@ -17,6 +17,7 @@ interface ICharAtlasConfig { fontWeightBold: string; scaledCharWidth: number; scaledCharHeight: number; + allowTransparency: boolean; colors: IColorSet; } @@ -112,6 +113,7 @@ function generateConfig(scaledCharWidth: number, scaledCharHeight: number, termi fontSize: terminal.options.fontSize, fontWeight: terminal.options.fontWeight, fontWeightBold: terminal.options.fontWeightBold, + allowTransparency: terminal.options.allowTransparency, colors: clonedColors }; } @@ -126,6 +128,7 @@ function configEquals(a: ICharAtlasConfig, b: ICharAtlasConfig): boolean { 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 && diff --git a/src/renderer/TextRenderLayer.ts b/src/renderer/TextRenderLayer.ts index b2563e975..0617d2d20 100644 --- a/src/renderer/TextRenderLayer.ts +++ b/src/renderer/TextRenderLayer.ts @@ -192,6 +192,10 @@ export class TextRenderLayer extends BaseRenderLayer { } } + public onOptionsChanged(terminal: ITerminal): void { + this.setTransparency(terminal, terminal.options.allowTransparency); + } + /** * Whether a character is overlapping to the next cell. */ From 069b489fb666d467c656f180d6852a3e46a73c55 Mon Sep 17 00:00:00 2001 From: sitzmar Date: Fri, 26 Jan 2018 08:04:59 -0800 Subject: [PATCH 17/58] adjust timeout to ensure right-click event has fired --- src/handlers/Clipboard.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/handlers/Clipboard.ts b/src/handlers/Clipboard.ts index fd2b3d779..035b5fff9 100644 --- a/src/handlers/Clipboard.ts +++ b/src/handlers/Clipboard.ts @@ -100,6 +100,7 @@ export function moveTextAreaUnderMouseCursor(ev: MouseEvent, textarea: HTMLTextA textarea.focus(); // Reset the terminal textarea's styling + // Timeout needs to be long enough for click event to be handled. setTimeout(() => { textarea.style.position = null; textarea.style.width = null; @@ -107,7 +108,7 @@ export function moveTextAreaUnderMouseCursor(ev: MouseEvent, textarea: HTMLTextA textarea.style.left = null; textarea.style.top = null; textarea.style.zIndex = null; - }, 4); + }, 200); } /** From 327b16ac2e038892a1bc1fa4ecf619f0f69f77d0 Mon Sep 17 00:00:00 2001 From: npezza93 Date: Sat, 27 Jan 2018 21:30:24 -0500 Subject: [PATCH 18/58] Add repeat polyfill for repeating a string --- src/utils/Generic.ts | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/utils/Generic.ts b/src/utils/Generic.ts index 4bc6c487f..9f9d2666f 100644 --- a/src/utils/Generic.ts +++ b/src/utils/Generic.ts @@ -11,3 +11,31 @@ export function contains(arr: any[], el: any): boolean { return arr.indexOf(el) >= 0; } + +/** + * Returns a string repeated a given number of times + * Polyfill from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat + * @param {Number} count The number of times to repeat the string + * @param {String} string The string that is to be repeated + */ +export function repeat(count: number, str: string): string { + if (count < 0) throw new RangeError('repeat count must be non-negative'); + if (count === Infinity) throw new RangeError('repeat count must be less than infinity'); + + count = Math.floor(count); + if (str.length === 0 || count === 0) return ''; + + // Ensuring count is a 31-bit integer allows us to heavily optimize the + // main part. But anyway, most current (August 2014) browsers can't handle + // strings 1 << 28 chars or longer, so: + if (str.length * count >= 1 << 28) { + throw new RangeError('repeat count must not overflow maximum string size'); + } + + let rpt = ''; + for (let i = 0; i < count; i++) { + rpt += str; + } + + return rpt; +} From 833d8144990393ec7e50a1ccbf78a6cce3dd4aa1 Mon Sep 17 00:00:00 2001 From: npezza93 Date: Sat, 27 Jan 2018 21:30:53 -0500 Subject: [PATCH 19/58] Refactor alt-click to work independently of which buffer is being used --- src/handlers/AltClickHandler.ts | 265 ++++++++++++++++++++++---------- 1 file changed, 182 insertions(+), 83 deletions(-) diff --git a/src/handlers/AltClickHandler.ts b/src/handlers/AltClickHandler.ts index 59962d960..829daf97a 100644 --- a/src/handlers/AltClickHandler.ts +++ b/src/handlers/AltClickHandler.ts @@ -1,24 +1,32 @@ /** - * Alt+Click handler module: exports methods for handling all alt+click-related events in the - * terminal. + * Alt+Click handler module: exports methods for handling all alt+click-related + * events in the terminal. * @module xterm/handlers/AltClickHandler * @license MIT */ import { Terminal } from '../Terminal'; -import { CHAR_DATA_WIDTH_INDEX } from '../Buffer'; import { C0 } from '../EscapeSequences'; +import { repeat } from '../utils/Generic'; +import { CircularList } from '../utils/CircularList'; +import { LineData } from '../Types'; export class AltClickHandler { private _terminal: Terminal; - private _mouseRow: number; - private _mouseCol: number; + private _startRow: number; + private _startCol: number; + private _endRow: number; + private _endCol: number; + private _lines: CircularList; private _mouseEvent: MouseEvent; constructor(mouseEvent: MouseEvent, terminal: Terminal) { this._terminal = terminal; + this._lines = terminal.buffer.lines; + this._startCol = this._terminal.buffer.x; + this._startRow = this._terminal.buffer.y; - [this._mouseCol, this._mouseRow] = this._terminal.mouseHelper.getCoords( + [this._endCol, this._endRow] = this._terminal.mouseHelper.getCoords( (this._mouseEvent = mouseEvent), this._terminal.element, this._terminal.charMeasure, @@ -31,106 +39,197 @@ export class AltClickHandler { }); } + /** + * Writes the escape sequences of arrows to the terminal + */ public move(): void { - if (!this._mouseEvent.altKey) return; + if (this._mouseEvent.altKey) this._terminal.send(this._arrowSequences()); + } - let keyboardArrows; + /** + * Concatenates all the arrow sequences together. + * Resets the starting row to an unwrapped row, moves to the requested row, + * then moves to requested col. + */ + private _arrowSequences(): string { + return this._resetStartingRow() + + this._moveToRequestedRow() + + this._moveToRequestedCol(); + } - if (this._terminal.buffer === this._terminal.buffers.normal) { - keyboardArrows = this.buildArrowSequence(this.normalCharCount(), this.horizontalCursorCommand(this.normalMoveForward())); - } else { - let verticalChars = this.buildArrowSequence(this.altVerticalCharCount(), this.verticalCursorCommand(this.altMoveUpward())); - let horizontalChars = this.buildArrowSequence(this.altHorizontalCharCount(), this.horizontalCursorCommand(this.altMoveForward())); + /** + * If the initial position of the cursor is on a row that is wrapped, move the + * cursor up to the first row that is not wrapped to have accurate vertical + * positioning. + */ + private _resetStartingRow(): string { + return repeat(this._bufferLine( + this._startCol, this._startRow, this._startCol, + this._startRow - this._wrappedRowsForRow(this._startRow), false + ).length, this._colSequence(false)); + } - if (this.altMoveForward()) { - keyboardArrows = verticalChars + horizontalChars; - } else { - keyboardArrows = horizontalChars + verticalChars; + /** + * Using the reset starting and ending row, move to the requested row, + * ignoring wrapped rows + */ + private _moveToRequestedRow(): string { + let startRow = this._startRow - this._wrappedRowsForRow(this._startRow); + let endRow = this._endRow - this._wrappedRowsForRow(this._endRow); + + let rowsToMove = Math.abs(startRow - endRow) - this._wrappedRowsCount(); + + return repeat(rowsToMove, this._rowSequence(this._shouldMoveUp())); + } + + /** + * Move to the requested col on the ending row + */ + private _moveToRequestedCol(): string { + let startRow = this._endRow - this._wrappedRowsForRow(this._endRow); + let endRow = this._endRow; + let forward = this._shouldMoveForward(); + + return repeat(this._bufferLine( + this._startCol, startRow, this._endCol, endRow, forward + ).length, this._colSequence(forward)); + } + + /** + * Utility functions + */ + + /** + * Calculates the number of wrapped rows between the unwrapped starting and + * ending rows. These rows need to ignored since the cursor skips over them. + */ + private _wrappedRowsCount(): number { + let wrappedRows = 0; + let startRow = this._startRow - this._wrappedRowsForRow(this._startRow); + let endRow = this._endRow - this._wrappedRowsForRow(this._endRow); + + for (let i = 0; i < Math.abs(startRow - endRow); i++) { + let direction = this._shouldMoveUp() ? -1 : 1; + + if (this._lines.get(startRow + (direction * i)).isWrapped) wrappedRows++; + } + + return wrappedRows; + } + + /** + * Calculates the number of wrapped rows that make up a given row. + * @param currentRow The row to determine how many wrapped rows make it up + */ + private _wrappedRowsForRow(currentRow: number): number { + let rowCount = 0; + let lineWraps = this._lines.get(currentRow).isWrapped; + + while (lineWraps && currentRow >= 0 && currentRow < this._terminal.rows) { + rowCount++; + currentRow--; + lineWraps = this._lines.get(currentRow).isWrapped; + } + + return rowCount; + } + + /** + * Direction determiners + */ + + /** + * Determines if the right or left arrow is needed + */ + private _shouldMoveForward(): boolean { + let startRow = this._endRow - this._wrappedRowsForRow(this._endRow); + + return (this._startCol < this._endCol && + startRow <= this._endRow) || // down/right or same y/right + (this._startCol >= this._endCol && + startRow < this._endRow); // down/left or same y/left + } + + /** + * Determines if the up or down arrow is needed + */ + private _shouldMoveUp(): boolean { + return this._startRow > this._endRow; + } + + /** + * Constructs the string of chars in the buffer from a starting row and col + * to an ending row and col + * @param startCol The starting column position + * @param startRow The starting row position + * @param endCol The ending column position + * @param endRow The ending row position + * @param forward Direction to move + */ + private _bufferLine( + startCol: number, + startRow: number, + endCol: number, + endRow: number, + forward: boolean): string { + let currentRow = startCol; + let currentCol = startRow; + let bufferStr = ''; + + while (currentRow !== endCol || (currentCol !== endRow)) { + currentRow += forward ? 1 : -1; + + if (forward && currentRow > this._terminal.cols - 1) { + bufferStr += this._terminal.buffer.translateBufferLineToString( + currentCol, false, startCol, currentRow + ); + currentRow = 0; + startCol = 0; + currentCol++; + } else if (!forward && currentRow < 0) { + bufferStr += this._terminal.buffer.translateBufferLineToString( + currentCol, false, 0, startCol + 1 + ); + currentRow = this._terminal.cols - 1; + startCol = currentRow; + currentCol--; } } - this._terminal.send(keyboardArrows); + return bufferStr + this._terminal.buffer.translateBufferLineToString( + currentCol, false, startCol, currentRow + ); } - private buildArrowSequence(count: number, sequence: string): string { - return Array(count).join(sequence); - } + /** + * Arrow escape sequences + */ - private altMoveUpward(): boolean { - return this._terminal.buffer.y > this._mouseRow; - } - - private altMoveForward(): boolean { - return this._terminal.buffer.x < this._mouseCol; - } - - private normalMoveForward(): boolean { - return (this._terminal.buffer.x < this._mouseCol && - this._terminal.buffer.y <= this._mouseRow) || // down/right or same row/right - (this._terminal.buffer.x >= this._mouseCol && - this._terminal.buffer.y < this._mouseRow); // down/left or same row/left - } - - private horizontalCursorCommand(moveForward: boolean): string { + /** + * Constructs the escape sequence for the left or right arrow + * @param forward Right arrow or left arrow + */ + private _colSequence(forward: boolean): string { let mod = this._terminal.applicationCursor ? 'O' : '['; - if (moveForward) { + if (forward) { return C0.ESC + mod + 'C'; } else { return C0.ESC + mod + 'D'; } } - private verticalCursorCommand(moveUp: boolean): string { + /** + * Constructs the escape sequence for clicking the up or down arrow + * @param up Up arrow or down arrow + */ + private _rowSequence(up: boolean): string { let mod = this._terminal.applicationCursor ? 'O' : '['; - if (moveUp) { + if (up) { return C0.ESC + mod + 'A'; } else { return C0.ESC + mod + 'B'; } } - - private altVerticalCharCount(): number { - return Math.abs(this._terminal.buffer.y - this._mouseRow) + 1; - } - - private altHorizontalCharCount(): number { - return Math.abs(this._terminal.buffer.x - this._mouseCol) + 1; - } - - private normalCharCount(): number { - let currentX = this._terminal.buffer.x; - let currentY = this._terminal.buffer.y; - let startCol = this._terminal.buffer.x; - let bufferStr = ''; - - while (currentX !== this._mouseCol || (currentY !== this._mouseRow)) { - if (this.normalMoveForward()) { - currentX++; - if (currentX > this._terminal.cols - 1) { - bufferStr += this._terminal.buffer.translateBufferLineToString(currentY, false, startCol, currentX); - currentX = 0; - startCol = 0; - currentY++; - } - } else { - currentX--; - if (currentX < 0) { - bufferStr += this._terminal.buffer.translateBufferLineToString(currentY, false, 0, startCol + 1); - currentX = this._terminal.cols - 1; - startCol = currentX; - currentY--; - } - } - } - - if (this.normalMoveForward()) { - currentX++; - } else { - currentX--; - } - bufferStr += this._terminal.buffer.translateBufferLineToString(currentY, false, startCol, currentX); - return bufferStr.length; - } } From dc59f33ccf4a2075461285fff8fd5c1661bd7f57 Mon Sep 17 00:00:00 2001 From: npezza93 Date: Sat, 27 Jan 2018 22:06:31 -0500 Subject: [PATCH 20/58] Fix translateBufferToString bug --- src/Buffer.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Buffer.ts b/src/Buffer.ts index 3e7d61224..9d47666f4 100644 --- a/src/Buffer.ts +++ b/src/Buffer.ts @@ -217,7 +217,10 @@ export class Buffer implements IBuffer { // needed here because some chars are 0 characters long (eg. after wide // chars) and some chars are longer than 1 characters long (eg. emojis). let startIndex = startCol; - endCol = endCol || line.length; + // Only set endCol to the line length when it is null. 0 is a valid column. + if (endCol === null) { + endCol = line.length; + } let endIndex = endCol; for (let i = 0; i < line.length; i++) { From a4ee7236651564dcde2554c0968f5fae0c996126 Mon Sep 17 00:00:00 2001 From: npezza93 Date: Sat, 27 Jan 2018 22:06:58 -0500 Subject: [PATCH 21/58] Fix backward row/col definition --- src/handlers/AltClickHandler.ts | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/handlers/AltClickHandler.ts b/src/handlers/AltClickHandler.ts index 829daf97a..bddde6fbc 100644 --- a/src/handlers/AltClickHandler.ts +++ b/src/handlers/AltClickHandler.ts @@ -172,32 +172,32 @@ export class AltClickHandler { endCol: number, endRow: number, forward: boolean): string { - let currentRow = startCol; - let currentCol = startRow; + let currentCol = startCol; + let currentRow = startRow; let bufferStr = ''; - while (currentRow !== endCol || (currentCol !== endRow)) { - currentRow += forward ? 1 : -1; + while (currentCol !== endCol || currentRow !== endRow) { + currentCol += forward ? 1 : -1; - if (forward && currentRow > this._terminal.cols - 1) { + if (forward && currentCol > this._terminal.cols - 1) { bufferStr += this._terminal.buffer.translateBufferLineToString( - currentCol, false, startCol, currentRow + currentRow, false, startCol, currentCol ); - currentRow = 0; + currentCol = 0; startCol = 0; - currentCol++; - } else if (!forward && currentRow < 0) { + currentRow++; + } else if (!forward && currentCol < 0) { bufferStr += this._terminal.buffer.translateBufferLineToString( - currentCol, false, 0, startCol + 1 + currentRow, false, 0, startCol + 1 ); - currentRow = this._terminal.cols - 1; - startCol = currentRow; - currentCol--; + currentCol = this._terminal.cols - 1; + startCol = currentCol; + currentRow--; } } return bufferStr + this._terminal.buffer.translateBufferLineToString( - currentCol, false, startCol, currentRow + currentRow, false, startCol, currentCol ); } From 6a48022a454aff1811bf6349f3389b07db5b81a8 Mon Sep 17 00:00:00 2001 From: npezza93 Date: Sat, 27 Jan 2018 22:28:41 -0500 Subject: [PATCH 22/58] Don't reset starting position if the row is not moved. Mainly due to the normal buffer --- src/handlers/AltClickHandler.ts | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/handlers/AltClickHandler.ts b/src/handlers/AltClickHandler.ts index bddde6fbc..94a1a7ecb 100644 --- a/src/handlers/AltClickHandler.ts +++ b/src/handlers/AltClickHandler.ts @@ -63,10 +63,17 @@ export class AltClickHandler { * positioning. */ private _resetStartingRow(): string { - return repeat(this._bufferLine( - this._startCol, this._startRow, this._startCol, - this._startRow - this._wrappedRowsForRow(this._startRow), false - ).length, this._colSequence(false)); + let startRow = this._endRow - this._wrappedRowsForRow(this._endRow); + let endRow = this._endRow; + + if (this._moveToRequestedRow().length === 0) { + return "" + } else { + return repeat(this._bufferLine( + this._startCol, this._startRow, this._startCol, + this._startRow - this._wrappedRowsForRow(this._startRow), false + ).length, this._colSequence(false)); + } } /** @@ -86,7 +93,13 @@ export class AltClickHandler { * Move to the requested col on the ending row */ private _moveToRequestedCol(): string { - let startRow = this._endRow - this._wrappedRowsForRow(this._endRow); + let startRow; + if (this._moveToRequestedRow().length > 0) { + startRow = this._endRow - this._wrappedRowsForRow(this._endRow); + } else { + startRow = this._startRow; + } + let endRow = this._endRow; let forward = this._shouldMoveForward(); @@ -142,7 +155,12 @@ export class AltClickHandler { * Determines if the right or left arrow is needed */ private _shouldMoveForward(): boolean { - let startRow = this._endRow - this._wrappedRowsForRow(this._endRow); + let startRow; + if (this._moveToRequestedRow().length > 0) { + startRow = this._endRow - this._wrappedRowsForRow(this._endRow); + } else { + startRow = this._startRow; + } return (this._startCol < this._endCol && startRow <= this._endRow) || // down/right or same y/right From 544fa67851125413f84b110a22bb38ba3c243862 Mon Sep 17 00:00:00 2001 From: npezza93 Date: Sat, 27 Jan 2018 22:36:53 -0500 Subject: [PATCH 23/58] Move repeat out of generic --- src/handlers/AltClickHandler.ts | 28 ++++++++++++++++++++++++++++ src/utils/Generic.ts | 28 ---------------------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/handlers/AltClickHandler.ts b/src/handlers/AltClickHandler.ts index 94a1a7ecb..6955423ba 100644 --- a/src/handlers/AltClickHandler.ts +++ b/src/handlers/AltClickHandler.ts @@ -251,3 +251,31 @@ export class AltClickHandler { } } } + +/** + * Returns a string repeated a given number of times + * Polyfill from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat + * @param {Number} count The number of times to repeat the string + * @param {String} string The string that is to be repeated + */ +function repeat(count: number, str: string): string { + if (count < 0) throw new RangeError('repeat count must be non-negative'); + if (count === Infinity) throw new RangeError('repeat count must be less than infinity'); + + count = Math.floor(count); + if (str.length === 0 || count === 0) return ''; + + // Ensuring count is a 31-bit integer allows us to heavily optimize the + // main part. But anyway, most current (August 2014) browsers can't handle + // strings 1 << 28 chars or longer, so: + if (str.length * count >= 1 << 28) { + throw new RangeError('repeat count must not overflow maximum string size'); + } + + let rpt = ''; + for (let i = 0; i < count; i++) { + rpt += str; + } + + return rpt; +} diff --git a/src/utils/Generic.ts b/src/utils/Generic.ts index 9f9d2666f..4bc6c487f 100644 --- a/src/utils/Generic.ts +++ b/src/utils/Generic.ts @@ -11,31 +11,3 @@ export function contains(arr: any[], el: any): boolean { return arr.indexOf(el) >= 0; } - -/** - * Returns a string repeated a given number of times - * Polyfill from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat - * @param {Number} count The number of times to repeat the string - * @param {String} string The string that is to be repeated - */ -export function repeat(count: number, str: string): string { - if (count < 0) throw new RangeError('repeat count must be non-negative'); - if (count === Infinity) throw new RangeError('repeat count must be less than infinity'); - - count = Math.floor(count); - if (str.length === 0 || count === 0) return ''; - - // Ensuring count is a 31-bit integer allows us to heavily optimize the - // main part. But anyway, most current (August 2014) browsers can't handle - // strings 1 << 28 chars or longer, so: - if (str.length * count >= 1 << 28) { - throw new RangeError('repeat count must not overflow maximum string size'); - } - - let rpt = ''; - for (let i = 0; i < count; i++) { - rpt += str; - } - - return rpt; -} From d61aa6e4706bc2b5c46051f5a80e8c90d7a7dda8 Mon Sep 17 00:00:00 2001 From: npezza93 Date: Sat, 27 Jan 2018 22:37:31 -0500 Subject: [PATCH 24/58] Fix lints --- src/handlers/AltClickHandler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/handlers/AltClickHandler.ts b/src/handlers/AltClickHandler.ts index 6955423ba..eae491b8b 100644 --- a/src/handlers/AltClickHandler.ts +++ b/src/handlers/AltClickHandler.ts @@ -67,7 +67,7 @@ export class AltClickHandler { let endRow = this._endRow; if (this._moveToRequestedRow().length === 0) { - return "" + return ''; } else { return repeat(this._bufferLine( this._startCol, this._startRow, this._startCol, From c41a4b5168ab9b3955b57438b4a7676340e92db2 Mon Sep 17 00:00:00 2001 From: npezza93 Date: Sat, 27 Jan 2018 22:37:57 -0500 Subject: [PATCH 25/58] Move repeat import --- src/handlers/AltClickHandler.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/handlers/AltClickHandler.ts b/src/handlers/AltClickHandler.ts index eae491b8b..bed9a8631 100644 --- a/src/handlers/AltClickHandler.ts +++ b/src/handlers/AltClickHandler.ts @@ -7,7 +7,6 @@ import { Terminal } from '../Terminal'; import { C0 } from '../EscapeSequences'; -import { repeat } from '../utils/Generic'; import { CircularList } from '../utils/CircularList'; import { LineData } from '../Types'; From 65b6901170a0bea3a49491e63461ab3a29dae75d Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sat, 27 Jan 2018 21:50:28 -0800 Subject: [PATCH 26/58] Fix compile error --- src/handlers/AltClickHandler.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/handlers/AltClickHandler.ts b/src/handlers/AltClickHandler.ts index bed9a8631..e52bd1a3a 100644 --- a/src/handlers/AltClickHandler.ts +++ b/src/handlers/AltClickHandler.ts @@ -123,7 +123,9 @@ export class AltClickHandler { for (let i = 0; i < Math.abs(startRow - endRow); i++) { let direction = this._shouldMoveUp() ? -1 : 1; - if (this._lines.get(startRow + (direction * i)).isWrapped) wrappedRows++; + if ((this._lines.get(startRow + (direction * i))).isWrapped) { + wrappedRows++; + } } return wrappedRows; @@ -135,12 +137,12 @@ export class AltClickHandler { */ private _wrappedRowsForRow(currentRow: number): number { let rowCount = 0; - let lineWraps = this._lines.get(currentRow).isWrapped; + let lineWraps = (this._lines.get(currentRow)).isWrapped; while (lineWraps && currentRow >= 0 && currentRow < this._terminal.rows) { rowCount++; currentRow--; - lineWraps = this._lines.get(currentRow).isWrapped; + lineWraps = (this._lines.get(currentRow)).isWrapped; } return rowCount; From 39abf8aecf7650df4ae8bfb6940345b393846c2c Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sat, 27 Jan 2018 22:26:00 -0800 Subject: [PATCH 27/58] Change render layer id to a class It's only used to identify them in DOM explorer currently Fixes #1255 --- src/renderer/BaseRenderLayer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts index 20a41cfa3..17f6f750b 100644 --- a/src/renderer/BaseRenderLayer.ts +++ b/src/renderer/BaseRenderLayer.ts @@ -31,7 +31,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { protected _colors: IColorSet ) { this._canvas = document.createElement('canvas'); - this._canvas.id = `xterm-${id}-layer`; + this._canvas.classList.add(`xterm-${id}-layer`); this._canvas.style.zIndex = zIndex.toString(); this._ctx = this._canvas.getContext('2d', {alpha: _alpha}); this._ctx.scale(window.devicePixelRatio, window.devicePixelRatio); From edadb6e0f1941b8c05b0eebd1dcc879948a7a7d9 Mon Sep 17 00:00:00 2001 From: npezza93 Date: Sun, 28 Jan 2018 10:44:01 -0500 Subject: [PATCH 28/58] Update the copyright header --- src/handlers/AltClickHandler.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/handlers/AltClickHandler.ts b/src/handlers/AltClickHandler.ts index e52bd1a3a..471977dda 100644 --- a/src/handlers/AltClickHandler.ts +++ b/src/handlers/AltClickHandler.ts @@ -1,7 +1,5 @@ /** - * Alt+Click handler module: exports methods for handling all alt+click-related - * events in the terminal. - * @module xterm/handlers/AltClickHandler + * Copyright (c) 2017 The xterm.js authors. All rights reserved. * @license MIT */ From 0202659c389c84009ca6998b7a8fc80b22276cc5 Mon Sep 17 00:00:00 2001 From: npezza93 Date: Sun, 28 Jan 2018 10:46:48 -0500 Subject: [PATCH 29/58] Set terminal and mouseevent inside constructor args --- src/handlers/AltClickHandler.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/handlers/AltClickHandler.ts b/src/handlers/AltClickHandler.ts index 471977dda..9cfda3ec5 100644 --- a/src/handlers/AltClickHandler.ts +++ b/src/handlers/AltClickHandler.ts @@ -9,22 +9,19 @@ import { CircularList } from '../utils/CircularList'; import { LineData } from '../Types'; export class AltClickHandler { - private _terminal: Terminal; private _startRow: number; private _startCol: number; private _endRow: number; private _endCol: number; private _lines: CircularList; - private _mouseEvent: MouseEvent; - constructor(mouseEvent: MouseEvent, terminal: Terminal) { - this._terminal = terminal; - this._lines = terminal.buffer.lines; + constructor(private _mouseEvent: MouseEvent, private _terminal: Terminal) { + this._lines = this._terminal.buffer.lines; this._startCol = this._terminal.buffer.x; this._startRow = this._terminal.buffer.y; [this._endCol, this._endRow] = this._terminal.mouseHelper.getCoords( - (this._mouseEvent = mouseEvent), + this._mouseEvent, this._terminal.element, this._terminal.charMeasure, this._terminal.options.lineHeight, From 08af2ebeea472bee19b9d0509710eaa9cfb5ee54 Mon Sep 17 00:00:00 2001 From: npezza93 Date: Sun, 28 Jan 2018 12:29:52 -0500 Subject: [PATCH 30/58] Utilize enum to simplify sequence generation --- src/handlers/AltClickHandler.ts | 73 +++++++++++++++------------------ 1 file changed, 33 insertions(+), 40 deletions(-) diff --git a/src/handlers/AltClickHandler.ts b/src/handlers/AltClickHandler.ts index 9cfda3ec5..c67034855 100644 --- a/src/handlers/AltClickHandler.ts +++ b/src/handlers/AltClickHandler.ts @@ -8,6 +8,13 @@ import { C0 } from '../EscapeSequences'; import { CircularList } from '../utils/CircularList'; import { LineData } from '../Types'; +enum Direction { + Up = 'A', + Down = 'B', + Right = 'C', + Left = 'D' +}; + export class AltClickHandler { private _startRow: number; private _startCol: number; @@ -66,7 +73,7 @@ export class AltClickHandler { return repeat(this._bufferLine( this._startCol, this._startRow, this._startCol, this._startRow - this._wrappedRowsForRow(this._startRow), false - ).length, this._colSequence(false)); + ).length, this._sequence(Direction.Left)); } } @@ -80,7 +87,7 @@ export class AltClickHandler { let rowsToMove = Math.abs(startRow - endRow) - this._wrappedRowsCount(); - return repeat(rowsToMove, this._rowSequence(this._shouldMoveUp())); + return repeat(rowsToMove, this._sequence(this._verticalDirection())); } /** @@ -95,11 +102,12 @@ export class AltClickHandler { } let endRow = this._endRow; - let forward = this._shouldMoveForward(); + let direction = this._horizontalDirection(); return repeat(this._bufferLine( - this._startCol, startRow, this._endCol, endRow, forward - ).length, this._colSequence(forward)); + this._startCol, startRow, this._endCol, endRow, + direction === Direction.Right + ).length, this._sequence(direction)); } /** @@ -116,7 +124,7 @@ export class AltClickHandler { let endRow = this._endRow - this._wrappedRowsForRow(this._endRow); for (let i = 0; i < Math.abs(startRow - endRow); i++) { - let direction = this._shouldMoveUp() ? -1 : 1; + let direction = this._verticalDirection() === Direction.Up ? -1 : 1; if ((this._lines.get(startRow + (direction * i))).isWrapped) { wrappedRows++; @@ -150,7 +158,7 @@ export class AltClickHandler { /** * Determines if the right or left arrow is needed */ - private _shouldMoveForward(): boolean { + private _horizontalDirection(): Direction { let startRow; if (this._moveToRequestedRow().length > 0) { startRow = this._endRow - this._wrappedRowsForRow(this._endRow); @@ -158,17 +166,25 @@ export class AltClickHandler { startRow = this._startRow; } - return (this._startCol < this._endCol && + if ((this._startCol < this._endCol && startRow <= this._endRow) || // down/right or same y/right (this._startCol >= this._endCol && - startRow < this._endRow); // down/left or same y/left + startRow < this._endRow)) { // down/left or same y/left + return Direction.Right; + } else { + return Direction.Left; + } } /** * Determines if the up or down arrow is needed */ - private _shouldMoveUp(): boolean { - return this._startRow > this._endRow; + private _verticalDirection(): Direction { + if (this._startRow > this._endRow) { + return Direction.Up; + } else { + return Direction.Down; + } } /** @@ -216,36 +232,13 @@ export class AltClickHandler { } /** - * Arrow escape sequences + * Constructs the escape sequence for clicking an arrow + * @param direction The direction to move */ - - /** - * Constructs the escape sequence for the left or right arrow - * @param forward Right arrow or left arrow - */ - private _colSequence(forward: boolean): string { - let mod = this._terminal.applicationCursor ? 'O' : '['; - - if (forward) { - return C0.ESC + mod + 'C'; - } else { - return C0.ESC + mod + 'D'; - } - } - - /** - * Constructs the escape sequence for clicking the up or down arrow - * @param up Up arrow or down arrow - */ - private _rowSequence(up: boolean): string { - let mod = this._terminal.applicationCursor ? 'O' : '['; - - if (up) { - return C0.ESC + mod + 'A'; - } else { - return C0.ESC + mod + 'B'; - } - } + private _sequence(direction: Direction): string { + const mod = this._terminal.applicationCursor ? 'O' : '['; + return C0.ESC + mod + direction; + } } /** From aeae40e1105f722a0b5e8a38d9c9884e1d2074f5 Mon Sep 17 00:00:00 2001 From: npezza93 Date: Sun, 28 Jan 2018 12:38:20 -0500 Subject: [PATCH 31/58] Use the terminal and circular list interface --- src/Types.ts | 3 ++- src/handlers/AltClickHandler.ts | 7 +++---- src/utils/TestUtils.test.ts | 4 ++++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Types.ts b/src/Types.ts index f3e9bb941..df52dd8ac 100644 --- a/src/Types.ts +++ b/src/Types.ts @@ -188,12 +188,13 @@ export interface ITerminal extends PublicTerminal, IElementAccessor, IBufferAcce isFocused: boolean; mouseHelper: IMouseHelper; bracketedPasteMode: boolean; - + applicationCursor: boolean; /** * Emit the 'data' event and populate the given data. * @param data The data to populate in the event. */ handler(data: string): void; + send(data: string): void; scrollLines(disp: number, suppressScrollEvent?: boolean): void; cancel(ev: Event, force?: boolean): boolean | void; log(text: string): void; diff --git a/src/handlers/AltClickHandler.ts b/src/handlers/AltClickHandler.ts index c67034855..ccdec7aee 100644 --- a/src/handlers/AltClickHandler.ts +++ b/src/handlers/AltClickHandler.ts @@ -3,9 +3,8 @@ * @license MIT */ -import { Terminal } from '../Terminal'; +import { ITerminal, ICircularList } from '../Types'; import { C0 } from '../EscapeSequences'; -import { CircularList } from '../utils/CircularList'; import { LineData } from '../Types'; enum Direction { @@ -20,9 +19,9 @@ export class AltClickHandler { private _startCol: number; private _endRow: number; private _endCol: number; - private _lines: CircularList; + private _lines: ICircularList; - constructor(private _mouseEvent: MouseEvent, private _terminal: Terminal) { + constructor(private _mouseEvent: MouseEvent, private _terminal: ITerminal) { this._lines = this._terminal.buffer.lines; this._startCol = this._terminal.buffer.x; this._startRow = this._terminal.buffer.y; diff --git a/src/utils/TestUtils.test.ts b/src/utils/TestUtils.test.ts index 0744cd142..d53c8c58b 100644 --- a/src/utils/TestUtils.test.ts +++ b/src/utils/TestUtils.test.ts @@ -70,6 +70,9 @@ export class MockTerminal implements ITerminal { write(data: string): void { throw new Error('Method not implemented.'); } + send(data: string): void { + throw new Error('Method not implemented.'); + } bracketedPasteMode: boolean; mouseHelper: IMouseHelper; renderer: IRenderer; @@ -93,6 +96,7 @@ export class MockTerminal implements ITerminal { scrollback: number; buffers: IBufferSet; buffer: IBuffer; + applicationCursor: boolean; handler(data: string): void { throw new Error('Method not implemented.'); } From e60704255f518a9feff106885849147011fe0df5 Mon Sep 17 00:00:00 2001 From: npezza93 Date: Sun, 28 Jan 2018 13:00:11 -0500 Subject: [PATCH 32/58] Fix lints --- src/handlers/AltClickHandler.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/handlers/AltClickHandler.ts b/src/handlers/AltClickHandler.ts index ccdec7aee..307fa14a6 100644 --- a/src/handlers/AltClickHandler.ts +++ b/src/handlers/AltClickHandler.ts @@ -3,16 +3,15 @@ * @license MIT */ -import { ITerminal, ICircularList } from '../Types'; +import { ITerminal, ICircularList, LineData } from '../Types'; import { C0 } from '../EscapeSequences'; -import { LineData } from '../Types'; enum Direction { Up = 'A', Down = 'B', Right = 'C', Left = 'D' -}; +} export class AltClickHandler { private _startRow: number; From f726c1fd0d065fa6b43e5b14d7c7194bf754ebca Mon Sep 17 00:00:00 2001 From: npezza93 Date: Sun, 28 Jan 2018 13:06:54 -0500 Subject: [PATCH 33/58] Allow selection and alt click to live conflict free --- src/SelectionManager.ts | 11 ++++++++++- src/Terminal.ts | 2 -- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/SelectionManager.ts b/src/SelectionManager.ts index 10612c5c6..75ada79af 100644 --- a/src/SelectionManager.ts +++ b/src/SelectionManager.ts @@ -11,6 +11,7 @@ import { CircularList } from './utils/CircularList'; import { EventEmitter } from './EventEmitter'; import { SelectionModel } from './SelectionModel'; import { CHAR_DATA_WIDTH_INDEX, CHAR_DATA_CHAR_INDEX } from './Buffer'; +import { AltClickHandler } from './handlers/AltClickHandler'; /** * The number of pixels the mouse needs to be above or below the viewport in @@ -96,6 +97,8 @@ export class SelectionManager extends EventEmitter implements ISelectionManager private _mouseUpListener: EventListener; private _trimListener: (...args: any[]) => void; + private _mouseDownTimeStamp: number; + constructor( private _terminal: ITerminal, private _charMeasure: CharMeasure @@ -317,6 +320,7 @@ export class SelectionManager extends EventEmitter implements ISelectionManager * @param event The mousedown event. */ public onMouseDown(event: MouseEvent): void { + this._mouseDownTimeStamp = event.timeStamp; // If we have selection, we want the context menu on right click even if the // terminal is in mouse mode. if (event.button === 2 && this.hasSelection) { @@ -536,10 +540,15 @@ export class SelectionManager extends EventEmitter implements ISelectionManager * @param event The mouseup event. */ private _onMouseUp(event: MouseEvent): void { + let timeElapsed = event.timeStamp - this._mouseDownTimeStamp; + this._removeMouseDownListeners(); - if (this.hasSelection) + if (this.selectionText.length <= 1 && timeElapsed < 500) { + (new AltClickHandler(event, this._terminal)).move(); + } else if (this.hasSelection) { this._terminal.emit('selection'); + } } private _onBufferActivate(e: {activeBuffer: IBuffer, inactiveBuffer: IBuffer}): void { diff --git a/src/Terminal.ts b/src/Terminal.ts index 2977154ee..5536cf03c 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -30,7 +30,6 @@ import { CompositionHelper } from './CompositionHelper'; import { EventEmitter } from './EventEmitter'; import { Viewport } from './Viewport'; import { rightClickHandler, moveTextAreaUnderMouseCursor, pasteHandler, copyHandler } from './handlers/Clipboard'; -import { AltClickHandler } from './handlers/AltClickHandler'; import { CircularList } from './utils/CircularList'; import { C0 } from './EscapeSequences'; import { InputHandler } from './InputHandler'; @@ -953,7 +952,6 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT // if the selection manager is having selection forced (ie. a modifier is // held). if (!this.mouseEvents || this.selectionManager.shouldForceSelection(ev)) { - (new AltClickHandler(ev, this)).move(); return; } From 3313716c87f9c1a25bf8d37c0895503ed0ca276c Mon Sep 17 00:00:00 2001 From: npezza93 Date: Sun, 28 Jan 2018 13:15:42 -0500 Subject: [PATCH 34/58] Add new lines back in types --- src/Types.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Types.ts b/src/Types.ts index df52dd8ac..da3cc9d2a 100644 --- a/src/Types.ts +++ b/src/Types.ts @@ -189,6 +189,7 @@ export interface ITerminal extends PublicTerminal, IElementAccessor, IBufferAcce mouseHelper: IMouseHelper; bracketedPasteMode: boolean; applicationCursor: boolean; + /** * Emit the 'data' event and populate the given data. * @param data The data to populate in the event. From 3bdc069f1961d7c78773ad099173db97d754d60a Mon Sep 17 00:00:00 2001 From: npezza93 Date: Sun, 28 Jan 2018 13:16:20 -0500 Subject: [PATCH 35/58] Set copyright header to 2018 --- src/handlers/AltClickHandler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/handlers/AltClickHandler.ts b/src/handlers/AltClickHandler.ts index 307fa14a6..e09438838 100644 --- a/src/handlers/AltClickHandler.ts +++ b/src/handlers/AltClickHandler.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * Copyright (c) 2018 The xterm.js authors. All rights reserved. * @license MIT */ From af375eadb4a14dc5c1b65414e77e9bc774c8cc60 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 28 Jan 2018 12:27:01 -0800 Subject: [PATCH 36/58] Run tsc as a travis job This will hard fail when there are semantic errors. Currently building does not do this and we will merge these in as a result. --- .travis.yml | 1 + package.json | 1 + 2 files changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 7a37af1e7..c41ebf797 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,7 @@ before_install: - npm install -g npm@5.1.0 env: matrix: + - NPM_COMMAND=tsc - NPM_COMMAND=lint - NPM_COMMAND=test notifications: diff --git a/package.json b/package.json index cf3df57be..ba988d613 100644 --- a/package.json +++ b/package.json @@ -82,6 +82,7 @@ "lint": "tslint src/*.ts src/**/*.ts", "test": "gulp test", "build:docs": "jsdoc -c jsdoc.json", + "tsc": "tsc", "build": "gulp build", "prepublish": "npm run build", "coveralls": "gulp coveralls", From fc2af1d806e970b4d6ff331401b93f8417f8b784 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 28 Jan 2018 14:13:25 -0800 Subject: [PATCH 37/58] Fix lint, reduce duplication, don't scale ctx Scaling ctx was breaking the scale when setOption was called, not sure it was doing anything. --- src/renderer/BaseRenderLayer.ts | 36 +++++++++++++++++---------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts index 23eb8f213..35e1a57e8 100644 --- a/src/renderer/BaseRenderLayer.ts +++ b/src/renderer/BaseRenderLayer.ts @@ -24,7 +24,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { private _charAtlas: HTMLCanvasElement | ImageBitmap; constructor( - container: HTMLElement, + private _container: HTMLElement, id: string, zIndex: number, private _alpha: boolean, @@ -33,13 +33,16 @@ export abstract class BaseRenderLayer implements IRenderLayer { this._canvas = document.createElement('canvas'); this._canvas.classList.add(`xterm-${id}-layer`); this._canvas.style.zIndex = zIndex.toString(); - this._ctx = this._canvas.getContext('2d', {alpha: _alpha}); - this._ctx.scale(window.devicePixelRatio, window.devicePixelRatio); + this._initCanvas(); + this._container.appendChild(this._canvas); + } + + private _initCanvas(): void { + this._ctx = this._canvas.getContext('2d', {alpha: this._alpha}); // Draw the background if this is an opaque layer - if (!_alpha) { + if (!this._alpha) { this.clearAll(); } - container.appendChild(this._canvas); } public onOptionsChanged(terminal: ITerminal): void {} @@ -54,23 +57,22 @@ export abstract class BaseRenderLayer implements IRenderLayer { } protected setTransparency(terminal: ITerminal, alpha: boolean): void { + // Do nothing when alpha doesn't change if (alpha === this._alpha) { return; } - this._alpha = alpha - const oldCanvas = this._canvas - // Cloning preserves canvas properties and permits to acquire a new context + + // Create new canvas and replace old one + const oldCanvas = this._canvas; + this._alpha = alpha; + // Closing preserves properties this._canvas = this._canvas.cloneNode(); - this._ctx = this._canvas.getContext('2d', {alpha: this._alpha}); - this._ctx.scale(window.devicePixelRatio, window.devicePixelRatio); - // Draw the background if this is an opaque layer - if (!this._alpha) { - this.clearAll(); - } - oldCanvas.parentNode.replaceChild(this._canvas, oldCanvas); + this._initCanvas(); + this._container.replaceChild(this._canvas, oldCanvas); + + // Regenerate char atlas and force a full redraw this._refreshCharAtlas(terminal, this._colors); - // Force a full redraw - this.onGridChanged(terminal, 0, terminal.rows - 1) + this.onGridChanged(terminal, 0, terminal.rows - 1); } /** From e8666cafc92a21802526c3d9883703ba4ae7d373 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 28 Jan 2018 14:44:33 -0800 Subject: [PATCH 38/58] Small clean up --- src/SelectionManager.ts | 8 ++++++- src/handlers/AltClickHandler.ts | 37 +++++++++++++-------------------- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/SelectionManager.ts b/src/SelectionManager.ts index 75ada79af..3c927839e 100644 --- a/src/SelectionManager.ts +++ b/src/SelectionManager.ts @@ -29,6 +29,12 @@ const DRAG_SCROLL_MAX_SPEED = 15; */ const DRAG_SCROLL_INTERVAL = 50; +/** + * The maximum amount of time that can have elapsed for an alt click to move the + * cursor. + */ +const ALT_CLICK_MOVE_CURSOR_TIME = 500; + /** * A string containing all characters that are considered word separated by the * double click to select work logic. @@ -544,7 +550,7 @@ export class SelectionManager extends EventEmitter implements ISelectionManager this._removeMouseDownListeners(); - if (this.selectionText.length <= 1 && timeElapsed < 500) { + if (this.selectionText.length <= 1 && timeElapsed < ALT_CLICK_MOVE_CURSOR_TIME) { (new AltClickHandler(event, this._terminal)).move(); } else if (this.hasSelection) { this._terminal.emit('selection'); diff --git a/src/handlers/AltClickHandler.ts b/src/handlers/AltClickHandler.ts index e09438838..c9c51cbe5 100644 --- a/src/handlers/AltClickHandler.ts +++ b/src/handlers/AltClickHandler.ts @@ -20,7 +20,10 @@ export class AltClickHandler { private _endCol: number; private _lines: ICircularList; - constructor(private _mouseEvent: MouseEvent, private _terminal: ITerminal) { + constructor( + private _mouseEvent: MouseEvent, + private _terminal: ITerminal + ) { this._lines = this._terminal.buffer.lines; this._startCol = this._terminal.buffer.x; this._startRow = this._terminal.buffer.y; @@ -42,7 +45,9 @@ export class AltClickHandler { * Writes the escape sequences of arrows to the terminal */ public move(): void { - if (this._mouseEvent.altKey) this._terminal.send(this._arrowSequences()); + if (this._mouseEvent.altKey) { + this._terminal.send(this._arrowSequences()); + } } /** @@ -199,7 +204,8 @@ export class AltClickHandler { startRow: number, endCol: number, endRow: number, - forward: boolean): string { + forward: boolean + ): string { let currentCol = startCol; let currentRow = startRow; let bufferStr = ''; @@ -233,36 +239,23 @@ export class AltClickHandler { * Constructs the escape sequence for clicking an arrow * @param direction The direction to move */ - private _sequence(direction: Direction): string { - const mod = this._terminal.applicationCursor ? 'O' : '['; - return C0.ESC + mod + direction; - } + private _sequence(direction: Direction): string { + const mod = this._terminal.applicationCursor ? 'O' : '['; + return C0.ESC + mod + direction; + } } /** * Returns a string repeated a given number of times * Polyfill from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat - * @param {Number} count The number of times to repeat the string - * @param {String} string The string that is to be repeated + * @param count The number of times to repeat the string + * @param string The string that is to be repeated */ function repeat(count: number, str: string): string { - if (count < 0) throw new RangeError('repeat count must be non-negative'); - if (count === Infinity) throw new RangeError('repeat count must be less than infinity'); - count = Math.floor(count); - if (str.length === 0 || count === 0) return ''; - - // Ensuring count is a 31-bit integer allows us to heavily optimize the - // main part. But anyway, most current (August 2014) browsers can't handle - // strings 1 << 28 chars or longer, so: - if (str.length * count >= 1 << 28) { - throw new RangeError('repeat count must not overflow maximum string size'); - } - let rpt = ''; for (let i = 0; i < count; i++) { rpt += str; } - return rpt; } From bbac1801e5328900328667e129f6fb8428aa93fe Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 28 Jan 2018 17:33:51 -0800 Subject: [PATCH 39/58] Small clean up --- src/SelectionManager.ts | 4 +++- src/handlers/Clipboard.ts | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/SelectionManager.ts b/src/SelectionManager.ts index 00d22fb6a..0d425a914 100644 --- a/src/SelectionManager.ts +++ b/src/SelectionManager.ts @@ -257,7 +257,9 @@ export class SelectionManager extends EventEmitter implements ISelectionManager return false; } - return (start[1] < coords[1] && end[1] > coords[1]) || (start[1] === coords[1] && coords[0] > start[0]) || (end[1] === coords[1] && coords[0] < end[0]); + return (start[1] < coords[1] && end[1] > coords[1]) || + (start[1] === coords[1] && coords[0] > start[0]) || + (end[1] === coords[1] && coords[0] < end[0]); } /** diff --git a/src/handlers/Clipboard.ts b/src/handlers/Clipboard.ts index 807516c78..7ac97714d 100644 --- a/src/handlers/Clipboard.ts +++ b/src/handlers/Clipboard.ts @@ -121,8 +121,9 @@ export function moveTextAreaUnderMouseCursor(ev: MouseEvent, textarea: HTMLTextA export function rightClickHandler(ev: MouseEvent, textarea: HTMLTextAreaElement, selectionManager: ISelectionManager, shouldSelectWord: boolean): void { moveTextAreaUnderMouseCursor(ev, textarea); - if (shouldSelectWord && !selectionManager.isClickInSelection(ev)) + if (shouldSelectWord && !selectionManager.isClickInSelection(ev)) { selectionManager.selectWordAtCursor(ev); + } // Get textarea ready to copy from the context menu textarea.value = selectionManager.selectionText; From 69ebb3e53e3ee8cfe35ab57844850a39b70a8503 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 29 Jan 2018 07:42:59 -0800 Subject: [PATCH 40/58] Fix recent typo in comment --- src/renderer/BaseRenderLayer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts index 35e1a57e8..9423f65d3 100644 --- a/src/renderer/BaseRenderLayer.ts +++ b/src/renderer/BaseRenderLayer.ts @@ -65,7 +65,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { // Create new canvas and replace old one const oldCanvas = this._canvas; this._alpha = alpha; - // Closing preserves properties + // Cloning preserves properties this._canvas = this._canvas.cloneNode(); this._initCanvas(); this._container.replaceChild(this._canvas, oldCanvas); From 983af8fac218a082741368e591b57108bdfa5802 Mon Sep 17 00:00:00 2001 From: Bruno Ribeito Date: Wed, 31 Jan 2018 00:01:46 +0000 Subject: [PATCH 41/58] Use _selectWordA --- src/SelectionManager.ts | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/SelectionManager.ts b/src/SelectionManager.ts index 0d425a914..c01d7b6d5 100644 --- a/src/SelectionManager.ts +++ b/src/SelectionManager.ts @@ -269,13 +269,8 @@ export class SelectionManager extends EventEmitter implements ISelectionManager public selectWordAtCursor(event: MouseEvent): void { const coords = this._getMouseBufferCoords(event); if (coords) { - const wordPosition = this._getWordAt(coords, false); - if (wordPosition) { - this._model.selectionStart = [wordPosition.start, coords[1]]; - this._model.selectionStartLength = wordPosition.length; - this._model.selectionEnd = [this._model.areSelectionValuesReversed() ? wordPosition.start : (wordPosition.start + wordPosition.length), coords[1]]; - this.refresh(true); - } + this._selectWordAt(coords, false); + this.refresh(true); } } From e8496295333b91372b463c1aa0497f93b6e0fcf3 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 31 Jan 2018 11:25:13 -0800 Subject: [PATCH 42/58] typescript@2.7 Tuples using a fixed length by default will be helpful for CharData --- package-lock.json | 3526 ++++++++++++++++++++++++++++++++++++++++++++- package.json | 2 +- 2 files changed, 3523 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index f7c01276d..03bbd1155 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "xterm", - "version": "3.0.0", + "version": "3.1.0-master", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -77,6 +77,15 @@ "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", "dev": true }, + "acorn-dynamic-import": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz", + "integrity": "sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ=", + "dev": true, + "requires": { + "acorn": "4.0.13" + } + }, "acorn-globals": { "version": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz", "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=", @@ -92,6 +101,35 @@ } } }, + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "dev": true, + "requires": { + "co": "4.6.0", + "fast-deep-equal": "1.0.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" + } + }, + "ajv-keywords": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", + "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", + "dev": true + }, + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "dev": true, + "requires": { + "kind-of": "3.2.2", + "longest": "1.0.1", + "repeat-string": "1.6.1" + } + }, "amdefine": { "version": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", @@ -108,6 +146,16 @@ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true }, + "anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "dev": true, + "requires": { + "micromatch": "2.3.11", + "normalize-path": "2.1.1" + } + }, "argparse": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", @@ -117,6 +165,21 @@ "sprintf-js": "1.0.3" } }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "1.1.0" + } + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, "array-differ": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", @@ -164,6 +227,12 @@ "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", "dev": true }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, "asn1": { "version": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", @@ -203,6 +272,21 @@ "acorn": "4.0.13" } }, + "async": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", + "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", + "dev": true, + "requires": { + "lodash": "4.17.4" + } + }, + "async-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "dev": true + }, "asynckit": { "version": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", @@ -319,6 +403,18 @@ "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=", "dev": true }, + "big.js": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", + "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", + "dev": true + }, + "binary-extensions": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", + "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", + "dev": true + }, "bn.js": { "version": "4.11.7", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.7.tgz", @@ -343,6 +439,17 @@ "concat-map": "0.0.1" } }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" + } + }, "brorand": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", @@ -601,11 +708,27 @@ "integrity": "sha1-0JxLUoAKpMB44t2BqGmqyQ0uVOc=", "dev": true }, + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", + "dev": true + }, "caseless": { "version": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=", "dev": true }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "dev": true, + "requires": { + "align-text": "0.1.4", + "lazy-cache": "1.0.4" + } + }, "chai": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/chai/-/chai-3.5.0.tgz", @@ -660,6 +783,23 @@ "supports-color": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz" } }, + "chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "dev": true, + "requires": { + "anymatch": "1.3.2", + "async-each": "1.0.1", + "fsevents": "1.1.3", + "glob-parent": "2.0.0", + "inherits": "2.0.3", + "is-binary-path": "1.0.1", + "is-glob": "2.0.1", + "path-is-absolute": "1.0.1", + "readdirp": "2.1.0" + } + }, "cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", @@ -670,6 +810,17 @@ "safe-buffer": "5.1.1" } }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "dev": true, + "requires": { + "center-align": "0.1.3", + "right-align": "0.1.3", + "wordwrap": "0.0.2" + } + }, "clone": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", @@ -699,6 +850,18 @@ "through2": "2.0.3" } }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, "color-convert": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", @@ -876,6 +1039,17 @@ "sha.js": "2.4.8" } }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "4.1.1", + "shebang-command": "1.2.0", + "which": "1.3.0" + } + }, "cryptiles": { "version": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", @@ -915,6 +1089,15 @@ "cssom": "https://registry.npmjs.org/cssom/-/cssom-0.3.2.tgz" } }, + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "dev": true, + "requires": { + "es5-ext": "0.10.38" + } + }, "dashdash": { "version": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", @@ -942,6 +1125,12 @@ "integrity": "sha1-J0Pjq7XD/CRi5SfcpEXgTp9N7hc=", "dev": true }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, "deep-is": { "version": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", @@ -1070,6 +1259,120 @@ "minimalistic-crypto-utils": "1.0.1" } }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true + }, + "enhanced-resolve": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz", + "integrity": "sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "memory-fs": "0.4.1", + "object-assign": "4.1.1", + "tapable": "0.2.8" + }, + "dependencies": { + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + } + } + }, + "errno": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.6.tgz", + "integrity": "sha512-IsORQDpaaSwcDP4ZZnHxgE85werpo34VYn1Ud3mq+eUsF593faR8oCZNXrROVkpFu2TsbrNhHin0aUrTsQ9vNw==", + "dev": true, + "requires": { + "prr": "1.0.1" + } + }, + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "dev": true, + "requires": { + "is-arrayish": "0.2.1" + } + }, + "es5-ext": { + "version": "0.10.38", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.38.tgz", + "integrity": "sha512-jCMyePo7AXbUESwbl8Qi01VSH2piY9s/a3rSU/5w/MlTIx8HPL1xn2InGN8ejt/xulcJgnTO7vqNtOAxzYd2Kg==", + "dev": true, + "requires": { + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.38", + "es6-symbol": "3.1.1" + } + }, + "es6-map": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.38", + "es6-iterator": "2.0.3", + "es6-set": "0.1.5", + "es6-symbol": "3.1.1", + "event-emitter": "0.3.5" + } + }, + "es6-set": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", + "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.38", + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1", + "event-emitter": "0.3.5" + } + }, + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.38" + } + }, + "es6-weak-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", + "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.38", + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1" + } + }, "escape-string-regexp": { "version": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", @@ -1098,11 +1401,55 @@ } } }, + "escope": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", + "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", + "dev": true, + "requires": { + "es6-map": "0.1.5", + "es6-weak-map": "2.0.2", + "esrecurse": "4.2.0", + "estraverse": "4.2.0" + }, + "dependencies": { + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + } + } + }, "esprima": { "version": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", "dev": true }, + "esrecurse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", + "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", + "dev": true, + "requires": { + "estraverse": "4.2.0", + "object-assign": "4.1.1" + }, + "dependencies": { + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + } + } + }, "estraverse": { "version": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", @@ -1113,6 +1460,16 @@ "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", "dev": true }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.38" + } + }, "events": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", @@ -1128,12 +1485,45 @@ "create-hash": "1.1.3" } }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "requires": { + "cross-spawn": "5.1.0", + "get-stream": "3.0.0", + "is-stream": "1.1.0", + "npm-run-path": "2.0.2", + "p-finally": "1.0.0", + "signal-exit": "3.0.2", + "strip-eof": "1.0.0" + } + }, "exit-on-epipe": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==", "dev": true }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "0.1.1" + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "dev": true, + "requires": { + "fill-range": "2.2.3" + } + }, "express": { "version": "4.13.4", "resolved": "https://registry.npmjs.org/express/-/express-4.13.4.tgz", @@ -1513,6 +1903,15 @@ "integrity": "sha1-WkdDU7nzNT3dgXbf03uRyDpG8dQ=", "dev": true }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, "extsprintf": { "version": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz", "integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=", @@ -1585,11 +1984,66 @@ } } }, + "fast-deep-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", + "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, "fast-levenshtein": { "version": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "dev": true + }, + "fill-range": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", + "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "dev": true, + "requires": { + "is-number": "2.1.0", + "isobject": "2.1.0", + "randomatic": "1.1.7", + "repeat-element": "1.1.2", + "repeat-string": "1.6.1" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "2.0.0" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true, + "requires": { + "for-in": "1.0.2" + } + }, "forever-agent": { "version": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", @@ -1642,6 +2096,910 @@ } } }, + "fsevents": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.3.tgz", + "integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==", + "dev": true, + "optional": true, + "requires": { + "nan": "2.8.0", + "node-pre-gyp": "0.6.39" + }, + "dependencies": { + "abbrev": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "ajv": { + "version": "4.11.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "co": "4.6.0", + "json-stable-stringify": "1.0.1" + } + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "aproba": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "1.0.0", + "readable-stream": "2.2.9" + } + }, + "asn1": { + "version": "0.2.3", + "bundled": true, + "dev": true, + "optional": true + }, + "assert-plus": { + "version": "0.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "asynckit": { + "version": "0.4.0", + "bundled": true, + "dev": true, + "optional": true + }, + "aws-sign2": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "aws4": { + "version": "1.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "balanced-match": { + "version": "0.4.2", + "bundled": true, + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "tweetnacl": "0.14.5" + } + }, + "block-stream": { + "version": "0.0.9", + "bundled": true, + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "boom": { + "version": "2.10.1", + "bundled": true, + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, + "brace-expansion": { + "version": "1.1.7", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "0.4.2", + "concat-map": "0.0.1" + } + }, + "buffer-shims": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "caseless": { + "version": "0.12.0", + "bundled": true, + "dev": true, + "optional": true + }, + "co": { + "version": "4.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "combined-stream": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "requires": { + "delayed-stream": "1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "cryptiles": { + "version": "2.0.5", + "bundled": true, + "dev": true, + "requires": { + "boom": "2.10.1" + } + }, + "dashdash": { + "version": "1.14.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "debug": { + "version": "2.6.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-extend": { + "version": "0.4.2", + "bundled": true, + "dev": true, + "optional": true + }, + "delayed-stream": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "ecc-jsbn": { + "version": "0.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "extend": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "extsprintf": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "optional": true + }, + "form-data": { + "version": "2.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.15" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "fstream": { + "version": "1.0.11", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "inherits": "2.0.3", + "mkdirp": "0.5.1", + "rimraf": "2.6.1" + } + }, + "fstream-ignore": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fstream": "1.0.11", + "inherits": "2.0.3", + "minimatch": "3.0.4" + } + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "1.1.1", + "console-control-strings": "1.1.0", + "has-unicode": "2.0.1", + "object-assign": "4.1.1", + "signal-exit": "3.0.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wide-align": "1.1.2" + } + }, + "getpass": { + "version": "0.1.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "glob": { + "version": "7.1.2", + "bundled": true, + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "graceful-fs": { + "version": "4.1.11", + "bundled": true, + "dev": true + }, + "har-schema": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "optional": true + }, + "har-validator": { + "version": "4.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ajv": "4.11.8", + "har-schema": "1.0.5" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "hawk": { + "version": "3.1.3", + "bundled": true, + "dev": true, + "requires": { + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" + } + }, + "hoek": { + "version": "2.16.3", + "bundled": true, + "dev": true + }, + "http-signature": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "0.2.0", + "jsprim": "1.4.0", + "sshpk": "1.13.0" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "ini": { + "version": "1.3.4", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-typedarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "isstream": { + "version": "0.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "jodid25519": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "jsbn": { + "version": "0.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "json-schema": { + "version": "0.2.3", + "bundled": true, + "dev": true, + "optional": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "jsonify": "0.0.0" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "jsonify": { + "version": "0.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "jsprim": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.0.2", + "json-schema": "0.2.3", + "verror": "1.3.6" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "mime-db": { + "version": "1.27.0", + "bundled": true, + "dev": true + }, + "mime-types": { + "version": "2.1.15", + "bundled": true, + "dev": true, + "requires": { + "mime-db": "1.27.0" + } + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "node-pre-gyp": { + "version": "0.6.39", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "1.0.2", + "hawk": "3.1.3", + "mkdirp": "0.5.1", + "nopt": "4.0.1", + "npmlog": "4.1.0", + "rc": "1.2.1", + "request": "2.81.0", + "rimraf": "2.6.1", + "semver": "5.3.0", + "tar": "2.2.1", + "tar-pack": "3.4.0" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1.1.0", + "osenv": "0.1.4" + } + }, + "npmlog": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "1.1.4", + "console-control-strings": "1.1.0", + "gauge": "2.7.4", + "set-blocking": "2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "oauth-sign": { + "version": "0.8.2", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "performance-now": { + "version": "0.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "1.0.7", + "bundled": true, + "dev": true + }, + "punycode": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "optional": true + }, + "qs": { + "version": "6.4.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "0.4.2", + "ini": "1.3.4", + "minimist": "1.2.0", + "strip-json-comments": "2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.2.9", + "bundled": true, + "dev": true, + "requires": { + "buffer-shims": "1.0.0", + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "1.0.1", + "util-deprecate": "1.0.2" + } + }, + "request": { + "version": "2.81.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aws-sign2": "0.6.0", + "aws4": "1.6.0", + "caseless": "0.12.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.1.4", + "har-validator": "4.2.1", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.15", + "oauth-sign": "0.8.2", + "performance-now": "0.2.0", + "qs": "6.4.0", + "safe-buffer": "5.0.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.2", + "tunnel-agent": "0.6.0", + "uuid": "3.0.1" + } + }, + "rimraf": { + "version": "2.6.1", + "bundled": true, + "dev": true, + "requires": { + "glob": "7.1.2" + } + }, + "safe-buffer": { + "version": "5.0.1", + "bundled": true, + "dev": true + }, + "semver": { + "version": "5.3.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sntp": { + "version": "1.0.9", + "bundled": true, + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, + "sshpk": { + "version": "1.13.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.7", + "jodid25519": "1.0.2", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "string_decoder": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "5.0.1" + } + }, + "stringstream": { + "version": "0.0.5", + "bundled": true, + "dev": true, + "optional": true + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "2.2.1", + "bundled": true, + "dev": true, + "requires": { + "block-stream": "0.0.9", + "fstream": "1.0.11", + "inherits": "2.0.3" + } + }, + "tar-pack": { + "version": "3.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "2.6.8", + "fstream": "1.0.11", + "fstream-ignore": "1.0.5", + "once": "1.4.0", + "readable-stream": "2.2.9", + "rimraf": "2.6.1", + "tar": "2.2.1", + "uid-number": "0.0.6" + } + }, + "tough-cookie": { + "version": "2.3.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "punycode": "1.4.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "bundled": true, + "dev": true, + "optional": true + }, + "uid-number": { + "version": "0.0.6", + "bundled": true, + "dev": true, + "optional": true + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "uuid": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "verror": { + "version": "1.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "extsprintf": "1.0.2" + } + }, + "wide-align": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "1.0.2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + } + } + }, "function-bind": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.0.tgz", @@ -1661,6 +3019,18 @@ "is-property": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz" } }, + "get-caller-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", + "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", + "dev": true + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, "getpass": { "version": "https://registry.npmjs.org/getpass/-/getpass-0.1.6.tgz", "integrity": "sha1-KD/9n8ElaECHUxHBtg6MQBhxEOY=", @@ -1766,6 +3136,25 @@ } } }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dev": true, + "requires": { + "glob-parent": "2.0.0", + "is-glob": "2.0.1" + } + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "2.0.1" + } + }, "glogg": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.0.tgz", @@ -1775,6 +3164,12 @@ "sparkles": "1.0.0" } }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, "graceful-readlink": { "version": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", @@ -8613,6 +10008,12 @@ "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", "dev": true }, + "hosted-git-info": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", + "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", + "dev": true + }, "html-encoding-sniffer": { "version": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.1.tgz", "integrity": "sha1-eb96eF6klf5mFl5zQVPzY/9UN9o=", @@ -8699,12 +10100,93 @@ } } }, + "interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", + "dev": true + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "1.11.0" + } + }, "is-buffer": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=", "dev": true }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true, + "requires": { + "builtin-modules": "1.1.1" + } + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", + "dev": true + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "dev": true, + "requires": { + "is-primitive": "2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, "is-my-json-valid": { "version": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.15.0.tgz", "integrity": "sha1-k27do8o8IR/ZjzstPgjaQ/eykVs=", @@ -8716,6 +10198,15 @@ "xtend": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" } }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, "is-plain-object": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.3.tgz", @@ -8733,11 +10224,29 @@ } } }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", + "dev": true + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "dev": true + }, "is-property": { "version": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", "dev": true }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, "is-typedarray": { "version": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", @@ -8749,6 +10258,29 @@ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + } + } + }, "isstream": { "version": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", @@ -9019,11 +10551,23 @@ } } }, + "json-loader": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz", + "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==", + "dev": true + }, "json-schema": { "version": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", "dev": true }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", + "dev": true + }, "json-stable-stringify": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", @@ -9038,6 +10582,12 @@ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", "dev": true }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + }, "jsonify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", @@ -9065,6 +10615,15 @@ "verror": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz" } }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.5" + } + }, "labeled-stream-splicer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.0.tgz", @@ -9076,6 +10635,21 @@ "stream-splicer": "2.0.0" } }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", + "dev": true + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "requires": { + "invert-kv": "1.0.0" + } + }, "levn": { "version": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", @@ -9094,6 +10668,51 @@ "astw": "2.2.0" } }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "strip-bom": "3.0.0" + } + }, + "loader-runner": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.0.tgz", + "integrity": "sha1-9IKuqC1UPgeSFwDVpG7yb9rGuKI=", + "dev": true + }, + "loader-utils": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", + "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", + "dev": true, + "requires": { + "big.js": "3.2.0", + "emojis-list": "2.1.0", + "json5": "0.5.1" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "2.0.0", + "path-exists": "3.0.0" + } + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + }, "lodash._basecopy": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", @@ -9148,6 +10767,12 @@ "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=", "dev": true }, + "lodash.clone": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", + "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=", + "dev": true + }, "lodash.escape": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", @@ -9192,6 +10817,12 @@ "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=", "dev": true }, + "lodash.some": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", + "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=", + "dev": true + }, "lodash.sortby": { "version": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", @@ -9224,6 +10855,73 @@ "lodash.escape": "3.2.0" } }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", + "dev": true + }, + "lru-cache": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "dev": true, + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + } + }, + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "dev": true, + "requires": { + "mimic-fn": "1.1.0" + } + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "0.1.6", + "readable-stream": "2.3.3" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, "merge-stream": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", @@ -9289,6 +10987,27 @@ } } }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "arr-diff": "2.0.0", + "array-unique": "0.2.1", + "braces": "1.8.5", + "expand-brackets": "0.1.5", + "extglob": "0.3.2", + "filename-regex": "2.0.1", + "is-extglob": "1.0.0", + "is-glob": "2.0.1", + "kind-of": "3.2.2", + "normalize-path": "2.1.1", + "object.omit": "2.0.1", + "parse-glob": "3.0.4", + "regex-cache": "0.4.4" + } + }, "miller-rabin": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.0.tgz", @@ -9312,6 +11031,12 @@ "mime-db": "https://registry.npmjs.org/mime-db/-/mime-db-1.26.0.tgz" } }, + "mimic-fn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", + "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=", + "dev": true + }, "minimalistic-assert": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", @@ -9339,6 +11064,23 @@ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + } + } + }, "mocha": { "version": "3.4.2", "resolved": "https://registry.npmjs.org/mocha/-/mocha-3.4.2.tgz", @@ -9691,6 +11433,111 @@ "integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo=", "dev": true }, + "node-libs-browser": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz", + "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==", + "dev": true, + "requires": { + "assert": "1.4.1", + "browserify-zlib": "0.2.0", + "buffer": "4.9.1", + "console-browserify": "1.1.0", + "constants-browserify": "1.0.0", + "crypto-browserify": "3.11.1", + "domain-browser": "1.1.7", + "events": "1.1.1", + "https-browserify": "1.0.0", + "os-browserify": "0.3.0", + "path-browserify": "0.0.0", + "process": "0.11.10", + "punycode": "1.4.1", + "querystring-es3": "0.2.1", + "readable-stream": "2.3.3", + "stream-browserify": "2.0.1", + "stream-http": "2.7.2", + "string_decoder": "1.0.3", + "timers-browserify": "2.0.6", + "tty-browserify": "0.0.0", + "url": "0.11.0", + "util": "0.10.3", + "vm-browserify": "0.0.4" + }, + "dependencies": { + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "requires": { + "pako": "1.0.6" + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "pako": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", + "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==", + "dev": true + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "timers-browserify": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.6.tgz", + "integrity": "sha512-HQ3nbYRAowdVd0ckGFvmJPPCOH/CHleFN/Y0YQCX1DVaB7t+KFvisuyN09fuP8Jtp1CpfSh8O8bMkHbdbPe6Pw==", + "dev": true, + "requires": { + "setimmediate": "1.0.5" + } + } + } + }, "node-pty": { "version": "0.7.3", "resolved": "https://registry.npmjs.org/node-pty/-/node-pty-0.7.3.tgz", @@ -9833,12 +11680,919 @@ "requires": { "anymatch": "1.3.0", "async-each": "1.0.1", + "fsevents": "1.1.3", "glob-parent": "2.0.0", "inherits": "2.0.3", "is-binary-path": "1.0.1", "is-glob": "2.0.1", "path-is-absolute": "1.0.1", "readdirp": "2.1.0" + }, + "dependencies": { + "fsevents": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.3.tgz", + "integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==", + "dev": true, + "optional": true, + "requires": { + "nan": "2.8.0", + "node-pre-gyp": "0.6.39" + }, + "dependencies": { + "abbrev": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "ajv": { + "version": "4.11.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "co": "4.6.0", + "json-stable-stringify": "1.0.1" + } + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "aproba": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "1.0.0", + "readable-stream": "2.2.9" + } + }, + "asn1": { + "version": "0.2.3", + "bundled": true, + "dev": true, + "optional": true + }, + "assert-plus": { + "version": "0.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "asynckit": { + "version": "0.4.0", + "bundled": true, + "dev": true, + "optional": true + }, + "aws-sign2": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "aws4": { + "version": "1.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "balanced-match": { + "version": "0.4.2", + "bundled": true, + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "tweetnacl": "0.14.5" + } + }, + "block-stream": { + "version": "0.0.9", + "bundled": true, + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "boom": { + "version": "2.10.1", + "bundled": true, + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, + "brace-expansion": { + "version": "1.1.7", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "0.4.2", + "concat-map": "0.0.1" + } + }, + "buffer-shims": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "caseless": { + "version": "0.12.0", + "bundled": true, + "dev": true, + "optional": true + }, + "co": { + "version": "4.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "combined-stream": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "requires": { + "delayed-stream": "1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "cryptiles": { + "version": "2.0.5", + "bundled": true, + "dev": true, + "requires": { + "boom": "2.10.1" + } + }, + "dashdash": { + "version": "1.14.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "debug": { + "version": "2.6.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-extend": { + "version": "0.4.2", + "bundled": true, + "dev": true, + "optional": true + }, + "delayed-stream": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "ecc-jsbn": { + "version": "0.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "extend": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "extsprintf": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "optional": true + }, + "form-data": { + "version": "2.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.15" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "fstream": { + "version": "1.0.11", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "inherits": "2.0.3", + "mkdirp": "0.5.1", + "rimraf": "2.6.1" + } + }, + "fstream-ignore": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fstream": "1.0.11", + "inherits": "2.0.3", + "minimatch": "3.0.4" + } + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "1.1.1", + "console-control-strings": "1.1.0", + "has-unicode": "2.0.1", + "object-assign": "4.1.1", + "signal-exit": "3.0.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wide-align": "1.1.2" + } + }, + "getpass": { + "version": "0.1.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "glob": { + "version": "7.1.2", + "bundled": true, + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "graceful-fs": { + "version": "4.1.11", + "bundled": true, + "dev": true + }, + "har-schema": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "optional": true + }, + "har-validator": { + "version": "4.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ajv": "4.11.8", + "har-schema": "1.0.5" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "hawk": { + "version": "3.1.3", + "bundled": true, + "dev": true, + "requires": { + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" + } + }, + "hoek": { + "version": "2.16.3", + "bundled": true, + "dev": true + }, + "http-signature": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "0.2.0", + "jsprim": "1.4.0", + "sshpk": "1.13.0" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "ini": { + "version": "1.3.4", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-typedarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "isstream": { + "version": "0.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "jodid25519": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "jsbn": { + "version": "0.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "json-schema": { + "version": "0.2.3", + "bundled": true, + "dev": true, + "optional": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "jsonify": "0.0.0" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "jsonify": { + "version": "0.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "jsprim": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.0.2", + "json-schema": "0.2.3", + "verror": "1.3.6" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "mime-db": { + "version": "1.27.0", + "bundled": true, + "dev": true + }, + "mime-types": { + "version": "2.1.15", + "bundled": true, + "dev": true, + "requires": { + "mime-db": "1.27.0" + } + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "node-pre-gyp": { + "version": "0.6.39", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "1.0.2", + "hawk": "3.1.3", + "mkdirp": "0.5.1", + "nopt": "4.0.1", + "npmlog": "4.1.0", + "rc": "1.2.1", + "request": "2.81.0", + "rimraf": "2.6.1", + "semver": "5.3.0", + "tar": "2.2.1", + "tar-pack": "3.4.0" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1.1.0", + "osenv": "0.1.4" + } + }, + "npmlog": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "1.1.4", + "console-control-strings": "1.1.0", + "gauge": "2.7.4", + "set-blocking": "2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "oauth-sign": { + "version": "0.8.2", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "performance-now": { + "version": "0.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "1.0.7", + "bundled": true, + "dev": true + }, + "punycode": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "optional": true + }, + "qs": { + "version": "6.4.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "0.4.2", + "ini": "1.3.4", + "minimist": "1.2.0", + "strip-json-comments": "2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.2.9", + "bundled": true, + "dev": true, + "requires": { + "buffer-shims": "1.0.0", + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "1.0.1", + "util-deprecate": "1.0.2" + } + }, + "request": { + "version": "2.81.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aws-sign2": "0.6.0", + "aws4": "1.6.0", + "caseless": "0.12.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.1.4", + "har-validator": "4.2.1", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.15", + "oauth-sign": "0.8.2", + "performance-now": "0.2.0", + "qs": "6.4.0", + "safe-buffer": "5.0.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.2", + "tunnel-agent": "0.6.0", + "uuid": "3.0.1" + } + }, + "rimraf": { + "version": "2.6.1", + "bundled": true, + "dev": true, + "requires": { + "glob": "7.1.2" + } + }, + "safe-buffer": { + "version": "5.0.1", + "bundled": true, + "dev": true + }, + "semver": { + "version": "5.3.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sntp": { + "version": "1.0.9", + "bundled": true, + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, + "sshpk": { + "version": "1.13.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.7", + "jodid25519": "1.0.2", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "string_decoder": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "5.0.1" + } + }, + "stringstream": { + "version": "0.0.5", + "bundled": true, + "dev": true, + "optional": true + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "2.2.1", + "bundled": true, + "dev": true, + "requires": { + "block-stream": "0.0.9", + "fstream": "1.0.11", + "inherits": "2.0.3" + } + }, + "tar-pack": { + "version": "3.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "2.6.8", + "fstream": "1.0.11", + "fstream-ignore": "1.0.5", + "once": "1.4.0", + "readable-stream": "2.2.9", + "rimraf": "2.6.1", + "tar": "2.2.1", + "uid-number": "0.0.6" + } + }, + "tough-cookie": { + "version": "2.3.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "punycode": "1.4.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "bundled": true, + "dev": true, + "optional": true + }, + "uid-number": { + "version": "0.0.6", + "bundled": true, + "dev": true, + "optional": true + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "uuid": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "verror": { + "version": "1.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "extsprintf": "1.0.2" + } + }, + "wide-align": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "1.0.2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + } + } + } } }, "concat-map": { @@ -10854,6 +13608,42 @@ } } }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "dev": true, + "requires": { + "hosted-git-info": "2.5.0", + "is-builtin-module": "1.0.0", + "semver": "5.5.0", + "validate-npm-package-license": "3.0.1" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "1.0.2" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "2.0.1" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, "oauth-sign": { "version": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", @@ -10900,6 +13690,16 @@ } } }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "dev": true, + "requires": { + "for-own": "0.1.5", + "is-extendable": "0.1.1" + } + }, "object.pick": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.2.0.tgz", @@ -10952,6 +13752,47 @@ "integrity": "sha1-ScoCk+CxlZCl9d4Qx/JlphfY/lQ=", "dev": true }, + "os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "dev": true, + "requires": { + "execa": "0.7.0", + "lcid": "1.0.0", + "mem": "1.1.0" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-limit": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", + "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", + "dev": true, + "requires": { + "p-try": "1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "1.2.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, "pako": { "version": "0.2.9", "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", @@ -10980,12 +13821,51 @@ "pbkdf2": "3.0.12" } }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "dev": true, + "requires": { + "glob-base": "0.3.0", + "is-dotfile": "1.0.3", + "is-extglob": "1.0.0", + "is-glob": "2.0.1" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "1.3.1" + } + }, "path-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", "dev": true }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, "path-parse": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", @@ -10998,6 +13878,15 @@ "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", "dev": true }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "2.3.0" + } + }, "pbkdf2": { "version": "3.0.12", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.12.tgz", @@ -11011,6 +13900,12 @@ "sha.js": "2.4.8" } }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, "pinkie": { "version": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", @@ -11035,6 +13930,12 @@ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "dev": true + }, "printj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.0.tgz", @@ -11053,6 +13954,18 @@ "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", "dev": true }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, "public-encrypt": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz", @@ -11083,6 +13996,47 @@ "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", "dev": true }, + "randomatic": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", + "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", + "dev": true, + "requires": { + "is-number": "3.0.0", + "kind-of": "4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "1.1.5" + } + } + } + }, "randombytes": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.5.tgz", @@ -11133,6 +14087,27 @@ } } }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "2.0.0", + "normalize-package-data": "2.4.0", + "path-type": "2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "2.1.0", + "read-pkg": "2.0.0" + } + }, "readable-stream": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", @@ -11145,12 +14120,77 @@ "string_decoder": "0.10.31" } }, + "readdirp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", + "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "minimatch": "3.0.4", + "readable-stream": "2.3.3", + "set-immediate-shim": "1.0.1" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, + "regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "dev": true, + "requires": { + "is-equal-shallow": "0.1.3" + } + }, "remove-trailing-separator": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.0.2.tgz", "integrity": "sha1-abBi2XhyetFNxrVrpKt3L9jXBRE=", "dev": true }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, "replace-ext": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", @@ -11224,6 +14264,18 @@ "tough-cookie": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz" } }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, "resolve": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", @@ -11233,6 +14285,15 @@ "path-parse": "1.0.5" } }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "dev": true, + "requires": { + "align-text": "0.1.4" + } + }, "ripemd160": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", @@ -11260,6 +14321,24 @@ "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", "dev": true }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", + "dev": true + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, "sha.js": { "version": "2.4.8", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.8.tgz", @@ -11279,6 +14358,21 @@ "sha.js": "2.4.8" } }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, "shell-quote": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", @@ -11291,6 +14385,12 @@ "jsonify": "0.0.0" } }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, "sntp": { "version": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", @@ -11390,6 +14490,12 @@ } } }, + "source-list-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz", + "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==", + "dev": true + }, "source-map": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", @@ -11402,6 +14508,27 @@ "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=", "dev": true }, + "spdx-correct": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "dev": true, + "requires": { + "spdx-license-ids": "1.2.2" + } + }, + "spdx-expression-parse": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", + "dev": true + }, + "spdx-license-ids": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", + "dev": true + }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -11623,6 +14750,39 @@ } } }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + } + } + }, "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", @@ -11642,6 +14802,18 @@ "ansi-regex": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz" } }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, "subarg": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", @@ -11670,6 +14842,12 @@ "acorn": "4.0.13" } }, + "tapable": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.8.tgz", + "integrity": "sha1-mTcqXJmb8t8WCvwNdL7U9HlIzSI=", + "dev": true + }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -11868,11 +15046,54 @@ "dev": true }, "typescript": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.4.2.tgz", - "integrity": "sha1-+DlfhdRZJ2BnyYiqQYN6j4KHCEQ=", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.7.1.tgz", + "integrity": "sha512-bqB1yS6o9TNA9ZC/MJxM0FZzPnZdtHj0xWK/IZ5khzVqdpGul/R/EIiHRgFXlwTD7PSIaYVnGKq1QgMCu2mnqw==", "dev": true }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "dev": true, + "requires": { + "source-map": "0.5.6", + "uglify-to-browserify": "1.0.2", + "yargs": "3.10.0" + }, + "dependencies": { + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "dev": true, + "requires": { + "camelcase": "1.2.1", + "cliui": "2.1.0", + "decamelize": "1.2.0", + "window-size": "0.1.0" + } + } + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "dev": true, + "optional": true + }, + "uglifyjs-webpack-plugin": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz", + "integrity": "sha1-uVH0q7a9YX5m9j64kUmOORdj4wk=", + "dev": true, + "requires": { + "source-map": "0.5.6", + "uglify-js": "2.8.29", + "webpack-sources": "1.1.0" + } + }, "umd": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.1.tgz", @@ -11920,6 +15141,16 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, + "validate-npm-package-license": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "dev": true, + "requires": { + "spdx-correct": "1.0.2", + "spdx-expression-parse": "1.0.4" + } + }, "verror": { "version": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz", "integrity": "sha1-z/XfEpRtKX0rqu+qJoniW+AcAFw=", @@ -12107,11 +15338,136 @@ "indexof": "0.0.1" } }, + "watchpack": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.4.0.tgz", + "integrity": "sha1-ShRyvLuVK9Cpu0A2gB+VTfs5+qw=", + "dev": true, + "requires": { + "async": "2.6.0", + "chokidar": "1.7.0", + "graceful-fs": "4.1.11" + } + }, "webidl-conversions": { "version": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.1.tgz", "integrity": "sha1-gBWherg+fhsxFjhIas6B2mziBqA=", "dev": true }, + "webpack": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.10.0.tgz", + "integrity": "sha512-fxxKXoicjdXNUMY7LIdY89tkJJJ0m1Oo8PQutZ5rLgWbV5QVKI15Cn7+/IHnRTd3vfKfiwBx6SBqlorAuNA8LA==", + "dev": true, + "requires": { + "acorn": "5.3.0", + "acorn-dynamic-import": "2.0.2", + "ajv": "5.5.2", + "ajv-keywords": "2.1.1", + "async": "2.6.0", + "enhanced-resolve": "3.4.1", + "escope": "3.6.0", + "interpret": "1.1.0", + "json-loader": "0.5.7", + "json5": "0.5.1", + "loader-runner": "2.3.0", + "loader-utils": "1.1.0", + "memory-fs": "0.4.1", + "mkdirp": "0.5.1", + "node-libs-browser": "2.1.0", + "source-map": "0.5.6", + "supports-color": "4.5.0", + "tapable": "0.2.8", + "uglifyjs-webpack-plugin": "0.4.6", + "watchpack": "1.4.0", + "webpack-sources": "1.1.0", + "yargs": "8.0.2" + }, + "dependencies": { + "acorn": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz", + "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "webpack-sources": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.1.0.tgz", + "integrity": "sha512-aqYp18kPphgoO5c/+NaUvEeACtZjMESmDChuD3NBciVpah3XpMEU9VAAtIaB1BsfJWWTSdv8Vv1m3T0aRk2dUw==", + "dev": true, + "requires": { + "source-list-map": "2.0.0", + "source-map": "0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "webpack-stream": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/webpack-stream/-/webpack-stream-4.0.0.tgz", + "integrity": "sha1-82c92QfW2bHqe/UfzR24W1/Z4PI=", + "dev": true, + "requires": { + "gulp-util": "3.0.8", + "lodash.clone": "4.5.0", + "lodash.some": "4.6.0", + "memory-fs": "0.4.1", + "through": "2.3.8", + "vinyl": "2.1.0", + "webpack": "3.10.0" + }, + "dependencies": { + "clone": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", + "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=", + "dev": true + }, + "clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", + "dev": true + }, + "replace-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", + "dev": true + }, + "vinyl": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.1.0.tgz", + "integrity": "sha1-Ah+cLPlR1rk5lDyJ617lrdT9kkw=", + "dev": true, + "requires": { + "clone": "2.1.1", + "clone-buffer": "1.0.0", + "clone-stats": "1.0.0", + "cloneable-readable": "1.0.0", + "remove-trailing-separator": "1.0.2", + "replace-ext": "1.0.0" + } + } + } + }, "whatwg-encoding": { "version": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.1.tgz", "integrity": "sha1-PGxFGhmO567FWx7GHQkgxngBpfQ=", @@ -12120,6 +15476,71 @@ "iconv-lite": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz" } }, + "which": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", + "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "dev": true, + "requires": { + "isexe": "2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", + "dev": true + }, + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + } + } + }, "xml-name-validator": { "version": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz", "integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU=", @@ -12130,6 +15551,103 @@ "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", "dev": true }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yargs": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz", + "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=", + "dev": true, + "requires": { + "camelcase": "4.1.0", + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.2", + "os-locale": "2.1.0", + "read-pkg-up": "2.0.0", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "2.1.1", + "which-module": "2.0.0", + "y18n": "3.2.1", + "yargs-parser": "7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + } + } + }, + "yargs-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", + "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", + "dev": true, + "requires": { + "camelcase": "4.1.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + } + } + }, "zmodem.js": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/zmodem.js/-/zmodem.js-0.1.6.tgz", diff --git a/package.json b/package.json index ba988d613..3e14ff3f9 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "nodemon": "1.10.2", "sorcery": "^0.10.0", "tslint": "^5.9.1", - "typescript": "~2.4.0", + "typescript": "~2.7.1", "vinyl-buffer": "^1.0.0", "vinyl-source-stream": "^1.1.0", "webpack": "^3.10.0", From 2ac5a8da4970d82fbe67bdb9b4998e956ecd7943 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 31 Jan 2018 17:42:33 -0800 Subject: [PATCH 43/58] Allow support of modifiers with links Fixes #1021 --- src/Linkifier.ts | 7 +++++++ src/Types.ts | 8 ++++++++ src/input/MouseZoneManager.ts | 15 ++++++++------- src/input/Types.ts | 7 ++++--- typings/xterm.d.ts | 12 ++++++++++-- 5 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index da901a6ed..a9617952d 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -150,6 +150,7 @@ export class Linkifier extends EventEmitter implements ILinkifier { validationCallback: options.validationCallback, hoverTooltipCallback: options.tooltipCallback, hoverLeaveCallback: options.leaveCallback, + willLinkActivate: options.willLinkActivate, priority: options.priority || 0 }; this._addLinkMatcherToList(matcher); @@ -290,6 +291,12 @@ export class Linkifier extends EventEmitter implements ILinkifier { if (matcher.hoverLeaveCallback) { matcher.hoverLeaveCallback(); } + }, + e => { + if (matcher.willLinkActivate) { + return matcher.willLinkActivate(e, uri); + } + return true; } )); } diff --git a/src/Types.ts b/src/Types.ts index da3cc9d2a..9dd7dda2d 100644 --- a/src/Types.ts +++ b/src/Types.ts @@ -161,6 +161,7 @@ export interface ILinkMatcher { matchIndex?: number; validationCallback?: LinkMatcherValidationCallback; priority?: number; + willLinkActivate?: (event: MouseEvent, uri: string) => boolean; } export interface ICharset { @@ -321,6 +322,13 @@ export interface ILinkMatcherOptions { * default value is 0. */ priority?: number; + /** + * A callback that fires when the mousedown and click events occur that + * determines whether a link will be activated upon click. This enables + * only activating a link when a certain modifier is held down, if not the + * mouse event will continue propagation (eg. double click to select word). + */ + willLinkActivate?: (event: MouseEvent, uri: string) => boolean; } export interface IBrowser { diff --git a/src/input/MouseZoneManager.ts b/src/input/MouseZoneManager.ts index 98377f36c..79c02b5f2 100644 --- a/src/input/MouseZoneManager.ts +++ b/src/input/MouseZoneManager.ts @@ -151,10 +151,10 @@ export class MouseZoneManager implements IMouseZoneManager { // components from handling the mouse event. const zone = this._findZoneEventAt(e); if (zone) { - // TODO: When link modifier support is added, the event should only be - // cancelled when the modifier is held (see #1021) - e.preventDefault(); - e.stopImmediatePropagation(); + if (zone.willLinkActivate(e)) { + e.preventDefault(); + e.stopImmediatePropagation(); + } } } @@ -189,9 +189,10 @@ export class MouseZone implements IMouseZone { public x2: number, public y: number, public clickCallback: (e: MouseEvent) => any, - public hoverCallback?: (e: MouseEvent) => any, - public tooltipCallback?: (e: MouseEvent) => any, - public leaveCallback?: () => void + public hoverCallback: (e: MouseEvent) => any, + public tooltipCallback: (e: MouseEvent) => any, + public leaveCallback: () => void, + public willLinkActivate: (e: MouseEvent) => boolean ) { } } diff --git a/src/input/Types.ts b/src/input/Types.ts index 21514a53c..f13984646 100644 --- a/src/input/Types.ts +++ b/src/input/Types.ts @@ -13,7 +13,8 @@ export interface IMouseZone { x2: number; y: number; clickCallback: (e: MouseEvent) => any; - hoverCallback?: (e: MouseEvent) => any; - tooltipCallback?: (e: MouseEvent) => any; - leaveCallback?: () => any; + hoverCallback: (e: MouseEvent) => any | undefined; + tooltipCallback: (e: MouseEvent) => any | undefined; + leaveCallback: () => any | undefined; + willLinkActivate: (e: MouseEvent) => boolean; } diff --git a/typings/xterm.d.ts b/typings/xterm.d.ts index 0b35edf11..2f6b4cd85 100644 --- a/typings/xterm.d.ts +++ b/typings/xterm.d.ts @@ -174,8 +174,8 @@ declare module 'xterm' { matchIndex?: number; /** - * A callback that validates an individual link, returning true if valid and - * false if invalid. + * A callback that validates whether to create an individual link, pass + * whether the link is valid to the callback. */ validationCallback?: (uri: string, callback: (isValid: boolean) => void) => void; @@ -196,6 +196,14 @@ declare module 'xterm' { * default value is 0. */ priority?: number; + + /** + * A callback that fires when the mousedown and click events occur that + * determines whether a link will be activated upon click. This enables + * only activating a link when a certain modifier is held down, if not the + * mouse event will continue propagation (eg. double click to select word). + */ + willLinkActivate?: (event: MouseEvent, uri: string) => boolean; } export interface IEventEmitter { From 610597530867e10fb91baf85d65cadf6c38c214a Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 1 Feb 2018 10:24:17 -0800 Subject: [PATCH 44/58] Ensure viewport is attached before syncing scrollbar Fixes #1265 --- src/Viewport.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Viewport.ts b/src/Viewport.ts index 87ecd69ec..59dc304d4 100644 --- a/src/Viewport.ts +++ b/src/Viewport.ts @@ -93,6 +93,12 @@ export class Viewport implements IViewport { * @param ev The scroll event. */ private onScroll(ev: Event): void { + // Don't attempt to scroll if the element is not visible, otherwise scrollTop will be corrupt + // which causes the terminal to scroll the buffer to the top + if (!this.viewportElement.offsetParent) { + return; + } + const newRow = Math.round(this.viewportElement.scrollTop / this.currentRowHeight); const diff = newRow - this.terminal.buffer.ydisp; this.terminal.scrollLines(diff, true); From 04ccb638b44b2b8fd5f4dbba1e8138cc8b500db7 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 1 Feb 2018 11:28:56 -0800 Subject: [PATCH 45/58] Fix lint --- src/Types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Types.ts b/src/Types.ts index 9dd7dda2d..c84337079 100644 --- a/src/Types.ts +++ b/src/Types.ts @@ -328,7 +328,7 @@ export interface ILinkMatcherOptions { * only activating a link when a certain modifier is held down, if not the * mouse event will continue propagation (eg. double click to select word). */ - willLinkActivate?: (event: MouseEvent, uri: string) => boolean; + willLinkActivate?: (event: MouseEvent, uri: string) => boolean; } export interface IBrowser { From 5550bfd90b9b9a96f8344a0d3cd89400a228b61d Mon Sep 17 00:00:00 2001 From: Bruno Ribeito Date: Thu, 1 Feb 2018 21:37:06 +0000 Subject: [PATCH 46/58] Fix is click in selection --- src/SelectionManager.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SelectionManager.ts b/src/SelectionManager.ts index c01d7b6d5..a639a75e4 100644 --- a/src/SelectionManager.ts +++ b/src/SelectionManager.ts @@ -258,8 +258,8 @@ export class SelectionManager extends EventEmitter implements ISelectionManager } return (start[1] < coords[1] && end[1] > coords[1]) || - (start[1] === coords[1] && coords[0] > start[0]) || - (end[1] === coords[1] && coords[0] < end[0]); + (start[1] === end[1] && start[1] === coords[1] && coords[0] > start[0] && coords[0] < end[0]) || + (start[1] < end[1] && end[1] === coords[1] && coords[0] < end[0]); } /** From 3c6cab1491c84e99b0c9de92d20ea0272c99141a Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 1 Feb 2018 17:20:33 -0800 Subject: [PATCH 47/58] Clear selectionEnd when selecting word at cursor --- src/SelectionManager.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SelectionManager.ts b/src/SelectionManager.ts index a639a75e4..f571b74cd 100644 --- a/src/SelectionManager.ts +++ b/src/SelectionManager.ts @@ -270,6 +270,7 @@ export class SelectionManager extends EventEmitter implements ISelectionManager const coords = this._getMouseBufferCoords(event); if (coords) { this._selectWordAt(coords, false); + this._model.selectionEnd = null; this.refresh(true); } } From cab097c09c60dfc342eaac2b8d66a3235f2edd96 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 1 Feb 2018 17:27:49 -0800 Subject: [PATCH 48/58] Clean up condition for readability --- src/SelectionManager.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SelectionManager.ts b/src/SelectionManager.ts index 33853036b..11856a922 100644 --- a/src/SelectionManager.ts +++ b/src/SelectionManager.ts @@ -266,9 +266,9 @@ export class SelectionManager extends EventEmitter implements ISelectionManager return false; } - return (start[1] < coords[1] && end[1] > coords[1]) || - (start[1] === end[1] && start[1] === coords[1] && coords[0] > start[0] && coords[0] < end[0]) || - (start[1] < end[1] && end[1] === coords[1] && coords[0] < end[0]); + 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]); } /** From c302bc9f1762140d28adc9359a4345cbea0f1367 Mon Sep 17 00:00:00 2001 From: Krasimir Tsonev Date: Mon, 5 Feb 2018 09:32:34 +0200 Subject: [PATCH 49/58] Update README.md In `Getting Started` section we read `npm install` only. Shouldn't be `npm install xterm`? --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a5d34632b..740ff0aad 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ It enables applications to provide fully featured terminals to their users and c First you need to install the module, we ship exclusively through [npm](https://www.npmjs.com/) so you need that installed and then add xterm.js as a dependency by running: ``` -npm install +npm install xterm ``` To start using xterm.js on your browser, add the `xterm.js` and `xterm.css` to the head of your html page. Then create a `
` onto which xterm can attach itself. From d0f45fee25d67cc0f703caf52d28dc33b2e583b6 Mon Sep 17 00:00:00 2001 From: Paris Kasidiaris Date: Mon, 5 Feb 2018 14:30:57 +0200 Subject: [PATCH 50/58] Fix #1232: Add `webpack:watch` gulp task --- Procfile | 1 + gulpfile.js | 4 ++++ package.json | 4 ++-- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Procfile b/Procfile index 063b78f46..64562488d 100644 --- a/Procfile +++ b/Procfile @@ -1 +1,2 @@ web: npm start +webpack: npm run webpack:watch diff --git a/gulpfile.js b/gulpfile.js index 7a65d7f28..de64ee919 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -192,6 +192,10 @@ gulp.task('webpack', ['build'], function() { .pipe(gulp.dest('demo/dist/')); }); +gulp.task('webpack:watch', ['webpack'], () => { + gulp.watch('./src/*', ['webpack']); +}); + /** * Submit coverage results to coveralls.io */ diff --git a/package.json b/package.json index 3e14ff3f9..c16409dc3 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,6 @@ "zmodem.js": "^0.1.5" }, "scripts": { - "prestart": "gulp webpack", "start": "node demo/app", "prestart-zmodem": "npm run build", "start-zmodem": "node build/addons/zmodem/demo/app", @@ -86,7 +85,8 @@ "build": "gulp build", "prepublish": "npm run build", "coveralls": "gulp coveralls", - "webpack": "gulp webpack" + "webpack": "gulp webpack", + "webpack:watch": "gulp webpack:watch" }, "dependencies": {} } From 182426dd0fa79fa212cdad95d05400f33e62ad91 Mon Sep 17 00:00:00 2001 From: Paris Kasidiaris Date: Tue, 6 Feb 2018 10:28:34 +0200 Subject: [PATCH 51/58] =?UTF-8?q?Rename=20gulp=20task:=20`webpack:watch`?= =?UTF-8?q?=20=E2=86=92=20watch`=20and=20also=20monitor=20subdirectories?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Procfile | 2 +- gulpfile.js | 4 ++-- package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Procfile b/Procfile index 64562488d..44bf043c3 100644 --- a/Procfile +++ b/Procfile @@ -1,2 +1,2 @@ web: npm start -webpack: npm run webpack:watch +webpack: npm run watch diff --git a/gulpfile.js b/gulpfile.js index de64ee919..4353e46d1 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -192,8 +192,8 @@ gulp.task('webpack', ['build'], function() { .pipe(gulp.dest('demo/dist/')); }); -gulp.task('webpack:watch', ['webpack'], () => { - gulp.watch('./src/*', ['webpack']); +gulp.task('watch', ['webpack'], () => { + gulp.watch(['./src/*', './src/**/*'], ['webpack']); }); /** diff --git a/package.json b/package.json index c16409dc3..1a718fbc2 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,7 @@ "prepublish": "npm run build", "coveralls": "gulp coveralls", "webpack": "gulp webpack", - "webpack:watch": "gulp webpack:watch" + "watch": "gulp watch" }, "dependencies": {} } From f02903a6df9e380a9131ae95046a793f1578b954 Mon Sep 17 00:00:00 2001 From: Paris Kasidiaris Date: Tue, 6 Feb 2018 11:16:57 +0200 Subject: [PATCH 52/58] Update README.md and Docker files --- Dockerfile | 2 +- README.md | 47 +++++++++++++++++++++++++++++++++++++++------- demo/index.html | 2 +- docker-compose.yml | 7 +++++++ 4 files changed, 49 insertions(+), 9 deletions(-) diff --git a/Dockerfile b/Dockerfile index 22556f431..1c72e6790 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:6 +FROM node:8 MAINTAINER Paris Kasidiaris # Set the working directory diff --git a/README.md b/README.md index 740ff0aad..cc1c89503 100644 --- a/README.md +++ b/README.md @@ -131,27 +131,60 @@ Do you use xterm.js in your application as well? Please [open a Pull Request](ht ## Demo -### Linux or macOS +Xterm.js ships with a barebones demo implementation, designed for the development and evaluation of the library only. Exposing the demo to the public as is would introduce security risks for the host. -First, be sure that a C++ compiler such as GCC-C++ or Clang is installed, then run these commands: +Below you can find instructions on how to run the demo on different platforms. + +### SourceLair + +SourceLair will run the demo and builder in parallel automatically. Just make sure to choose the "Node.js" project type, when cloning the xterm.js repo (or just use this shortcut; https://lair.io/xtermjs/xtermjs). + +Then open your project's [Public URL](https://help.sourcelair.com/projects/the-public-url/) to access the demo. + +### Docker + +First, make sure you have Docker Engine 1.13.0 (or newer) and Docker Compose 1.10.0 (or newer). To run the demo and builder in parallel, run the following command in your terminal: + +``` +docker-compose up +``` + +Then open http://0.0.0.0:3000 in a web browser to access the demo. If you prefer a different port than `3000` to access the xterm.js demo, then set the `XTERMJS_PORT` environment variable to the desired port. + +### Foreman (or other Procfile runner) + +First, be sure that a C++ compiler such as GCC-C++ or Clang is installed, then run the following commands in your terminal: ``` npm install -npm start +foreman start # Replace foreman with "honcho", "forego" etc. depending on your runner ``` -Then open http://0.0.0.0:3000 in a web browser. +Then open http://0.0.0.0:3000 in a web browser to access the demo. + +### Linux or macOS + +First, be sure that a C++ compiler such as GCC-C++ or Clang is installed, then run the following commands in your terminal: + +``` +npm install +npm start # Run this in its own terminal +npm run watch # Run this in its own terminal +``` + +Then open http://0.0.0.0:3000 in a web browser to access the demo. ### Windows -First, ensure [node-gyp](https://github.com/nodejs/node-gyp) is installed and configured correctly, then run these commands. +First, ensure [node-gyp](https://github.com/nodejs/node-gyp) is installed and configured correctly, then run the following commands in your terminal: ``` npm install -npm start +npm start # Run this in its own terminal +npm run watch # Run this in its own terminal ``` -Then open http://127.0.0.1:3000 in a web browser. +Then open http://127.0.0.1:3000 in a web browser to access the demo. *Note: Do not use ConEmu, as it seems to break the demo for some reason.* diff --git a/demo/index.html b/demo/index.html index da348f5e6..b6d0ff61e 100644 --- a/demo/index.html +++ b/demo/index.html @@ -67,7 +67,7 @@ -

Attention: The demo is a barebones implementation and is designed for xterm.js evaluation purposes only. Exposing the demo to the public as is would introduce security risks for the host.

+

Attention: The demo is a barebones implementation and is designed for the development and evaluation of xterm.js only. Exposing the demo to the public as is would introduce security risks for the host.

diff --git a/docker-compose.yml b/docker-compose.yml index 03e88fbc1..effd975c9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,3 +7,10 @@ services: - ./:/usr/src/app ports: - ${XTERMJS_PORT:3000}:3000 + command: ["npm", "start"] + + watch: + build: . + volumes: + - ./:/usr/src/app + command: ["npm", "run", "watch"] From 35ea593806ab675ccf2b3c3cbbb5c8788f3f760d Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 6 Feb 2018 02:03:09 -0800 Subject: [PATCH 53/58] Update readme copyright statement --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 740ff0aad..4501aad46 100644 --- a/README.md +++ b/README.md @@ -175,6 +175,6 @@ To contribute either code, documentation or issues to xterm.js please read the [ If you contribute code to this project, you are implicitly allowing your code to be distributed under the MIT license. You are also implicitly verifying that all code is your original work. +Copyright (c) 2017-2018, [The xterm.js authors](https://github.com/xtermjs/xterm.js/graphs/contributors) (MIT License) Copyright (c) 2014-2017, SourceLair, Private Company ([www.sourcelair.com](https://www.sourcelair.com/home)) (MIT License) - Copyright (c) 2012-2013, Christopher Jeffrey (MIT License) From dc759a93bc7753fcd733a06fbb3a67220120876b Mon Sep 17 00:00:00 2001 From: Thomas Zilz Date: Tue, 6 Feb 2018 12:31:17 +0100 Subject: [PATCH 54/58] Support setting padding on the .xterm element (#1208) * Support padding on the .xterm element --- demo/index.html | 4 ++++ demo/main.js | 17 +++++++++++------ src/SelectionManager.ts | 4 ++-- src/Terminal.ts | 18 +++++++++++------- src/Types.ts | 3 +++ src/Viewport.ts | 16 +++++++++------- src/addons/fit/fit.ts | 15 ++++++++++----- src/input/MouseZoneManager.ts | 2 +- src/renderer/Renderer.ts | 12 ++++++++---- src/utils/TestUtils.test.ts | 3 +++ src/xterm.css | 11 ++++++++++- 11 files changed, 72 insertions(+), 33 deletions(-) diff --git a/demo/index.html b/demo/index.html index b6d0ff61e..a62cff0e3 100644 --- a/demo/index.html +++ b/demo/index.html @@ -64,6 +64,10 @@ +
+ + +
diff --git a/demo/main.js b/demo/main.js index 1faf77d8a..264a205d3 100644 --- a/demo/main.js +++ b/demo/main.js @@ -33,23 +33,27 @@ var terminalContainer = document.getElementById('terminal-container'), bellStyle: document.querySelector('#option-bell-style') }, colsElement = document.getElementById('cols'), - rowsElement = document.getElementById('rows'); + rowsElement = document.getElementById('rows'), + paddingElement = document.getElementById('padding'); function setTerminalSize() { var cols = parseInt(colsElement.value, 10); var rows = parseInt(rowsElement.value, 10); - var viewportElement = document.querySelector('.xterm-viewport'); - var scrollBarWidth = viewportElement.offsetWidth - viewportElement.clientWidth; - var width = (cols * term.renderer.dimensions.actualCellWidth + 20 /*room for scrollbar*/).toString() + 'px'; + var width = (cols * term.renderer.dimensions.actualCellWidth + term.viewport.scrollBarWidth).toString() + 'px'; var height = (rows * term.renderer.dimensions.actualCellHeight).toString() + 'px'; - terminalContainer.style.width = width; terminalContainer.style.height = height; - term.resize(cols, rows); + term.fit(); +} + +function setPadding() { + term.element.style.padding = parseInt(paddingElement.value, 10).toString() + 'px'; + term.fit(); } colsElement.addEventListener('change', setTerminalSize); rowsElement.addEventListener('change', setTerminalSize); +paddingElement.addEventListener('change', setPadding); actionElements.findNext.addEventListener('keypress', function (e) { if (e.key === "Enter") { @@ -119,6 +123,7 @@ function createTerminal() { setTimeout(function () { colsElement.value = term.cols; rowsElement.value = term.rows; + paddingElement.value = 0; // Set terminal size again to set the specific dimensions on the demo setTerminalSize(); diff --git a/src/SelectionManager.ts b/src/SelectionManager.ts index 11856a922..dc1d0682a 100644 --- a/src/SelectionManager.ts +++ b/src/SelectionManager.ts @@ -309,7 +309,7 @@ export class SelectionManager extends EventEmitter implements ISelectionManager * @param event The mouse event. */ private _getMouseBufferCoords(event: MouseEvent): [number, number] { - const coords = this._terminal.mouseHelper.getCoords(event, this._terminal.element, this._charMeasure, this._terminal.options.lineHeight, this._terminal.cols, this._terminal.rows, true); + const coords = this._terminal.mouseHelper.getCoords(event, this._terminal.screenElement, this._charMeasure, this._terminal.options.lineHeight, this._terminal.cols, this._terminal.rows, true); if (!coords) { return null; } @@ -329,7 +329,7 @@ export class SelectionManager extends EventEmitter implements ISelectionManager * @param event The mouse event. */ private _getMouseEventScrollAmount(event: MouseEvent): number { - let offset = MouseHelper.getCoordsRelativeToElement(event, this._terminal.element)[1]; + let offset = MouseHelper.getCoordsRelativeToElement(event, this._terminal.screenElement)[1]; const terminalHeight = this._terminal.rows * Math.ceil(this._charMeasure.height * this._terminal.options.lineHeight); if (offset >= 0 && offset <= terminalHeight) { return 0; diff --git a/src/Terminal.ts b/src/Terminal.ts index c55dd924d..1bc9cfbb0 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -96,6 +96,7 @@ const DEFAULT_OPTIONS: ITerminalOptions = { export class Terminal extends EventEmitter implements ITerminal, IInputHandlingTerminal { public textarea: HTMLTextAreaElement; public element: HTMLElement; + public screenElement: HTMLElement; /** * The HTMLElement that the terminal is created in, set by Terminal.open. @@ -609,15 +610,18 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT this.viewportScrollArea.classList.add('xterm-scroll-area'); this.viewportElement.appendChild(this.viewportScrollArea); - this._mouseZoneManager = new MouseZoneManager(this); - this.on('scroll', () => this._mouseZoneManager.clearAll()); - this.linkifier.attachToDom(this._mouseZoneManager); - + this.screenElement = document.createElement('div'); + this.screenElement.classList.add('xterm-screen'); // Create the container that will hold helpers like the textarea for // capturing DOM Events. Then produce the helpers. this.helperContainer = document.createElement('div'); this.helperContainer.classList.add('xterm-helpers'); - fragment.appendChild(this.helperContainer); + this.screenElement.appendChild(this.helperContainer); + fragment.appendChild(this.screenElement); + + this._mouseZoneManager = new MouseZoneManager(this); + this.on('scroll', () => this._mouseZoneManager.clearAll()); + this.linkifier.attachToDom(this._mouseZoneManager); this.textarea = document.createElement('textarea'); this.textarea.classList.add('xterm-helper-textarea'); @@ -735,7 +739,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT button = getButton(ev); // get mouse coordinates - pos = self.mouseHelper.getRawByteCoords(ev, self.element, self.charMeasure, self.options.lineHeight, self.cols, self.rows); + pos = self.mouseHelper.getRawByteCoords(ev, self.screenElement, self.charMeasure, self.options.lineHeight, self.cols, self.rows); if (!pos) return; sendEvent(button, pos); @@ -761,7 +765,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT // ^[[M 3<^[[M@4<^[[M@5<^[[M@6<^[[M@7<^[[M#7< function sendMove(ev: MouseEvent): void { let button = pressed; - let pos = self.mouseHelper.getRawByteCoords(ev, self.element, self.charMeasure, self.options.lineHeight, self.cols, self.rows); + let pos = self.mouseHelper.getRawByteCoords(ev, self.screenElement, self.charMeasure, self.options.lineHeight, self.cols, self.rows); if (!pos) return; // buttons marked as motions diff --git a/src/Types.ts b/src/Types.ts index 599299e3d..3ea9fce69 100644 --- a/src/Types.ts +++ b/src/Types.ts @@ -85,6 +85,7 @@ export interface IInputHandlingTerminal extends IEventEmitter { } export interface IViewport { + scrollBarWidth: number; syncScrollArea(): void; onWheel(ev: WheelEvent): void; onTouchStart(ev: TouchEvent): void; @@ -175,6 +176,7 @@ export interface ILinkHoverEvent { } export interface ITerminal extends PublicTerminal, IElementAccessor, IBufferAccessor, ILinkifierAccessor { + screenElement: HTMLElement; selectionManager: ISelectionManager; charMeasure: ICharMeasure; renderer: IRenderer; @@ -188,6 +190,7 @@ export interface ITerminal extends PublicTerminal, IElementAccessor, IBufferAcce buffers: IBufferSet; isFocused: boolean; mouseHelper: IMouseHelper; + viewport: IViewport; bracketedPasteMode: boolean; applicationCursor: boolean; diff --git a/src/Viewport.ts b/src/Viewport.ts index 59dc304d4..35a2aa689 100644 --- a/src/Viewport.ts +++ b/src/Viewport.ts @@ -7,11 +7,14 @@ import { IColorSet } from './renderer/Types'; import { ITerminal, IViewport } from './Types'; import { CharMeasure } from './utils/CharMeasure'; +const FALLBACK_SCROLL_BAR_WIDTH = 15; + /** * Represents the viewport of a terminal, the visible area within the larger buffer of output. * Logic for the virtual scroll bar is included in this object. */ export class Viewport implements IViewport { + public scrollBarWidth: number = 0; private currentRowHeight: number = 0; private lastRecordedBufferLength: number = 0; private lastRecordedViewportHeight: number = 0; @@ -31,6 +34,10 @@ export class Viewport implements IViewport { private scrollArea: HTMLElement, private charMeasure: CharMeasure ) { + // Measure the width of the scrollbar. If it is 0 we can assume it's an OSX overlay scrollbar. + // Unfortunately the overlay scrollbar would be hidden underneath the screen element in that case, + // therefore we account for a standard amount to make it visible + this.scrollBarWidth = (this.viewportElement.offsetWidth - this.scrollArea.offsetWidth) || FALLBACK_SCROLL_BAR_WIDTH; this.viewportElement.addEventListener('scroll', this.onScroll.bind(this)); // Perform this async to ensure the CharMeasure is ready. @@ -48,13 +55,8 @@ export class Viewport implements IViewport { private refresh(): void { if (this.charMeasure.height > 0) { this.currentRowHeight = this.terminal.renderer.dimensions.scaledCellHeight / window.devicePixelRatio; - - if (this.lastRecordedViewportHeight !== this.terminal.renderer.dimensions.canvasHeight) { - this.lastRecordedViewportHeight = this.terminal.renderer.dimensions.canvasHeight; - this.viewportElement.style.height = this.lastRecordedViewportHeight + 'px'; - } - - const newBufferHeight = Math.round(this.currentRowHeight * this.lastRecordedBufferLength); + this.lastRecordedViewportHeight = this.viewportElement.offsetHeight; + const 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'; diff --git a/src/addons/fit/fit.ts b/src/addons/fit/fit.ts index 75e854d97..f6f593dcf 100644 --- a/src/addons/fit/fit.ts +++ b/src/addons/fit/fit.ts @@ -28,17 +28,22 @@ export function proposeGeometry(term: Terminal): IGeometry { } const parentElementStyle = window.getComputedStyle(term.element.parentElement); const parentElementHeight = parseInt(parentElementStyle.getPropertyValue('height')); - const parentElementWidth = Math.max(0, parseInt(parentElementStyle.getPropertyValue('width')) - 17); + const parentElementWidth = Math.max(0, parseInt(parentElementStyle.getPropertyValue('width'))); const elementStyle = window.getComputedStyle(term.element); - const elementPaddingVer = parseInt(elementStyle.getPropertyValue('padding-top')) + parseInt(elementStyle.getPropertyValue('padding-bottom')); - const elementPaddingHor = parseInt(elementStyle.getPropertyValue('padding-right')) + parseInt(elementStyle.getPropertyValue('padding-left')); + const 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')) + }; + const elementPaddingVer = elementPadding.top + elementPadding.bottom; + const elementPaddingHor = elementPadding.right + elementPadding.left; const availableHeight = parentElementHeight - elementPaddingVer; - const availableWidth = parentElementWidth - elementPaddingHor; + const availableWidth = parentElementWidth - elementPaddingHor - (term).viewport.scrollBarWidth; const geometry = { cols: Math.floor(availableWidth / (term).renderer.dimensions.actualCellWidth), rows: Math.floor(availableHeight / (term).renderer.dimensions.actualCellHeight) }; - return geometry; } diff --git a/src/input/MouseZoneManager.ts b/src/input/MouseZoneManager.ts index 79c02b5f2..3ab86e7c1 100644 --- a/src/input/MouseZoneManager.ts +++ b/src/input/MouseZoneManager.ts @@ -169,7 +169,7 @@ export class MouseZoneManager implements IMouseZoneManager { } private _findZoneEventAt(e: MouseEvent): IMouseZone { - const coords = this._terminal.mouseHelper.getCoords(e, this._terminal.element, this._terminal.charMeasure, this._terminal.options.lineHeight, this._terminal.cols, this._terminal.rows); + const coords = this._terminal.mouseHelper.getCoords(e, this._terminal.screenElement, this._terminal.charMeasure, this._terminal.options.lineHeight, this._terminal.cols, this._terminal.rows); if (!coords) { return null; } diff --git a/src/renderer/Renderer.ts b/src/renderer/Renderer.ts index 11c247332..3792a9dab 100644 --- a/src/renderer/Renderer.ts +++ b/src/renderer/Renderer.ts @@ -38,10 +38,10 @@ export class Renderer extends EventEmitter implements IRenderer { } this._renderLayers = [ - new TextRenderLayer(this._terminal.element, 0, this.colorManager.colors, this._terminal.options.allowTransparency), - new SelectionRenderLayer(this._terminal.element, 1, this.colorManager.colors), - new LinkRenderLayer(this._terminal.element, 2, this.colorManager.colors, this._terminal), - new CursorRenderLayer(this._terminal.element, 3, this.colorManager.colors) + new TextRenderLayer(this._terminal.screenElement, 0, this.colorManager.colors, this._terminal.options.allowTransparency), + new SelectionRenderLayer(this._terminal.screenElement, 1, this.colorManager.colors), + new LinkRenderLayer(this._terminal.screenElement, 2, this.colorManager.colors, this._terminal), + new CursorRenderLayer(this._terminal.screenElement, 3, this.colorManager.colors) ]; this.dimensions = { scaledCharWidth: null, @@ -120,6 +120,10 @@ export class Renderer extends EventEmitter implements IRenderer { this._terminal.refresh(0, this._terminal.rows - 1); } + // Resize the screen + this._terminal.screenElement.style.width = `${this.dimensions.canvasWidth + this._terminal.viewport.scrollBarWidth}px`; + this._terminal.screenElement.style.height = `${this.dimensions.canvasHeight}px`; + this.emit('resize', { width: this.dimensions.canvasWidth, height: this.dimensions.canvasHeight diff --git a/src/utils/TestUtils.test.ts b/src/utils/TestUtils.test.ts index d53c8c58b..d48ad12ca 100644 --- a/src/utils/TestUtils.test.ts +++ b/src/utils/TestUtils.test.ts @@ -80,6 +80,7 @@ export class MockTerminal implements ITerminal { isFocused: boolean; options: ITerminalOptions = {}; element: HTMLElement; + screenElement: HTMLElement; rowContainer: HTMLElement; selectionContainer: HTMLElement; selectionManager: ISelectionManager; @@ -96,6 +97,7 @@ export class MockTerminal implements ITerminal { scrollback: number; buffers: IBufferSet; buffer: IBuffer; + viewport: IViewport; applicationCursor: boolean; handler(data: string): void { throw new Error('Method not implemented.'); @@ -308,6 +310,7 @@ export class MockRenderer implements IRenderer { } export class MockViewport implements IViewport { + scrollBarWidth: number = 0; onThemeChanged(colors: IColorSet): void { throw new Error('Method not implemented.'); } diff --git a/src/xterm.css b/src/xterm.css index b3ee50f0f..3edaf3ff5 100644 --- a/src/xterm.css +++ b/src/xterm.css @@ -96,9 +96,18 @@ background-color: #000; overflow-y: scroll; cursor: default; + position: absolute; + right: 0; + left: 0; + top: 0; + bottom: 0; } -.xterm canvas { +.xterm .xterm-screen { + position: relative; +} + +.xterm .xterm-screen canvas { position: absolute; left: 0; top: 0; From 760837e5cb46e9aab6dd9d25c9c72104c8dbc559 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 6 Feb 2018 07:25:54 -0800 Subject: [PATCH 55/58] Mark enableBold setting as deprecated --- typings/xterm.d.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/typings/xterm.d.ts b/typings/xterm.d.ts index 1d14243ef..cd59b81dd 100644 --- a/typings/xterm.d.ts +++ b/typings/xterm.d.ts @@ -55,6 +55,8 @@ declare module 'xterm' { /** * Whether to enable the rendering of bold text. + * + * @deprecated Use fontWeight and fontWeightBold instead. */ enableBold?: boolean; From 1dbe7b3a8cb17014e7f48127228c8329df84d10b Mon Sep 17 00:00:00 2001 From: Paris Kasidiaris Date: Fri, 9 Feb 2018 08:42:39 +0000 Subject: [PATCH 56/58] Bump version to 3.1.0 Signed-off-by: Paris Kasidiaris --- AUTHORS | 13 +++++++++++++ package.json | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index 1bd4c87d3..47328bc95 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,12 +1,15 @@ List of xterm.js contributors. Updated before every release. +Adrian Labbé Aleksandr Andrienko Aleksandr Andriienko Alessandro Nadalin Alexander Olsson Alexey Kontsevoy +Andres Mejia Anish Athalye Anthony Lapenna +Antonin Stefanutti Antonis Kalipetis Anton Skshidlevsky Anton Yurovskykh @@ -19,6 +22,7 @@ Bill Church Bob Reid bottleofwater Brian Mock +Bruno Ribeiro Bruno Ribeito Carson Anderson CHaBou @@ -26,6 +30,7 @@ Christian Budde Christensen Christof Marti Christopher Jeffrey coderaiser +Damien Tournoud Dan Brown Daniel Griffen Daniel Imms @@ -46,20 +51,25 @@ imoses InDieTasten irokas Jakob Gillich +Jan Kuri Jean Bruenn Jeremy Danyow +Jianhui Zhao Joao Moreno Joao Moreno Johannes Zellner Jon Masters Jörg Breitbart +Justin Luk Justin Mecham Kirill Merkushev +Krasimir Tsonev Luca Lucian Buzzo Lukas Drgon Maël Nison Marc Dumais +Markus F.X.J. Oberhumer Martin Chloride Martin Koppehel Martin Wang @@ -75,10 +85,12 @@ Paris Kasidiaris Peter Baumgarten Rick Baker runarberg +Saad Malik Samuel Williams Saswat Das Saul Costa Shuanglei Tao +sitzmar Steven Silvester stuicey t-amqi @@ -90,3 +102,4 @@ Tyler Jewell Vincent Woo yutaka YuviPanda +ZHAO Xudong diff --git a/package.json b/package.json index 1a718fbc2..079333de1 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "xterm", "description": "Full xterm terminal, in your browser", - "version": "3.1.0-master", + "version": "3.1.0", "ignore": [ "demo", "test", From b5ba9ae771bbe901431826fb8e0b8663add12433 Mon Sep 17 00:00:00 2001 From: Oleksandr Andriienko Date: Mon, 12 Feb 2018 12:30:26 +0200 Subject: [PATCH 57/58] Fix xterm.js in headless mode yields TypeError on resize Signed-off-by: Oleksandr Andriienko --- src/Terminal.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Terminal.ts b/src/Terminal.ts index 1bc9cfbb0..9f8bc4337 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -1889,7 +1889,9 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT this.rows = y; this.buffers.setupTabStops(this.cols); - this.charMeasure.measure(this.options); + if (this.charMeasure) { + this.charMeasure.measure(this.options); + } this.refresh(0, this.rows - 1); this.emit('resize', {cols: x, rows: y}); From 64ed8309a1cfecc87561351b406e0aad04e2170c Mon Sep 17 00:00:00 2001 From: Matthew James Date: Mon, 12 Feb 2018 20:26:09 +0000 Subject: [PATCH 58/58] Added FreeMAN to list of real-world uses --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f1bb422a5..cdaf0d71a 100644 --- a/README.md +++ b/README.md @@ -110,7 +110,7 @@ Xterm.js is used in several world-class applications to provide great terminal e - [**Selenoid UI**](https://github.com/aerokube/selenoid-ui): Simple UI for the scallable golang implementation of Selenium Hub named Selenoid. We use XTerm for streaming logs over websockets from docker containers. - [**Portainer**](https://portainer.io): Simple management UI for Docker. - [**SSHy**](https://github.com/stuicey/SSHy): HTML5 Based SSHv2 Web Client with E2E encryption utilising `xterm.js`, SJCL & websockets. -- [**JupyterLab**](https://github.com/jupyterlab/jupyterlab): An extensible +- [**JupyterLab**](https://github.com/jupyterlab/jupyterlab): An extensible computational environment for Jupyter, supporting interactive data science and scientific computing across all programming languages. - [**Theia**](https://github.com/theia-ide/theia): Theia is a cloud & desktop IDE framework implemented in TypeScript. - [**Opshell**](https://github.com/ricktbaker/opshell) Ops Helper tool to make life easier working with AWS instances across multiple organizations. @@ -126,6 +126,7 @@ computational environment for Jupyter, supporting interactive data science and s - [**Pisth**](https://github.com/ColdGrub1384/Pisth): An SFTP and SSH client for iOS - [**abstruse**](https://github.com/bleenco/abstruse): Abstruse CI is a continuous integration platform based on Node.JS and Docker. - [**Microsoft SQL Operations Studio**](https://github.com/Microsoft/sqlopsstudio): A data management tool that enables working with SQL Server, Azure SQL DB and SQL DW from Windows, macOS and Linux +- [**FreeMAN**](https://github.com/matthew-matvei/freeman): A free, cross-platform file manager for power users Do you use xterm.js in your application as well? Please [open a Pull Request](https://github.com/sourcelair/xterm.js/pulls) to include it here. We would love to have it in our list.